基於以太坊搭建私有鏈

簡介

本文主要學習以太坊的底層操做,環境搭建,查看系統信息,帳號建立,挖礦,交易,智能合約部署等操做node

安裝

機器:Mac
源碼:https://github.com/ethereum/g... 本文以go版本的ethereum爲例
若是是其它機型請參照 官方安裝文檔git

brew tap ethereum/ethereum
brew install ethereum

# 若是但願基於ethereum的develop分支安裝,執行 brew install ethereum --devel
brew install ethereum

初始化

以默認方式啓動會鏈接以太坊主鏈,同步數據到本地,佔用本地磁盤空間,因此不建議這麼作。咱們以私鏈的方式運行便可。運行私有鏈那麼就必須定義本身的創世區塊github

默認方式啓動,單機環境不建議使用,命令供參考web

> geth

或dev模式運行
> get --dev console 2>> geth-log

# 若是這種方式啓動,進入控制檯須要使用 geth attach 命令

初始化
在指定目錄下新建一個目錄用於保存生成的數據json

cd /tmp && mkdir blockchain && cd blockchain
mkdir data
touch genesis.json

目錄結構以下
.
├── data
└── genesis.json

genesis.json:初始化私有鏈的配置文件,配置創世區塊信息
data:存放區塊鏈數據的目錄。segmentfault

genesis.json內容以下bash

{
  "config": {
    "chainId": 15,
    "homesteadBlock": 0,
    "eip155Block": 0,
    "eip158Block": 0
  },
  "alloc": {},
  "nonce": "0x0000000000000042",
  "difficulty": "0x020000",
  "mixhash": "0x0000000000000000000000000000000000000000000000000000000000000000",
  "coinbase": "0x0000000000000000000000000000000000000000",
  "timestamp": "0x00",
  "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
  "extraData": "0x11bbe8db4e347b4e8c937c1c8370e4b5ed33adb3db69cbdb7a38e1e50b1b82fa",
  "gasLimit": "0x4c4b40"
}

參數解釋:網絡

alloc:用來預設置帳號以及帳號的 ether 數量。由於私有鏈挖礦比較容易,因此咱們不須要預設置帳號。好比,{"0x880004bb64282fb01a3a2500ddf1f4bb5ad4b64a":{"balance":"100000000000000000000000000000"}}
nonce:一個64位隨機數,用於挖礦。
mixhash:和 nonce 配合用於挖礦,由上一個區塊的一部分生成的 hash。
difficulty:設置當前區塊的難度,若是難度過大,cpu挖礦就很難,因此這邊設置的很小,不要跟本身過不去嘛。
coinbase:默認挖礦的礦工帳號。
timestamp:設置創世塊的時間戳。
parentHash:上一個區塊的hash值,由於是創世塊,因此值是0。
extraData:附加信息,隨便填。
gasLimit:設置對GAS的消耗總量限制,用來限制區塊能包含的交易信息總和。由於咱們是私有鏈,因此能夠寫的大一些,方便開發測試。

接下來咱們就須要將創世區塊的初始信息寫入區塊鏈中,使用geth init命令app

cd /tmp/blockchain
geth --datadir "./data" --networkid 31415926 --rpc --rpccorsdomain "*" init ./genesis.json

大體會輸出以下信息:cors

INFO [03-12|19:36:02] Allocated cache and file handles
INFO [03-12|19:36:02] Writing custom genesis block
INFO [03-12|19:36:02] Persisted trie from memory database
INFO [03-12|19:36:02] Successfully wrote genesis state

此時的目錄結構就變成以下:

.
├── data
│  ├── geth
│  │  ├── chaindata
│  │  │  ├── 000001.log
│  │  │  ├── CURRENT
│  │  │  ├── LOCK
│  │  │  ├── LOG
│  │  │  └── MANIFEST-000000
│  │  └── lightchaindata
│  │      ├── 000001.log
│  │      ├── CURRENT
│  │      ├── LOCK
│  │      ├── LOG
│  │      └── MANIFEST-000000
│  └── keystore
└── genesis.json

其中keystore目錄用來保存帳戶信息,geth目錄用來保存區塊信息。

啓動私有鏈

geth --datadir data --networkid 31415926 --rpc --rpccorsdomain "*" --nodiscover console

輸出以下即表示成功進入 geth 的控制檯:

Welcome to the Geth JavaScript console!

instance: Geth/v1.8.2-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

>

基本操做

  1. 建立帳號
# 查看一下系統有的用戶
> eth.accounts
[]

# 查看詳細的用戶信息
> personal

# 建立兩個帳號用於轉帳,或者使用 personal.newAccount() 也會提示輸入密碼
> personal.newAccount('123456')
> personal.newAccount('123456')

> eth.accounts
["0x18a6581a285f40ac3faaa646e13d7c6dd87276f4", "0x2455572ef500cf8634a4090d6d6096c588013e2a"]
# 此時能夠看下 keystore 目錄,多出了兩個文件,也就是咱們剛纔建立的兩個帳戶密鑰(丟了它,你就等於丟了幣)
  1. 挖礦

帳號建立好了,可是一開始帳號都沒有 ether,這時就須要挖礦獲取幣了。
使用miner.start()命令開啓挖礦,默認挖出的 ether 是存到 eth.coinbase 帳戶中的,也就是第一個帳戶。

# 查看帳號1下的餘額
> eth.getBalance(eth.accounts[0])

# 查看coinbase帳號
> eth.coinbase
0x18a6581a285f40ac3faaa646e13d7c6dd87276f4

# 若是想要把挖到的礦存入其餘帳戶,可使用
> miner.setEtherbase(eth.accounts[1])
true

開始挖礦,咱們先把coinbase改爲帳號1
> miner.setEtherbase(eth.accounts[0])
true

# 若是出現 miner.start() 直接返回 null 的狀況,請先查看是否還未建立過帳戶。
> miner.start(1)
INFO [05-31|19:57:17] Updated mining threads                   threads=0
INFO [05-31|19:57:17] Transaction pool price threshold updated price=18000000000
INFO [05-31|19:57:17] Starting mining operation
INFO [05-31|19:57:17] Commit new mining work                   number=12 txs=0 uncles=0 elapsed=194.667µs
INFO [05-31|19:57:19] Successfully sealed new block            number=12 hash=82d29d…65290c
INFO [05-31|19:57:19] 🔨 mined potential block                  number=12 hash=82d29d…65290c
INFO [05-31|19:57:19] Commit new mining work                   number=13 txs=0 uncles=0 elapsed=159.066µs
INFO [05-31|19:57:19] Successfully sealed new block            number=13 hash=e91844…e962a6
INFO [05-31|19:57:19] 🔨 mined potential block                  number=13 hash=e91844…e962a6
等到 percentage 達到100就能挖出來了,請耐心等待~,出現小錘頭的時候意味着你挖到了!

# 已經挖到了,咱們先暫停挖礦,注意:輸入的字符會被挖礦刷屏信息沖掉,沒有關係,只要輸入完整的miner.stop()以後回車,便可中止挖礦。正在執行的挖礦進程不會當即暫停,仍然會等到當前完整快寫完後纔會暫停
> miner.stop()
true

而後查看帳戶餘額
> eth.getBalance(eth.accounts[0])
112000000000000000000
# 不要被這個零的個數嚇到,這裏默認顯示的以 wei 爲單位的,而 1 ether = 10^18 wei,因此咱們轉換一下單位立馬就清晰了,

> web3.fromWei(eth.getBalance(eth.accounts[0]), 'ether')
112
# 嗯,其實咱們目前就挖了112個ether

轉帳

在轉帳前,咱們須要先解鎖帳號

> personal.unlockAccount(eth.accounts[0])

# 咱們先轉8個ether給帳號2
> eth.sendTransaction({from:eth.accounts[0],to:eth.accounts[1],value:web3.toWei(8,'ether')})

INFO [03-12|20:24:15] Submitted transaction      fullhash=0x996a3037b75585415ece5b1dc28181833691760176b3f24066c93e7093a967e5 recipient=0x29a079BdbC6D4d122178FBe01558E5DF2D008523

咱們能夠看到目前只是向區塊鏈提交了這筆轉帳交易,誰來執行這筆交易呢?礦工。咱們仍是得開啓挖礦模式,把這筆轉帳交易執行掉。而後咱們再來看看好朋友的帳戶裏面有多少 ether 了,

> miner.start(1)
# 持續幾秒
> miner.stop()

# 而後查看帳號2的餘額,已經有餘額
> eth.getBalance(eth.accounts[1])
8000000000000000000

鏈接到其它節點

鏈接到其它節點的前提條件:

  1. 網絡必須是互通的,不能一個在局域網,一個在公網
  2. 端口開放,8545和30303
  3. 指定相同的networkid

方法一:
首先咱們要知道節點二的enode信息,在節點二上執行:

> admin.nodeInfo.enode
"enode://9e86289ea859ca041f235aed87a091d0cd594b377cbe13e1c5f5a08a8a280e62d4019ac54063ed6a1d0e3c3eaedad0b73c40b99a16a176993f0373ffe92be672@[::]:30303"

而後在節點一上執行:

> admin.addPeer("enode://9e86289ea859ca041f235aed87a091d0cd594b377cbe13e1c5f5a08a8a280e62d4019ac54063ed6a1d0e3c3eaedad0b73c40b99a16a176993f0373ffe92be672@remote_ip:30303")
remote_ip須要替換成節點2的IP

返回true就說明執行成功,咱們能夠經過admin.peers查看新增的節點信息,同步操做是異步的,可能不能立馬看到節點2的信息
addPeer()的參數就是節點二的enode信息,鏈接成功後,節點二就會開始同步節點一的區塊,同步完成後,任意一個節點開始挖礦,另外一個節點會自動同步區塊,向任意一個節點發送交易,另外一個節點也會收到該筆交易。

方法二:
除了上面的方法,也能夠在啓動節點的時候指定--bootnodes選項鍊接到其餘節點。
示例:指定兩個節點

geth --bootnodes enode://pubkey1@ip1:port1,enode://pubkey2@ip2:port2

以太坊錢包

關於以幾種客戶端的介紹請參考 以太坊客戶端介紹

咱們如今以Ethereum Wallet爲例來鏈接本地私有鏈,下載Ethereum Wallet後,直接點圖標啓動默認會連接以太坊共鏈。因此咱們須要在命令行啓動,並指定私有鏈地址

cd /Applications
./Ethereum\ Wallet.app/Contents/MacOS/Ethereum\ Wallet --rpc "私有鏈ipc地址"

私有鏈地址在私有鏈啓動時,日誌的第16行能夠找到,以本機爲例,啓動命令就是

./Ethereum\ Wallet.app/Contents/MacOS/Ethereum\ Wallet --rpc /Users/moon/geth/data/geth.ipc

若是須要鏈接遠程節點,請參考 以太坊客戶端鏈接遠程節點



歡迎訂閱「K叔區塊鏈」 - 專一於區塊鏈技術學習

博客地址: http://www.jouypub.com
簡書主頁: https://www.jianshu.com/u/756c9c8ae984
segmentfault主頁: https://segmentfault.com/blog/jouypub
騰訊雲主頁: https://cloud.tencent.com/developer/column/72548
相關文章
相關標籤/搜索