区块链开发之搭建以太坊私有链
(一)區塊鏈開發之搭建以太坊私有鏈
本文鏈接:https://blog.csdn.net/rwdxll/article/details/82929417
1、安裝ethereum/Go client(以太坊客戶端)
https://github.com/ethereum/go-ethereum/wiki/Installation-Instructions-for-Mac
https://github.com/ethereum/homebrew-ethereum
一、命令行客戶端
1、克隆倉庫
brew tap ethereum/ethereum
2、安裝go 客戶端
brew install ethereum
3、運行
geth
二、圖形化客戶端
https://github.com/ethereum/mist/releases/
說明:
安裝目錄:/usr/local/Cellar/ethereum/1.8.14,將bin目錄添加到環境變量里.
2、創建私有鏈
i.新建一個geth工作目錄
mkdir geth
cd geth
touch gensis.json
ii.創世區塊配置文件
創世(gensis)區塊是區塊鏈的起點,是區塊鏈的第一塊區塊--------0號區塊,唯一一個沒有前任的區塊。這個協議確保了沒有其他節點會和你的節點的區塊鏈版本一致,除非它們的創世區塊和你的一模一樣,通過這個方法可以創建多個私有區塊鏈。
文件:gensis.json
{
? "config": {
? ? ? ? "chainId": 15,
? ? ? ? "homesteadBlock": 0,
? ? ? ? "eip155Block": 0,
? ? ? ? "eip158Block": 0
? ? },
? "alloc" ? ? ?: {"0x6e1d19B1D713E39fD77Db95ff2929db78dB4ad34":{"balance":"100000"}
? },
? "coinbase" ? : "0x0000000000000000000000000000000000000000",
? "difficulty" : "0x01",
? "extraData" ?: "0x",
? "gasLimit" ? : "0xfffffff",
? "nonce" ? ? ?: "0x0000000000000001",
? "mixhash" ? ?: "0x0000000000000000000000000000000000000000000000000000000000000000",
? "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000",
? "timestamp" ?: "0x00"
}
?
| 參數 | 描述 |
| 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 | 用來預置賬號以及賬號的以太幣數量,因為私有鏈挖礦比較容易,所以我們不需要預置有幣的賬號,需要的時候自己創建即可以。可以使用MetaMask創建地址。 |
| coinbase | 礦工的賬號,隨便填 |
| timestamp | 設置創世塊的時間戳 |
| parentHash | 上一個區塊的hash值,因為是創世塊,所以這個值是0 |
| extraData | 附加信息,隨便填,可以填你的個性信息 |
| gasLimit | 該值設置對GAS的消耗總量限制,用來限制區塊能包含的交易信息總和,因為我們是私有 |
iii.初始化
cd geth
mkdir db
geth --datadir "./db" init gensis.json
geth init 命令用來初始化區塊鏈,命令可以帶有選項和參數,其中--datadir選項后面跟一個文件夾名db,gensis.json是init命令行參數。初始成功后會在數據目錄db下生產geth和keystore兩個文件夾。此時目錄結構如下:
其中,geth/db/chaindata中存放的是區塊鏈數據,geth/db/keystore中存放的是賬戶數據。
iv.啟動節點
geth geth --datadir "./db" --rpc --rpcaddr=0.0.0.0 --rpcport 8545 --rpccorsdomain "*" --rpcapi "eth,net,web3,personal,admin,shh,txpool,debug,miner" --nodiscover --maxpeers 30 --networkid 1981 --port 30303 --mine --minerthreads 1 --etherbase "0x6e1d19B1D713E39fD77Db95ff2929db78dB4ad34" console
參數說明:
| ? | identity | 區塊鏈的標示,隨便填寫,用于標示目前網絡的名字 |
| ? | init | 指定創世塊文件的位置,并創建初始塊 |
| ? | datadir | 設置當前區塊鏈網絡數據存放的位置 |
| ? | port | 網絡監聽端口 |
| ? | rpc | 啟動rpc通信,可以進行智能合約的部署和調試 |
| ? | rpcaddr | 指定HTTP-RPC服務監聽地址,默認為“localhost” |
| ? | rpcapi | 設置允許連接的rpc的客戶端,一般為db,eth,net,web3 |
| ? | rpcport | 指定允許連接的rpc服務監聽端口,默認為8545 |
| ? | networkid | 設置當前區塊鏈的網絡ID,用于區分不同的網絡,是一個數字 |
| ? | etherbase | 指定曠工賬號,默認為keystore中的首個賬號 |
| ? | mine | 開啟挖礦,默認為CPU挖礦 |
| ? | minerthreads | 挖礦占用CPU的線程數,默認為4 |
| ? | nodiscover | 關閉自動連接節點,但是可以手動添加節點,在搭建私有鏈時,為避免其他節點連入私有鏈,可以使用該命令 |
| ? | maxpeers | 設置允許最大連接節點數目,默認為25 |
| ? | console | 啟動命令行模式,可以在Geth中執行命令? |
log:
INFO [10-09|11:25:34.522] Maximum peer count ? ? ? ? ? ? ? ? ? ? ? ETH=30 LES=0 total=30
INFO [10-09|11:25:34.552] Starting peer-to-peer node ? ? ? ? ? ? ? instance=Geth/v1.8.14-stable/darwin-amd64/go1.10.3
INFO [10-09|11:25:34.552] Allocated cache and file handles ? ? ? ? database=/Users/xxx/Desktop/nasnano/ethereum/geth/db/geth/chaindata cache=768 handles=1024
INFO [10-09|11:25:34.662] Initialised chain configuration ? ? ? ? ?config="{ChainID: 15 Homestead: 0 DAO: <nil> DAOSupport: false EIP150: <nil> EIP155: 0 EIP158: 0 Byzantium: <nil> Constantinople: <nil> Engine: unknown}"
INFO [10-09|11:25:34.663] Disk storage enabled for ethash caches ? dir=/Users/xxx/Desktop/nasnano/ethereum/geth/db/geth/ethash count=3
INFO [10-09|11:25:34.663] Disk storage enabled for ethash DAGs ? ? dir=/Users/xxx/.ethash ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?count=2
INFO [10-09|11:25:34.663] Initialising Ethereum protocol ? ? ? ? ? versions="[63 62]" network=1981
INFO [10-09|11:25:34.664] Loaded most recent local header ? ? ? ? ?number=0 hash=f62ece…c00ca7 td=1
INFO [10-09|11:25:34.664] Loaded most recent local full block ? ? ?number=0 hash=f62ece…c00ca7 td=1
INFO [10-09|11:25:34.664] Loaded most recent local fast block ? ? ?number=0 hash=f62ece…c00ca7 td=1
INFO [10-09|11:25:34.665] Regenerated local transaction journal ? ?transactions=0 accounts=0
INFO [10-09|11:25:34.666] Starting P2P networking
INFO [10-09|11:25:34.667] RLPx listener up ? ? ? ? ? ? ? ? ? ? ? ? self="enode://576e857437aba95e59cfee3570a0fdd0d00dc9c4656ef9e48b47649cdc9b56f86bbf54081a5e38cec85fa150b4b088e22ccd93978e3de0c52aeed6b43471ee79@[::]:30303?discport=0"
INFO [10-09|11:25:34.669] IPC endpoint opened ? ? ? ? ? ? ? ? ? ? ?url=/Users/xxx/Desktop/nasnano/ethereum/geth/db/geth.ipc
INFO [10-09|11:25:34.697] HTTP endpoint opened ? ? ? ? ? ? ? ? ? ? url=http://0.0.0.0:8545 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?cors=* vhosts=localhost
INFO [10-09|11:25:34.697] Transaction pool price threshold updated price=18000000000
INFO [10-09|11:25:34.698] Commit new mining work ? ? ? ? ? ? ? ? ? number=1 uncles=0 txs=0 gas=0 fees=0 elapsed=514.993μs
Welcome to the Geth JavaScript console!
instance: Geth/v1.8.14-stable/darwin-amd64/go1.10.3
coinbase: 0x6e1d19b1d713e39fd77db95ff2929db78db4ad34
at block: 0 (Thu, 01 Jan 1970 08:00:00 CST)
?datadir: /Users/xxx/Desktop/nasnano/ethereum/geth/db
?modules: admin:1.0 debug:1.0 eth:1.0 ethash:1.0 miner:1.0 net:1.0 personal:1.0 rpc:1.0 txpool:1.0 web3:1.0
> INFO [10-09|11:25:37.341] Generating DAG in progress ? ? ? ? ? ? ? epoch=0 percentage=0 elapsed=1.492s
INFO [10-09|11:25:38.962] Generating DAG in progress ? ? ? ? ? ? ? epoch=0 percentage=1 elapsed=3.113s
v.進入JavaScript控制臺
通過attach命令,連接到iv啟動的節點(會在db下生成geth.ipc),啟動js命令環境
geth --datadir "./db" attach ipc:./db/geth.ipc
Welcome to the Geth JavaScript console!
instance: Geth/v1.8.14-stable/darwin-amd64/go1.10.3
coinbase: 0x6e1d19b1d713e39fd77db95ff2929db78db4ad34
at block: 0 (Thu, 01 Jan 1970 08:00:00 CST)
?datadir: /Users/liliang/Desktop/nasnano/ethereum/geth/db
?modules: admin:1.0 debug:1.0 eth:1.0 ethash:1.0 miner:1.0 net:1.0 personal:1.0 rpc:1.0 txpool:1.0 web3:1.0
>
vi.以太坊JavaScript控制臺命令
js控制臺內置了一些對象,通過這些對象可以很方便的與以太坊交互,這些內置對象包括:
eth:提供操作區塊鏈相關的方法
net:提供了查看p2p網絡狀態的的方法
admin:提供了管理節點相關的方法
miner:提供啟動和停止挖礦的方法
personal:提供了管理賬戶的方法
txpool:提供了查看交易內存池的方法
web3:除了包含以上對象中有的方法,還包含一些單位換算的方法
1、新建賬戶
> personal.newAccount("123456")
"0x98d03a20eb02fc526534cabbda6dc2e6b43de214"
personal.newAccount("password"),傳入的參數是賬戶的密碼。執行成功后會返回賬戶的公鑰,生成的賬戶文件在keystor目錄下.
查看賬戶:
eth.accounts
["0x2dd6b2362d6351b18bd3af9519b8e5b2e44d0339", "0x98d03a20eb02fc526534cabbda6dc2e6b43de214"]
2、查看余額
> balance=web3.fromWei(eth.getBalance(eth.accounts[0]),"ether")
0
> balance=web3.fromWei(eth.getBalance(eth.accounts[1]),"ether")
0
eth.accouts[index]會按傳入的索引返回已有的賬戶,eth.getBalance(address)會返回賬戶的余額,余額為wei為單位,傳入的參數是賬戶的公鑰。web3.fromWei單位轉換,在這個例子中是將wei轉換成ether。
創建的賬戶都是0,怎樣獲得以太幣呢,答案是挖礦。
3、挖礦
為了獲取以太幣,我們需要開始挖礦,不過在開啟挖礦之前,我們要先設置挖礦獎勵的地址
> miner.setEtherbase(eth.accounts[0])
true
查看設置是否成功:
> eth.coinbase
"0x2dd6b2362d6351b18bd3af9519b8e5b2e44d0339"
開啟挖礦:
miner.start(1),參數是線程數,表示可以開啟幾個線程來挖礦,本例中設置的是一個線程。當出現小錘子表示開始挖礦了。當挖礦時會有大量的輸入填滿終端,為了方便操作,你可以重現打開一個新的控制臺,執行attach命令,進入一個新的JavaScript環境。
關閉挖礦,等需要的時候在開:
>miner.stop()
true
查看下余額:
> ?balance=web3.fromWei(eth.getBalance(eth.accounts[0]),"ether")
6330
在以太坊上任何操作都需要借助交易來完成,如轉賬、部署合約、用用只能合約
4、解鎖賬戶
在發送交易之前,要先解鎖賬戶,否則會報錯,執行以下命令解鎖賬戶
> personal.unlockAccount(eth.accounts[0],"123456")
true
或
> personal.unlockAccount(eth.accounts[0],"123456",300)
true
personal.unlockAccount(addr,passwd,duration)命令用來解鎖賬戶,第一個參數解鎖地址,第二個參數是密碼,第三個參數傳入解鎖狀態持續時間,其中duration單位為秒。
5、交易
> eth.sendTransaction({from: eth.accounts[0],to: eth.accounts[1],value:web3.toWei(1,"ether")})
"0x590f47c8d2aac75460c08cd761fa81559e2053ce608f9f4fb68c27a73cb86379"
查看交易池等待被打幣的交易。
> txpool.status
{
? pending: 1,
? queued: 0
}
pending表示已提交,但未被處理的交易。
查看pending交易的詳情。
> txpool.inspect.pending
{
? 0x2dd6b2362D6351B18BD3af9519b8E5B2e44d0339: {
? ? 0: "0x98D03a20EB02Fc526534CaBbdA6Dc2e6b43DE214: 1000000000000000000 wei + 90000 gas × 18000000000 wei"
? }
}
要使交易被處理,必須要挖礦。這里我們啟動挖礦,然后等待挖到一個區塊之后就停止挖礦:
miner.start(1);admin.sleepBlocks(1);miner.stop();
交易被打包,并且加入到區塊鏈中了,查下余額
> balance=web3.fromWei(eth.getBalance(eth.accounts[1]),"ether")
1
vii.區塊
查詢發起轉賬交易的詳情,參數為交易hash:
> eth.getTransaction("0x590f47c8d2aac75460c08cd761fa81559e2053ce608f9f4fb68c27a73cb86379")
{
? blockHash: "0x5e5cf36663b967ed1c1bb26018fbe5df8af645dc6d9abced0eb317697a220722",
? blockNumber: 1423,
? from: "0x2dd6b2362d6351b18bd3af9519b8e5b2e44d0339",
? gas: 90000,
? gasPrice: 18000000000,
? hash: "0x590f47c8d2aac75460c08cd761fa81559e2053ce608f9f4fb68c27a73cb86379",
? input: "0x",
? nonce: 0,
? r: "0x3a562af2294afae7116c0ae2f4ba09da53f9fab8ca74d7e6ace0d22562f93636",
? s: "0x5bf7b3df00558695dd315c049c238021b60b6d0fd05a06b2b9c5cf5a169c87c2",
? to: "0x98d03a20eb02fc526534cabbda6dc2e6b43de214",
? transactionIndex: 0,
? v: "0x42",
? value: 1000000000000000000
}
交易參數:
| blockHash | 交易所在區塊的哈希值。當這個區塊處于pending時將會返回null |
| blockNumber | 交易所在區塊號。當這個區塊處于pending時將會返回null |
| from | 交易發起者的地址 |
| gas | 交易發起者提供的gas數量 |
| gasprice | 交易發起者提供的gas數量 |
| hash | 交易的哈希值 |
| input | 交易附帶的數據 |
| nonce | 交易的發起者在之前發起過的交易數量 |
| transactionIndex | 交易在區塊中的序號。當這個區塊處于pending時將會返回null |
| value | 交易附帶貨幣量,單位為Wei |
| to | 交易接收者的地址 |
查看發起交易在區塊中的詳細信息:
> eth.getTransactionReceipt("0x590f47c8d2aac75460c08cd761fa81559e2053ce608f9f4fb68c27a73cb86379")
{
? blockHash: "0x5e5cf36663b967ed1c1bb26018fbe5df8af645dc6d9abced0eb317697a220722",
? blockNumber: 1423,
? contractAddress: null,
? cumulativeGasUsed: 21000,
? from: "0x2dd6b2362d6351b18bd3af9519b8e5b2e44d0339",
? gasUsed: 21000,
? logs: [],
? logsBloom: "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
? root: "0xf977149c1937aa24648e0225c7626a2e3b3a8446baa1e60fc9d210ea395f7861",
? to: "0x98d03a20eb02fc526534cabbda6dc2e6b43de214",
? transactionHash: "0x590f47c8d2aac75460c08cd761fa81559e2053ce608f9f4fb68c27a73cb86379",
? transactionIndex: 0
}
TransactionReceipt參數詳解
| blockHash | 交易所在區塊哈希 |
| blockNumber | 交易所在去考的塊號 |
| contractAddress | 創建的合約地址。如果是一個合約創建交易,則返回合約地址,其他情況返回null |
| cumulativeGasUsed | 當前交易執行后累計話費的gas總值 |
| from | 交易發送者的地址 |
| gasUsed | 執行當前這個交易單獨花費的gas |
| logs | logsBloom由logs中的address與topics共同決定,詳細請查看以太坊黃皮書 |
| root | 交易執行后的stateroot |
| to | 交易接受者的地址。如果是一個合約創建的交易,返回null |
| transactionHash | 交易哈希值 |
| transactionIndex | 交易在區塊里面的序號 |
常用的一些查詢區塊的命令:
查看當前區塊總數:
> eth.blockNumber
1433
查詢最新的區塊(參數為區塊數或Hash)
> eth.getBlock('latest')
{
? difficulty: 235650,
? extraData: "0xd98301080e846765746888676f312e31302e338664617277696e",
? gasLimit: 66190083,
? gasUsed: 0,
? hash: "0xd6a6e5da6ef0c5127363c468570c7f9a679b2d33dc14570ea751b916c0e17087",
? logsBloom: "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
? miner: "0x6e1d19b1d713e39fd77db95ff2929db78db4ad34",
? mixHash: "0xbf6a2bdde494f66921a763829a3d3d8ecc65bdbfbc4feba4ee9f99a599dec4a3",
? nonce: "0x0df18fb718d8ab3c",
? number: 1433,
? parentHash: "0xf631a736994fc3e9bd2772cbbcb092b2f8f58b49f0f7607deed83006d8500b61",
? receiptsRoot: "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
? sha3Uncles: "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
? size: 540,
? stateRoot: "0xd604935e26d44991888489c6412a6f4cf04bbd25913a6eeda0b5920b8d0cef51",
? timestamp: 1539072197,
? totalDifficulty: 264521090,
? transactions: [],
? transactionsRoot: "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
? uncles: []
}
> eth.getBlock(0)
{
? difficulty: 1,
? extraData: "0x",
? gasLimit: 268435455,
? gasUsed: 0,
? hash: "0xf62ece4906c7cadd848274fc800e0d881f9d296db67c9641121ea5315ec00ca7",
? logsBloom: "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
? miner: "0x0000000000000000000000000000000000000000",
? mixHash: "0x0000000000000000000000000000000000000000000000000000000000000000",
? nonce: "0x0000000000000001",
? number: 0,
? parentHash: "0x0000000000000000000000000000000000000000000000000000000000000000",
? receiptsRoot: "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
? sha3Uncles: "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
? size: 505,
? stateRoot: "0x19ef3cc3d7fdd74a91b4fcdcb8b18f6d151a74a6aa6dbab57ba0314152dadd2d",
? timestamp: 0,
? totalDifficulty: 1,
? transactions: [],
? transactionsRoot: "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
? uncles: []
}
區塊參數詳解
| diffculty | 挖礦難度,后面區塊難度會隨著區塊高度升高而提高 |
| extraData | 當前區塊附件信息,若創世區塊該值為空,則在第二個區塊中會保存創建該私有鏈時的geth、go,以及操作系統版本,保存的信息為第一個挖到該區塊的礦工信息 |
| gasLimit | 該區塊允許的最大gas數 |
| gasUsed | gas花費,在以太坊中交易和部署智能合約會消耗gas,暫時可理解為以太幣 |
| hash | 當前區塊hash值 |
| logsBloom | logsBloom由logs中的address與topics共同決定,詳細請看以太坊黃皮書。作用是便于快速查找監聽的事件是否在該交易中產生 |
| miner | 挖到該區塊的礦工地址 |
| mixHash | 與nonce配合用于挖礦,由上一個區塊的一部分生成的hash |
| nonce | 工作量證明 |
| number | 當前的區塊高度 |
| parentHash | 上一個區塊hash值 |
| receiptsRoot | 區塊receipt trie的根 |
| sha3Uncles | 對叔區塊進行的hash運算的結果 |
| size | 區塊大小,以字節為單位 |
| stateRoot | 塊的狀態樹根結果 |
| timestamp | 時間戳 |
| totalDifficulty | 達到該區塊的難度總數 |
| transactions | 以數組的形式保存交易的tx值 |
| transactionsRoot | 交易的默克爾樹根 |
| uncles | 當前區塊引用的叔父區塊的哈希值 |
viii.遠程節點管理
之前是單機上的操作,需要和其他節點醉成一個以太坊網絡,需要獲取其他節點的信息。
查看節點信息:
> admin.nodeInfo
{
? enode: "enode://576e857437aba95e59cfee3570a0fdd0d00dc9c4656ef9e48b47649cdc9b56f86bbf54081a5e38cec85fa150b4b088e22ccd93978e3de0c52aeed6b43471ee79@[::]:30303?discport=0",
? id: "576e857437aba95e59cfee3570a0fdd0d00dc9c4656ef9e48b47649cdc9b56f86bbf54081a5e38cec85fa150b4b088e22ccd93978e3de0c52aeed6b43471ee79",
? ip: "::",
? listenAddr: "[::]:30303",
? name: "Geth/v1.8.14-stable/darwin-amd64/go1.10.3",
? ports: {
? ? discovery: 0,
? ? listener: 30303
? },
? protocols: {
? ? eth: {
? ? ? config: {
? ? ? ? chainId: 15,
? ? ? ? eip150Hash: "0x0000000000000000000000000000000000000000000000000000000000000000",
? ? ? ? eip155Block: 0,
? ? ? ? eip158Block: 0,
? ? ? ? homesteadBlock: 0
? ? ? },
? ? ? difficulty: 264521090,
? ? ? genesis: "0xf62ece4906c7cadd848274fc800e0d881f9d296db67c9641121ea5315ec00ca7",
? ? ? head: "0xd6a6e5da6ef0c5127363c468570c7f9a679b2d33dc14570ea751b916c0e17087",
? ? ? network: 1981
? ? }
? }
}
添加其他節點:
獲取另一個節點的encode的信息,將enode中的[::]替換成節點二的IP地址:
> admin.nodeInfo.enode
"enode://576e857437aba95e59cfee3570a0fdd0d00dc9c4656ef9e48b47649cdc9b56f86bbf54081a5e38cec85fa150b4b088e22ccd93978e3de0c52aeed6b43471ee79@[::]:30303?discport=0"
> admin.addpeer("enode://576e857437aba95e59cfee3570a0fdd0d00dc9c4656ef9e48b47649cdc9b56f86bbf54081a5e38cec85fa150b4b088e22ccd93978e3de0c52aeed6b43471ee79@172.16.15.145:30303")
true
查看遠程節點:
> admin.peers
?
-------------------
使用最新版本geth客戶,當執行personal.unlockAccount()或在程序中調用personal_unlockAccount接口時,會出現:account unlock with HTTP access is forbidden異常。
異常原因
新版本geth,出于安全考慮,默認禁止了HTTP通道解鎖賬戶,相關issue:https://github.com/ethereum/go-ethereum/pull/17037
解決方案
如果已經了解打開此功能的風險,可通啟動命令中添加參數:
--allow-insecure-unlock來進行打開操作。
示例:
geth --rpc --rpcapi eth,web3,personal --allow-insecure-unlock?
以太坊測試區塊鏈環境搭建
比特幣吸金之道系列文章,由計算機黑客發明的網絡貨幣,無國界,無政府,無中心。沒有政府濫發貨幣,沒有通貨膨脹。在全球計算機網絡中,自由的實現貨幣兌換和流通。
本系列文章只講程序和策略,不談挖礦…
關于作者:
- 張丹(Conan), 程序員/Quant: Java,R,Nodejs
- blog:?http://blog.fens.me
- email: bsspirit@gmail.com
轉載請注明出處:
http://blog.fens.me/bitcoin-geth-testnet
前言
以太坊(ETH)的出現開啟了區塊鏈的2.0時代,要進行ETH的開發和測試,我們先要搭建起來ETH的測試區塊鏈網絡。在測試環境中,我們可以直接通過參數配置,生成創世區塊,設置挖礦難度,設置gas消耗,執行轉賬交易,定義智能合約等的操作。
目錄
1. 搭建測試區塊鏈
由于在以太坊公鏈上做任何操作,都需要消耗以太幣(eth),對于開發者來說,很有必要在本地自行搭建一個測試區塊鏈網絡,進行智能合約的開發,最后再將開發好的合約部署到公鏈上。私有區塊鏈不同于以太坊公鏈,給我們很多的自由度,直接可能通過參數配置,生成創世區塊,設置挖礦難度,設置gas消耗,執行轉賬交易,定義智能合約等的操作,這些都需要我們手動進行設置。
私有區塊鏈的搭建,也是基于geth客戶端來完成的,geth的安裝過程,請參考文章?geth以太坊節點安裝。
下面,我們就用geth客戶端,開始搭建測試區塊鏈。創建測試節點的文件存儲目錄。
> mkdir /data0/eth-test/ > cd /data0/eth-test/新建配置文件genesis.json
> vi genesis.json {"nonce": "0x0000000000000042","timestamp": "0x0","parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000","mixhash": "0x0000000000000000000000000000000000000000000000000000000000000000","extraData": "0x","gasLimit": "0x80000000","difficulty": "0x3","coinbase": "0x3333333333333333333333333333333333333333","config":{"chainId": 55,"homesteadBlock": 0,"eip155Block": 0},"alloc": {} }參數設置:
- nonce:64位隨機數,用于挖礦
- timestamp:創世塊的時間戳
- parentHash:上一個區塊的hash值,因為是創世塊,所以這個值是0
- mixhash:與 nonce 配合用于挖礦,由上一個區塊的一部分生成的 hash。
- extraData:附加信息,任意填寫
- gasLimit :對GAS的消耗總量限制,用來限制區塊能包含的交易信息總和,因為我們就測試鏈,所以隨意填寫。
- difficulty:難度值,越大越難
- coinbase:礦工賬號,第一個區塊挖出后將給這個礦工賬號發送獎勵的以太幣。
- alloc: 預設賬號以及賬號的以太幣數量,測試鏈挖礦比較容易可以不配置
- chainId 指定了獨立的區塊鏈網絡 ID,不同 ID 網絡的節點無法互相連接。
初始化區塊鏈,生成創世區塊和初始狀態。
> geth --datadir=/data0/eth-test init /data0/eth-test/genesis.json INFO [06-26|08:10:32.943749] Maximum peer count ETH=25 LES=0 total=25 INFO [06-26|08:10:32.944172] Allocated cache and file handles database=/data0/eth-test/geth/chaindata cache=16 handles=16 INFO [06-26|08:10:32.989586] Persisted trie from memory database nodes=0 size=0.00B time=3.877μs gcnodes=0 gcsize=0.00B gctime=0s livenodes=1 livesize=0.00B INFO [06-26|08:10:32.989983] Successfully wrote genesis state database=chaindata hash=4a306e…543a63 INFO [06-26|08:10:32.990028] Allocated cache and file handles database=/data0/eth-test/geth/lightchaindata cache=16 handles=16 INFO [06-26|08:10:33.036685] Persisted trie from memory database nodes=0 size=0.00B time=3.258μs gcnodes=0 gcsize=0.00B gctime=0s livenodes=1 livesize=0.00B INFO [06-26|08:10:33.037027] Successfully wrote genesis state database=lightchaindata hash=4a306e…543a63運行日志,包括了允許最大點對點連接當前節點數為total=25,普通節點連接數ETH=25,LES輕節點連接數0。數據庫存儲的目錄在 /data0/eth-test/geth/chaindata ,當前存活的節點 livenodes=1。
參數說明
- datadir, 設置當前區塊鏈網絡數據存放的位置
- init,初始化,生成創世區塊
接下來,啟動測試節點,并進入 geth 命令行界面。
> geth --identity "TestNode" --rpc --rpcport "8545" --datadir=/data0/eth-test --port "30303" --nodiscover console INFO [06-26|08:14:00.916738] Maximum peer count ETH=25 LES=0 total=25 INFO [06-26|08:14:00.918148] Starting peer-to-peer node instance=Geth/TestNode/v1.8.12-unstable-f1986f86/linux-amd64/go1.10.3 INFO [06-26|08:14:00.918235] Allocated cache and file handles database=/data0/eth-test/geth/chaindata cache=768 handles=512 INFO [06-26|08:14:00.979836] Initialised chain configuration config="{ChainID: 55 Homestead: 0 DAO: DAOSupport: false EIP150: EIP155: 0 EIP158: Byzantium: Constantinople: Engine: unknown}" INFO [06-26|08:14:00.979915] Disk storage enabled for ethash caches dir=/data0/eth-test/geth/ethash count=3 INFO [06-26|08:14:00.979943] Disk storage enabled for ethash DAGs dir=/root/.ethash count=2 INFO [06-26|08:14:00.980023] Initialising Ethereum protocol versions="[63 62]" network=1 INFO [06-26|08:14:00.980566] Loaded most recent local header number=0 hash=4a306e…543a63 td=3 INFO [06-26|08:14:00.980634] Loaded most recent local full block number=0 hash=4a306e…543a63 td=3 INFO [06-26|08:14:00.980662] Loaded most recent local fast block number=0 hash=4a306e…543a63 td=3 INFO [06-26|08:14:00.980842] Regenerated local transaction journal transactions=0 accounts=0 INFO [06-26|08:14:00.981818] Starting P2P networking INFO [06-26|08:14:00.982303] RLPx listener up self="enode://15653a443e91b04040fe2731e0a0fa556a1d050580fa587110b17460cf471a8c3b42ac08dbc3d84a404f8c102ae35b28d9e2c1b9f2eae4c828a0dfa21c1f2117@[::]:30303?discport=0" INFO [06-26|08:14:00.985029] IPC endpoint opened url=/data0/eth-test/geth.ipc INFO [06-26|08:14:00.985503] HTTP endpoint opened url=http://127.0.0.1:8545 cors= vhosts=localhost Welcome to the Geth JavaScript console!instance: Geth/TestNode/v1.8.12-unstable-f1986f86/linux-amd64/go1.10.3modules: 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>- identity, 自定義的節點名字
- rpc , 允許 HTTP-RPC 訪問
- rpcport , HTTP_RPC的訪問端口,默認為8545
- port , 網絡監聽端口,默認為30303
- datadir, 設置當前區塊鏈網絡數據存放的位置
- console, 啟動命令行模式,可以在Geth中執行命令
- nodiscover, 私有鏈地址,不會被網上看到
這樣我們就把一個測試網絡啟動起來了,由于是單節點,網絡沒有其他的節點,所以并沒有直接的數據輸出。
2. 開始挖礦
接下來,我們在自己搭建的私有網絡中,開始做常規ETH的操作。
2.1 創建賬號
創建一個新賬號,密碼為123456,賬號的地址為:0x9cac40f650e2cbe459dcb32c7c23103497134467。
> personal.newAccount("123456") "0x9cac40f650e2cbe459dcb32c7c23103497134467"另一種方式,生成一個新賬號。
> personal.newAccount() Passphrase: Repeat passphrase: "0x762a2e28c5dbab9cd31369db5f3cbb48f421c0e3"查看所有賬號
> eth.accounts ["0x9cac40f650e2cbe459dcb32c7c23103497134467", "0x762a2e28c5dbab9cd31369db5f3cbb48f421c0e3"]2.2 挖礦
接下來,我們開始挖礦。挖礦,就是產生以太幣的過程。之前在genesis.json文件中,設置的difficulty=3,挖礦難比較低,很快就是挖出以太幣來。
# 開始挖礦 > miner.start(1) INFO [06-26|08:19:58.086688] Updated mining threads threads=1 INFO [06-26|08:19:58.086828] Transaction pool price threshold updated price=18000000000# 礦工賬號:如果有多個賬戶的情況下,挖礦獲得的eth,會自動計入第一賬戶中。 INFO [06-26|08:19:58.086887] Etherbase automatically configured address=0x9cac40F650E2CBE459dcb32c7c23103497134467 INFO [06-26|08:19:58.087015] Starting mining operation # 開始探索新區塊,沒有交易內容 INFO [06-26|08:19:58.087793] Commit new mining work number=1 txs=0 uncles=0 elapsed=659.441μs # 成功發現新區塊 INFO [06-26|08:19:58.451612] Successfully sealed new block number=1 hash=c120d3…23dad2 # 確認挖到新區塊 INFO [06-26|08:19:58.452182] mined potential block number=1 hash=c120d3…23dad2 INFO [06-26|08:19:58.45237] Commit new mining work number=2 txs=0 uncles=0 elapsed=165.519μs INFO [06-26|08:20:00.683558] Successfully sealed new block number=2 hash=011b1c…100594 INFO [06-26|08:20:00.68399] mined potential block number=2 hash=011b1c…100594 INFO [06-26|08:20:00.684181] Commit new mining work number=3 txs=0 uncles=0 elapsed=111.601μs INFO [06-26|08:20:09.965339] Successfully sealed new block number=3 hash=173ea5…c059ef INFO [06-26|08:20:09.965789] mined potential block number=3 hash=173ea5…c059ef INFO [06-26|08:20:09.966091] Commit new mining work number=4 txs=0 uncles=0 elapsed=246.371μs INFO [06-26|08:20:11.622999] Successfully sealed new block number=4 hash=56240d…0910a3// 省略INFO [06-26|08:20:16.264066] Commit new mining work number=10 txs=0 uncles=0 elapsed=155.89μs INFO [06-26|08:20:16.466436] Successfully sealed new block number=10 hash=819037…fbcd88 INFO [06-26|08:20:16.466774] block reached canonical chain number=5 hash=7f1015…f53c57 INFO [06-26|08:20:16.466794] mined potential block number=10 hash=819037…fbcd88 INFO [06-26|08:20:16.466965] Commit new mining work number=11 txs=0 uncles=0 elapsed=92.726μs# 停止挖礦 > miner.stop() true開始挖了幾秒,就產生了10個區塊。查看賬戶資金為50000000000000000000 wei。第一個賬戶為礦工賬號,第二個賬戶是一個普通賬號。
> eth.getBalance(eth.accounts[0]) 50000000000000000000 > eth.getBalance(eth.accounts[1]) 0由于Wei是最小的單位,我們把Wei轉換為ether為單位,比較好看,就是為 50 ether = 50000000000000000000/10^18
> web3.fromWei(eth.getBalance(eth.accounts[0]), "ether") 50轉換單位
- Wei = 10^0 Wei
- Ada = 10^3 Wei
- Babbage = 10^6 Wei
- Shannon = 10^9 Weiv
- Szabo = 10^12 Wei
- Finney = 10^15 Wei
- Ether = 10^18 Wei
- Einstein = 10^21 Wei
- Douglas = 10^42 Wei
2.3 查看區塊高度
下一步,我們查看一下區塊高度,并分析一下區塊的細節。
# 查看區塊高度 > eth.blockNumber 10# 查看第10個區塊的細節 > eth.getBlock(10) {difficulty: 131648,extraData: "0xd88301080c846765746888676f312e31302e33856c696e7578",gasLimit: 2126604064,gasUsed: 0,hash: "0x819037bcc65eb789eca82fcc3d6c686852ab8297df6396cffa6cfffeaffbcd88",logsBloom: "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",miner: "0x9cac40f650e2cbe459dcb32c7c23103497134467",mixHash: "0x311cd5ef45d9295d8c1b1b8778fb05b0e49dc6cae5971763c2e2d7e3d20bd895",nonce: "0x0b1aae8070cdff77",number: 10,parentHash: "0x1c5609a70d36a460234b95116fcc391e49890c5082af41d8cba3b5b366aa0028",receiptsRoot: "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",sha3Uncles: "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",size: 537,stateRoot: "0x0917e990c98b3daf316d0d38a4a2eefd0ad30436bab8ae61adb1ca24723eea81",timestamp: 1529972416,totalDifficulty: 1313603,transactions: [],transactionsRoot: "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",uncles: [] }第10個區塊為當前的最后一個區塊,挖礦難度difficulty=131648,沒有交易gasUsed=0,當前塊的hash值hash: “0x819037bcc65eb789eca82fcc3d6c686852ab8297df6396cffa6cfffeaffbcd88”,,上一個塊的地址parentHash: “0x819037bcc65eb789eca82fcc3d6c686852ab8297df6396cffa6cfffeaffbcd88”,礦工賬號miner: “0x9cac40f650e2cbe459dcb32c7c23103497134467”,區塊高度number=10。
3. 第一筆轉賬
接下來,讓我完成第一筆轉賬。從礦工賬號轉賬30ether到第二個賬號。
> eth.sendTransaction({from:eth.accounts[0],to:eth.accounts[1],value:web3.toWei(30,"ether")}) Error: authentication needed: password or unlockat web3.js:3143:20at web3.js:6347:15at web3.js:5081:36at :1:1第一次,執行轉賬操作時,出現錯誤。需要把轉輸eth的賬號進行解鎖,才能轉賬。
# 解鎖賬號 > personal.unlockAccount(eth.accounts[0]) Unlock account 0x9cac40f650e2cbe459dcb32c7c23103497134467 Passphrase: true# 再次轉賬 > eth.sendTransaction({from:eth.accounts[0],to:eth.accounts[1],value:web3.toWei(30,"ether")}) INFO [06-26|08:26:44.060461] Submitted transaction fullhash=0x8d6d1eb3c1c82be1f419d8f772048644361c41362fd8de27f8252470f975d6bb recipient=0x762A2e28C5DbaB9cD31369DB5f3CBB48f421C0E3 "0x8d6d1eb3c1c82be1f419d8f772048644361c41362fd8de27f8252470f975d6bb"交易日志,交易的hash值fullhash=0x8d6d1eb3c1c82be1f419d8f772048644361c41362fd8de27f8252470f975d6bb,收款賬號recipient=0x762A2e28C5DbaB9cD31369DB5f3CBB48f421C0E3。
我們提交了第一筆的轉賬,查看2個賬戶的余額。
> eth.getBalance(eth.accounts[0]) 50000000000000000000 > eth.getBalance(eth.accounts[1]) 0賬戶的余額并沒有發生變化,這是因為基于區塊鏈的轉賬操作需要礦工確認才能完成,礦工確認的過程是要經過挖礦的。我們的轉賬的操作的任務已經提交,但是交易并未完成,還需要礦工挖礦提交新的區塊,在區塊中加入這次轉賬交易,提交新的區塊全網的節點(按百分比算,具體還沒細看源代碼)確認完成后,交易才正式生效。
由于鏈上只有我們自己,我們要重新開起挖礦程序。
# 開始挖礦 > miner.start(1) INFO [06-26|08:27:24.712255] Updated mining threads threads=1 INFO [06-26|08:27:24.712434] Transaction pool price threshold updated price=18000000000 INFO [06-26|08:27:24.712617] Starting mining operation # 探索新的區塊,包含一個操作信息txs=1 INFO [06-26|08:27:24.713512] Commit new mining work number=11 txs=1 uncles=0 elapsed=808.72μs INFO [06-26|08:27:27.638518] Successfully sealed new block number=11 hash=68495b…35d4fe INFO [06-26|08:27:27.638986] block reached canonical chain number=6 hash=3617e8…0dd7f5 INFO [06-26|08:27:27.639006] mined potential block number=11 hash=68495b…35d4fe INFO [06-26|08:27:27.639245] Commit new mining work number=12 txs=0 uncles=0 elapsed=227.705μs INFO [06-26|08:27:28.199602] Successfully sealed new block number=12 hash=96fd37…37c016 INFO [06-26|08:27:28.199963] block reached canonical chain number=7 hash=a8d6d5…e6036d INFO [06-26|08:27:28.19998] mined potential block number=12 hash=96fd37…37c016 INFO [06-26|08:27:28.200427] Commit new mining work number=13 txs=0 uncles=0 elapsed=276.033μs INFO [06-26|08:27:29.766971] Successfully sealed new block number=13 hash=a13201…c051c8 INFO [06-26|08:27:29.767429] block reached canonical chain number=8 hash=16222d…7a9445 INFO [06-26|08:27:29.767447] mined potential block number=13 hash=a13201…c051c8 INFO [06-26|08:27:29.767572] Commit new mining work number=14 txs=0 uncles=0 elapsed=110.439μs INFO [06-26|08:27:30.302882] Successfully sealed new block number=14 hash=e1ab15…e44665 INFO [06-26|08:27:30.303213] block reached canonical chain number=9 hash=1c5609…aa0028 INFO [06-26|08:27:30.303243] mined potential block number=14 hash=e1ab15…e44665 INFO [06-26|08:27:30.303471] Commit new mining work number=15 txs=0 uncles=0 elapsed=114.85μs INFO [06-26|08:27:35.685475] Successfully sealed new block number=15 hash=e1b5a4…1bab9e INFO [06-26|08:27:35.686032] block reached canonical chain number=10 hash=819037…fbcd88 INFO [06-26|08:27:35.686146] mined potential block number=15 hash=e1b5a4…1bab9e INFO [06-26|08:27:35.686523] Commit new mining work number=16 txs=0 uncles=0 elapsed=294.263μs# 停止挖礦 > miner.stop() true在高度number=11的區塊上,我們發現了有一筆轉賬信息。再次,查看賬戶余額,發現賬戶余額發生了變化。
> eth.getBalance(eth.accounts[0]) 45000000000000000000 > eth.getBalance(eth.accounts[1]) 30000000000000000000第一個賬戶變成了 45 ether,第二個賬號變成了30 ether。第二個賬戶余額,正是我們之前設定的轉賬金額。
# 查看當前塊的高度 > eth.blockNumber 15# 第11個區塊的細節 > eth.getBlock(11)difficulty: 131072,extraData: "0xd88301080c846765746888676f312e31302e33856c696e7578",gasLimit: 2124527304,gasUsed: 21000,hash: "0x68495bf329e886a8043d1af74d145a870ae6aa2d4e42134499b3730e5c35d4fe",logsBloom: "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",miner: "0x9cac40f650e2cbe459dcb32c7c23103497134467",mixHash: "0xbbf5053e0409cded11f0c8f1059cad389d366723cb2f6c077d6c71c36d31a254",nonce: "0x3cc35610dc92f143",number: 11,parentHash: "0x819037bcc65eb789eca82fcc3d6c686852ab8297df6396cffa6cfffeaffbcd88",receiptsRoot: "0x170861bbc9f17f29b4c8ef046f44fa7435c3ad3a54e752591c87050345c29d31",sha3Uncles: "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",size: 653,stateRoot: "0x6e44fbe836ebf62523a37bbbb1beaad0c0802be9ff5c4e7b19c16a1eb4c50112",timestamp: 1529972844,totalDifficulty: 1444675,transactions: ["0x8d6d1eb3c1c82be1f419d8f772048644361c41362fd8de27f8252470f975d6bb"],transactionsRoot: "0x98881bb99ed82df9a69726705fb2ac2d1371e9ba992c52ed3b4cd3ee50762d38",uncles: [] }第11個區塊發生了交易,消耗的gas手續費為gasUsed=21000 Wei,交易一共發生1筆transactions=0x8d6d1eb3c1c82be1f419d8f772048644361c41362fd8de27f8252470f975d6bb,礦工賬號miner: “0x9cac40f650e2cbe459dcb32c7c23103497134467″。
總結一下,本文介紹了如何搭建以太坊的私有節點,實現了挖礦的過程,并完了2個賬戶的第一筆轉賬操作。下一篇文章,找我了解智能合約的編寫。
?
?
總結
以上是生活随笔為你收集整理的区块链开发之搭建以太坊私有链的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: SpringBoot + Vue + n
- 下一篇: 区块链】利用Node.js开发与合约交互