使用 Go-Ethereum 1.7.2搭建以太坊私有鏈


1、什么是Ethereum(以太坊)

  以太坊(Ethereum)並不是一個機構,而是一款能夠在區塊鏈上實現智能合約、開源的底層系統,以太坊從誕生到2017年5月,短短3年半時間,全球已有200多個以太坊應用誕生。以太坊是一個平台和一種編程語言,使開發人員能夠建立和發布下一代分布式應用。 以太坊可以用來編程,分散,擔保和交易任何事物:投票,域名,金融交易所,眾籌,公司管理, 合同和大部分的協議,知識產權,還有得益於硬件集成的智能資產。

  以太坊的白皮書:https://github.com/ethereum/wiki/wiki/White-Paper

1.2、以太坊的幾個基本概念:

  以太坊簡單來說就是區塊鏈與智能合約的結合,是基於solidity語言實現的。在以太坊中,智能合約也有一個帳戶地址。

  • EVM

  以太坊虛擬機(EVM)是以太坊中智能合約的運行環境。它不僅被沙箱封裝起來,事實上它被完全隔離,運行在EVM內部的代碼不能接觸到網絡、文件系統或者其它進程。甚至智能合約之間也只有有限的調用。

  • Accounts

  以太坊中有兩類賬戶,它們共用同一個地址空間。外部賬戶,該類賬戶被公鑰-私鑰對控制。合約賬戶,該類賬戶被存儲在賬戶中的代碼控制。 外部賬戶的地址是由公鑰決定的,合約賬戶的地址是在創建合約時確定的。

  每個賬戶都有一個以太幣余額(單位是“Wei”),該賬戶余額可以通過向它發送帶有以太幣的交易來改變。

  • Transactions

  每一筆交易都是一條信息,可以通過交易,將余額從一個帳戶發至另一個帳戶。

  • Gas

  每一筆交易需要支付一定的gasgas price是由創建者設置的,調用合約的發送賬戶需要交易費用 = gas price * gas amount。

1.3、以太坊周邊的常用工具

2、什么是 Go-Ethereum?

  Go-Ethereum是由以太坊基金會提供的官方客戶端軟件。它是用Go編程語言編寫的,簡稱Geth。其中以下幾個組件是值得了解的:

  • Geth 客戶端

  當你開始這個客戶程序,它連接到其他客戶端(也稱為節點)的網絡下載同步區塊。它將不斷地與其他節點進行通信來保持它的副本是最新的。它還具有挖掘區塊並將交易添加到塊鏈的能力,驗證並執行區塊中的交易。它還可以充當服務器,您可以通過RPC來訪問暴露的API接口。

mshk.top

  • Geth 終端

  這是一個命令行工具,可以讓您連接到正在運行的節點,並執行各種操作,如創建和管理帳戶,查詢區塊鏈,簽署並將交易提交給區塊鏈等等。更多介紹 點擊這里

3、Go-Ethereum的開源地址在哪里?

  https://github.com/ethereum/go-ethereum

4、如何安裝Go-Ethereum 1.7.2

  本文中使用的方法是通過Git下載源碼,本地編譯Go-Ethereum 1.7.2

git clone https://github.com/ethereum/go-ethereum.git cd go-ethereum git checkout v1.7.2 make geth make all 

  查看安裝好的geth版本號

➜ /Users/lion >geth version Geth Version: 1.7.2-stable Git Commit: 1db4ecdc0b9e828ff65777fb466fc7c1d04e0de9 Architecture: amd64 Protocol Versions: [63 62] Network Id: 1 Go Version: go1.9.1 Operating System: darwin GOPATH=/Users/lion/my_project/_golang GOROOT=/usr/local/Cellar/go/1.9.1/libexec 

5、開始創建以太坊私有鏈

5.1、初始化一個創世區塊

  初始化創世區塊時,要先創建一個genesis.json文件,內容如下:

  genesis.json:

{ "config": { "chainId": 10, "homesteadBlock": 0, "eip155Block": 0, "eip158Block": 0 }, "coinbase" : "0x0000000000000000000000000000000000000000", "difficulty" : "0x20000", "extraData" : "", "gasLimit" : "0x2fefd8", "nonce" : "0x0000000000000042", "mixhash" : "0x0000000000000000000000000000000000000000000000000000000000000000", "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000", "timestamp" : "0x00", "alloc" : {}, } 
參數名稱 參數描述
mixhash 與nonce配合用於挖礦,由上一個區塊的一部分生成的hash。注意他和nonce的設置需要滿足以太坊的Yellow paper, 4.3.4. Block Header Validity, (44)章節所描述的條件。
nonce nonce就是一個64位隨機數,用於挖礦,注意他和mixhash的設置需要滿足以太坊的Yellow paper, 4.3.4. Block Header Validity, (44)章節所描述的條件。
difficulty 設置當前區塊的難度,如果難度過大,cpu挖礦就很難,這里設置較小難度
alloc 用來預置賬號以及賬號的以太幣數量,因為私有鏈挖礦比較容易,所以我們不需要預置有幣的賬號,需要的時候自己創建即可以。
coinbase 礦工的賬號,隨便填
timestamp 設置創世塊的時間戳
parentHash 上一個區塊的hash值,因為是創世塊,所以這個值是0
extraData 附加信息,隨便填,可以填你的個性信息
gasLimit 該值設置對GAS的消耗總量限制,用來限制區塊能包含的交易信息總和,因為我們是私有鏈,所以填最大。

  

  接下來,我們使用geth init ./genesis.json --datadir "./chain"命令,來進行創世區塊的初始化,當前區塊鏈網絡數據存放的位置會保存在chain目錄中:

➜ /Users/lion/my_project/_eth/test >geth init ./genesis.json --datadir "./chain" WARN [10-22|14:49:09] No etherbase set and no accounts found as default INFO [10-22|14:49:09] Allocated cache and file handles database=/Users/lion/my_project/_eth/test/chain/geth/chaindata cache=16 handles=16 INFO [10-22|14:49:09] Writing custom genesis block INFO [10-22|14:49:09] Successfully wrote genesis state database=chaindata hash=5e1fc7…d790e0 INFO [10-22|14:49:09] Allocated cache and file handles database=/Users/lion/my_project/_eth/test/chain/geth/lightchaindata cache=16 handles=16 INFO [10-22|14:49:09] Writing custom genesis block INFO [10-22|14:49:09] Successfully wrote genesis state database=lightchaindata hash=5e1fc7…d790e0 

  

5.2、啟用私有鏈

  使用以下命令,啟用私有鏈:

geth \
  --datadir "./chain" \ --nodiscover \ console 2>>eth_output.log 

  
  啟動后的效果如下:

➜ /Users/lion/my_project/_eth/test >geth \ --datadir "./chain" \ --nodiscover \ console 2>>eth_output.log Welcome to the Geth JavaScript console! instance: Geth/v1.6.7-stable-ab5646c5/darwin-amd64/go1.9.1 modules: admin:1.0 debug:1.0 eth:1.0 miner:1.0 net:1.0 personal:1.0 rpc:1.0 txpool:1.0 web3:1.0 > 
參數名稱 參數描述
datadir 設置當前區塊鏈網絡數據存放的位置
console 啟動命令行模式,可以在Geth中執行命令
nodiscover 私有鏈地址,不會被網上看到

  

  在當前目錄執行tail -f eth_output.log,可以看到輸出日志。

➜ /Users/lion/my_project/_eth/test >tail -f eth_output.log INFO [10-22|14:50:04] Bloom-bin upgrade completed elapsed=149.285µs INFO [10-22|14:50:04] Initialising Ethereum protocol versions="[63 62]" network=1 INFO [10-22|14:50:04] Database conversion successful INFO [10-22|14:50:04] Loaded most recent local header number=0 hash=5e1fc7…d790e0 td=131072 INFO [10-22|14:50:04] Loaded most recent local full block number=0 hash=5e1fc7…d790e0 td=131072 INFO [10-22|14:50:04] Loaded most recent local fast block number=0 hash=5e1fc7…d790e0 td=131072 INFO [10-22|14:50:04] Starting P2P networking INFO [10-22|14:50:04] RLPx listener up self="enode://bcc414219b7423f56da261857508771c229a5ee370e2d5bee7a9d1a3886ae9c207956a80e03f7ba44ed5f9f7777ac64db9b6939d18f3f44786dc6fc5690035b1@[::]:30303?discport=0" INFO [10-22|14:50:04] IPC endpoint opened: /Users/lion/my_project/_eth/test/chain/geth.ipc INFO [10-22|14:50:05] Mapped network port proto=tcp extport=30303 intport=30303 interface=NAT-PMP(10.0.0.1) 

后面章節中的命令,都是在啟動私有鏈后的Geth javascript console中操作

  

5.2.1、帳戶的添加和查看

  查看帳戶,可以看到當前帳戶是空的

> web3.eth.accounts [] 

  
  創建帳戶的方式有兩種,第一種創建帳戶時直接初始化密碼

> web3.personal.newAccount("123456") "0xbe323cc4fde114269a9513a27d3e985f82b9e25d" 

其中返回的0xbe323cc4fde114269a9513a27d3e985f82b9e25d是帳戶,123456是帳戶的密碼

  
  第二種方法是先創建賬戶,然后輸入密碼

> web3.personal.newAccount() Passphrase: Repeat passphrase: "0x3b0ec02b4193d14abdc9cc5b264b5e3f39624d70" 

  
  這時我們再查看帳戶,能夠看到剛才創建的兩個帳戶已經存在了

> web3.eth.accounts ["0xbe323cc4fde114269a9513a27d3e985f82b9e25d", "0x3b0ec02b4193d14abdc9cc5b264b5e3f39624d70"] 

  

5.2.2、開始挖礦和停止挖礦

  挖礦執行以下命令:

> miner.start(1) 

  
  執行以后,通過剛才查看日志的方法tail -f eth_output.log,能夠看到類似下面的日志,說明挖礦已經在進行.

INFO [10-22|15:01:32] Commit new mining work number=70 txs=0 uncles=0 elapsed=2.000s INFO [10-22|15:01:34] Successfully sealed new block number=70 hash=a0cfd2…f99c06 INFO [10-22|15:01:34] 🔗 block reached canonical chain number=65 hash=3f6d16…586aba INFO [10-22|15:01:34] 🔨 mined potential block number=70 hash=a0cfd2…f99c06 INFO [10-22|15:01:34] Commit new mining work number=71 txs=0 uncles=0 elapsed=163.977µs INFO [10-22|15:01:34] Successfully sealed new block number=71 hash=f84b8a…7468e1 INFO [10-22|15:01:34] 🔗 block reached canonical chain number=66 hash=6ca3b9…e959e8 INFO [10-22|15:01:34] 🔨 mined potential block number=71 hash=f84b8a…7468e1 

挖礦會默認保存到創建的第一個帳戶0xbe323cc4fde114269a9513a27d3e985f82b9e25d中。
block number=66,說明我們已經創建了66個區塊
在以太坊官方的網絡上,平均每15秒產生一個區塊

  停止挖礦執行以下命令:

> miner.stop() 

停止挖礦后,以太幣則不會產生,同樣智能合約、轉帳等操作也不會起作用。

  

5.2.3、查看帳戶余額

  查看帳戶余額的方法如下:

> web3.eth.getBalance("0xbe323cc4fde114269a9513a27d3e985f82b9e25d") 1.245e+21 > web3.eth.getBalance("0x3b0ec02b4193d14abdc9cc5b264b5e3f39624d70") 0 

  
  每次記一長串的地址很麻煩,我們可以通過設置變量來acc0表示帳戶10xbe323cc4fde114269a9513a27d3e985f82b9e25d,acc1表示帳戶20x3b0ec02b4193d14abdc9cc5b264b5e3f39624d70.

> acc0 = web3.eth.accounts[0] "0xbe323cc4fde114269a9513a27d3e985f82b9e25d" > acc1 = web3.eth.accounts[1] "0x3b0ec02b4193d14abdc9cc5b264b5e3f39624d70" > web3.eth.getBalance(acc0) 1.245e+21 > web3.eth.getBalance(acc1) 0 ## 使用這個方法可以查看格式化的以太幣 > web3.fromWei(web3.eth.getBalance(acc0)) 1245 

以太幣最小的單位是wei(18個0)

  
  因為geth javascript console是基於javascript的,所以也可以創建js函數,查看所有帳戶余額

> function checkAllBalances() { var totalBal = 0; for (var acctNum in eth.accounts) { var acct = eth.accounts[acctNum]; var acctBal = web3.fromWei(eth.getBalance(acct), "ether"); totalBal += parseFloat(acctBal); console.log(" eth.accounts[" + acctNum + "]: \t" + acct + " \tbalance: " + acctBal + " ether"); } console.log(" Total balance: " + totalBal + " ether"); }; > checkAllBalances() eth.accounts[0]: 0xbe323cc4fde114269a9513a27d3e985f82b9e25d balance: 1245 ether eth.accounts[1]: 0x3b0ec02b4193d14abdc9cc5b264b5e3f39624d70 balance: 0 ether Total balance: 1245 ether 

如果命令較多,可以保存到一個腳本里,使用命令載入腳本:loadScript('/path/script/here.js')

  

5.2.4、轉帳操作

  從帳戶0xbe323cc4fde114269a9513a27d3e985f82b9e25d轉3個以太幣到0x3b0ec02b4193d14abdc9cc5b264b5e3f39624d70,如果不指定單位ether,默認轉的是wei。

> web3.eth.sendTransaction({from:acc0,to:acc1,value:web3.toWei(3,"ether")}) Error: authentication needed: password or unlock at web3.js:3104:20 at web3.js:6191:15 at web3.js:5004:36 at <anonymous>:1:1 

當直接執行此方法時會拋出異常,顯示帳號被鎖

  
  解鎖轉帳帳戶

> web3.personal.unlockAccount(acc0,"123456") true 

  
  解鎖完成之后,即可執行轉賬操作。

> web3.eth.sendTransaction({from:acc0,to:acc1,value:web3.toWei(3,"ether")}) "0x472f26a00d244b91fea9ff05d9cd5ff5259d8618301bb14af4499827eb159056" 

  
  但此時查看時會發現接收賬戶依舊為原來數值。此時需要執行挖礦命令,才會把轉賬真正完成。

> checkAllBalances() eth.accounts[0]: 0xbe323cc4fde114269a9513a27d3e985f82b9e25d balance: 1245 ether eth.accounts[1]: 0x3b0ec02b4193d14abdc9cc5b264b5e3f39624d70 balance: 0 ether Total balance: 1245 ether undefined > miner.start() null > checkAllBalances() eth.accounts[0]: 0xbe323cc4fde114269a9513a27d3e985f82b9e25d balance: 1257 ether eth.accounts[1]: 0x3b0ec02b4193d14abdc9cc5b264b5e3f39624d70 balance: 3 ether Total balance: 1260 ether undefined > miner.stop() true 

博文作者:迦壹
博客地址:使用 Go-Ethereum 1.7.2搭建以太坊私有鏈
轉載聲明:可以轉載, 但必須以超鏈接形式標明文章原始出處和作者信息及版權聲明,謝謝合作!

比特幣地址:1KdgydfKMcFVpicj5w4vyn3T88dwjBst6Y
以太坊地址:0xbB0a92d634D7b9Ac69079ed0e521CC2e0a97c420


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM