以太坊白皮書解析

@git

導讀概念

以太坊中常見的概念:
塊:塊是存儲在區塊鏈中的單個事務或數據片斷。
區塊鏈:區塊鏈是一個不斷增加的記錄列表(「鏈」),稱爲塊,稱爲塊,按時間順序連接並使用加密技術進行保護。
區塊鏈網絡:區塊鏈網絡和區塊鏈是可互換使用的術語。它們表明了從結構自己到它所屬網絡的整個區塊鏈。
權力下放:參與者共同合做以在不依賴中央機構的狀況下驗證交易的概念。
參與者:擁有區塊鏈副本並驗證網絡中交易的客戶。
時間戳:建立塊的時間決定了它在區塊鏈上的位置。
交易數據:要安全存儲在塊中的信息。
哈希:經過組合塊自己內的全部內容(也稱爲數字指紋)生成的惟一代碼。也可解讀爲從特定輸入生成的計算字母和數字字符串的一種算法
Previous Hash:每一個塊在其哈希以前都有一個對塊的引用。這就是區塊鏈的獨特之處,由於若是一個塊被篡改,這個連接就會被破壞。
Genesis Block:創世塊是區塊鏈上的第一個區塊,一般硬編碼到區塊鏈結構中。做爲區塊鏈的第一個區塊,它沒有前一個哈希的連接。
交易:區塊鏈網絡參與者之間的價值交換。
共識:贊成區塊鏈網絡上的交易的過程的機制。
工做量證實:區塊鏈中的一項安全功能。後續詳細說明
礦工:計算工做證實以挖掘新區塊的特殊參與者。
Nonce:礦工猜想的一個數字,當與塊結合時產生一個可接受的哈希值。
最長鏈:最可信賴的鏈,在計算工做量時完成了最大量的計算工做。程序員

以太坊是一個全新開放的區塊鏈平臺,它容許任何人在平臺中創建和使用經過區塊鏈技術運行的去中心化應用
和比特比相同點:就像比特幣同樣,以太坊不受任何人控制,也不歸任何人全部——它是一個開放源代碼項目,由全球範圍內的不少人共同建立。
和比特幣的不一樣點:和比特幣協議有所不一樣的是,以太坊的設計十分靈活,極具適應性。在以太坊平臺上創立新的應用十分簡便.github

歷史沿革

去中心化早在幾十年前就已經被提出->1980.1990匿名電子現金協議(仍然依賴於一箇中心化的中介機構)->戴偉的 b-money 首次引入了經過解決計算難題和去中心化共識創造貨幣的思想(該建議並未給出如何實現去中心化共識的具體方法)
->2005 年,芬尼引入了「可重複使用的工做量證實機制」概念,它同時使用 b-money 的思想和 Adam Back提出的計算困難的哈希現金( Hashcash)難題來創造密碼學貨幣(仍然依賴於可信任的計算做爲後端)算法

上述發展面臨問題:
比特幣之前的全部電子貨幣協議所遇到的主要障礙是,儘管對如何建立安全的拜占庭問題容錯多方共識系統的研究已經歷時多年,可是上述協議只解決了問題的一半。這些協議假設系統的全部參與者是已知的,併產生如「若是有 N 方參與到系統中,那麼系統可
以容忍 N/4 的惡意參與者
」這樣形式的安全邊界。然而這個假設的問題在於,在匿名的狀況下,系統設置的安全邊界容易遭受女巫攻擊,由於一個攻擊者能夠在一臺服務器或者僵屍網絡上建立數以千計的節點,從而單方面確保擁有多數份額。數據庫

PS:若是網絡中存在一個惡意節點,那麼同一個惡意節點能夠具備多重身份,就如電影 <女巫> 的女主角均可以分裂出16個身份,那麼惡意節點比它還能分。這一分可好,原來須要備份到多個節點的數據被欺騙地備份到了同一個惡意節點(該惡意節點假裝成多重身份),這就是女巫攻擊。 編程

中本聰的理念

將一個很是簡單的基於節點的去中心化共識協議與工做量證實機制結合在一塊兒。節點經過工做量證實機制得到參與到系統的權利,每十分鐘將交易打包到「區塊」中,從而建立出不斷增加的區塊鏈。擁有大量算力的節點有更大的影響力,但得到比整個網絡更多的算力比建立一百萬個節點困可貴多。 儘管比特幣的區塊鏈模型很簡陋,可是他的思路真的解決了上述的發展問題。實踐證實它已經足夠好用了,在將來五年,它將成爲全世界兩百個以上的貨幣和協議的基石。後端

做爲狀態轉換系統的比特幣

比特幣帳本能夠被認爲是一個狀態轉換系統該系統包括全部現存的比特幣全部權狀態和「狀態轉換函數」。狀態轉換函數以當前狀態和交易爲輸入,輸出新的狀態.
在標準的銀行系統中,狀態就是一個資產負債表,一個從 A 帳戶向 B 帳戶轉帳 X 美圓的請求是一筆交易,狀態轉換函數將從 A 帳戶中減去 X 美圓,向 B 帳戶增長 X 美圓。若是 A 帳戶的餘額小於 X 美圓,狀態轉換函數就會返回錯誤提示。
狀態轉換函數原型爲:瀏覽器

APPLY(S,TX) > S’ or ERROR

具體以下狀態轉換函數以下:安全

APPLY({ Alice: $50, Bob: $50 },」send $20 from Alice to Bob」) = { Alice:$30,Bob: $70 }
APPLY({ Alice: $50, Bob: $50 },」send $70 from Alice to Bob」) = ERROR

在比特幣的設計中,並無帳戶概念(這是後來纔有的概念,HyperLedger 和Ethereum 一開始並無採用 UTXO[Unspent Transaction Output],如今前者已經切換回 UTXO,後者打算增長這個選項。)。

爲了理解比特幣的狀態轉換關係,須要對一下進行解釋:
1.比特幣系統的「狀態」是全部已經被挖出的、沒有花費的比特幣(UTXO)的集合。
2.一筆交易包括一個或多個輸入和一個或多個輸出。
3.每一個輸出包含一個新的加入到狀態中的 UTXO。

在比特幣系統中,狀態轉換函數 APPLY(S,TX)->S‟大致上能夠以下定義:

  1. 交易的每一個輸入:
    若是引用的 UTXO 不存在於如今的狀態中( S),返回錯誤提示 (防止交易的發送者花費不存在的比特幣,聯想銀行系統的轉換函數)
    若是簽名與 UTXO 全部者的簽名不一致,返回錯誤提示(防止交易的發送者花費其餘人的比特幣。)
  2. 若是全部的 UTXO 輸入面值總額小於全部的 UTXO 輸出面值總額,返回錯誤提示(確保價值守恆。)
  3. 返回新狀態 S‟,新狀態 S‟中移除了全部的輸入 UTXO,增長了全部的輸出 UTXO。

下面用圖示加以解析:(圖摘自幣學院)
咱們假設一個這樣的場景:
張三挖到12.5 枚比特幣。過了幾天,他把其中 2.5 枚支付給李四。又過了幾天,他和李四各出資 2.5 比特幣湊成 5 比特幣付給王五。
若是是基於帳戶的設計,張、李、王三人在數據庫中各有一個帳戶,則他們三人的帳戶變化以下圖所示:


解釋:
上圖第一個交易 #1001 號交易是 coinbase 交易。比特幣是礦工挖出來的。當一個礦機費盡九牛二虎之力找到一個合格的區塊以後,它就得到一個特權,可以創造一個 coinbase 交易,在其中放入一筆新錢,而且在交易輸出的收款人地址一欄,堂堂正正的寫上本身的地址。
過了幾天,張三打算付 2.5 個比特幣給李四,張三就發起一#2001號交易,這個交易的資金來源項寫着「#1001(1)」,也就是 #1001 號交易——張三挖出礦的那個 coinbase 交易——的第一項 UTXO。而後在本交易的交易輸出 UTXO 項中,把2.5個比特幣的收款人地址設爲李四的地址。

請注意,這一筆交易必須將前面產生那一項 12.5 個比特幣的輸出項所有消耗,而因爲張三隻打算付給李四 2.5 個比特幣,爲了要消耗剩下的10比特幣,他只好把剩餘的那 10 個比特幣支付給本身,這樣才能符合輸入與輸出配平的規則。

再過幾天,張三和李四打算AA制合起來給王五付 5 枚比特幣。那麼張三或李四發起 #3001 號交易,在交易輸入部分,有兩個資金來源,分別是#2001(1) 和 #2001(2),表明第 #2001 號交易的第 (1) 和第 (2) 項 UTXO。而後在這個交易的輸出部分裏如法炮製,給王五5比特幣,把張三剩下的 7.5 比特幣發還給本身。之後王五若要再花他這5比特幣,就必須在他的交易裏註明資金的來源是 #3001(1)。

當咱們說張三擁有 10 枚比特幣的時候,我其實是說,當前區塊鏈帳本中,有若干筆交易的 UTXO 項收款人寫的是張三的地址,而這些 UTXO 項的數額總和是 10。要知道本身的一大堆地址裏一共收了多少 UTXO,人是算不過來的,須要由比特幣錢包代爲跟蹤計算。

以上即爲 UTXO 的一個簡要的介紹。

白皮書中作了一個簡要的例子:

假設 Alice 想給 Bob 發送 11.7BTC。事實上, Alice 不可能正好有 11.7BTC。假設,她能獲得的最小數額比特幣的方式是: 6+4+2=12。因此,她能夠建立一筆有 3個輸入, 2 個輸出的交易。第一個輸出的面值是 11.7BTC,全部者是 Bob( Bob的比特幣地址),第二個輸出的面值是 0.3BTC,全部者是 Alice 本身,也就是找零。

挖礦

咱們想把比特幣系統建成爲去中心化的貨幣系統,爲了確保每一個人都贊成交易的順序,咱們須要將狀態轉換系統與一個共識系統(這裏指的是工做量機制)結合起來。
比特幣的去中心化共識進程要求網絡中的節點不斷嘗試將交易打包成「區塊」。
網絡被設計爲大約每十分鐘產生一個區塊,每一個區塊包含一個時間戳、一個隨機數(Nonce)、一個對上一個區塊的引用(即哈希)和上一區塊生成以來發生的全部交易列表。
這樣隨着時間流逝就建立出了一個持續增加的區塊鏈,它不斷地更新,從而可以表明比特幣帳本的最新狀態。

依照這個範式,檢查一個區塊是否有效的算法以下:

  1. 檢查區塊引用的上一個區塊是否存在且有效。
  2. 檢查區塊的時間戳是否晚於之前的區塊的時間戳,並且早於將來 2 小時。
  3. 檢查區塊的工做量證實是否有效。
  4. 將上一個區塊的最終狀態賦於 S[0]。
  5. 假設 TX 是區塊的交易列表,包含 n 筆交易。對於屬於 0……n-1 的全部 i,進行狀態轉換 S[i+1] = APPLY(S[i],TX[i])。若是任何一筆交易 i 在狀態轉換中出錯,退出程序,返回錯誤。
  6. 返回正確,狀態 S[n]是這一區塊的最終狀態。

另外,須要注意礦工將交易收錄進區塊的順序。若是一個區塊中有A、 B 兩筆交易, B 花費的是 A 建立的 UTXO,若是 A 在 B 之前,這個區塊是有效的,不然,這個區塊是無效的。

「工做量證實」:對每一個區塊進行 SHA256 哈希處理,將獲得的哈希視爲長度爲 256 比特的數值,該數值必須小於不斷動態調整的目標數值。工做量證實的目的是使區塊的建立變得困難,從而阻止女巫攻擊者惡意從新生成區塊鏈。由於 SHA256 是徹底不可預測的僞隨機函數,建立有效區塊的惟一方法就是簡單地不斷試錯,不斷地增長隨機數的數值,查看新的哈希數值是否小於目標數值。若是當前的目標數值是 2^192,就意味着平均須要嘗試 2^64 次才能生成有效的區塊。通常而言,比特幣網絡每隔 2016 個區塊從新設定目標數值,保證平均每十分鐘生成一個區塊。爲了對礦工的計算工做進行獎勵,每個成功生成區塊的礦工有權在區塊中包含一筆憑空發給他們本身 25BTC 的交易。另外,若是交易的輸入大於輸出,差額部分就做爲「交易費用」付給礦工。順便提一下,對礦工的獎勵是比特幣發行的惟一機制,創世狀態中並無比特幣。

爲了更好地理解挖礦的目的,讓咱們分析比特幣網絡出現惡意攻擊者時會發生什麼。由於比特幣的密碼學基礎是很是安全的,因此攻擊者會選擇攻擊沒有被密碼學直接保護的部分:交易順序。攻擊者的策略很是簡單:

  1. 向賣家發送 100BTC 購買商品(尤爲是無需郵寄的電子商品)。
  2. 等待直至商品發出。
  3. 建立另外一筆交易,將相同的 100BTC 發送給本身的帳戶。
  4. 使比特幣網絡相信發送給本身帳戶的交易是最早發出的。

攻擊的圖示以下(本身畫的,勿噴。。):

一旦步驟( 1)發生,幾分鐘後礦工將把這筆交易打包到區塊,假設是第 270000個區塊。大約一個小時之後,在此區塊後面將會有五個區塊,每一個區塊間接地指向這筆交易,從而確認這筆交易。這時賣家收到貨款,並向買家發貨。由於咱們假設這是數字商品,攻擊者能夠即時收到貨。如今,攻擊者建立另外一筆交易,將相同的 100BTC 發送到本身的帳戶。若是攻擊者只是向全網廣播這一消息,這一筆交易不會被處理。礦工會運行狀態轉換函數 APPLY(S,TX),發現這筆交易將花費已經不在狀態中的 UTXO。因此,攻擊者會對區塊鏈進行分叉,將第269999 個區塊做爲父區塊從新生成第 270000 個區塊,在此區塊中用新的交易取代舊的交易。由於區塊數據是不一樣的,這要求從新進行工做量證實。另外,由於攻擊者生成的新的第 270000 個區塊有不一樣的哈希,因此原來的第 270001 到第 270005的區塊不指向它,所以原有的區塊鏈和攻擊者的新區塊是徹底分離的。在發生區塊鏈分叉時,區塊鏈長的分支被認爲是誠實的區塊鏈,合法的的礦工將會沿着原有的第 270005 區塊後挖礦,只有攻擊者一人在新的第 270000 區塊後挖礦。攻擊者爲了使得他的區塊鏈最長,他須要擁有比除了他之外的全網更多的算力來追趕(即 51%攻擊)。也就是說,攻擊者從新生成6個Nonce的速度和全網絡計算的速度必定相比起來,是慢了不少的。

默克爾樹

對於默克爾樹的介紹以下:

默克爾樹是一種二叉樹,由一組葉節點、一組中間節點和一個根節點構成。最下面的大量的葉節點包含基礎數據,每一箇中間節點是它的兩個子節點的哈希,根節點也是由它的兩個子節點的哈希,表明了默克爾樹的頂部。默克爾樹的目的是容許區塊的數據能夠零散地傳送:節點能夠從一個源下載區塊頭,從另外的源下載與其有關的樹的其它部分,而依然可以確認全部的數據都是正確的。之因此如此是由於哈希向上的擴散:若是一個惡意用戶嘗試在樹的下部加入一個僞造的交易,所引發的改動將致使樹的上層節點的改動,以及更上層節點的改動,最終致使根節點的改動以及區塊哈希的改動,這樣協議就會將其記錄爲一個徹底不一樣的區塊(幾乎能夠確定是帶着不正確的工做量證實的)。

左:僅提供默克爾樹( Merkle tree)上的少許節點已經足夠給出分支的合法證實。
右:任何對於默克爾樹的任何部分進行改變的嘗試都會最終致使鏈上某處的不一致。(圖:摘自白皮書)

比特幣系統的一個重要的可擴展特性是:它的區塊存儲在多層次的數據結構中。
一個區塊的哈希實際上只是區塊頭的哈希,區塊頭是包含時間戳、隨機數、上個區塊哈希和存儲了全部的區塊交易的默克爾樹的根哈希的長度大約爲 200 字節的一段數據。
默克爾樹協議對比特幣的長期持續性能夠說是相當重要的。在 2014 年 4 月,比特幣網絡中的一個全節點-存儲和處理全部區塊的所有數據的節點-須要佔用15GB 的內存空間,並且還以每月超過 1GB 的速度增加。目前,這一存儲空間對臺式計算機來講尚可接受,可是手機已經負載不了如此巨大的數據了。將來只有商業機構和愛好者纔會充當完整節點。簡化支付確認( SPV)協議容許另外一種節點存在,這樣的節點被成爲「輕節點」,它下載區塊頭,使用區塊頭確認工做量證實,而後只下載與其交易相關的默克爾樹「分支」。這使得輕節點只要下載整個區塊鏈的一小部分,就能夠安全地肯定任何一筆比特幣交易的狀態和帳戶的當前餘額。

其它的區塊鏈應用

  • 域名幣( namecoin) - 建立於 2010 年,被稱爲去中心化的名稱註冊數據庫。利用區塊鏈解決帳戶重名問題。
  • 彩色幣( Colored coins) - 彩色幣的目的是爲人們在比特幣區塊鏈上建立本身的數字貨幣,或者,在更重要的通常意義上的貨幣 – 數字令牌提供服務。

    元幣( Metacoins)

  1. 採用了不一樣的狀態轉換函數 APPLY->爲建立任意的、先進的不能在比特幣系統中實現的密碼學貨幣協議提供了一個簡單的解決方法
  2. 創建共識困難
  3. 沒有繼承比特幣能夠進行簡化確認支付( SPV) 的特性
    另外,咱們預測去中心化共識技術的應用將會服從冪律分佈,大多數的應用過小不足以保證自由區塊鏈的安全,咱們還注意到大量的去中心化應用,尤爲是去中心化自治組織,須要進行應用之間的交互。

腳本

即便不對比特幣協議進行擴展,它也能在必定程度上實現」智能合約」。比特幣的UTXO 能夠被不僅一個公鑰擁有,也能夠被用基於堆棧的編程語言所編寫的更加複雜的腳本所擁有。在這一模式下,花費這樣的 UTXO,必須提供知足腳本的數據。事實上,基本的公鑰全部權機制也是經過腳本實現的:腳本將橢圓曲線簽名做爲輸入,驗證交易和擁有這一 UTXO 的地址,若是驗證成功,返回 1,不然返回 0。更加複雜的腳本用於其它不一樣的應用狀況。例如,人們能夠建立要求集齊三把私鑰中的兩把才能進行交易確認的腳本(多重簽名),對公司帳戶、儲蓄帳戶和某些商業代理來講,這種腳本是很是有用的。腳本也能用來對解決計算問題的用戶發送獎勵。

然而,比特幣系統的腳本語言存在一些嚴重的限制:

  • 缺乏圖靈完備性 – 這就是說,儘管比特幣腳本語言能夠支持多種計算,可是它不能支持全部的計算。最主要的缺失是循環語句。不支持循環語句的目的是避免交易確認時出現無限循環。理論上,對於腳本程序員來講,這是能夠克服的障礙,由於任何循環均可以用屢次重複 if 語句的方式來模擬,可是這樣作會致使腳本空間利用上的低效率,例如,實施一個替代的橢圓曲線簽名算法可能將須要 256次重複的乘法,而每次都須要單獨編碼。
  • 價值盲( Value-blindness)。 UTXO 腳本不能爲帳戶的取款額度提供精細的控制。例如,預言機合約( oracle contract)的一個強大應用是對衝合約, A 和 B各自向對衝合約中發送價值 1000 美圓的比特幣, 30 天之後,腳本向 A 發送價值 1000 美圓的比特幣,向 B 發送剩餘的比特幣。雖然實現對衝合約須要一個預言機決定一比特幣值多少美圓,與如今徹底中心化的解決方案相比,這一機制已經在減小信任和基礎設施方面有了巨大的進步。然而,由於 UTXO是不可分割的,爲實現此合約,惟一的方法是很是低效地採用許多有不一樣面值的UTXO並使預言機挑出正確的 UTXO 發送給 A 和 B。
    ps:對衝合約

    例如:甲客戶在2009年最後一個交易日在期貨市場買開倉大豆1009合約100手;乙客戶在2010年第一個交易日賣開倉大豆1009合約100手。第二天在期貨市場把甲客戶把買進開倉的100手大豆合約作賣出平倉,乙客戶把賣出開倉100手大豆合約作買入平倉。
    甲乙雙方互爲交易對手交易倉單發生的平倉交易叫作對衝合約。

  • 缺乏狀態 – UTXO 只能是已花費或者未花費狀態,這就沒有給須要任何其它內部狀態的多階段合約或者腳本留出生存空間。這使得實現多階段期權合約、去中心化的交換要約或者兩階段加密承諾協議(對確保計算獎勵很是必要)很是困難。這也意味着 UTXO 只能用於創建簡單的、一次性的合約,而不是例如去中心化組織這樣的有着更加複雜的狀態的合約,使得元協議難以實現。二元狀態與價值盲結合在一塊兒意味着另外一個重要的應用-取款限額-是不可能實現的。
    ps:取款限額:央行規定人民幣天天只能取5萬如下,不含5萬,5萬以上就得預定。若是是美圓,1萬以上就需預定。
  • 區塊鏈盲( Blockchain-blindness) - UTXO 看不到區塊鏈的數據,例如隨機數和上一個區塊的哈希。這一缺陷剝奪了腳本語言所擁有的基於隨機性的潛在價值,嚴重地限制了博彩等其它領域應用。

基於以上,以太坊考察了在密碼學貨幣上創建高級應用的三種方法:創建一個新的區塊鏈,在比特幣區塊鏈上使用腳本,在比特幣區塊鏈上創建元幣協議。
創建新區塊鏈的方法能夠自由地實現任意的特性,成本是開發時間和培育努力。使用腳本的方法很是容易實現和標準化,可是它的能力有限。元幣協議儘管很是容易實現,可是存在擴展性差的缺陷。
在以太坊系統中,其目的是創建一個可以同時具備這三種模式的全部優點的通用框架。

以太坊

以太坊的目的是基於腳本、競爭幣和鏈上元協議( on-chain meta-protocol)概念進行整合和提升,使得開發者可以建立任意的基於共識的、可擴展的、標準化的、特性完備的、易於開發的和協同的應用。以太坊經過創建終極的抽象的基礎層-內置有圖靈完備編程語言的區塊鏈-使得任何人都可以建立合約和去中心化應用,並在其中設立他們自由定義的全部權規則、交易方式和狀態轉換函數。

以太坊帳戶

以太坊系統中,狀態是由被稱爲「帳戶」(每一個帳戶由一個 20 字節的地址)的對象和在兩個帳戶之間轉移價值和信息的狀態轉換構成的。以太坊的帳戶包含四個部分:

  • 隨機數,用於肯定每筆交易只能被處理一次的計數器
  • 帳戶目前的以太幣餘額
  • 帳戶的合約代碼,若是有的話
  • 帳戶的存儲(默認爲空)

以太幣( Ether)是以太坊內部的主要加密燃料,用於支付交易費用。通常而言,以太坊有兩種類型的帳戶:外部全部的帳戶(由私鑰控制的)和合約帳戶(由合約代碼控制)。外部全部的帳戶沒有代碼,人們能夠經過建立和簽名一筆交易從一個外部帳戶發送消息。每當合約帳戶收到一條消息,合約內部的代碼就會被激活,容許它對內部存儲進行讀取和寫入,和發送其它消息或者建立合約。

消息和交易

以太坊的消息在某種程度上相似於比特幣的交易,可是二者之間存在三點重要的不一樣。

  1. 以太坊的消息能夠由外部實體或者合約建立,然而比特幣的交易只能從外部建立。
  2. 以太坊消息能夠選擇包含數據。
  3. 若是以太坊消息的接受者是合約帳戶,能夠選擇進行迴應,這意味着以太坊消息也包含函數概念。

以太坊中「交易」是指存儲從外部帳戶發出的消息的簽名數據包。交易包含消息的接收者、用於確認發送者的簽名、以太幣帳戶餘額、要發送的數據和兩個被稱爲STARTGAS 和 GASPRICE 的數值。爲了防止代碼的指數型爆炸和無限循環,每筆交易須要對執行代碼所引起的計算步驟-包括初始消息和全部執行中引起的消息-作出限制。 STARTGAS 就是限制, GASPRICE 是每一計算步驟須要支付礦工的費用。若是執行交易的過程當中, 「用完了燃料」,全部的狀態改變恢復原狀態,可是已經支付的交易費用不可收回了。若是執行交易停止時還剩餘燃料,那麼這些燃料將退還給發送者。建立合約有單獨的交易類型和相應的消息類型;合約的地址是基於帳號隨機數和交易數據的哈希計算出來的。

爲了較爲深刻的理解以上過程,下面簡要的對此過程進行分析:(摘自 南京-菜根譚的博客)
設定有以下場景:假設發送者設置gas limit(STARTGAS)爲50,000,gas price爲20gwei。這就表示發送者願意最多支付50,000*20gwei = 1,000,000,000,000,000 Wei = 0.001 Ether來執行此交易。

gas limit表明用戶願意花費在gas上的錢的最大值。若是在他們的帳戶餘額中有足夠的Ether來支付這個最大值費用,那麼就沒問題。在交易結束時任何未使用的gas都會被返回給發送者,以原始費率兌換。

在發送者沒有提供足夠的gas來執行交易,那麼交易執行就會出現「gas不足」而後被認爲是無效的。在這種狀況下,交易處理就會被終止以及全部已改變的狀態將會被恢復,最後咱們就又回到了交易以前的狀態—完徹底全的以前狀態就像這筆交易歷來沒有發生。由於機器在耗盡gas以前仍是爲計算作出了努力,
因此理論上,將不會有任何的gas被返回給發送者。(這樣就能防止惡意的無限交易)

這些gas的錢到底去了哪裏?發送者在gas上花費的全部錢都發送給了「受益人」地址,一般狀況下就是礦工的地址。由於礦工爲了計算和驗證交易作出了努力,因此礦工接收gas的費用做爲獎勵。

消息機制的一個重要後果是以太坊的「頭等公民」財產-合約與外部帳戶擁有一樣權利,包括髮送消息和建立其它合約的權利。這使得合約能夠同時充當多個不一樣的角色,例如,用戶能夠使去中心化組織(一個合約)的一個成員成爲一箇中介帳戶(另外一個合約),爲一個偏執的使用定製的基於量子證實的蘭波特簽名(第三個合約)的我的和一個自身使用由五個私鑰保證安全的帳戶(第四個合約)的共同簽名實體提供居間服務。以太坊平臺的強大之處在於去中心化的組織和代理合約不須要關心合約的每一參與方是什麼類型的帳戶。

以太坊狀態轉換函數

以太坊的狀態轉換函數: APPLY(S,TX) -> S’ ,能夠定義以下:

  1. 檢查交易的格式是否正確(即有正確數值)、簽名是否有效和隨機數是否與發送者帳戶的隨機數匹配。如否,返回錯誤。
  2. 計算交易費用:fee=STARTGAS * GASPRICE,並從簽名中肯定發送者的地址。從發送者的帳戶中減去交易費用和增長髮送者的隨機數。若是帳戶餘額不足,返回錯誤。
  3. 設定初值 GAS = STARTGAS,並根據交易中的字節數減去必定量的燃料值。
  4. 從發送者的帳戶轉移價值到接收者帳戶。若是接收帳戶還不存在,建立此帳戶。若是接收帳戶是一個合約,運行合約的代碼,直到代碼運行結束或者燃料用完。
  5. 若是由於發送者帳戶沒有足夠的錢或者代碼執行耗盡燃料致使價值轉移失敗,恢復原來的狀態,可是還須要支付交易費用,交易費用加至礦工帳戶。
  6. 不然,將全部剩餘的燃料歸還給發送者,消耗掉的燃料做爲交易費用發送給礦工。

白皮書中給的例子爲:

假設合約存儲器開始時是空的,一個值爲 10 以太,燃料爲 2000,燃料價格爲 0.001 以太而且兩個數據字段值爲[ 2, „CHARLIE‟ ] [3]的交易發送後,狀態轉換函數的處理過程以下:

  1. 檢查交易是否有效、格式是否正確。
  2. 檢查交易發送者至少有 2000*0.001=2 個以太幣。若是有,從發送者帳戶中減去2 個以太幣。
  3. 初始設定 gas=2000,假設交易長爲 170 字節,每字節的費用是 5,減去 850,因此還剩 1150。
  4. 從發送者帳戶減去 10 個以太幣,爲合約帳戶增長 10 個以太幣。
  5. 運行代碼。在這個合約中,運行代碼很簡單:它檢查合約存儲器索引爲 2 處是否已使用,注意到它未被使用,而後將其值置爲 CHARLIE。假設這消耗了 187 單位的燃料,因而剩餘的燃料爲 1150 – 187 = 963。
  6. 向發送者的帳戶增長 963*0.001=0.963 個以太幣,返回最終狀態。

若是沒有合約接收交易,那麼全部的交易費用就等於 GASPRICE 乘以交易的字節長度,交易的數據就與交易費用無關了。
另外,須要注意的是,合約發起的消息能夠對它們產生的計算分配燃料限額,若是子計算的燃料用完了,它只恢復到消息發出時的狀態。所以,就像交易同樣,合約也能夠經過對它產生的子計算設置嚴格的限制,保護它們的計算資源。

從以上的過程上看,咱們能夠看出:
執行交易一共須要如下的gas:
1. 執行交易預訂gas費用
2. 隨交易發送的數據的gas費用(按照字節)
3. 若是交易是合約建立交易,還須要額外的gas費用

代碼執行(EVM層)

以太坊合約的代碼使用低級的基於堆棧的字節碼的語言寫成的,被稱爲「以太坊虛擬機代碼」或者「EVM 代碼」。代碼由一系列字節構成,每個字節表明一種操做。通常而言,代碼執行是無限循環,程序計數器每增長一(初始值爲零)就執行一次操做,直到代碼執行完畢或者遇到錯誤, STOP 或者 RETURN 指令。
像以前定義的那樣,EVM是圖靈完備虛擬機器。EVM本質上是被gas束縛->所以,能夠完成的計算總量本質上是被提供的gas總量限制的。
操做能夠訪問三種存儲數據的空間:

  • 堆棧,一種後進先出的數據存儲, 32 字節的數值能夠入棧,出棧。
  • 內存,可無限擴展的字節隊列。
  • 合約的長期存儲,一個祕鑰/數值的存儲,其中祕鑰和數值都是 32 字節大小,與計算結束即重置的堆棧和內存不一樣,存儲內容將長期保持。代碼能夠象訪問區塊頭數據同樣訪問數值,發送者和接受到的消息中的數據,代碼還能夠返回數據的字節隊列做爲輸出。

EVM 代碼的正式執行模型使人驚訝地簡單。當以太坊虛擬機運行時,它的完整的計算狀態能夠由元組(block_state, transaction, message, code, memory,stack, pc, gas)來定義,這裏 block_state 是包含全部帳戶餘額和存儲的全局狀態。每輪執行時,經過調出代碼的第 pc(程序計數器)個字節,當前指令被找到,每一個指令都有定義本身如何影響元組。例如, ADD 將兩個元素出棧並將它們的和入棧,將 gas(燃料)減一併將 pc 加一, SSTORE 將頂部的兩個元素出棧並將第二個元素插入到由第一個元素定義的合約存儲位置,一樣減小最多 200 的gas 值並將 pc 加一,雖然有許多方法經過即時編譯去優化以太坊,但以太坊的基礎性的實施能夠用幾百行代碼實現。

區塊鏈和挖礦

雖然有一些不一樣,但以太坊的區塊鏈在不少方面相似於比特幣區塊鏈。它們的區塊鏈架構的不一樣在於,以太坊區塊不只包含交易記錄和最近的狀態,還包含區塊序號和難度值。
以太坊中的區塊確認算法以下:

  1. 檢查區塊引用的上一個區塊是否存在和有效
  2. 檢查區塊的時間戳是否比引用的上一個區塊大,並且小於 15 分鐘。
  3. 檢查區塊序號、難度值、 交易根,叔根和燃料限額是否有效。
  4. 檢查區塊的工做量證實是否有效。
  5. 將 S[0]賦值爲上一個區塊的 STATE_ROOT。
  6. 將 TX 賦值爲區塊的交易列表,一共有 n 筆交易。對於屬於 0……n-1 的 i,進行狀態轉換 S[i+1] = APPLY(S[i],TX[i])。若是任何一個轉換髮生錯誤,或者程序執行到此處所花費的燃料( gas)超過了 GASLIMIT,返回錯誤。
  7. 用 S[n]給 S_FINAL 賦值, 向礦工支付區塊獎勵。
  8. 檢查 S-FINAL 是否與 STATE_ROOT 相同。若是相同,區塊是有效的。不然,區塊是無效的。

這一確認方法乍看起來彷佛效率很低,由於它須要存儲每一個區塊的全部狀態,可是事實上以太坊的確認效率能夠與比特幣相提並論。緣由是狀態存儲在樹結構中,每增長一個區塊只須要改變樹結構的一小部分。所以,通常而言,兩個相鄰的區塊的樹結構的大部分應該是相同的,所以存儲一次數據,能夠利用指針(即子樹哈希)引用兩次。一種被稱爲帕特里夏樹( 」Patricia Tree」)的樹結構能夠實現這一點,其中包括了對默克爾樹概念的修改,不只容許改變節點,並且還能夠插入和刪除節點。另外,由於全部的狀態信息是最後一個區塊的一部分,因此沒有必要存儲所有的區塊歷史-這一方法若是可以能夠應用到比特幣系統中,經計算能夠對存儲空間有 10-20 倍的節省。

以太坊應用舉例

以太坊應用通常分爲三類:

  1. 金融應用,爲用戶提供更強大的用他們的錢管理和參與合約的方法。包括子貨幣,金融衍生品,對衝合約,儲蓄錢包,遺囑,甚至一些種類的全面的僱傭合約。
  2. 半金融應用,這裏有錢的存在但也有很重的非金錢的方面,一個完美的例子是爲解決計算問題而設的自我強制懸賞。
  3. 還有在線投票和去中心化治理這樣的徹底的非金融應用。

令牌系統

鏈上令牌系統有不少應用,從表明如美圓或黃金等資產的子貨幣到公司股票,單獨的令牌表明智能資產,安全的不可僞造的優惠券,甚至與傳統價值徹底沒有聯繫的用來進行積分獎勵的令牌系統。在以太坊中實施令牌系統容易得讓人吃驚。
關鍵的一點是理解,全部的貨幣或者令牌系統,從根本上來講是一個帶有以下操做的數據庫:從 A 中減去 X 單位並把 X 單位加到 B 上,前提條件是(1)A 在交易以前有至少 X 單位以及(2)交易被 A 批准。實施一個令牌系統就是把這樣一個邏輯實施到一個合約中去。用 Serpent 語言實施一個令牌系統的基本代碼以下:

from = msg.sender
to = msg.data[0]
value = msg.data[1]
if contract.storage[from] >= value:
contract.storage[from] = contract.storage[from] -value
contract.storage[to] = contract.storage[to] + value

這從本質上來講是本文將要進一步描述的「銀行系統」狀態轉變功能的一個最小化實施。須要增長一些額外的代碼以提供在初始和其它一些邊緣狀況下分發貨幣的功能,理想狀況下會增長一個函數讓其它合約來查詢一個地址的餘額。就足夠了。

理論上,基於以太坊的充當子貨幣的令牌系統可能包括一個基於比特幣的鏈上元幣所缺少的重要功能:直接用這種貨幣支付交易費的能力。實現這種能力的方法是在合約裏維護一個以太幣帳戶以用來爲發送者支付交易費,經過收集被用來充當交易費用的內部貨幣並把它們在一個不斷運行的拍賣中拍賣掉,合約不斷爲該以太幣帳戶注資。這樣用戶須要用以太幣「激活」他們的帳戶,但一旦帳戶中有以太幣它將會被重複使用由於每次合約都會爲其充值。(??..what)

金融衍生品和價值穩定的貨幣

對衝合約

金融衍生品是「智能合約」的最廣泛的應用,也是最易於用代碼實現的之一。實現金融合約的主要挑戰是它們中的大部分須要參照一個外部的價格發佈器;例如,一個需求很是大的應用是一個用來對衝以太幣(或其它密碼學貨幣)相對美圓價格波動的智能合約,但該合約須要知道以太幣相對美圓的價格。最簡單的方法是經過由某特定機構(例如納斯達克)維護的「數據提供「合約進行,該合約的設計使得該機構可以根據須要更新合約,並提供一個接口使得其它合約可以經過發送一個消息給該合約以獲取包含價格信息的回覆.

當這些關鍵要素都齊備,對衝合約看起來會是下面的樣子:
等待 A 輸入 1000 以太幣。 .
等待 B 輸入 1000 以太幣。
經過查詢數據提供合約,將 1000 以太幣的美圓價值,例如, x 美圓,記錄至存儲器。

30 天后,容許 A 或 B「從新激活「合約以發送價值 x 美圓的以太幣(從新查詢數據提供合約,以獲取新價格並計算)給 A 並將剩餘的以太幣發送給 B。
這樣的合約在密碼學商務中有非同尋常的潛力。密碼學貨幣常常被詬病的一個問題就是其價格的波動性;雖然大量的用戶和商家可能須要密碼學資產所帶來的安全和便利,可他們不太會樂意麪對一天中資產跌去 23%價值的情形。(某特定機構例如納斯達克應該是會維護價格的穩定性)

發行者背書資產與去中心化市場

直到如今,最爲常見的推薦方案是發行者背書資產;思想是發行者建立一種子貨幣,對此種子貨幣他們有權發行和贖回,給予(線下)提供給他們一個單位特定相關資產(例如黃金,美圓)的人一個單位子貨幣。發行者承諾當任何人送還一個單位密碼學資產時。發還一個單位的相關資產。這種機制可以使任何非密碼學資產被「升級「爲密碼學資產,若是發行者值得信任的話.

然而實踐中發行者並不是老是值得信任的,而且一些狀況下銀行體系太脆弱,或者不夠誠實守信從而使這樣的服務沒法存在。金融衍生品提供了一種替代方案。這裏將再也不有提供儲備以支撐一種資產的單獨的發行者,取而代之的是一個由賭一種密碼學資產的價格會上升的投機者構成的去中心化市場。與發行者不一樣,投機者一方沒有討價還價的權利,由於對衝合約把他們的儲備凍結在了契約中。注意這種方法並不是是徹底去中心化的,由於依然須要一個可信任的提供價格信息的數據源,儘管依然有爭議這依然是在下降基礎設施需求(與發行者不一樣,一個價格發佈器不須要牌照而且彷佛可歸爲自由言論一類)和下降潛在欺詐風險方面的一個巨大的進步。

身份和信譽系統

最先的替代幣,域名幣,嘗試使用一個類比特幣塊鏈來提供一個名稱註冊系統,在那裏用戶能夠將他們的名稱和其它數據一塊兒在一個公共數據庫註冊。最經常使用的應用案例把象「bitcoin.org「(或者再域名幣中, 」bitcoin.bit「)同樣的域名與一個IP 地址對應的域名系統。其它的應用案例包括電子郵件驗證系統和潛在的更先進的信譽系統。這裏是以太坊中提供與域名幣相似的的名稱註冊系統的基礎合約.

if !contract.storage[tx.data[0]]:
contract.storage[tx.data[0]] = tx.data[1]

合約很是簡單;就是一個以太坊網絡中的能夠被添加但不能被修改或移除的數據庫。任何人均可以把一個名稱註冊爲一個值並永遠不變。一個更復雜的名稱註冊合約將包含容許其餘合約查詢的「功能條款「,以及一個讓一個名稱的」擁有者(即 「第一個註冊者)修改數據或者轉讓全部權的機制。甚至能夠在其上添加信譽和信任網絡功能。

去中心化存儲

在過去的幾年裏出現了一些大衆化的在線文件存儲初創公司,最突出的是Dropbox,它尋求容許用戶上傳他們的硬盤備份, 提供備份存儲服務並容許用戶訪問從而按月向用戶收取費用。然而,在這一點上這個文件存儲市場有時相對低效;對現存服務的粗略觀察代表,特別地在「神祕谷「20-200GB 這一既沒有免費空間也沒有企業級用戶折扣的水平上,主流文件存儲成本每個月的價格意味着支付在一個月裏支付整個硬盤的成本。以太坊合約容許去中心化存儲生態的開發,這樣用戶經過將他們本身的硬盤或未用的網絡空間租出去以得到少許收益,從而下降了文件存儲的成本。

這樣的設施的基礎性構件就是咱們所謂的「去中心化 Dropbox 合約「。這個合約工做原理以下。

  1. 某人將須要上傳的數據分紅塊,對每一塊數據加密以保護隱私,而且以此構建一個默克爾樹。而後建立一個含如下規則的合約,每 N 個塊,合約將從默克爾樹中抽取一個隨機索引
  2. 給第一個實體 X 以太以支撐在樹中特定索引處的塊的全部權證實。當一個用戶想從新下載他的文件,他能夠使用微支付通道協議(例如每 32k 字節支付 1 薩博)恢復文件。

這個協議的一個重要特徵是,雖然看起來象是一我的信任許多不許備丟失文件的隨機節點,可是他能夠經過祕密分享把文件分紅許多小塊,而後經過監視合同得知每一個小塊都還被某個節點的保存着。若是一個合約依然在付款,那麼就提供了某我的依然在保存文件的證據。

去中心化自治組織( DAO)

一般意義上「去中心化自治組織( DAO)」的概念指的是一個擁有必定數量成員或股東的虛擬實體,依靠好比 67%多數來決定花錢以及修改代碼。成員會集體決定組織如何分配資金。分配資金的方法多是懸賞,工資或者更有吸引力的機制好比用內部貨幣獎勵工做。這僅僅使用密碼學塊鏈技術就從根本上覆制了傳統公司或者非營利組織的法律意義以實現強制執行。至此許多圍繞 DAO 的討論都是圍繞一個帶有接受分成的股東和可交易的股份的「去中心化自治公司( DAC) 」的「資本家」模式;做爲替代者,一個被描述爲「去中心化自治社區」的實體將使全部成員都在決策上擁有同等的權利而且在增減成員時要求 67%多數贊成。每一個人都只能擁有一個成員資格這一規則須要被羣體強制實施。

下面是一個如何用代碼實現 DO 的綱要。最簡單的設計就是一段若是三分之二成員贊成就能夠自我修改的代碼。雖然理論上代碼是不可更改的,然而經過把代碼主幹放在一個單獨的合約內而且把合約調用的地址指向一個可更改的存儲依然能夠容易地繞開障礙而使代碼變得可修改,在一個這樣的 DAO 合約的簡單實現中有三種交易類型,由交易提供的數據區分:

  • [0,i,K,V] 註冊索引爲 i 的對存儲地址索引爲 K 至 v 的內容的更改建議。
  • [0,i] 註冊對建議 i 的投票。
  • [2,i] 若有足夠投票則確認建議 i。

而後合約對每一項都有具體的條款。它將維護一個全部開放存儲的更改記錄以及一個誰投票表決的表。還有一個全部成員的表。當任何存儲內容的更改得到了三分之二多數贊成,一個最終的交易將執行這項更改。一個更加複雜的框架會增長內置的選舉功能以實現如發送交易,增減成員,甚至提供委任制民主一類的投票表明(即任何人均可以委託另一我的來表明本身投票,並且這種委託關係是能夠傳遞的,因此若是 A 委託了 B 而後 B 委託了 C 那麼 C 將決定 A 的投票)。這種設計將使 DAO 做爲一個去中心化社區有機地成長, 令人們最終可以把挑選合適人選的任務交給專家, 與當前系統不一樣,隨着社區成員不斷改變他們的站隊假以時日專家會容易地出現和消失。

一個替代的模式是去中心化公司,那裏任何帳戶能夠擁有 0 到更多的股份,決策須要三分之二多數的股份贊成。一個完整的框架將包括資產管理功能-能夠提交買賣股份的訂單以及接受這種訂單的功能(前提是合約裏有訂單匹配機制)。表明依然以委任制民主的方式存在,產生了「董事會」的概念。

更先進的組織治理機制可能會在未來實現;如今一個去中心化組織( DO)能夠從去中心化自治組織( DAO)開始描述。 DO 和 DAO 的區別是模糊的,一個大體的分割線是治理是否能夠經過一個相似政治的過程或者一個「自動」過程實現,一個不錯的直覺測試是「無通用語言」標準:若是兩個成員不說一樣的語言組織還能正常運行嗎?顯然,一個簡單的傳統的持股式公司會失敗,而像比特幣協議這樣的卻極可能成功,羅賓· 漢森的「futarchy」,一個經過預測市場實現組織化治理的機制是一個真正的說明「自治」式治理多是什麼樣子的好例子。注意一我的無需假設全部 DAO 比全部 DO 優越;自治只是一個在一些特定場景下有很大優點的,但在其它地方未必可行的範式,許多半 DAO 可能存在。

進一步應用

  • 儲蓄錢包
  • 做物保險
  • 去中心化的數據發佈器
  • 多重簽名智能契約
  • 雲計算
  • 點對點賭博
  • 預測市場
  • 鏈上去中心化市場

相關雜項

改進版幽靈協議的實施

兩個問題

  1. 幽靈協議提出的動機是當前快速確認的塊鏈由於區塊的高做廢率而受到低安全性困擾

    區塊須要花必定時間(設爲 t)擴散至全網,若是礦工 A 挖出了一個區塊而後礦工 B 碰巧在 A 的區塊擴散至 B 以前挖出了另一個區塊,礦工 B 的區塊就會做廢而且沒有對網絡安全做出貢獻。
    解決:經過在計算哪條鏈「最長」的時候把廢區塊也包含進來,幽靈協議解決了下降網絡安全性的第一個問題;這就是說,不只一個區塊的父區塊和更早的祖先塊,祖先塊的做廢的後代區塊也被加進來以計算哪個區塊擁有支持其的最大工做量證實。

  2. 算力中心化問題

    若是 A 是一個擁有全網 30%算力的礦池而 B 擁有 10%的算力, A 將面臨 70%的時間都在產生做廢區塊的風險而 B 在 90%的時間裏都在產生做廢區塊。所以,若是做廢率高,A 將簡單地由於更高的算力份額而更有效率。
    解決:以太坊實施了一個只下探到有限層的簡化版本的幽靈協議。其特色是,廢區塊只能以叔區塊的身份被其父母的第二代至第五代後輩區塊,而不是更遠關係的後輩區塊(例如父母區塊的第六代後輩區塊,或祖父區塊的第三代後輩區塊)歸入計算。這樣作有幾個緣由。1. 無條件的幽靈協議將給計算給定區塊的哪個叔區塊合法帶來過多的複雜性。2. 帶有以太坊所使用的無條件補償的幽靈協議剝奪了礦工的一部分激勵。

最後,計算代表帶有激勵的五層幽靈協議即便在出塊時間爲 15s 的狀況下也實現了了 95%以上的效率,而擁有 25%算力的礦工從中心化獲得的益處小於 3%。

費用

由於每一個發佈到區塊鏈的交易都佔用了下載和驗證的成本,須要有一個包括交易費的規範機制來防範濫發交易。
比特幣使用的默認方法是純自願的交易費用,依靠礦工擔當守門人並設定動態的最低費用。由於這種方法是「基於市場的」,使得礦工和交易發送者可以按供需來決訂價格,因此這種方法在比特幣社區被很順利地接受了。然而,這個邏輯的問題在於,交易處理並不是一個市場;雖然根據直覺把交易處理解釋成礦工給發送者提供的服務是頗有吸引力的,但事實上一個礦工收錄的交易是須要網絡中每一個節點處理的,因此交易處理中最大部分的成本是由第三方而不是決定是否收錄交易的礦工承擔的。

然而,當給出一個特殊的不夠精確的簡化假設時,這個基於市場的機制的漏洞很神奇地消除了本身的影響。論證以下。假設:

  1. 一個交易帶來 k 步操做, 提供獎勵 kR 給任何收錄該交易的礦工,這裏 R 由交易發佈者設定, k 和 R 對於礦工都是事先(大體上)可見的。
  2. 每一個節點處理每步操做的成本都是 C (即全部節點的效率一致)。
  3. 有 N 個挖礦節點,每一個算力一致(即全網算力的 1/N)。
  4. 沒有不挖礦的全節點

當預期獎勵大於成本時,礦工願意挖礦。這樣,由於礦工有 1/N 的機會處理下一個區塊,因此預期的收益是 kR/N , 礦工的處理成本簡單爲 kC. 這樣當kR/N > kC, 即 R > NC 時。礦工願意收錄交易。注意 R 是由交易發送者提供的每步費用,是礦工從處理交易中獲益的下限。 NC 是全網處理一個操做的成本。因此,礦工僅有動機去收錄那些收益大於成本的交易。

然而,這些假設與實際狀況有幾點重要的偏離:

  1. 由於額外的驗證時間延遲了塊的廣播於是增長了塊成爲廢塊的機會,處理交易的礦工比其它的驗證節點付出了更高的成本。
  2. 不挖礦的全節點是存在的。
  3. 實踐中算力分佈可能最後是極端不平均的。
  4. 以破壞網絡爲己任的投機者,政敵和瘋子確實存在,而且他們可以聰明地設置合同使得他們的成本比其它驗證節點低得多

上面第 1 點驅使礦工收錄更少的交易,第 2 點增長了 NC; 所以這兩點的影響至少部分互相抵消了. 第 3 點和第 4 點是主要問題;做爲解決方案咱們簡單地創建了一個浮動的上限:沒有區塊可以比 BLK_LIMIT_FACTOR 倍長期指數移動平均值更多的操做數。具體地:

blk.oplimit = floor((blk.parent.oplimit * (EMAFACTOR – 1) + floor(parent.opcount * BLK_LIMIT_FACTOR)) /EMA_FACTOR)

BLK_LIMIT_FACTOR 和 EMA_FACTOR 是暫且被設爲 65536 和 1.5 的常數,但可能會在更深刻的分析後調整。

計算和圖靈完備

須要強調的是以太坊虛擬機是圖靈完備的; 這意味着 EVM 代碼能夠實現任何能夠想象的計算,包括無限循環。 EVM 代碼有兩種方式實現循環。首先, JUMP指令可讓程序跳回至代碼前面某處,還有容許如 while x < 27: x = x * 2 同樣的條件語句的 JUMPI 指令實現條件跳轉。其次,合約能夠調用其它合約,有經過遞歸實現循環的潛力。這很天然地致使了一個問題:惡意用戶可以經過迫使礦工和全節點進入無限循環而不得不關機嗎? 這問題出現是由於計算機科學中一個叫停機問題(可計算理論)的問題:通常意義上沒有辦法知道,一個給定的程序是否能在有限的時間內結束運行。

正如在狀態轉換章節所述,咱們的方案經過爲每個交易設定運行執行的最大計算步數來解決問題,若是超過則計算被恢復原狀但依然要支付費用。消息以一樣的方式工做。爲顯示這一方案背後的動機,請考慮下面的例子:

  • 一個攻擊者建立了一個運行無限循環的合約,而後發送了一個激活循環的交易給礦工,礦工將處理交易,運行無限循環直到燃料耗盡。即便燃料耗盡交易半途中止,交易依然正確(回到原處)而且礦工依然從攻擊者哪裏掙到了每一步計算的費用。
  • 一個攻擊者建立一個很是長的無限循環意圖迫使礦工長時間內一直計算導致在計算結束前若干區塊已經產生因而礦工沒法收錄交易以賺取費用。然而,攻擊者須要發佈一個 STARTGAS 值以限制可執行步數,於是礦工將提早知道計算將耗費過多的步數。
  • 一個攻擊者看到一個包含諸如 send(A,contract.storage[A]); contract.storage[A]= 0 格式的合約而後發送帶有隻夠執行第一步的費用的而不夠執行第二步的交易(即提現但不減小帳戶餘額)。合約做者無需擔憂防衛相似攻擊,由於若是執行中途中止則全部變動都被回覆。

選擇圖靈完備

圖靈完備的替代品是圖靈不完備,這裏 JUMP 和 JUMPI 指令不存在而且在某個給定時間每一個合約只容許有一個拷貝存在於調用堆棧內。在這樣的系統裏,上述的費用系統和圍繞咱們的方案的效率的不肯定性可能都是不須要的,由於執行一個合約的成本將被它的大小決定。此外,圖靈不完備甚至不是一個大的限制,在咱們內部設想的全部合約例子中,至今只有一個須要循環,並且即便這循環也能夠被 26 個單行代碼段的重複所代替。考慮到圖靈完備帶來的嚴重的麻煩和有限的益處,爲何不簡單地使用一種圖靈不完備語言呢?事實上圖靈不完備遠非一個簡潔的解決方案。爲何?請考慮下面的合約:

C0: call(C1); call(C1);
C1: call(C2); call(C2);
C2: call(C3); call(C3);

C49: call(C50); call(C50);
C50: (run one step of a program and record the change in storage)

如今,發送一個這樣的交易給 A,這樣,在 51 個交易中,咱們有了一個須要花費 250 步計算的合約,
問題點:

  1. 礦工可能嘗試經過爲每個合約維護一個最高可執行步數而且對於遞歸調用其它合約的合約計算可能執行步數從而預先檢測這樣的邏輯炸彈,可是這會使礦工禁止建立其它合約的合約(由於上面 26 個合約的建立和執行能夠很容易地放入一個單獨合約內)。
  2. 另一個問題點是一個消息的地址字段是一個變量,因此一般來說可能甚至沒法預先知道一個合約將要調用的另一個合約是哪個
    因而,最終咱們有了一個驚人的結論:圖靈完備的管理驚人地容易,而在缺少一樣的控制時圖靈不完備的管理驚人地困難- 那爲何不讓協議圖靈完備呢?

貨幣和發行

以太坊網絡包含自身的內置貨幣以太幣,以太幣扮演雙重角色,爲各類數字資產交易提供主要的流動性,更重要的是提供了了支付交易費用的一種機制。爲便利及避免未來的爭議期間(參見當前的 mBTC/uBTC/聰的爭論),不一樣面值的名稱將被提早設置:

  • wei偉
  • 10^12: 薩博
  • 10^15: 芬尼
  • 10^18: 以太

這應該被看成是「元」和「分」或者「比特幣」和「聰」的概念的擴展版,在不遠的未來,咱們指望「以太」被用做普通交易, 「芬尼」用來進行微交易, 「薩博」和「偉」用來進行關於費用和協議實施的討論。

發行模式以下:

  • 經過發售活動,以太幣將以每 BTC 1337-2000 以太的價格發售,一個旨在爲以太坊組織籌資而且爲開發者支付報酬的機制已經在其它一些密碼學貨幣平臺上成功使用。早期購買者會享受較大的折扣,發售所得的 BTC 將徹底用來支付開發者和研究者的工資和懸賞,以及投入密碼學貨幣生態系統的項目。
  • 0.099x ( x 爲發售總量)將被分配給 BTC 融資或其它的肯定性融資成功以前參與開發的早期貢獻者,另一個 0.099x 將分配給長期研究項目。
  • 自上線時起每一年都將有 0.26x( x 爲發售總量)被礦工挖出。

發行分解

永久線性增加模型下降了在比特幣中出現的財富過於集中的風險,而且給予了活在當下和未來的人公平的機會去獲取貨幣,同時保持了對獲取和持有以太幣的激勵,由於長期來看「貨幣供應增加率」是趨於零的。咱們還推斷,隨着時間流逝總會發生由於粗心和死亡等緣由帶來的幣的遺失,假設幣的遺失是每一年貨幣供應量的一個固定比例,則最終總的流通中的貨幣供應量會穩定在一個等於年貨幣發行量除以遺失率的值上(例如,當遺失率爲 1%時,當供應量達到 30x 時,每一年有0.3x 被挖出同時有 0.3x 丟失, 達到一個均衡)。

除了線性的發行方式外,和比特幣同樣以太幣的的供應量增加率長期來看也趨於零。

挖礦的中心化

比特幣挖礦算法基本上是讓礦工千萬次地輕微改動區塊頭,直到最終某個節點的改動版本的哈希小於目標值。然而,這種挖礦算法容易被兩種形式的中心化攻擊。

  1. 挖礦生態系統被專門設計的於是在比特幣挖礦這一特殊任務上效率提升上千倍的 ASICs(專用集成電路)和電腦芯片控制。這意味着比特幣挖礦再也不是高度去中心化的和追求平等主義的,而是須要鉅額資本的有效參與。
  2. 大部分比特幣礦工事實上再也不在本地完成區塊驗證;而是依賴中心化的礦池提供區塊頭。這個問題能夠說很嚴重:有時最大的兩個礦池間接地控制了大約全網 50%的算力,這就有聯合體可能會嘗試 51%攻擊的可能性。

以太坊使用如下兩種方案:

  1. 以太坊如今的目的是使用一個基於爲每 1000 個隨機數隨機產生惟一哈希的函數的挖礦算法,用足夠寬的計算域,去除專用硬件的優點。這樣的策略固然不會使中心化的收益減小爲零,可是也不須要。注意每單個用戶使用他們的私人筆記本電腦或臺式機就能夠幾乎免費地完成必定量的挖礦活動,但當到了 100%的 CPU使用率以後更多地挖礦就會須要他們支付電力和硬件成本。 ASIC 挖礦公司須要從第一個哈希開始就爲電力和硬件支付成本。因此,若是中心化收益可以保持在(E + H) /E 如下,那麼即便 ASICs 被製造出來普通礦工依然有生存空間。
  2. 計劃將挖礦算法設計成挖礦須要訪問整個區塊鏈,迫使礦工存儲完成的區塊鏈或者至少可以驗證每筆交易。這去除了對中心化礦池的須要;雖然礦池依然能夠扮演平滑收益分配的隨機性的角色,但這功能能夠被沒有中心化控制的 P2P礦池完成地一樣好。這樣即便大部分普通用戶依然傾向選擇輕客戶端,經過增長網絡中的全節點數量也有助於抵禦中心化

擴展性

擴展性問題是以太坊常被關注的地方,與比特幣同樣,以太坊也遭受着每一個交易都須要網絡中的每一個節點處理這一困境的折磨。比特幣的當前區塊鏈大小約爲20GB,以每小時 1MB 的速度增加。以太坊可能也會經歷類似的甚至更糟的增加模式,由於在以太坊區塊鏈之上還有不少應用,而不是像比特幣只是簡單的貨幣,但以太坊全節點只需存儲狀態而不是完整的區塊鏈歷史這一事實讓狀況獲得了改善。

大區塊鏈的問題是中心化風險。若是塊鏈大小增長至好比 100TB,可能的場景將是隻有很是小數目的大商家會運行全節點,而常規用戶使用輕的 SPV 節點。這會增長對全節點合夥欺詐牟利(例如更改區塊獎勵,給他們本身 BTC)的風險的擔心。輕節點將沒有辦法馬上檢測到這種欺詐。固然,至少可能存在一個誠實的全節點,而且幾個小時以後有關詐騙的信息會經過 Reddit 這樣的渠道泄露,但這時已經太晚:任憑普通用戶作出怎樣的努力去廢除已經產生的區塊,他們都會遇到與發動一次成功的 51%攻擊同等規模的巨大的不可行的協調問題。在比特幣這裏,如今這是一個問題,但 Peter Todd 建議的一個改動能夠緩解這個問題。

以太坊會使用兩個附加的策略以應對此問題。

  1. 由於基於區塊鏈的挖礦算法,至少每一個礦工會被迫成爲一個全節點,這保證了必定數量的全節點。
  2. 更重要的是,處理完每筆交易後,咱們會把一箇中間狀態樹的根包含進區塊鏈。即便區塊驗證是中心化的,只要有一個誠實的驗證節點存在,中心化的問題就能夠經過一個驗證協議避免。若是一個礦工發佈了一個不正確的區塊,這區塊要麼是格式錯,要麼狀態 S[n]是錯的。由於 S[0]是正確的,必然有第一個錯誤狀態 S[i]但 S[i-1]是正確的,驗證節點將提供索引 i,一塊兒提供的還有處理APPLY(S[i-1],TX[i]) -> S[i]所需的帕特里夏樹節點的子集。這些節點將受命進行這部分計算,看產生的 S[i]與先前提供的值是否一致。

更復雜的是惡意礦工發佈不完整區塊進行攻擊,形成沒有足夠的信息去肯定區塊是否正確。解決方案是質疑-迴應協議:驗證節點對目標交易索引起起質疑,接受到質疑信息的輕節點會對相應的區塊取消信任,直到另一個礦工或者驗證者提供一個帕特里夏節點子集做爲正確的證據。

總結

上述合約機制使得任何一我的可以在一個虛擬機上創建經過全網共識來運行命令行應用,它可以更改一個全網可訪問的狀態做爲它的「硬盤」。
以太坊的比較完整的架構以下:

然而,對於多數人來講,用做交易發送機制的命令行接口缺少足夠的用戶友好使得去中心化成爲有吸引力的替代方案。一個完整的「去中心化應用」應該包括底層的商業邏輯組件和上層的圖形用戶接口組件。以太坊客戶端被設計成一個網絡瀏覽器,但包括對「eth」 Javascript API 對象的支持,可被客戶端裏看到的特定的網頁用來與以太坊區塊鏈交互。從「傳統」網頁的角度看來,這些網頁是徹底靜態的內容,由於區塊鏈和其它去中心化協議將徹底代替服務器來處理用戶發起的請求。最後,去中心化協議有但願本身利用某種方式使用以太坊來存儲網頁。

以太坊協議最初是做爲一個經過高度通用的語言提供如鏈上契約,提現限制和金融合約,賭博市場等高級功能的升級版密碼學貨幣來構思的。以太坊協議將不直接「支持」任何應用,但圖靈完備編程語言的存在乎味着理論上任意的合約均可覺得任何交易類型和應用建立出來。然而關於以太坊更有趣的是,以太坊協議比單純的貨幣走得更遠,圍繞去中心化存儲,去中心化計算和去中心化預測市場以及數十個相似概念創建的協議和去中心化應用,有潛力從根本上提高計算行業的效率。最終,一樣會有大批與金錢毫無關係的應用出現。

以太坊協議實現的任意狀態轉換概念提供了一個具備獨特潛力的平臺;與封閉式的,爲諸如數據存儲,賭博或金融等單一目的設計的協議不一樣,以太坊從設計上是開放式的,而且咱們相信它極其適合做爲基礎層服務於在未來的年份裏出現的極其大量的金融和非金融協議。

最後,附上以太坊的官方github連接

相關文章
相關標籤/搜索