以太坊搭建私鏈(二):創建私有區塊鏈、挖礦以及轉賬

本教程是基於CentOS7.5系統進行的。

區塊鏈是由若干個區塊組成的。因此我們首先需要爲私有鏈創建第一個區塊(即創世區塊),類似於數據結構中鏈表的頭節點。

創建創世區塊

首先,你需要創建一個創世區塊,這個區塊的創建應該讓所有節點都知道,並且都同意。

創建創世區塊的配置主要存儲於一個JSON文件中,這裏我們存在一個叫genesis.json的文件中。

爲了使結構更加清晰,先創建一個文件夾,專門存放私有鏈相關數據。

mkdir private_eth
cd private_eth
touch genesis.json

把下面的具體配置拷貝到genesis.json中,並保存

{
  "config": {
    "chainId": 10001,
    "homesteadBlock": 0,
    "eip150Block": 0,
    "eip155Block": 0,
    "eip158Block": 0,
    "byzantiumBlock": 0,
    "constantinopleBlock": 0,
    "petersburgBlock": 0
  },
  "alloc": {},
  "coinbase": "0x0000000000000000000000000000000000000000",
  "difficulty": "0x20000",
  "extraData": "",
  "gasLimit": "0x2fefd8",
  "nonce": "0x0000000000000042",
  "mixhash": "0x0000000000000000000000000000000000000000000000000000000000000000",
  "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
  "timestamp": "0x00"
}

如果你想爲一些賬戶預先分配一些資金便於測試,那麼可以在配置中創建賬戶並分配一些資金。這時候,你只需要用下面的配置替換掉上面的"alloc":{ }即可:

"alloc": {
  "0x0000000000000000000000000000000000000001": {
    "balance": "111111111"
  },
  "0x0000000000000000000000000000000000000002": {
    "balance": "222222222"
  }
}

 

初始化區塊鏈

啓動之前,先進行初始化:

geth init genesis.json --datadir test 

test目錄表示保存區塊鏈相關數據的目錄,這裏的test 與 genesis.json 文件在同一個目錄下。

test目錄是之前不存在的,執行後會自動生成。

test目錄下有兩個子目錄:

  • geth:存儲同步區塊鏈以及相關的數據;
  • keystore:保存了賬戶文件。由於私鏈剛創建,此時keystore目錄爲空。

注意:

如果直接執行

geth init genesis.json

可能會出現如下錯誤:

Fatal: Failed to write genesis block: database contains incompatible genesis (have d4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3, new a3c5c170988f516e00ea3078b2461a149bcd4d0422c8c894923c6cfa22d6926b)

因此記得通過--datadir 設置相應的存儲區塊鏈相關數據的目錄。

 

啓動以太坊客戶端

geth --rpc --rpccorsdomain="*"  --nodiscover --allow-insecure-unlock  --datadir './test' console

執行成功之後,如下圖所示:

一些常用相關參數總結:

// Ethereum參數
--config value:表示TOML配置文件的目錄;
--datadir value:存儲區塊鏈相關數據的文件目錄,包含geth和keystore兩個文件夾(默認爲 "/home/ligi/.ethereum"),geth目錄存儲同步區塊鏈以及相關的數據,keystore存儲賬戶相關數據;
--datadir.ancient value             Data directory for ancient chain segments (default = inside chaindata)
--keystore value                    賬戶祕鑰的存儲目錄 (默認在datadir裏面)
--networkid value                   網絡標識符 (integer, 1=Frontier, 2=Morden (disused), 3=Ropsten, 4=Rinkeby) (default: 1)
--testnet                           Ropsten network: pre-configured proof-of-work test network
--rinkeby                           Rinkeby network: pre-configured proof-of-authority test network
--syncmode value                    區塊鏈同步模式 ("fast", "full", or "light") (default: fast)
--exitwhensynced                    塊同步完成後退出
--identity value                    自定義節點名稱


//DEVELOPER CHAIN OPTIONS:
--dev                               擁有一些預先設置了資金的開發者賬戶的臨時權威證明網絡,並且可以直接挖礦
--dev.period value                  在開發者模式中使用塊(出塊)的時間,0表示只有在交易掛起的時候纔會挖礦,1表示不用等有了交易才挖礦 (default: 0)


//ACCOUNT OPTIONS:
  --unlock value                      要解鎖的賬戶列表(多個賬戶用逗號分隔)
  --password value                    用於非交互式密碼輸入的密碼文件


//API AND CONSOLE OPTIONS:
  --ipcdisable                        禁用(關閉)IPC-RPC服務器
  --ipcpath value                     Filename for IPC socket/pipe within the datadir (explicit paths escape it)
  --rpc                               啓用HTTP-RPC服務器
  --rpcaddr value                     HTTP-RPC服務器監聽的IP地址 (default: "localhost")
  --rpcport value                     HTTP-RPC 服務器監聽端口(default: 8545)
  --port:指定和其他節點連接所用的端口號(默認爲 30303);
  --rpcapi value                      通過HTTP-RPC接口提供的API
  --rpc.gascap value                  設置可以在eth_call/estimateGas中使用的gas上限(默認值:0) (default: 0)
  --rpccorsdomain value               哪些域名允許訪問跨域請求(多個域名用逗號分隔)(瀏覽器執行),"*"表示允許通過任意域名進行訪問
  --rpcvhosts value                   允許哪些虛擬主機名接受請求(多個的時候用逗號分開)(服務器執行). 接受 '*' 通配符. (default: "localhost")
  --ws                                啓用WS-RPC服務器
  --wsaddr value                      WS-RPC服務器監聽的地址 (default: "localhost")
  --wsport value                      WS-RPC服務器監聽的端口號 (default: 8546)
  --wsapi value                       WS-RPC接口提供的API
  --wsorigins value                   接受websockets請求的源


//NETWORKING OPTIONS:
  --nodiscover                        禁用節點發現機制,防止加入有同樣初始配置的的陌生節點


--verbosity: 表示設置日誌等級,0=silent, 1=error, 2=warn, 3=info, 4=debug, 5=detail (default: 

更多具體的參數解析請看:[Command Line Options](https://github.com/ethereum/go-ethereum/wiki/Command-Line-Options)

 

開始挖礦

 

(1)使用之前genesis.json中配置的賬戶進行挖礦

挖礦之前,先將賬戶和礦工進行綁定。miner是JavaScript控制檯中內置的礦工對象,在控制檯中可以使用如下的命令將genesis.json文件中的“alloc”中的某個地址與miner對象進行綁定,綁定的目的之一就是爲了明確挖礦得到的獎勵存到哪個賬戶去;

miner.setEtherbase("0x0000000000000000000000000000000000000001")

 

開始挖礦之前,我們可以查看一下兩個臨時賬戶的餘額

eth.getBalance("0x0000000000000000000000000000000000000001")
eth.getBalance("0x0000000000000000000000000000000000000002")

結果如下:

開始挖礦

miner.start()

查看當前區塊鏈中的區塊數

eth.blockNumber

再次查詢兩個臨時賬戶的餘額

eth.getBalance("0x0000000000000000000000000000000000000001")
eth.getBalance("0x0000000000000000000000000000000000000002")

由於礦工挖礦得到了一些挖礦的獎勵(以太幣),所以我們可以發現與礦工綁定的賬戶的餘額變多了。

 

(2)創建一個新的賬戶用於挖礦

進入JavaScript控制檯之後,然後先創建一個新賬戶,執行下面的命令輸入兩次密碼即可完成新賬戶的創建:

personal.newAccount()

創建完之後可以查看現有的賬戶

personal.listAccounts

結果如下圖所示,第二個賬戶就是我們創建的新賬戶:

將新賬戶與礦工進行綁定

miner.setEtherbase("0x7a3f4c28a85ec58f3c8bd862ab201b8a03dfff5f")

查看新賬戶的餘額

web3.fromWei(eth.getBalance(eth.coinbase), "ether")  //剛開始餘額爲0
//eth.coinbase直接使用賬戶的具體地址也可以實現上面一樣的效果,比如
web3.fromWei(eth.getBalance("0x7a3f4c28a85ec58f3c8bd862ab201b8a03dfff5f"), "ether")

開啓挖礦

miner.start()

停止挖礦

miner.stop()

查詢賬戶餘額,此時賬戶餘額有所增加,因爲礦工挖礦得到了相應的獎勵

web3.fromWei(eth.getBalance(eth.coinbase), "ether")
// or
web3.fromWei(eth.getBalance("0x7a3f4c28a85ec58f3c8bd862ab201b8a03dfff5f"), "ether")

 

轉賬

我們可以將A賬戶的以太幣轉賬給B賬戶,這裏我們用兩個賬戶進行轉賬操作的展示。

personal.listAccounts

可以發現我們這裏有兩個賬戶:

  • 第一個是"0xf157aa0bc8350484171eb0c18e739db03a2f23ce";
  • 第二個是"0x7a3f4c28a85ec58f3c8bd862ab201b8a03dfff5f"(這個是和礦工進行綁定了的);

現在我們用第二個賬戶向第一個賬戶轉賬3個Ether。

  • (1)首先我們查看轉賬之前,兩個賬戶的餘額是多少
web3.fromWei(eth.getBalance("0x7a3f4c28a85ec58f3c8bd862ab201b8a03dfff5f"), "ether")   // 22 Ether 
web3.fromWei(eth.getBalance("0xf157aa0bc8350484171eb0c18e739db03a2f23ce"), "ether")  // 542 Ether

  • (2)在轉賬之前,我們需要先把賬戶解鎖(類似我們在銀行轉賬,要先輸密碼一樣)
personal.unlockAccount("0x7a3f4c28a85ec58f3c8bd862ab201b8a03dfff5f", "123456", 300)   //"123456"表示該賬戶的密碼

如果轉賬之前沒有解鎖賬戶,會出現如下錯誤:

WARN [11-11|16:11:04.940] Served eth_sendTransaction               reqid=35 t=13.912431ms err="authentication needed: password or unlock"
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
  • (3)從第二個賬戶向第一個賬戶轉賬3個Ether
eth.sendTransaction({from: '0x7a3f4c28a85ec58f3c8bd862ab201b8a03dfff5f', to: '0xf157aa0bc8350484171eb0c18e739db03a2f23ce', value: web3.toWei(3, "ether")})

執行完成之後,會有如下顯示:

INFO [11-11|16:12:35.946] Setting new local account                address=0x7a3F4c28A85eC58F3c8bD862ab201B8a03Dfff5F
INFO [11-11|16:12:35.946] Submitted transaction                    fullhash=0x0fb7355356dc901976c9d996e59bfed1315bdd0546a5dbf9abca2fdabffff35c recipient=0xF157Aa0BC8350484171eb0C18e739DB03A2F2
"0x0fb7355356dc901976c9d996e59bfed1315bdd0546a5dbf9abca2fdabffff35c"

address 表示從哪個賬戶轉出;

fullhash 表示交易hash值;

recipient 表示轉入哪個賬戶;

這個時候我們再次查詢兩個賬戶的餘額,可以發現這兩個賬戶的餘額依然不變。

這是因爲交易在挖礦之後才能記入到區塊中並上鏈,所以我們需要進行挖礦。

miner.start(1)

然後再停止挖礦

miner.stop()

最後,查詢兩個賬戶的餘額

web3.fromWei(eth.getBalance("0x7a3f4c28a85ec58f3c8bd862ab201b8a03dfff5f"), "ether")
web3.fromWei(eth.getBalance("0xf157aa0bc8350484171eb0c18e739db03a2f23ce"), "ether")

我們可以發現第一個賬戶(0xf157aa0bc8350484171eb0c18e739db03a2f23ce)增加了 3 Ether,第二個賬戶(0x7a3f4c28a85ec58f3c8bd862ab201b8a03dfff5f)之前是22 Ether,現在也增加到了 29 Ether,這是因爲第二個賬戶挖礦得到了 10 Ether的獎勵,所以減去轉出的 3 Ether,還有29 Ether。

 

參考:

Go Ethereum

以太坊(2):CentOS下以太坊私有鏈環境下的賬戶管理操作、挖礦、轉賬

CentOS 以太坊(Etherum) 環境搭建及挖礦

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章