以太坊開發(fā)(三)使用 Go-Ethereum 1.8.1搭建以太坊私有鏈

什么是 Go-Ethereum

Go-Ethereum是由以太坊基金會提供的官方客戶端軟件。它是用Go編程語言編寫的,簡稱Geth。

Geth是以太坊協(xié)議的具體落地實現(xiàn),通過Geth,你可以實現(xiàn)以太坊的各種功能,如賬戶的新建編輯刪除,開啟挖礦,ether幣的轉(zhuǎn)移,智能合約的部署和執(zhí)行等等。

Geth官網(wǎng):https://geth.ethereum.org/
Geth的Github地址:https://github.com/ethereum/go-ethereum

本文環(huán)境:

Mac OS 10.13.3

Homebrew v1.5.4

Geth v1.8.1

Geth的安裝

這里使用Homebrew演示在Mac OS上的下載安裝

首先安裝Homebrew

Homebrew是一款Mac OS平臺下的軟件包管理工具,擁有安裝、卸載、更新、查看、搜索等很多實用的功能。簡單的一條指令,就可以實現(xiàn)包管理,而不用你關(guān)心各種依賴和文件路徑的情況,十分方便快捷。

Homebrew官網(wǎng):https://brew.sh

/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

安裝完成后查看版本信息,確認是否安裝成功

yuyangdeMacBook-Pro:~ yuyang$ brew -v
Homebrew 1.5.4
Homebrew/homebrew-core (git revision 68c5; last commit 2018-02-19)

安裝Geth

brew tap ethereum/ethereum
brew install ethereum

安裝完成后,查看版本后確認安裝是否成功

yuyangdeMacBook-Pro:~ yuyang$ geth version
Geth
Version: 1.8.1-stable
Architecture: amd64
Protocol Versions: [63 62]
Network Id: 1
Go Version: go1.10
Operating System: darwin
GOPATH=
GOROOT=/usr/local/opt/go/libexec

如果安裝失敗

我當(dāng)時安裝一直失敗,忘了截圖錯誤原因了。后來查了很久,找到了一篇可能的解決方法(但我不確定我當(dāng)時就是文中的錯誤信息)。用了文中方法失敗,然后我又嘗試運行安裝Geth的兩條指令,結(jié)果安裝成功。

Got an error while installing cpp-ethereum using brew.
https://github.com/ethereum/homebrew-ethereum/issues/116

<Install Xcode or the CLI from developer.apple.com/xcode>

brew update
brew upgrade
brew tap ethereum/ethereum
brew reinstall llvm

<At this point, close the terminal, and relaunch it.>

brew install leveldb libmicrohttpd cryptopp
brew install cpp-ethereum --devel --successful --verbose

簡單理解就是:

  1. 安裝Xcode或者CLI(我是把兩個都安裝了)
    • Xcode直接去AppStore安裝。

    • CLI一款能用命令行自由操作各種軟件獲取各種系統(tǒng)信息的工具。

      安裝命令:

       sh -c "$(curl -fsSL https://raw.githubusercontent.com/guarinogabriel/mac-cli/master/mac-cli/tools/install)
      

      安裝完成后查看是否成功:

      yuyangdeMacBook-Pro:~ yuyang$ Mac list
      
       ? mac CLI – OS X command line tools for developers
      

      關(guān)于CLI的使用可以查看這篇文章

  1. 執(zhí)行以下命令:

    brew update
    brew upgrade
    brew tap ethereum/ethereum
    brew reinstall llvm

  2. 完成后重啟命令行

  3. 執(zhí)行以下命令:

    brew install leveldb libmicrohttpd cryptopp
    brew install cpp-ethereum --devel --successful --verbose
    

這是解決辦法提供者對此的解釋:

Running all those commands will install the latest version of the C++ Ethereum client using the develop branch that has successfully passed CI.

創(chuàng)建以太坊私有鏈

初始化一個創(chuàng)世區(qū)塊

初始化創(chuàng)世區(qū)塊時,要先創(chuàng)建一個genesis.json文件,內(nèi)容如下:

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

接下來,創(chuàng)建項目目錄,然后使用geth init ./genesis.json --datadir "./chain"命令,來進行創(chuàng)世區(qū)塊的初始化,當(dāng)前區(qū)塊鏈網(wǎng)絡(luò)數(shù)據(jù)存放的位置會保存在chain目錄中:

yuyangdeMacBook-Pro:~ yuyang$ mkdir TestGeth
yuyangdeMacBook-Pro:~ yuyang$ cd TestGeth
yuyangdeMacBook-Pro:TestGeth yuyang$ geth init ./genesis.json --datadir "./chain"
INFO [02-24|11:08:41] Maximum peer count                       ETH=25 LES=0 total=25
INFO [02-24|11:08:41] Allocated cache and file handles         database=/Users/yuyang/TestGeth/chain/geth/chaindata cache=16 handles=16
INFO [02-24|11:08:41] Writing custom genesis block 
INFO [02-24|11:08:41] Persisted trie from memory database      nodes=0 size=0.00B time=10.106μs gcnodes=0 gcsize=0.00B gctime=0s livenodes=1 livesize=0.00B
INFO [02-24|11:08:41] Successfully wrote genesis state         database=chaindata                                   hash=5e1fc7…d790e0
INFO [02-24|11:08:41] Allocated cache and file handles         database=/Users/yuyang/TestGeth/chain/geth/lightchaindata cache=16 handles=16
INFO [02-24|11:08:41] Writing custom genesis block 
INFO [02-24|11:08:41] Persisted trie from memory database      nodes=0 size=0.00B time=1.743μs  gcnodes=0 gcsize=0.00B gctime=0s livenodes=1 livesize=0.00B
INFO [02-24|11:08:41] Successfully wrote genesis state         database=lightchaindata                                   hash=5e1fc7…d790e0

啟用私有鏈

使用以下命令,啟用私有鏈,并創(chuàng)建log日志文件:

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

啟動后的效果如下:

yuyangdeMacBook-Pro:TestGeth yuyang$ geth \
>   --datadir "./chain" \
>   --nodiscover \
>   console 2>>eth_output.log
Welcome to the Geth JavaScript console!

instance: Geth/v1.8.1-stable/darwin-amd64/go1.10
 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
參數(shù)名稱 參數(shù)描述
datadir 設(shè)置當(dāng)前區(qū)塊鏈網(wǎng)絡(luò)數(shù)據(jù)存放的位置
console 啟動命令行模式,可以在Geth中執(zhí)行命令
nodiscover 私有鏈地址,不會被網(wǎng)上看到

在當(dāng)前目錄執(zhí)行tail -f eth_output.log,可以看到輸出日志(需要新開命令行)。

yuyangdeMacBook-Pro:~ yuyang$ cd /Users/yuyang/TestGeth 
yuyangdeMacBook-Pro:TestGeth yuyang$ tail -f eth_output.log
INFO [02-24|12:03:49] Disk storage enabled for ethash caches   dir=/Users/yuyang/TestGeth/chain/geth/ethash count=3
INFO [02-24|12:03:49] Disk storage enabled for ethash DAGs     dir=/Users/yuyang/.ethash                    count=2
INFO [02-24|12:03:49] Initialising Ethereum protocol           versions="[63 62]" network=1
INFO [02-24|12:03:49] Loaded most recent local header          number=0 hash=5e1fc7…d790e0 td=131072
INFO [02-24|12:03:49] Loaded most recent local full block      number=0 hash=5e1fc7…d790e0 td=131072
INFO [02-24|12:03:49] Loaded most recent local fast block      number=0 hash=5e1fc7…d790e0 td=131072
INFO [02-24|12:03:49] Regenerated local transaction journal    transactions=0 accounts=0
INFO [02-24|12:03:49] Starting P2P networking 
INFO [02-24|12:03:49] RLPx listener up                         self="enode://f49cd7741cb1e91624d284aa7896a3dca1bedfcc36a6a99f05e2f0bdd1c6f830c59391b2c47493eeafd7d9ca6fff0720a1ab5ebc20627b1314cdbc1dfc86c351@[::]:30303?discport=0"
INFO [02-24|12:03:49] IPC endpoint opened                      url=/Users/yuyang/TestGeth/chain/geth.ipc

在私有鏈中進行操作

帳戶的添加和查看

查看帳戶,可以看到當(dāng)前帳戶是空的

> web3.eth.accounts
[]

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

> web3,personal.newAccount("123456")
"0xf2e4cf8222e79b579543a5708ff0dfd1e6e37cfe"

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

第二種方法是先創(chuàng)建賬戶,然后輸入密碼

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

這時我們再查看帳戶,能夠看到剛才創(chuàng)建的兩個帳戶已經(jīng)存在了

> web3.eth.accounts
["0xf2e4cf8222e79b579543a5708ff0dfd1e6e37cfe", "0x69c9e2942557b25e4967672a72ee7b8f8c531a1c"]

開始挖礦和停止挖礦

挖礦執(zhí)行以下命令:

> miner.start()
null

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

INFO [02-24|12:33:12] Commit new mining work                   number=83 txs=0 uncles=0 elapsed=2.005s
INFO [02-24|12:33:13] Successfully sealed new block            number=83 hash=b72b9d…c117b8
INFO [02-24|12:33:13] ?? block reached canonical chain          number=78 hash=85741d…4330d5
INFO [02-24|12:33:13] ?? mined potential block                  number=83 hash=b72b9d…c117b8
INFO [02-24|12:33:13] Commit new mining work                   number=84 txs=0 uncles=0 elapsed=165.913μs
INFO [02-24|12:33:13] Successfully sealed new block            number=84 hash=46555c…078e21
INFO [02-24|12:33:13] ?? block reached canonical chain          number=79 hash=2d948b…ea81da
INFO [02-24|12:33:13] ?? mined potential block                  number=84 hash=46555c…078e21

挖礦會默認保存到創(chuàng)建的第一個帳戶0xf2e4cf8222e79b579543a5708ff0dfd1e6e37cfe中。
block number=79,說明我們已經(jīng)創(chuàng)建了79個區(qū)塊。
在以太坊官方的網(wǎng)絡(luò)上,平均每15秒產(chǎn)生一個區(qū)塊。

停止挖礦執(zhí)行以下命令:

> miner.stop()
true

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

查看賬戶余額

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

> web3.eth.getBalance("0xf2e4cf8222e79b579543a5708ff0dfd1e6e37cfe")
425000000000000000000
> web3.eth.getBalance("0x69c9e2942557b25e4967672a72ee7b8f8c531a1c")
0

每次記一長串的地址很麻煩,我們可以通過設(shè)置變量來acc0表示帳戶1
0xf2e4cf8222e79b579543a5708ff0dfd1e6e37cfe,acc1表示帳戶2
0x69c9e2942557b25e4967672a72ee7b8f8c531a1c。

> acc0 = web3.eth.accounts[0]
"0xf2e4cf8222e79b579543a5708ff0dfd1e6e37cfe"
> acc1 = web3.eth.accounts[1]
"0x69c9e2942557b25e4967672a72ee7b8f8c531a1c"
> web3.eth.getBalance(acc0)
425000000000000000000
> web3.eth.getBalance(acc1)
0

使用下面方法可以查看格式化的以太幣:

> web3.fromWei(web3.eth.getBalance(acc0))
425

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

因為geth javascript console是基于javascript的,所以也可以創(chuàng)建js函數(shù),查看所有帳戶余額。

> 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");
...  };
undefined
> checkAllBalances()
  eth.accounts[0]:  0xf2e4cf8222e79b579543a5708ff0dfd1e6e37cfe  balance: 425 ether
  eth.accounts[1]:  0x69c9e2942557b25e4967672a72ee7b8f8c531a1c  balance: 0 ether
  Total balance: 425 ether
undefined

轉(zhuǎn)帳操作

從帳戶0xf2e4cf8222e79b579543a5708ff0dfd1e6e37cfe轉(zhuǎn)3個以太幣到0x69c9e2942557b25e4967672a72ee7b8f8c531a1c,如果不指定單位ether,默認轉(zhuǎn)的是wei。

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

當(dāng)直接執(zhí)行此方法時會拋出異常,顯示帳號被鎖。

解鎖轉(zhuǎn)帳帳戶:

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

解鎖完成之后,即可執(zhí)行轉(zhuǎn)賬操作:

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

但此時查看時會發(fā)現(xiàn)接收賬戶依舊為原來數(shù)值。此時需要執(zhí)行挖礦命令,才會把轉(zhuǎn)賬真正完成。

> checkAllBalances()
  eth.accounts[0]:  0xf2e4cf8222e79b579543a5708ff0dfd1e6e37cfe  balance: 425 ether
  eth.accounts[1]:  0x69c9e2942557b25e4967672a72ee7b8f8c531a1c  balance: 0 ether
  Total balance: 425 ether
undefined
> miner.start()
null
> checkAllBalances()
  eth.accounts[0]:  0xf2e4cf8222e79b579543a5708ff0dfd1e6e37cfe  balance: 547 ether
  eth.accounts[1]:  0x69c9e2942557b25e4967672a72ee7b8f8c531a1c  balance: 3 ether
  Total balance: 550 ether
undefined
> miner.stop()
true

acc1余額增加是因為啟動挖礦后又有以太幣進賬。

fromWei和toWei

  • web3.fromWei
    把 wei 轉(zhuǎn)為如下種類的以太坊單位(還有其他代幣token單位)

    • kwei/ada
    • mwei/babbage
    • gwei/shannon
    • szabo
    • finney
    • ether
    • kether/grand/einstein
    • mether
    • gether
    • tether
> web3.fromWei("425000000000000000000", "ether")
"425"
  • web3.toWei
    把以太坊單位(包含代幣單位)轉(zhuǎn)為 wei
> web3.toWei("1", "ether")
"1000000000000000000"

參考:

  1. 使用 Go-Ethereum 1.7.2搭建以太坊私有鏈
    作者:迦壹
  2. 區(qū)塊鏈學(xué)堂(5):Geth 安裝
    作者:以太中文網(wǎng)
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容