區塊鏈入門 -- 01 區塊鏈介紹
一、比特幣的現有概念介紹
1、歷史
去中心化的貨幣概念,像產權登記等已經存在了幾十年了。上世紀80年代和90年代的匿名電子現金協議主要使用了一種被稱為“喬姆盲籤(Chaumian Blinding)”的加密技術,這種技術為這些新貨幣提供了很高的隱私保護,但是由於他們的基礎協議在很大程式上需要依賴一箇中央中介,因為未能獲得支援。1988年,戴偉(Dai Wei)的b-money首次引入了通過解決計算難題和去中心化的共識來創造貨幣的思想,但是該建議並未給出實現去中心化的共識的具體方法。2005年,芬妮(Hal Finney)引入了“可重複的工作證明”(reusable proofs of works)概念,它同時使用b-money的思想和Adam Back提出的計算困難的雜湊現金(Hashcash)難題來創造密碼學貨幣。但是,這種概念再次迷失於理想化,因為它需要可信任的計算作為後盾。在2009年,一種去中心化的貨幣由中本聰在實踐中首次得到實現,通過使用公共金鑰密碼來管理所有權,並通過一種一致性演算法來跟蹤貨幣的持有者,這種演算法被稱為“工作證明”。這“工作證明”的演算法是一種突破,因為它同時解決了兩個問題。首先,它提供了一種簡單的、有節制的有效的共識演算法,允許網路中的節點一起同意比特幣總賬狀態的一組更新。其次,它提供了一種機制,允許任何節點自由進入共識的處理過程,從而解決了誰來影響共識的政治難題,同時阻止了女巫攻擊
2、比特幣一個狀態轉移系統
從技術角度來說,這加密貨幣的賬本,如比特幣可以被看作為一個狀體轉移的系統,在這個系統裡,有一個包含了所有現在已存在的比特幣的持有者的狀態,並且有一個“狀態轉移函式”可以使用一個狀態和一個交易來產生一個新的狀態。在一個標準的銀行體系裡,這狀態就是一個資產負債表,當一個交易要求把 x$ 的錢,從A轉移到B時,那麼它的狀態轉移函式就會從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
這“狀態”,在比特幣中是指所有的已經被挖出的但是還沒有被消費的硬幣的集合(技術上被稱為:“沒有被花費的交易產出(unspent transaction out puts)”或者“UTXO”),每個UTXO都有一個面值和一個持有者(持有者是由20個位元組組成的地址,其本質是一個加密的公鑰)。一個交易包含了一個或者多個輸入,每一個輸入都包含了對一個已存在的UTXO的引用,和用持有者的地址所關聯著的私鑰來產生的一個加密簽名,並且會產生一個或者多個輸出,每一個輸出包含一個用於新增到狀態的新的UTXO。
這狀態轉移函式 APPLY(S, TX) --> S' 可以被大概的定義如下:
1.在TX中的每個輸入:
如果被應用的UTXO不再 S 裡,返回一個錯誤
如果提供的簽名和UTXO的所有者匹配不上,返回一個錯誤
2.如果所有的輸入的UTXO的面值和少於所有輸出的UTXO的面值和,返回一個錯誤
3.返回一個所有輸入的UTXO都被移除的,所有輸出的UTXO都被加進的新的 S'
第一個步驟的前半部分防止交易的傳送方消費不存在的硬幣,第一個步驟的後半部分阻止了交易的傳送方使用別人的硬幣,第二個步驟是強制的價值保護。為了使用這種支付方式,協議如下:
假設:
Alice 想傳送 11.7 BTC 給 Bob. 首先, Alice 要找到一組她自己擁有的有效的 UTXO ,且總數要至
少不低於 11.7 BTC. 實際上, Alice 不會恰巧剛好擁有 11.7 BTC; 她得到的最小值是 6+4+2=12,
她然後使用這 3 個輸入和 2 個輸出建立了一個交易。 這第一個輸出是 11.7 BTC ,是輸出 Bob,第
二個輸出是剩下的 0.3 BTC “找零”。如果 Alice 沒有要求把這個找零傳送到她自己的賬戶上,
那麼這礦工可以要求擁有這個零錢(即通常被成為的小費)。
3、挖礦
如果我們有一個可信任的中央伺服器, 那麼實現這個系統是一件很簡單的事情。就按照需求所描述的去編寫程式碼即可,把狀態記錄在中央伺服器的硬碟上。 然而,與比特幣一樣,我們試圖去建立一個去中心化的貨幣系統,所以,我們需要把狀態轉移系統和一致性系統結合起來,以確保每個人都同意這交易的順序。比特幣的去中心化的一致性處理程序要求網路中的節點連續不斷的去嘗試對交易進行打包,這些被打成的包就稱為“區塊”。 這個網路會故意的每隔 10 分鐘左右就建立一個區塊, 每一個區塊裡都包含一個時間戳,一個隨機數,一個對上一個區塊的引用 ,和從上一個區塊開始的所有交易的列表。隨著時間的推移,這會建立一個持久的,不斷增長的區塊鏈,這個區塊鏈不斷的被更新,使其始終代表著最新的比特幣總賬的狀態。
在這個範例中,用來驗證一個區塊是否有效的演算法如下:
1. 檢查其引用的上一個區塊是否存在並且有效.
2. 檢查這個區塊的時間戳是否大於上一個區塊的時間戳 並且小於 2 小時之內
3. 檢查這區塊上的工作證明是否有效.
4. 讓 S[0] 成為上一個區塊的最末端的狀態.
5. 假設 TX 是這個區塊的交易列表,且有 n 個交易。 做 for 迴圈,把 i 從 0 加到到 n-1,
設定 S[i+1] = APPLY(S[i],TX[i]) 如果任何一個應用(APPLY)返回錯誤,則退出並且返回。
6. 返回 true,並且把 S[n] 設定成這個區塊最末端的狀態。
從本質上說,區塊中的每一個交易都必須提供一個有效的狀態,從交易執行前的標準狀態到執行後的一個新的狀態。 注意,狀態並沒有以任何方式編碼進區塊中;它純粹是一個被驗證節點所記住的抽象,並且它只能用來被從創世區塊起的每一個區塊進行安全的計算,然後按照順序的應用在每一個區塊中的每一次交易中。此外,請注意礦工把交易打包進區塊的順序是很重要的,如果一個區塊中有 2 個交易 A 和 B,B 花了一個由 A 建立的 UTXO, 那麼如果 A 比 B 更早的進入區塊,那麼這個區塊將是有效的,不然就是無效的。
在上述列出的驗證條件中,“工作證明” 這一明確的條件就是每一個區塊的 2 次 SHA256 雜湊值,它作為一個 256 位的數字,必須小於一個動態調整的目標值,截止到本文寫作的時間,該動態調整的值的大小大約是 2 的 187 次方。 這樣做的目的是為了讓建立區塊的演算法變難,從而阻止幽靈攻擊者從對它們有利的角度來對區塊鏈進行整個的改造。因為 SHA256 被設計成一個完全不可預測的偽隨機函式,這建立一個有效區塊的唯一的方法只有是不斷的嘗試和出錯, 不斷對隨機數進行遞增,然後檢視新的雜湊值是否匹配。
按照當前的目標值 2 的 187 次方,這個網路在找到一個有效的區塊前,必須進行 2 的 69 次方次的嘗試。一般來說,每隔 2016 個區塊,這個目標值就會被網路調整一次 ,因此網路中平均每隔 10 分鐘就會有一些節點產生出一個新的區塊。為了補償這些礦工的計算工作,每一個區塊的礦工有權要求包含一筆發給他們自己的 12.5BTC(不知道從哪來的)的交易。另外,如果任何交易,它的總的輸入的面值比總的輸出要高,這一差額會作為“交易費用”轉給礦工。順便提一下,對礦工的獎勵是比特幣發行的唯一途徑,創世狀態中並沒有比特幣。
為了更好的理解挖礦的目的,讓我們來檢測一下,當惡意攻擊發生時會發生什麼。 由於比特幣的底層的加密技術眾所周知是安全的,所以這攻擊者的目標將是比特幣系統中的某個部份,那就是沒有被密碼直接保護的:交易的次序。攻擊者的策略其實很簡單:
1. 傳送 100 BTC 到一個商人,以兌換一些商品 (最好是快速交易的數字商品)
2. 等待商品的發貨
3. 建立另一個交易,傳送同樣的 100 BTC 給自己
4. 嘗試讓網路相信他發給他自己的那個交易是最新出現的。
一旦步驟 1發生,幾分鐘後,一些礦工就會把這個交易打包進一個區塊,假設宣告該區塊編號是270000。大約一個小時後, 在那個區塊之後又會有新增的五個區塊新增到區塊鏈中,這五個區塊都間接的指向了那個交易,從而“確認”了那交易是真的。在這一刻,商家接收到了貨款,並且發出了商品。因為我們假設是一個數字商品,所以攻擊者能立刻就收到貨。現在攻擊者建立另一個交易,向他自己的另一個賬戶傳送這 100 BTC 。如果這個攻擊者只是簡單的釋放了這個交易,那麼這個交易將不會被執行。礦工將會嘗試執行 APPLY(S,TX) ,注意那個 TX 消耗一個在以太坊狀態中已經不存在的 UTXO。因此,這個攻擊者建立了一個比特幣區塊鏈的“分支” , 開始挖取區塊 270000的另一個版本,這個版本指向同樣的區塊 269999 作為一個父親,但是用這新的交易替換了舊的。因為這區塊的資料是不同的 , 這就需要為相關的區塊重新做工作證明。 此外,這個攻擊者的新的版本的區塊 270000 有一個不同的雜湊,所以這已存在的區塊 270001 到 270005 不會指向它。因此,這原來的鏈和這攻擊者的新鏈是完全獨立的。區塊鏈的規則是:在分支中最長的區塊鏈鏈將會變成真正的鏈。所以合法的礦工將會繼續在 270005 這條鏈上工作,同時攻擊者自己一個人單獨的工作在新版本的 270000 這條鏈上。為了讓攻擊者他自己的區塊成為最長,他需要的計算能力比其他網路的總和還要多(“51%攻擊”)。比特幣的區塊依賴之前所有區塊的雜湊。一個擁有巨大計算能力的攻擊者可以重新設計工作的證明(PoW),並最終獲得大量的比特幣。
4、默克爾樹(Merkle Trees)
在默克爾樹中只要提供少數的幾個節點就可以給出一個分支有效性的證明
試圖改變默克爾樹的任一部分都將會導致鏈條上在某處發生不一致的情況
比特幣的一個重要特性,這區塊是存在一個多級資料結構中的 。一個區塊的“雜湊值”實際上只是這個區塊的頭資訊的雜湊值,一個大約 200 個位元組的資料,其中包含了時間戳,隨機數,上一個區塊的雜湊和一個儲存了這個區塊中所有交易的稱之為默克爾樹的資料結構的根雜湊。 默克爾樹是一種二叉樹,包含了一組節點,它們的含有基礎資訊的樹根有大量的葉子節點,一組中間節點,每一個節點都是它的 2 個子節點的雜湊,然後,最終的一個根節點,也是由它的 2 個子節點的雜湊形成,代表著這樹的“頂端”。 這個默克爾樹的目的是允許在一個區塊中的資料能夠被零散的傳遞:一個節點只能從一個源來下載一個區塊的頭資訊,樹的一小部分關聯著另一個源 ,並且仍然可以保證所有的資料都是正確的。之所以這樣做行得通,是因為雜湊值都是向上傳導的:如果一個惡意的使用者試圖在默克爾樹的底部替換一個假的交易,這個更改將導致上面的節點發生變化,然後上面的節點的變化又會導致上上面的節點發生變化,最終改變這個數根節點,因此也改變了這區塊的雜湊,導致這個協議把它註冊成一個完全不同的區塊 (幾乎可以肯定是一個無效的工作證明)。
這默克爾樹協議對比特幣的長期可持續發展是必不可少的。比特幣網路中的一個“完整節點” , 截止到 2014 年,佔用了大約 15G 的磁碟空間,並且每月正在以 10 億位元組的速度遞增。目前,這對於電腦來說是沒有問題的,但是在手機上卻是不現實的。在以後的將來,只有商業的和業餘愛好者才能參與玩比特幣。一個稱之為 “簡化支付驗證(simplified payment verification)” (SPV)的協議 允許另一種型別的節點存在,這種節點稱之為 “輕節點(light nodes)”, 其下載區塊的頭資訊,在這區塊頭資訊上驗證工作證明,然後只下載與之交易相關的“分支” 。 這使得輕節點只要下載整個區塊鏈的一小部分,就可以安全地確定任何一筆比特幣交易的狀態和賬戶的當前餘額。
5、山寨區塊鏈應用
將底層的區塊鏈理念應用到其他概念上的想法也有很長的歷史了。在 2005 年, 尼克薩博提出了這個概念 “用所有權保護產權(secure property titles with owner authority)”, 文件描述了“複製資料庫的新技術”將如何使用一個基於區塊鏈的系統來儲存誰擁有土地的註冊登記資訊, 建立一個精心設計的框架,包括“宅地”,“逆權侵佔”和 “地稅”等概念。然而,不幸的是,那個時候沒有一個有效的複製資料庫資訊,因此,協議從未付諸實踐。然而,在 2009 年之後,比特幣的去中心化的共識一被開發出來,許多山寨應用就迅速湧現出來。
Namecoin – 創建於 2010 年,名字幣是一個去中心化的名字註冊資料庫 。 在去中心化的協議中,像 Tor, Bitcoin 和 BitMessage, 這些需要有一些識別賬號的方法,這樣使用者就可以和其他人進行互動了,但是現存在的所有的解決方案中,這個識別符號都是一個偽隨機的雜湊字串像 1LW79wp5ZBqaHW1jL5TCiBCrhQYtHagUWy。在理想情況下,人們一般都希望擁有一個像 “george” 這樣的名字。然而,問題是如果一個使用者可以建立一個名為 “george” 的賬號的話, 那麼其他人也可以使用相同的過程來為自己註冊一個名為 “george” 的賬號,並且冒充他們。唯一的解決方案只能是先申請原則,第一個人可以註冊成功,其他人都註冊失敗 – 這是一個完全適用於比特幣的共識協議的解決方案。域名幣是利用區塊鏈實現名稱註冊系統的最早的、最成功的系統。
Colored coins – 彩色幣的目的是為人們在比特幣區塊鏈上建立自己的數字貨幣,或者,其他一般意義上的貨幣 – 數字令牌提供服務。依照彩色幣協議,人們可以通過為某一特別的比特幣 UTXO 指定顏色,發行新的貨幣。該協議遞迴地將其它 UTXO 定義為與交易輸入 UTXO 相同的顏色。這就允許使用者保持只包含某一特定顏色的 UTXO,傳送這些 UTXO 就像傳送普通的比特幣一樣,但是需要通過回溯全部的區塊鏈判斷收到的 UTXO 顏色。
Metacoins – 元幣的理念是在比特幣區塊鏈上建立新的協議,利用比特幣的交易儲存元幣的交易,但是採用了不同的狀態轉換函式 APPLY’。因為元幣協議不能阻止比特幣區塊鏈上的無效的元幣交易,所以增加一個規則如果 APPLY’(S,TX)返回錯誤,這一協議將預設APPLY’(S,TX) = S。這為建立任意的、先進的不能在比特幣系統中實現的密碼學貨幣協議提供了一個簡單的解決方法,而且開發成本非常低,因為挖礦和網路的問題已經由比特幣協議處理好了。
因此,總得來說,有 2種構建共識的方法:一是構建一個獨立的網路,二是在比特幣之上建立一個協議。 前一種方法,在名字幣這樣的應用中相當的成功,但很難實現;每一個獨立的實現都需要啟動一個獨立的區塊鏈,以及構建和測試所有必要的狀態轉移函式和網路程式碼。此外,我們預測去中心化技術的應用會以指數級別的速度增長,絕大多數的應用會因為太小,而不能保護好它們自己的區塊鏈,另外,我們還注意到存在大量去中心化的應用程式,特別是去中心化的自治組織,它們需要相互作用。
基於比特幣的方法,有一個缺陷,它沒有繼承比特幣的簡化支付驗證(SPV)的功能。SPV 可以讓比特幣使用區塊鏈的深度來做驗證;在某種程度上,一旦一個交易已經離的足夠遠了,就可以放心地說,這個交易就是合法的狀態的一部分。基於區塊鏈的元協議,從另一方面說,不能強制區塊鏈不包含用它們自己的協議驗證無效的交易。因此,一個完全安全的 SPV 元協議的實現需要從比特幣區塊鏈的末端一直掃描到頂端,這樣才能確定某些交易的合法性。
目前,基於比特幣的元協議的所有“輕”應用的實現都依賴於一個受信任的伺服器來提供資料,這可以說是一個非常不理想的,尤其是當一個加密貨幣的需要消除信任的時候。
6、指令碼
即便是沒有任何擴充套件,這比特幣的協議實際上確實促進了一個弱化版的“智慧合約”的概念。UTXO在比特幣中不是隻被一個公鑰持有, 而是還被在一個基於堆疊的程式語言組成的複雜的指令碼所持有著。 在這個範例中,一個交易消耗的 UTXO 必須提供滿足指令碼的資料。實際上,這最基本的公鑰所有權機制也是通過一個指令碼來實現的:這個指令碼使用一個橢圓曲線簽名作為一個輸入,驗證擁有這個 UTXO 的交易和地址,如果驗證成功,則返回 1,不然則返回 0。其他,更加複雜的指令碼存在於各種複雜的用例中。 例如,你可以構造一個指令碼,它要求從給定的三個私鑰中,至少要選其中的 2 個來做簽名驗證(“多重簽名”),這個對公司賬本,儲蓄賬戶等來說非常有用。指令碼也能用來對解決計算問題的使用者支付報酬。人們甚至可以建立這樣的指令碼“如果你能夠提供你已經發送一定數額的的狗幣給我的簡化確認支付證明,這一比特幣就是你的了”,本質上,比特幣系統允許不同的密碼學貨幣進行去中心化的兌換。
然而,在比特幣中的指令碼語言有幾個重要的限制:
缺乏圖靈- - 完備– 那就是說,雖然比特幣指令碼語言支援的計算方式很多,但是它不是所有的都支援。在主要類別中缺失迴圈。
它這樣做的目的是為了防止對交易的驗證出現死迴圈;理論上,它的指令碼是可以克服這個障礙的,因為任何的迴圈都可以通過 if 語句
重複多次底層程式碼來模擬,但是這樣的指令碼執行效率非常低下。
值的盲區 – 一個 UTXO 指令碼沒有辦法提供資金的顆粒度可控的出金操作。比如, 一個預言合約(oracle contract )的其中一個強大
的用例就是一個套期保值的合約,A 和 B 都把價值1000$的 BTC 放到合約中,30 天后,這個合約把價值 1000$的 BTC 發給了 A,剩下的發給了
B。 這就需要合約要確定 1BTC 以美元計值多少錢。然而,因為 UTXO 是不可分割的,為實現此合約,唯一的方法是非常低效地採用許多有不同面值
的 UTXO(例如有 2^k 的 UTXO,其中 K 可以最大到 30)並使預言合約挑出正確的 UTXO 傳送給 A 和 B。
狀態缺失 – UTXO 要麼被使用了,要麼沒有被使用;這會使得多階段的合約和指令碼沒有機會保持任何其他的內部狀態。這使得製作多階段
的期權合約、去中心化的交換協議或兩階段加密承諾協議變得困難(對於安全計算獎金來說是必要的)。這也意味著,UTXO 只能用於構建簡
單的、一次性的合約,而不是更復雜的“有狀態”的合約,比如去中心化的組織,並且使得元協議難以實現。
區塊鏈盲區 -UTXO 對某些區塊鏈資料視而不見,比如隨機數和之前的區塊的雜湊。這嚴重限制了博彩和其他一些類別的應用,因為它剝奪
了一種潛在的有價值的指令碼語言:隨機數!也就是在比特幣的指令碼中是沒有隨機數的。
因此,我們看到了在加密貨幣之上構建高階應用程式的三種方法:一,構建一個新的區塊鏈,二,在比特幣之上使用指令碼,三,在比特幣之上構建一個元協議。 構建一個新的區塊鏈可以無限制擴充套件功能集,但是這樣做非常消耗時間。使用指令碼很容易實現和標準化,但在其功能上非常有限,而元協議雖然容易,但在可伸縮性方面卻存在缺陷。在以太坊中,我們打算建立一個替代性的框架,它提供了更大的開發和更強大的輕客戶屬性,同時允許應用程式共享一個經濟環境和區塊鏈安全。
二、以太坊
1、以太坊
以太坊的目的是建立一種去中心化應用的協議,提供一套對大量的去中心化應用程式非常有用的新方案,特別強調快速開發,對小的和少數人使用的應用也非常安全(小而使用人少的應用容易被51%攻破),以及不同的應用程式之間能夠有效的互動。以太坊通過建立在本質上是抽象的基礎層來完成這一工作:一個區塊鏈其內建了圖靈完備的程式語言,允許任何人編寫智慧合約和去中心化的應用程式,在這些應用程式中,他們可以建立任意的屬於他們自己的規則、交易格式和狀態轉換函式。名字幣的一個簡單版本在以太坊可以用兩行程式碼來編寫完成,而其他協議如貨幣和信用系統則可以用不到 20 行的程式碼來構建。智慧合約-包含價值而且只有滿足某些條件才能開啟的加密箱子-也能在我們的平臺上構建,並且因為圖靈完備性、價值知曉(value-awareness)、區塊鏈知曉(blockchain-awareness)和多狀態所增加的力量,遠比特幣指令碼所能提供的功能強大得多。
2、以太坊虛擬機器
以太坊是一個可程式設計的區塊鏈,不僅僅是給使用者一些預定義操作(如比特幣只交易),以太坊允許使用者建立屬於他們自己的複雜的操作。以太坊作為一個平臺為不同的區塊鏈應用提供服務。
狹義來說,以太坊是一系列協議,其核心就是一個以太坊虛擬機器,能執行遵守協議的任何複雜的程式碼。以太坊虛擬機器是圖靈完備的,開發者可以在虛擬機器上使用像 javascript,python 這樣的友好的程式語言來建立應用。
和任何的區塊鏈一樣,以太坊包含了一個點對點的網路協議。這以太坊區塊鏈是被連結著這個網路的各個節點維護和更新的。網路中的各個節點的虛擬機器都執行相同的指令來共同維護區塊資料庫,因為這個原因,以太坊有時候被人稱為“世界計算機”。
以太坊全網的大規模平行計算不是隻為了提計算效率,而是為了保證全網的資料一致性。實際上,這使得在乙太網上的 運算要比傳統的電腦慢的多,成本也昂貴得多。全網中的每一臺虛擬機器的執行都是為確保全網資料庫的一致性。去中心化的一致性給全網極端的容錯能力;抗審查能力和永不宕機能力等!
3、以太坊賬戶
以太坊的基本單元是賬號。每一個賬戶都有一個 20 個位元組長度的地址 。以太坊區塊鏈跟蹤每一個賬號的狀態,區塊鏈上所有狀態的轉移都是賬戶之間的令牌(令牌即以太幣)和資訊的轉移。以太坊有 2 種賬戶型別:
外部賬號,簡稱 EOA,是由私鑰來控制的。
合約帳戶,由合約程式碼來控制,且只能由一個 EOA 賬號來操作。
對於大多數使用者來說,最基本的區別在於,使用者掌握著 EOA 賬號,因為使用者掌握著控制 EOA 賬號的私鑰。而合約賬號由內部程式程式碼來控制的,當然掌控私鑰的 EOA 賬戶可以通過編寫特定的程式程式碼來掌控合約賬戶。流行的術語“智慧合約”就是合約賬號中的程式碼,當一個交易被髮送到該賬戶時,合約中的程式碼就會被執行。使用者可以通過把程式碼部署到區塊鏈中來建立一個新合約,也即建立了一個新的合約賬戶。
合約賬戶只有在 EOA 賬戶發出一個指令的時候才會去執行一個操作。所以一個合約賬戶是不可能自己去執行一個操作的,如生產一個隨機數或執行一個 API 呼叫等,它只有在 EOA 賬戶作出確認的情況下才會去做這些事情。這是因為以太坊要求節點能夠對計算的結果無論對錯都達成一致,這就對操作有了一個必定會執行的要求。
在以太坊中,全網的狀態是由被“賬戶”的物件組成的,賬戶之間可以直接的進行價值和資訊的轉移,一個以太坊的賬戶包含下面 4 個欄位:
• 隨機數, 一個計數器,用以確保每個交易都只會被處理一次
• 賬戶當前的 以太幣額度
• 賬戶的 合約程式碼, 如果有的話
• 這個賬戶的 儲存 (預設空)
“以太幣” 是以太坊主要的內部加密燃料,並且被用來支付交易的費用。一般情況下,有 2 種類型的賬戶: 外部擁有的賬戶,被私鑰控制的,和 合約賬戶, 被合約程式碼控制的。外部擁有的賬戶沒有程式碼,使用者可以通過一個外部賬戶來建立和簽名一個交易來送一個訊息;合約賬戶中,每次當這個合約收到一個訊息的時候,它的程式碼就會被啟用,允許它讀取這個訊息,並且寫入到內部儲存中,然後按照一定順序傳送其他的訊息或建立合約等。
4、訊息和交易
名詞“交易”在以太坊中是指簽名的資料包,這個資料包中儲存了從外部賬戶傳送的訊息,交易包含以下內容:
• 訊息的接收者
• 一個可以識別傳送者的簽名
• 傳送方給接收方的以太幣的數量
• 一個可選的資料欄位
• 一個 STARTGAS 值, 表示執行這個交易允許消耗的最大計算步驟
• 一個 GASPRICE 值, 表示傳送方的每個計算步驟的費用
前面三個是每一個加密貨幣都有的標準欄位。預設情況下第四個資料欄位沒有任何功能,但是合約可以訪問這裡的資料;舉個例子,如果一個合約是在一個區塊鏈上提供域名註冊服務的,那麼它就會想把這資料欄位中的資料解析成 2 個欄位,第一個欄位是域名,第二個欄位是域名對應的 IP 地址。這個合約會從資料欄位中讀取這些值,然後適當把它們儲存下來。
這個 STARTGAS 和 GASPRICE 欄位 是以太坊的預防拒絕式攻擊用的,非常重要。為了防止在程式碼中出現意外或敵對的無限迴圈或其他計算浪費,每個交易都需要設定一個限制,以限制它的計算總步驟是一個明確的值。這計算的基本單位是“汽油(gas)”; 通常,一個計算成本是一個 1 滴汽油,但是一些操作需要消耗更多的汽油,因為它們的計算成本更高。在交易資料中每一個位元組需要消耗 5 滴汽油。這樣做的目的是為了讓攻擊者為他們所消耗的每一種資源,包括計算,頻寬和儲存支付費用;所以消耗網路資源越多,則交易成本就越大。
5、訊息
合約有能力向其他合約發生“訊息”。訊息是虛擬的物件,它從來不會被序列化,而且只存在於以太坊的執行環境中。一個訊息包含以下內容:
• 訊息的傳送者 (隱式)
• 訊息的接收者
• 與訊息一起傳送的以太幣的數量
• 一個可選的資料欄位
• 一個 STARTGAS 值
從本質上說,一個訊息就像一個交易, 只是它是由一個合約產生的而不是一個外部使用者。一個正在執行程式碼的合約,當執行到 CALL 程式碼時,會產生並執行一個訊息。就像一個交易,一個訊息會導致接收方的賬戶執行它的程式碼。因此,合約之間是可以互相發生作用的。
6、以太坊狀態轉移函式
以太坊的狀態轉移函式 APPLY(S,TX) -> S' 可以被定義成下面的:
1. 檢查這個交易是不是合法的 ,簽名是不是合法的, 這隨機數是不是匹配這個傳送者的賬戶,如果答案是否定的,那返回錯誤。
2. 用 STARTGAS * GASPRICE 計算交易的費用,並且從簽名中確定這個傳送者的地址。 從傳送者的餘額中減去費用,並且增加發送者的隨機值。
如果餘額不夠,則返回錯誤。
3. 初始化 GAS = STARTGAS, 並根據這交易中的位元組數拿走一定量的汽油。
4. 把交易的值從傳送的賬戶轉移到接收者的賬戶。如果接收者的賬戶還不存在,就建立一個。如果這個接收者的賬戶是一個合約,
那麼就執行合約的程式碼直到完成,或者報汽油消耗光的異常。
5. 如果值轉移失敗了,因為傳送者沒有足夠多的餘額,或程式碼執行消耗光了汽油,恢復除了支付的費用外的所有的狀態,並且把這個費用新增到礦工的賬戶上。
6. 另外,把所有剩下的汽油退還給傳送者,然後把用於支付費用的汽油傳送給礦工。
舉例,假設合約的程式碼是這樣的:
if !self.storage[calldataload(0)]:
self.storage[calldataload(0)] = calldataload(32)
注意:真實的合約程式碼是用底層的 EVM 程式碼編寫的;上述這個例子是用一個叫 Serpent 的高階語言寫的。
假設這個合約的儲存開始是空的,並且傳送了一個交易,其中包含 10 個以太幣,2000 個汽油,汽油價格是 0.001 比特幣,和 64 位元組的資料,其中 0-31 位元組代表數字 2,32-63 位元組代表字串 CHARLIE。在這個案例中,這狀態轉移函式的處理如下:
1. 檢查者交易是否有效並且格式完好。
2. 檢查者交易的傳送者是否至少有 2000 * 0.001 = 2 以太幣。如果有,則從傳送者的賬戶中減去 2 以太幣。
3. 初始化 汽油(gas)= 2000;假設這個交易是 170 個位元組長度並且每個位元組的費用是 5,那麼減去 850,汽油還剩 1150。
4. 從傳送者的賬戶減去 10 個以太幣,並且新增到合約的賬戶中。
5. 執行合約的程式碼. 在這裡例子中:檢查合約的儲存的第 2 個索引是否已經被使用,注意到它沒有,然後就把這資料儲存的第二個索引的值
設定為 CHARLIE. 假設這個操作消耗了 187 個汽油,那麼剩下的汽油總量是 1150 – 187 = 963
6. 把 963 * 0.001 = 0.963 以太幣加到傳送者的賬戶,然後反正結果狀態。
如果交易的接收端沒有合約,那麼這總的交易費用就簡單的等於汽油的價格乘以這個交易的位元組長度,與交易一起傳送的資料欄位的資料將無關重要。
注意,在恢復這個方面,訊息和交易的處理方式是相同的: 如果一個訊息執行消耗光了汽油,那麼這訊息的執行和其他被觸發的執行都會被恢復,但是父類的執行不會恢復。
7、程式碼執行
以太坊的合約程式碼是用底層的基於堆疊的位元組碼語言來編寫的,被稱為 “以太坊虛擬機器程式碼” or“EVM 程式碼”。這程式碼有一系列的位元組組成,其中每一個位元組都標識一個操作。在一般情況下,程式碼的執行是一個無限迴圈,直到程式碼執行結束或遇到錯誤,或檢測到 STOP 或 RETURN 指令。這些操作有三種類型的空間可用於儲存資料:
• 堆疊, 一種後進先出的容器
• 記憶體, 一種無線擴充套件的位元組陣列
• 合約的持久化 儲存, 一種鍵值對的方式. 不像堆疊和記憶體,計算結束後將會被重置, 儲存將長期儲存。
程式碼還可以訪問值(以太幣),傳送者,傳入的訊息的資料,以及區塊的頭資訊,並且也可以返回一組位元組陣列當做輸出。
8、區塊鏈和挖礦
這以太坊的區塊鏈和比特幣的區塊鏈有很多相似的地方,也有很多不同的地方。這個以太坊和比特幣在區塊鏈體系中最重要的不同點是 :以太坊的區塊同時包含了交易列表和最近區塊的狀態。除此之外,2 個其他的值,區塊的編號和難度值也存在在區塊中。以太坊中最基本的區塊驗證演算法如下:
1. 檢查上一個區塊是否存在和其有效性。
2. 檢測這區塊的時間戳,是不是比上一個區塊的大,並且小於 15 分鐘
3. 檢查這區塊編號,難度值,交易根(transaction root) , 叔根(uncle root)和汽油限制是否有效
4. 檢查這區塊的工作證明是否有效
5. 把 S[0] 設定成上一個區塊的末端的狀態
6. 讓 TX 成為這區塊的交易列表,如果有 n 個交易。則做 for 迴圈 For i in 0...n-1, 設定S[i+1] = APPLY(S[i],TX[i])。
如果任何一個應用發生錯誤,或這區塊中汽油的總的消耗達到了 GASLIMIT, 則返回一個錯誤。
7. 讓 S_FINAL 等於 S[n], 但是把支付給礦工的獎勵新增到這區塊裡。
8. 檢查這個狀態 S_FINAL 的默克爾樹樹根是不是和區塊頭資訊中所提供的狀態根是一樣的。如果是,則區塊有效,不然則無效。
乍看上去,這種方法似乎效率很低,因為它需要將整個狀態儲存在每個塊中,但在現實中,效率應該與比特幣相當。原因在於,狀態儲存在樹結構中,並且每個塊後,只需要修改樹的一小部分。此外,由於所有的狀態資訊都是最後一個區塊的一部分,所以不需要儲存整個區塊鏈的歷史——這一策略,如果它可以應用於比特幣,那麼它的磁碟空間將節省 5-20 倍。
以太坊網路中交易會被驗證這網路的節點收集起來。這些“礦工”在以太坊網路中收集、傳播、驗證和執行交易,然後整理歸檔這些交易,打包成一個區塊,與別的礦工競爭將區塊新增到區塊鏈中,新增成功的礦工將收到獎勵。通過這樣的措施,鼓勵人們為區塊鏈全網提供更多的硬體和電力支援。
三、應用
1、應用
以太坊框架本身並沒有什麼特別的功能。就好像 程式語言一樣,它做什麼,都是由企業或開發者自己來決定的。如,複雜的金融合約的自動化。比特幣可以讓使用者不通過第三方機構,如銀行,政府等就可以直接兌換貨幣。但是以太坊的介入可能會產生更加深遠的影響,因為任何複雜的金融操作都是可以自動被執行的,並且可以寫成程式碼在以太坊上執行。當然除了金融外,任何情況下,只要對信用、安全、和持久有極高的要求,比如資產註冊登記,投票,管理和物聯網等都有可能受到以太坊平臺的影響。
一般來說,在以太坊上有三種類型的應用。第一種是金融應用,這包括 子貨幣,金融衍生品,套期保值合約,和一些僱傭合同等。第二類是半金融應用,這裡有錢的存在但也有很重的非金錢的方面;最後,還有線上投票和去中心化治理這樣的完全的非金融應用。
2、參考資料
以太坊白皮書原文:https://github.com/ethereum/wiki/wiki/White-Paper相關推薦
區塊鏈入門 -- 01 區塊鏈介紹
一、比特幣的現有概念介紹1、歷史 去中心化的貨幣概念,像產權登記等已經存在了幾十年了。上世紀80年代和90年代的匿名電子現金協議主要使用了一種被稱為“喬姆盲籤(Chaumian Blinding)”的加密技術,這種技術為這些新貨幣提供了很高的隱私保護,但是由於他
區塊鏈入門教程區塊鏈共識算法分布式一致性算法Paxos
解決辦法 出現 後來 得到 pos 需要 之一 如果 區塊 分布式一致性算法Paxos Paxos是一種基於消息傳遞的分布式一致性算法,由Leslie Lamport(萊斯利·蘭伯特)於1990提出。是目前公認的解決分布式一致性問題的最有效算法之一。 要解決的問題及應用場景
區塊鏈入門教程Solidity教程地址類型介紹
intro 普通 eve 簡單 根據 test 停止 erl sets 兄弟連區塊鏈入門教程Solidity教程地址類型介紹 地址類型(Address)地址類型address是一個值類型,地址:?20字節(一個以太坊地址的長度),地址類型也有成員,地址是所有合約的基礎支持的
區塊鏈學習筆記01(基本介紹)
1、區塊鏈的定義區塊鏈:區塊鏈是一種按照時間順序將資料區塊以順序相連線、並以密碼學方式保證的不可篡改和不可偽造的分散式賬本(也稱資料庫)。它具有不可篡改、防偽、可追溯等特性,區塊鏈通過競爭機制,產生記賬權,保證記賬節點的去中心和所有記賬節點賬本資料的一致性 2、區塊鏈的結構區塊鏈結構:區塊(區塊頭 相當於頁
天使數貸--區塊鏈入門知識介紹
天使數貸是一家區塊鏈的科技公司,我是它的位元狗。今天我帶著一些剛入門區塊鏈應用的人來了解一下什麼是區塊鏈,若有錯誤,希望大家及時在評論區回覆我,我看到會第一時間解答的。 天使數貸--區塊鏈定義 區塊鏈是一種基於P2P網路、整合了密
區塊鏈入門:如何簡單易懂地介紹區塊鏈(圖文)
原標題:區塊鏈是什麼,如何簡單易懂地介紹區塊鏈? 區塊鏈目前就處於一個人人都談區塊鏈,卻無法感知其實際技術魅力的階段,正是因為此,做出區塊鏈的殺手級應用就至關重要,要做到這一點就需要進行各種場景的探索。 2月7日,快播CEO王欣出獄,在與58同城CEO姚勁波、YY董事長
區塊鏈入門(2):搭建以太坊私有鏈(private network of ethereum),以及挖礦的操作..
percent symbol 令行 sans miners margin ima ear 建立 在做一些測試工作的時候, 為了方便控制以及更快的進入真正的測試工作,可能需要搭建一個私有的以太坊網絡. 而以太坊節點之間能夠互相鏈接需要滿足1)相同的協議版本2)相同的netwo
區塊鏈入門(5)Truffle 項目實戰,Solidity IDE, 智能合約部署
第四章 margin 其中 exports nba 接口 ive 另一個 date 在上一張我們學習了Truffle項目的創建,部署等相關內容,今天我們就來實戰一下. 今天我們要做3件事: 1) 學習搭建一個Solidity IDE(Remix).
區塊鏈入門教程
部分 -a 媒體 sha 要求 title 寫入 機制 核心 區塊鏈(blockchain)是眼下的大熱門,新聞媒體大量報道,宣稱它將創造未來。 可是,簡單易懂的入門文章卻很少。區塊鏈到底是什麽,有何特別之處,很少有解釋。 下面,我就來嘗試,寫一篇最好懂的區塊鏈
區塊鏈入門視頻?國外視頻幫你快速入門了解區塊鏈!!!
自動化 比較 sans 公開 但是 條件 快速 xheditor 流行 還不知道區塊鏈是什麽呢~快來看看老外幫你5分鐘入門區塊鏈!!!詳情可以看視頻:潮流國外新鮮科技視頻 更多好玩好看充滿科技感富有知識的現代國外視頻請關註新浪微博區塊鏈技術如今非常的流行,但是,區塊鏈到底
區塊鏈入門學習
.com 入門學習 load tar nload target 區塊鏈技術 nbsp http 一:學習資料 1:區塊鏈技術指南 詳情 下載地址區塊鏈入門學習
區塊鏈入門
detail core 實驗 www. 新經濟 ech isp 技術分享 for C#區塊鏈零基礎入門,學習路線圖一、1分鐘短視頻《區塊鏈100問》了解區塊鏈基本概念http://tech.sina.com.cn/zt_d/blockchain_100/二、C#區塊鏈 智能
區塊鏈入門與去中心化應用實戰
證明 清晰 添加節點 簡單 鞏固 lan 問題 框架 ide 第1章 課程簡介與學習安排本章主要介紹為什麽要開設這門課,課程目標是什麽,誰適合學習這門課以及學習這門課需要哪些要求,然後詳細介紹本課程要講的主要內容,希望通過這章的學習,可以讓大家對課程有一個整體的,清晰的了解
兄弟連區塊鏈入門教程EOS源碼分析(2)運行
成功 單個 peer config 多節點 個數 put ddr 端口 EOS安裝完畢後,就可以運行EOS程序了。目前支持三種方式的運行,分別是: -?本地私有節點運行????在本地局域網中部署EOS節點,提供EOS服務,節點可以單個,也可以部署多節點-?在測試公網下運行?
兄弟連區塊鏈入門到精通視頻教程通過接口查詢幣種的提幣情況-tether
手續費 draw imp ddr address fun amp status 查詢 package main import ("errors""fmt""math""strconv""
兄弟連區塊鏈入門到精通教程基礎開發通過接口查詢tron提幣情況
arr module min value result ESS action rtb sed 兄弟連區塊鏈入門到精通教程基礎開發通過接口查詢tron提幣情況: package main import ( "errors" "fmt" "math"
兄弟連區塊鏈入門到精通教程基礎開發通過接口查詢xrp提幣情況
tran package account nil print data 數量 兩個 %d package main import ( "errors" "fmt" "math" "strconv" "strings" "g
兄弟連區塊鏈入門到精通教程區塊鏈共識算法分布式一致性算法Raft
拒絕 遞增 區塊 ack 序列 通知 小時 日誌同步 運行 Paxos自1990年提出以後,相當長時間內幾乎已成為分布式一致性算法的代名詞。但因其難以理解和實現,目前知名實現僅有Chubby、Zookeeper、libpaxos幾種,其中Zookeeper使用的ZAB對Pa
兄弟連區塊鏈入門教程分享區塊鏈POW證明代碼實現demo
fault dem val == 否則 缺點 ESS lang pos 這裏強調一下區塊鏈的協議分層?應用層?合約層?激勵機制?共識層?網絡層?數據層上 一篇主要實現了區塊鏈的 數據層,數據層主要使用的技術就是對數據的校驗,求hash。這裏介紹工作量證明POW, POW是屬
兄弟連區塊鏈入門教程eth源碼分析p2p-udp.go源碼分析(二)
targe man sys who endpoint exp tex its too ping方法與pending的處理,之前談到了pending是等待一個reply。 這裏通過代碼來分析是如何實現等待reply的。pending方法把pending結構體發送給addpen