什么是 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
簡單理解就是:
- 安裝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的使用可以查看這篇文章
-
執(zhí)行以下命令:
brew update
brew upgrade
brew tap ethereum/ethereum
brew reinstall llvm 完成后重啟命令行
-
執(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"
參考: