區塊鏈的基礎知識(區塊鏈教程(二):基礎知識介紹)
注:本教程為技術教程,不談論且不涉及炒作任何數字貨幣
本次組隊學習重點在于以太坊基礎知識、以太坊客戶端以及以太坊solidity編程,因此本節教程重點在于以太坊核心知識點的掌握,區塊鏈部分的基礎知識可以作為補充,請學習者量力而行。另外若學習者覺得本節內容難度太高,可以先對基本知識點有一個概覽,在第二節以及第三節實戰內容學習完成之后再深入學習本節內容。
一、區塊鏈簡介
1.1、區塊鏈與區塊鏈技術
在閱讀本教程之前,大家對比特幣原理不太了解同學可以先閱讀下此博客~,大家對比特幣有簡單了解后對于區塊鏈會有更好的認識。
區塊鏈是將記錄(區塊)通過密碼學串聯并加密的鏈式數據結構。而區塊鏈技術,是通過P2P網絡和區塊鏈來實現數據存儲的去中心化、不可逆和不可篡改。比特幣正是構建在區塊鏈技術上的典型應用。通過區塊鏈技術,我們可以將信息(數據、程序)保存在區塊上并接入到區塊鏈中,這樣就實現了信息的去中心化存儲、不可逆和不可篡改。區塊鏈應用是指利用區塊鏈技術開發的應用。
1.2、區塊鏈歷史
2008年,一個網名叫中本聰(Satoshi Nakamoto)的人發表了一篇名為《比特幣:一種點對點電子貨幣系統》的論文,論文中首次提到了“區塊鏈”這一概念。2009年,中本聰創立了以區塊鏈為底層技術的比特幣網絡,開發出了第一個區塊,被稱為“創世區塊”。該階段被稱為“區塊鏈1.0”。
由于比特幣是一個電子貨幣系統,所以主要功能就是記賬。但隨后人們發現,區塊鏈技術作為比特幣的底層技術,功能可以遠遠不止于記賬,許多關于“未知的信任”的問題,都可以通過區塊鏈來解決,例如電子存證、信息記錄等。于是在比特幣的基礎上,誕生了帶有智能合約的區塊鏈系統,即允許開發者通過編寫智能合約來實現特定的邏輯,這一階段被稱為“區塊鏈2.0”。這一階段的主要代表是以太坊。
隨后,人們想要提升區塊鏈應用的性能,于是出現了EOS、ArcBlock等系統,其特點是高性能、大吞吐量,但由于引入了超級節點、云節點等特性,弱化了“去中心化”這一特點,因此受到較大的爭議。這一階段被稱為“區塊鏈3.0”。
由于比特幣是一款電子貨幣,可擴展性較低,而所謂的“區塊鏈3.0”目前受到較大爭議,且部分項目的底層算法完全不同于典型的區塊鏈,因此學習區塊鏈2.0中的以太坊是目前學習區塊鏈的最佳方式。
1.3、區塊鏈基礎技術與算法
區塊鏈技術不是單獨的一項技術,而是一系列技術組成的技術棧,其具有以下的特點:
數據分布式存儲
存儲的數據不可逆、不可篡改、可回溯
數據的創建和維護由所有參與方共同參與
為了實現這些特點、維護區塊鏈應用的穩定運行,區塊鏈技術中包含了分布式存儲技術、密碼學技術、共識機制以及區塊鏈2.0提出的智能合約。
1.3.1、區塊
區塊鏈由一個個區塊(block)組成。區塊很像數據庫的記錄,每次寫入數據,就是創建一個區塊。
在這里插入圖片描述
每個區塊包含兩個部分。
區塊頭(Head):記錄當前區塊的特征值
區塊體(Body):實際數據
區塊頭包含了當前區塊的多項特征值。
生成時間
實際數據(即區塊體)的哈希
上一個區塊的哈希
...
1.3.2、分布式存儲技術
與傳統的數據存儲技術不同,在區塊鏈技術中,數據并不是集中存放在某個數據中心上,也不是由某個權威機構或是大多數節點來存儲,而是分散存儲在區塊鏈網絡中的每一個節點上。
在這里插入圖片描述
節點和區塊的關系是什么?
可以用共享文檔來簡單描述:所有可以訪問共享文檔的賬號就叫做節點,當然全節點需要同步共享文檔,也就是擁有全部的區塊數據區塊就是共享文檔。每個人更新了,所有人都可以查看最新的文檔
1.3.3、密碼學技術
為了實現數據的不可逆、不可篡改和可回溯,區塊鏈技術采用了一系列密碼學算法和技術,包括哈希算法、Merkle 樹、非對稱加密算法。
哈希算法
哈希算法是一個單向函數,可以將任意長度的輸入數據轉化為固定長度的輸出數據(哈希值),哈希值就是這段輸入數據唯一的數值表現。由于在計算上不可能找到哈希值相同而輸入值不同的字符串,因此兩段數據的哈希值相同,就可以認為這兩段數據也是相同的,所以哈希算法常被用于對數據進行驗證。
在區塊鏈中,數據存儲在區塊里。每個區塊都有一個區塊頭,區塊頭中存儲了一個將該區塊所有數據經過哈希算法得到的哈希值,同時,每個區塊中還存儲了前一個區塊的哈希值,這樣就形成了區塊鏈。如果想要篡改某一個區塊A中的數據,就會導致A的哈希值發生變化,后一個區塊B就無法通過哈希值正確地指向A,這樣篡改者又必須篡改B中的數據......也就是說,篡改者需要篡改被篡改的區塊以及后面的所有區塊,才能讓所有的節點都接受篡改。
Merkle樹
Merkle樹是一種樹形結構,在區塊鏈中,Merkle樹的葉子節點是區塊中數據的哈希值,非葉子節點是其子結點組合后的哈希值,這樣由葉子節點開始逐層往上計算,最終形成一個Merkle根,記錄在區塊的頭部,這樣就可以保證每一筆交易都無法篡改。
在這里插入圖片描述
非對稱加密技術
非對稱加密技術使用兩個非對稱密鑰:公鑰和私鑰。公鑰和私鑰具有兩個特點:
通過其中一個密鑰加密信息后,使用另一個密鑰才能解開
公鑰一般可以公開,私鑰則保密
在區塊鏈中,非對稱加密技術主要用于信息加密、數字簽名和登錄認證。在信息加密場景中,信息發送者A使用接收者B提供的公鑰對信息進行加密,B收到加密的信息后再通過自己的私鑰進行解密。再數字簽名場景中,發送者A通過自己的私鑰對信息進行加密,其他人通過A提供的公鑰來對信息進行驗證,證明信息確實是由A發出。在登錄認證場景中,客戶端使用私鑰加密登錄信息后進行發送,其他人通過客戶端公鑰來認證登錄信息。
RSA 算法 RSA加密算法是最常用的非對稱加密算法,CFCA在證書服務中離不了它。但是有不少新來的同事對它不太了解,恰好看到一本書中作者用實例對它進行了簡化而生動的描述,使得高深的數學理論能夠被容易地理解。 RSA是第一個比較完善的公開密鑰算法,它既能用于加密,也能用于數字簽名。RSA以它的三個發明者Ron Rivest, Adi Shamir, Leonard Adleman的名字首字母命名,這個算法經受住了多年深入的密碼分析,雖然密碼分析者既不能證明也不能否定RSA的安全性,但這恰恰說明該算法有一定的可信性,目前它已經成為最流行的公開密鑰算法。 RSA的安全基于大數分解的難度。其公鑰和私鑰是一對大素數(100到200位十進制數或更大)的函數。從一個公鑰和密文恢復出明文的難度,等價于分解兩個大素數之積(這是公認的數學難題)。
ECC 橢圓曲線算法 具體可以參見此文章:ECC橢圓曲線加密算法:介紹
1.3.4、共識機制
區塊鏈系統是一個分布式系統,分布式系統要解決都首要問題就是一致性問題,也就是如何使多個孤立的節點達成共識。在中心化系統中,由于有一個中心服務器這樣的“領導”來統一各個節點,因此達成一致性幾乎沒有問題。但在去中心化場景下,由于各個節點是相互獨立的,就可能會出現許多不一致的問題,例如由于網絡狀況等因素部分節點可能會有延遲、故障甚至宕機,造成節點之間通信的不可靠,因此一致性問題是分布式系統中一個很令人頭疼的問題。
由 Eirc Brewer 提出,Lynch 等人證明的 CAP 定理為解決分布式系統中的一致性問題提供了思路。CAP 定理的描述如下:在分布式系統中,一致性、可用性和分區容錯性三者不可兼得。這三個術語的解釋如下:
一致性(Consistency):所有節點在同一時刻擁有同樣的值(等同于所有節點訪問同一份最新的數據副本
可用性(Availability):每個請求都可以在有限時間內收到確定其是否成功的響應
分區容錯性(Partition tolerance):分區是指部分節點因為網絡原因無法與其他節點達成一致。分區容錯性是指由網絡原因導致的系統分區不影響系統的正常運行。例如,由于網絡原因系統被分為 A, B, C, D 四個區,A, B 中的節點無法正常工作,但 C, D 組成的分區仍能提供正常服務。
在某些場景下,對一致性、可用性和分區容錯性中的某一個特性要求不高時,就可以考慮弱化該特性,來保證整個系統的容錯能力。區塊鏈中常見的共識機制的基本思路正是來自 CAP 定理,部分區塊鏈應用中用到的共識機制如下表:
共識機制 應用 PoW 比特幣、萊特幣、以太坊的前三個階段 PoS PeerCoin、NXT、以太坊的第四個階段 PBFT Hyperledger Fabric
PoW(Proof of Work,工作量證明)
PoW 機制的大致流程如下:
向所有節點廣播新交易和一個數學問題
最先解決了數學問題的節點將交易打包成區塊,對全網廣播
其他節點驗證廣播區塊的節點是否解決了數學問題(完成了一定的工作量),驗證通過則接受該區塊,并將該區塊的哈希值放入下一個區塊中,表示承認該區塊
由于在 PoW 機制中,區塊的產生需要解決一個數學問題,也就是所謂的挖礦,這往往要消耗較大的算力和電力,因此節點們傾向于在最長的鏈的基礎上添加區塊,因為如果節點想在自己的鏈上添加新的區塊,那么就需要重新計算 1 個或 個這樣的數學問題(每添加一個區塊就需要計算一個)。因此在比特幣中最長的鏈被認為是合法的鏈,這樣節點間就形成了一套“共識”。
PoW 機制的優點是完全去中心化,缺點是需要依賴數學運算,資源的消耗會比其他的共識機制高,可監管性弱,同時每次達成共識需要全網共同參與運算,性能較低。
PoS(Proof of Stack,股權證明)
PoS 針對 PoW 的缺點做出了改進。PoS 要求參與者預先放置一些貨幣在區塊鏈上用于換取“股權”,從而成為驗證者(Validator),驗證者具有產生區塊的權利。PoS 機制會按照存放貨幣的量和時間給驗證者分配相應的利息,同時還引入了獎懲機制,打包錯誤區塊的驗證者將失去他的股權——即投入的貨幣以及產生區塊的權利。PoS 機制的大致流程如下:
加入 PoS 機制的都是持幣人,稱為驗證者
PoS 算法根據驗證者持幣的多少在驗證者中挑選出一個給予產生區塊的權利
如果一定時間內沒有產生區塊,PoS 就挑選下一個驗證者,給予產生區塊的權利
如果某個驗證者打包了一份欺詐性交易,PoS 將剝奪他的股權
PoS 的優點在于:
引入了利息,使得像比特幣這樣發幣總數有限的通貨緊縮系統在一定時間后不會“無幣可發”
引入了獎懲機制使節點的運行更加可控,同時更好地防止攻擊
與 PoW 相比,不需要為了生成新區塊而消耗大量電力和算力
與 PoW 相比,縮短了達成共識所需的時間
由于 PoS 機制需要用戶已經持有一定數量的貨幣,沒有提供在區塊鏈應用創立初始階段處理數字貨幣的方法,因此使用 PoS 機制的區塊鏈應用會在發布時預先出售貨幣,或在初期采用 PoW,讓礦工獲得貨幣后再轉換成 PoS,例如以太坊現階段采用的是 PoW 機制,在第四階段“寧靜”(Serenity)中將過渡到 PoS。
拜占庭將軍問題(Byzantine Generals Problem)
拜占庭將軍問題是分布式網絡中的通信容錯問題,可以描述為:
一組拜占庭將軍各領一支隊伍共同圍困一座城市。各支軍隊的行動策略限定為進攻或撤離兩種。因為部分軍隊進攻而部分軍隊撤離可能會造成災難性的后果,因此各將軍決定通過投標來達成一致策略,即“共進退”。因為各將軍位于城市不同方向,他們只能通過信使互相聯系。在投票過程中每位將軍都將自己的選擇(進攻或撤退)通過信使分別通知其他所有將軍,這樣一來每位將軍根據自己的投票和其他所有將軍送來的信息就可以知道共同投票的結果,進而做出行動。
在這里插入圖片描述
拜占庭將軍的問題在于,將軍中可能出現叛徒。假設3名將軍中有1名叛徒,2名忠誠將軍一人投進攻票,一人投撤退票,這時叛徒可能會故意給投進攻的將軍投進攻票,而給投撤退的將軍投撤退票。這就導致一名將軍帶隊發起進攻,而另外一名將軍帶隊撤退。
另外,由于將軍之間通過信使進行通訊,即使所有將軍都忠誠,也不能排除信使被敵人截殺,甚至信使叛變等情況。
假設存在叛變將軍或信使出問題等情況,如果忠誠將軍仍然能夠通過投票來決定他們的戰略,便稱系統達到了拜占庭容錯(Byzantine Fault Tolerance)。
拜占庭問題對應到區塊鏈中,將軍就是節點,信使就是網絡等通信系統,要解決的是存在惡意節點、網絡錯誤等情況下系統的一致性問題。
PBFT(Practical Byzantine Fault Tolerance) 是第一個得到廣泛應用且比較高效的拜占庭容錯算法,能夠在節點數量不小于 的情況下容忍 個拜占庭節點(惡意節點)。
二、以太坊介紹
首先我們要知道我們為什么要學習以太坊,主要有以下四個原因:
以太坊是區塊鏈2.0的代表,學習以太坊能了解到區塊鏈技術的所有知識
引入了智能合約,拓寬了區塊鏈的應用場景
對開發者友好、對用戶友好,容易編寫出簡單的區塊鏈應用,學習趣味性高
Solidity 語法與 Javascript、Go 等語言接近,易上手
2.1、以太坊簡介
區塊鏈技術常常被認為是自互聯網誕生以來最具顛覆性的技術,然而,自比特幣誕生后一直沒有很好的區塊鏈應用開發平臺。想要在比特幣基礎上開發區塊鏈應用是非常復雜繁瑣的,因為比特幣僅僅是一個加密數字貨幣系統,無法用來實現更廣闊的業務需求。以太坊是目前使用最廣泛的支持完備應用開發的共有區塊鏈系統。
和比特幣不同,比特幣只適合加密數字貨幣場景,不具備圖靈完備性,也缺乏保存實時狀態的賬戶概念,以及存在 PoW 機制帶來的效率和資源浪費的問題,而以太坊作為區塊鏈2.0的代表,目標是擴展智能合約和建立一個去中心化應用平臺,具有圖靈完備的特性、更高效的共識機制、支持智能合約等多種應用場景,使得開發者能夠很方便地在以太坊上開發出基于區塊鏈的應用。
2.1.1、以太坊的發展
2014年, Vitalik Buterin 發表了文章《以太坊:一個下一代智能合約和去中心化應用平臺》。同年,Buterin 在邁阿密比特幣會議中宣布啟動以太坊項目,并提出了多項創新性的區塊鏈技術。2015年,以太坊CCO Stephan Tual 在官方博客上宣布以太坊系統誕生,主網上線。
以太坊發展至今經歷了“前沿”(Frontier)、“家園”(Homestead)以及現在所處的“大都會”(Metropolis)三個階段。第四階段“寧靜”(Serenity)將作為以太坊的最后一個階段,目前尚未有計劃發布日期。
2.1.2、以太坊的特點
以太坊團隊和外界對以太坊的描述都是“世界計算機”,這代表它是一個開源的、全球的去中心化計算架構。它執行稱為智能合約的程序,并使用區塊鏈來同步和存儲系統狀態,以及使用名為以太幣的加密數字貨幣來計量和約束執行操作的資源成本。同時,以太坊提供了一系列的接口,使得開發者能夠通過以太坊來開發去中心化 Web 應用DApps。
2.1.3、智能合約
相比比特幣,以太坊最大的特點就是引入了智能合約。智能合約本質上就是一段編寫好的程序,可以在特定的條件下被觸發并執行特定的操作。由于區塊鏈具有不可逆和不可篡改的特點,因此智能合約與區塊鏈結合后,就成了一份“強制執行”的合約。
以太坊能夠作為一個去中心化應用平臺和”世界計算機”,其核心就是智能合約。智能合約的引入,使得開發者能夠實現許多(理論上是任何)業務邏輯。如果說比特幣是通過區塊鏈技術開發的特定計算器,那么引入了智能合約的以太坊就是基于區塊鏈技術的通用計算機。可以簡單的理解成:比特幣的交易系統就是一份寫死的智能合約,而以太坊則將智能合約的開發權限交給開發者。
以太坊提供了對智能合約的全面支持,包括編寫智能合約編程語言 Solidity 和運行智能合約的以太坊虛擬機(Ethereum Virtual Machine,EVM)。
2.1.4、幽靈協議
幽靈合約的英文是“Greedy Heaviest Observed Subtree" (GHOST) protocol,在介紹幽靈協議之前,先介紹以太坊中的叔區塊、叔塊獎勵和叔塊引用獎勵這三個概念。
在這里插入圖片描述
假設目前以太坊區塊鏈中的區塊高度(區塊鏈上的區塊個數)為6,現在產生了一筆新的交易,礦工A先將該筆交易打包成了區塊 Block 7,在礦工A將 Block 7 廣播到其他節點的這段時間里,礦工B和礦工C又分別產生了 Block 8 和 Block 9。Block 7、Block 8、Block 9 都指向 Block 6,即 Block 6 是他們的父區塊。由于 Block 7 是最先產生的,因此 Block 7 被認為是有效區塊,Block 8 和 Block 9 就是叔區塊(作廢區塊)。
在這里插入圖片描述
現在鏈上的區塊高度為7,在這基礎上又產生了新的交易,并被打包成了 Block 10。在以太坊中,Block 10 除了可以引用它的父區塊 Block 7 外,還可以引用叔區塊 Block 8 和 Block 9。并且,Block 8 和 Block 9 的礦工會因此獲得一筆獎勵,稱為叔塊獎勵,Block 10 的礦工除了基礎獎勵之外,由于引用了叔區塊,還會獲得一筆額外的叔塊引用獎勵。
幽靈協議是以太坊的一大創新。由于在比特幣中的出塊時間被設計為10分鐘,而以太坊為了提高出塊速度,將出塊時間設計為12秒(實際14~15秒左右),這樣的高速出塊意味著高速確認,高速確認會帶來區塊的高作廢率和低安全性。因為區塊需要花一定的時間才能廣播至全網,如果礦工 A 挖出了一個區塊,而礦工 B 碰巧在 A 的區塊擴散至 B 之前挖出了另一個區塊,礦工 B 的區塊就會作廢并且沒有對區塊鏈的網絡安全做出貢獻。此外,這樣的高速確認還會帶來中心化的問題:如果 A 擁有全網 30% 的算力而 B 擁有 10% 的算力,那么 A 將會在 70% 的時間內都在產生作廢區塊,而 B 在 90% 的時間內都在產生作廢區塊,這樣,B 永遠追不上 A,后果是 A 通過其算力份額擁有對挖礦過程實際上的控制權,出現了算力壟斷,弱化了去中心化。
幽靈協議正是為了解決上述問題而引入的,協議的主要內容如下:
計算最長鏈時,不僅包括當前區塊的父區塊和祖區塊,還包括祖先塊的作廢的后代區塊(叔區塊),將它們綜合考慮來計算哪一個區塊擁有支持其的最大工作量證明。這解決了網絡安全性的問題
以太坊付給以“叔區塊”身份為新塊確認作出貢獻的廢區塊87.5%的獎勵(叔塊獎勵),把它們納入計算的“侄子區塊”將獲得獎勵的12.5%(叔塊引用獎勵)。這就使得即使產生作廢區塊的礦工也能夠參與區塊鏈網絡貢獻并獲得獎勵,解決了中心化傾向的問題
叔區塊最深可以被其父母的第二代至第七代后輩區塊引用。這樣做是為了: 降低引用叔區塊的計算復雜性過多的叔塊引用獎勵會剝奪礦工在主鏈上挖礦的激勵,使得礦工有轉向公開攻擊者鏈上挖礦的傾向(即公開攻擊者可能會惡意產生大量作廢區塊,無限引用將會誘使礦工轉移到攻擊者的鏈上,從而拋棄合法的主鏈)計算表明帶有激勵的五層幽靈協議即使在出塊時間為15s的情況下也實現了了95%以上的效率,而擁有25%算力的礦工從中心化得到的益處小于3%
2.1.5、以太坊的組成部分
在以太坊中,包括了 P2P 網絡、共識機制、交易、狀態機、客戶端這幾個組成部分。
P2P 網絡:在以太坊主網上運行,可通過TCP端口30303訪問,并運行稱為 DΞVp2p 的協議。
共識機制:以太坊目前使用名為 Ethash 的 POW 算法,計劃在將來會過渡到稱為 Casper 的 POS 算法。
交易:以太坊中的交易本質上是網絡消息,包括發送者、接收者、值和數據載荷(payload)。
狀態機:以太坊的狀態轉移由以太坊虛擬機(Ethereum Virtual Machine,EVM)處理,EVM 能夠將智能合約編譯成機器碼并執行。
客戶端:用于用戶和以太坊進行交互操作的軟件實現,最突出的是 Go-Ethereum(Geth) 和 Parity。
2.1.6、以太坊中的概念
賬戶:以太坊中的賬戶類似于銀行賬戶、應用賬戶,每個賬戶有一個20字節的地址。賬戶又分為普通賬戶(又叫外部賬戶,External Owned Account, EOA)和合約賬戶(Contract)。普通賬戶是由以太坊使用者創建的賬戶,包含地址、余額和隨機數;合約賬戶是創建智能合約時建立的賬戶,包含存儲空間和合約代碼
狀態:狀態是由賬戶和兩個賬戶之間價值的轉移以及信息的狀態轉換構成的
地址:地址是一個賬戶 ECDSA 公鑰的 Keccak 散列最右邊的160位,通過地址可以在以太坊上接收或發送交易。在 Etherscan 上,可以通過地址來查詢一個賬戶的信息
交易:以太坊中的交易不僅包括發送和接收以太幣,還包括向合約賬戶發送交易來調用合約代碼、向空用戶發送交易來生成以交易信息為代碼塊的合約賬戶
Gas:Gas 是以太坊中的一種機制,用于執行智能合約或交易操作的虛擬燃料。由于以太坊是圖靈完備的,為了避免開發者無意或惡意編寫出死循環等浪費資源或濫用資源的情況,以太坊中的每一筆交易都需支付一定的 Gas (燃料費),即需支付一定的以太幣作為 Gas。Gas 的金額通常是由交易的發起者指定并支付的
挖礦:和比特幣類似,以太坊同樣通過挖礦來產生區塊。在以太坊目前的 PoW 機制下,每當一筆交易發出并廣播,就會吸引礦工來將該交易打包成區塊。每產生一個區塊都會有一筆固定獎勵給礦工,目前的固定獎勵是3個以太。同時,區塊中所有操作所需的 Gas 也會作為獎勵給礦工。與比特幣不同的是,以太坊中產生叔塊的礦工可能會獲得叔塊獎勵,引用叔塊的礦工會獲得叔塊引用獎勵
DApp(去中心化應用):通過智能合約,開發者能夠設計想要的邏輯,相當于是網站的后端。而 DApp 則相當于是一個完整的網站(前端+后端),因此 DApp = 智能合約 + Web 前端。以太坊提供了一個名為 web3.js 的 Javascript 庫,通過 web3.js 可以實現 Web 與以太坊區塊鏈的交互和與智能合約的交互,方便開發者創建 DApp
2.2、以太坊基礎
2.2.1、以太坊中的貨幣
以太坊中的貨幣稱為 以太幣,單位為以太(Ether),也稱 ETH 或符號 Ξ。以太可以被分割為更小的單位,最小的單位是 wei,1 以太 = wei。以太幣各單位的名稱及之間的關系如下表:
在這里插入圖片描述
2.2.2、以太坊錢包
以太坊錢包是用于創建和廣播交易的應用程序,常用的錢包有
MetaMask,一款基于瀏覽器擴展的錢包,可以很方便地添加到 Chrome, FireFox 等支持擴展的瀏覽器中
Jaxx,一款跨平臺、多幣種的錢包
MyEtherWallet(MEW),一款基于 Web 的錢包,可以在任何瀏覽器中運行
Emerald Wallet,一款被設計來用于以太坊經典區塊鏈的錢包,但也與其他以太坊區塊鏈兼容
MetaMask 基礎
以 Chrome 為例,訪問 Google 網上應用商店,搜索 MetaMask 并添加至 Chrome
在這里插入圖片描述
添加完成后 Chrome 會自動打開初始化頁面
在這里插入圖片描述
初次使用創建錢包
在這里插入圖片描述
為錢包設置密碼
在這里插入圖片描述
創建密碼后,MetaMask 會生成一串密語,密語是12個隨機的英文單詞,用于防止密碼忘記。密語可以直接當成密碼使用,因此需要妥善保管
在這里插入圖片描述
注冊完畢后就可以在 Chrome 地址欄右邊的擴展程序欄點擊 圖標使用 MetaMask 了
在這里插入圖片描述
獲取測試以太
除了以太坊主網以外,以太坊還提供了 Ropsten, Kovan, Rinkeby, Goerli 這幾個公共測試網絡,另外還支持局域網測試網絡和自建測試網絡。在這里我們切換到 Ropsten 測試網絡
隨后點擊 Buy 按鈕,點擊測試水管下方的獲取以太
在這里插入圖片描述
在打開的頁面中點擊 request 1 ether from faucet 就可以得到1個測試以太,當然,可以多次點擊。
在這里插入圖片描述
測試以太僅供測試使用,除此之外沒有任何價值,測試完畢后剩下的以太可以發送到水龍頭賬戶捐贈給水龍頭,以供他人測試使用。
2.3、以太坊交易的數據結構
在以太坊網絡中,交易執行屬于一個事務。具有原子性、一致性、隔離性、持久性特點。
原子性: 是不可分割的最小執行單位,要么做,要么不做。
一致性: 同一筆交易執行,必然是將以太坊賬本從一個一致性狀態變到另一個一致性狀態。
隔離性: 交易執行途中不會受其他交易干擾。
持久性: 一旦交易提交,則對以太坊賬本的改變是永久性的。后續的操作不會對其有任何影響。
以太坊交易的本質是由外部擁有的賬戶發起的簽名消息,由以太坊網絡傳輸,并被序列化后記錄在以太坊區塊鏈上,交易是唯一可以觸發狀態更改或導致合約在EVM中執行的事物
2.3.1、交易的數據結構
以太坊的數據結構主要可以分為四部分:nonce、gas、交易目標和消息(主要部分)、交易簽名
在這里插入圖片描述
開頭是一個 uint64 類型的數字,稱之為隨機數。用于撤銷交易、防止雙花和修改以太坊賬戶的 Nonce 值。
第二部分是關于交易執行限制的設置,gas 為愿意供以太坊虛擬機運行的燃料上限。 gasPrice 是愿意支付的燃料單價。gasPrcie * gas 則為愿意為這筆交易支付的最高手續費。
第三部分是交易發送者輸入以太坊虛擬機執行此交易的初始信息: 虛擬機操作對象(接收方 To)、從交易發送方轉移到操作對象的資產(Value),以及虛擬機運行時入參(input)。其中 To 為空時,意味著虛擬機無可操作對象,此時虛擬機將利用 input 內容部署一個新合約。
第四部分是交易發送方對交易的簽名結果,可以利用交易內容和簽名結果反向推導出簽名者,即交易發送方地址。以上總結如下:
nonce:由發起人EOA發出的序列號,用于防止交易消息重播。
gas price:交易發起人愿意支付的gas單價(wei)。
start gas:交易發起人愿意支付的最大gas量。
to:目的以太坊地址。
value:要發送到目的地的以太數量。
data:可變長度二進制數據負載(payload)。
v,r,s:發起人EOA的ECDSA簽名的三個組成部分。
交易消息的結構使用遞歸長度前綴(RLP)編碼方案進行序列化,該方案專為在以太坊中準確和字節完美的數據序列化而創建。
2.3.2、交易中的nonce
按以太坊黃皮書的定義, nonce是一個標量值,它等于從這個地址發送的交易數,或者對于關聯code的帳戶來說,是這個帳戶創建合約的數量。因此nonce便有以下特征:
nonce不會明確存儲為區塊鏈中帳戶狀態的一部分。相反,它是通過計算發送地址的已確認交易的數量來動態計算的。
nonce值還用于防止錯誤計算賬戶余額。nonce強制來自任何地址的交易按順序處理,沒有間隔,無論節點接收它們的順序如何。
使用nonce確保所有節點計算相同的余額和正確的序列交易,等同于用于防止比特幣“雙重支付”(“重放攻擊”)的機制。但是,由于以太坊跟蹤賬戶余額并且不單獨跟蹤 UTXO ,因此只有在錯誤地計算賬戶余額時才會發生“雙重支付”。nonce機制可以防止這種情況發生。
2.3.3、并發和nonce
以太坊是一個允許操作(節點,客戶端,DApps)并發的系統,但強制執行單例狀態。例如,出塊的時候只有一個系統狀態。假如我們有多個獨立的錢包應用或客戶端,比如 MetaMask 和 Geth,它們可以使用相同的地址生成交易。如果我們希望它們都夠同時發送交易,該怎么設置交易的nonce呢?一般有以下兩種做法:
用一臺服務器為各個應用分配nonce,先來先服務——可能出現單點故障,并且失敗的交易會將后續交易阻塞。
生成交易后不分配nonce,也不簽名,而是把它放入一個隊列等待。另起一個節點跟蹤nonce并簽名交易。同樣會有單點故障的可能,而且跟蹤nonce和簽名的節點是無法實現真正并發的。
2.3.4、交易中的gas
Gas 中譯是:瓦斯、汽油,代表一種可燃氣體。 這形象地比喻以太坊的交易手續費計算模式,不同于比特幣中直接支付比特幣作為轉賬手續費, 以太坊視為一個去中心化的計算網絡,當你發送Token、執行合約、轉移以太幣或者在此區塊上干其他的時候,計算機在處理這筆交易時需要進行計算消耗網絡資源,這樣你必須支付燃油費購買燃料才能讓計算機為你工作。最終燃料費作為手續費支付給礦工。
注:可以在Etherscan上查詢gas price與confirmation time的關系,如下圖
在這里插入圖片描述
因為手續費等于gasPrice * gasUsed,用戶在轉賬,特別是執行智能合約時 gasUsed 無法提前預知。 這樣存在一個風險,當用戶的交易涉及一個惡意的智能合約,該合約執行將消耗無限的燃料, 這樣會導致交易方的余額全部消耗(惡意的智能合約有可能是程序Bug,如合約執行陷入一個死循環)。
為了避免合約中的錯誤引起不可預計的燃料消耗,用戶需要在發送交易時設定允許消耗的燃料上限,即 gasLimit。 這樣不管合約是否良好,最壞情況也只是消耗 gasLimit 量的燃料。
然而,一筆交易所必須支付的燃料已經在區塊中通過該交易已執行的計算量記錄。 如果你不想支出太多燃料,而故意設置過低的 gasLimit 是沒太多幫助的。 你必須支付足夠燃料來支付本交易所必要的計算資源。如果交易尚未執行完成,而燃料已用完, 將出現一個 Out of Gas 的錯誤。特別注意的是,即使交易失敗,你也必須為已占用的計算資源所支付手續費。 比如,你通過合約給 TFBOYS 投票,設置 gasPrice=2 gwei,gasLimit=40000(實現投票需要40001的燃料開銷), 最終你投票失敗且仍然需要支付 40000*2 gwei= 80000 gwei= 0.00008 ETH。
另外,如果最終 gasUsed 低于 gasLimit,即燃料未用完。則剩余燃料(gasLimit - gasUsed )將在交易后退還給你。 比如你發送 1 Ether 到另一個賬戶B,設置 gas limit 為 400000,將有 400000 - 21000 返回給你。
注意:21000 是標準轉賬交易的gasUsed。因此一筆標準的轉賬交易你可以設置 gasLimit 為21000
2.4、以太坊賬戶
對比比特幣的UTXO余額模型,以太坊使用“賬戶”余額模型。 以太坊豐富了賬戶內容,除余額外還能自定義存放任意多數據。 并利用賬戶數據的可維護性,構建智能合約賬戶。下面我們首先將比特幣的UTXO余額模型與以太坊賬戶進行比較,說明其各自的優缺點以及適用性。
2.4.1、比特幣UTXO和以太坊賬戶結構比較
在當前的區塊鏈項目中,主要有兩種記錄保存方式,一種是賬戶/余額模型,一種是UTXO模型。比特幣采用就是UTXO模型,以太坊、EOS等則采用的是賬戶/余額模型。
2.4.2、比特幣UTXO
UTXO是 Unspent Transaction Output的縮寫,意思是**未花費的輸出,**可以簡單理解為還沒有用掉的收款。比如韓梅梅收到一筆比特幣,她沒有用掉,這筆比特幣對她來說就是一個UTXO。關于UTXO的具體介紹大家可以查看這篇文章。
**UTXO 核心設計思路是:它記錄交易事件,而不記錄最終狀態。**要計算某個用戶有多少比特幣,就要對其錢包里所有的UTXO求和,得到結果就是他的持幣數量。UTXO模型在轉賬交易時,是以UTXO為單位的,也就是說在支付時,調用的是整數倍UTXO,比如1個UTXO,3個UTXO,沒有0.5個UTXO的說法。
比特幣在基于UTXO的結構中存儲有關用戶余額的數據,系統的整個狀態就是一組UTXO的集合,每個UTXO都有一個所有者和一個面值(就像不同的硬幣),而交易會花費若干個輸入的UTXO,并根據規則創建若干個新的UTXO
每個引用的輸入必須有效并且尚未花費,對于一個交易,必須包含有每個輸入的所有者匹配的簽名,總輸入必須大于等于總輸出值。所以系統中用戶的余額是用戶具有私鑰的UTXO的總值
2.4.3、以太坊賬戶
為什么以太坊不用UTXO呢?顯然是因為麻煩,以太坊的做法更符合直覺,以太坊中的狀態就是系統中所有賬戶的列表,每個賬戶都包含了一個余額和以太坊特殊定義的數據(代碼和內部存儲)。如果發送賬戶有足夠多的余額來進行支付,則交易有效,在這種情況下發送賬戶先扣款,而收款賬戶將記入這筆收入。如果接受賬戶有相關代碼,則代碼會自動運行,并且它的內部存儲也可能被更改,或者代碼還可能向其他賬戶發送額外的消息,這就會導致進一步的借貸資金關系。
2.4.4、優缺點比較
比特幣UTXO的優點:
更高程度的隱私:如果用戶為他們收到的每筆交易使用新地址,那么通常很難將賬戶互相鏈接。這很大程度上適用于貨幣,但不太適用于任何dapps,因為dapps通常涉及跟蹤和用戶綁定的復雜狀態,可能不存在像貨幣那樣簡單的用戶狀態劃分方案
潛在的可擴展性:UTXO在理論上更符合可擴展性要求,因為我們只需要依賴擁有UTXO的那些人去維護基于Merkle樹的所有權證明就夠了,即使包括所有者在內的每個人都決定忘記該數據,那么也只有所有者受到對應的UTXO的損失,不影響接下來的交易。而在賬戶模式中,如果每個人都丟失了與賬戶相對應的Merkle樹的部分,那將會使得和該賬戶有關的消息完全無法處理,包括發幣給它。
以太坊賬戶模式的優點:
可以節省大量空間:不將UTXOs分開存儲,而是合成一個賬戶;每個交易只需要一個輸入、一個簽名并產生一個輸出
更好的可替代性:貨幣本質上都是同質化、可替代的;UTXO的設計使得貨幣從來源分成了“可花費”和“不可花費”兩類,這在實際應用中很難有對應模型
更加簡單:更容易編碼和理解,特別是設計復雜腳本的時候,UTXO的腳本邏輯復雜時更令人費解
便于維護持久輕節點:只要沿著特定方向掃描狀態樹,輕節點 可以很容易地隨時訪問賬戶相關的所有數據。而UTXO地每個交易都會使得狀態引用發生改變,這對應節點來說長時間運行Dapp會有很大壓力
2.4.5、總結
BitCoin Ethereum 設計定位 現金系統 去中心化應用平臺 數據組成 交易列表(賬本) 交易和賬戶狀態 交易對象 UTXO Accounts 代碼控制 腳本 智能合約
2.5、以太坊賬戶類型
以太坊作為智能合約操作平臺,將賬戶劃分為兩類:外部賬戶(EOAs)和合約賬戶(contract account),下面分別做簡要介紹:
在這里插入圖片描述
2.5.1、外部賬戶(EOA)
外部賬戶是由人來控制的,也就是常規理解的普通賬戶,外部賬戶包含以太幣余額,主要作用就是發送交易(是廣義的交易,包括轉幣和觸發合約代碼),是由用戶私鑰控制的,沒有關聯代碼,所有在以太坊上交易的發起者都是外部賬戶。
外部賬戶特點總結:
擁有以太余額。
能發送交易,包括轉賬和執行合約代碼。
被私鑰控制。
沒有相關的可執行代碼。
2.5.2、合約賬戶(CA)
合約賬戶有時也叫內部賬戶,有對應的以太幣余額和關聯代碼,它是由代碼控制的,可以通過交易或來自其他合約的調用消息來觸發代碼執行,執行代碼時可以操作自己的存儲空間,也可以調用其他合約
合約賬戶特點總結:
擁有以太余額。
有相關的可執行代碼(合約代碼)。
合約代碼能夠被交易或者其他合約消息調用。
合約代碼被執行時可再調用其他合約代碼。
合約代碼被執行時可執行復雜運算,可永久地改變合約內部的數據存儲。
如果大家對概念還理解不深可以先嘗試學習后面部分,本教程內容有限,推薦大家有精力閱讀以下讀物:
區塊鏈學習的書籍
區塊鏈入門教程
IBM教程
參考自:
[比特幣白皮書]https://www.8btc.com/wiki/bitcoin-a-peer-to-peer-electronic-cash-system)
以太坊白皮書
超級賬本白皮書
閃電網絡白皮書
注:本系列來自datawhale組隊學習教程,將近結束時跟據同學反饋重新整理而來 author:荒、越前浩波、Yurk、Don