kc-luk-188412

Background

最近要建礦池所以需要了解一下怎麼在Ethereum的區塊鏈上建一個node. 所以紀錄一下. 但本文中紀錄的是建立一個 private chain & 啟動 node. 使用AWS的VPS服務.

Installation

Basic

Update

$ sudo apt-get update
$ sudo apt-get dist-upgrade
$ sudo apt-get install build-essential make
$ sudo vim /etc/default/locale

/etc/default/locale

LANG=en_US.UTF-8
LC_ALL=en_US.UTF-8

Time

$ sudo mkdir /etc/sysconfig/
$ sudo vim /etc/sysconfig/clock
$ sudo ln -sf /usr/share/zoneinfo/Asia/Taipei /etc/localtime
$ sudo reboot

/etc/sysconfig/clock

ZONE="Asia/Taipei"
UTC=true

Golang

$ wget https://storage.googleapis.com/golang/go1.9.2.linux-amd64.tar.gz
$ sudo tar -xvf go1.9.2.linux-amd64.tar.gz
$ sudo mv go /usr/local
$ export GOROOT=/usr/local/go
$ export PATH=$GOPATH/bin:$GOROOT/bin:$PATH
$ export GOPATH=$HOME/go
$ go version
go version go1.9.2 linux/amd64

go-ethereum

$ git clone https://github.com/ethereum/go-ethereum
$ cd go-ethereum
$ make geth

Initialization

初始化private chain

$ cd go-ethereum
$ sudo cp build/bin/geth /usr/local/bin
$ mkdir privatechain
$ geth --datadir ./privatechain account new
Your new account is locked with a password. Please give a password. Do not forget this password.
Passphrase:
Repeat passphrase:
Address: {9ba728aa745d0a71bd12f86a7a3dca7e50b7a0ad}
$ vim custom_genesis.json
$ geth --datadir "./privatechain" --networkid 5566 init custom_genesis.json
INFO [02-04|20:01:22] Allocated cache and file handles         database=/home/ubuntu/go-ethereum/privatechain/geth/chaindata cache=16 handles=16
INFO [02-04|20:01:22] Writing custom genesis block
INFO [02-04|20:01:22] Successfully wrote genesis state         database=chaindata                                            hash=13bbed…b09fd5
INFO [02-04|20:01:22] Allocated cache and file handles         database=/home/ubuntu/go-ethereum/privatechain/geth/lightchaindata cache=16 handles=16
INFO [02-04|20:01:22] Writing custom genesis block
INFO [02-04|20:01:22] Successfully wrote genesis state         database=lightchaindata                                            hash=13bbed…b09fd5

建一條私鏈所以需要一個創世區塊(genesis block). 基本的config檔如下: 把剛剛得到的address填入alloc中並填入你想要的餘額, 這樣我們之後才能做一些交易的事情.

custom_genesis.json

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

Genesis block Explanation

補充一些config的各個參數的意思, 這邊我就不翻譯了.

  • mixhash: A 256-bit hash which proves, combined with the nonce, that a sufficient amount of computation has been carried out on this block: the Proof-of-Work (PoW). The combination of nonce and mixhash must satisfy a mathematical condition described in the Yellowpaper, 4.3.4. Block Header Validity, (44). It allows to verify that the Block has really been cryptographically mined, thus, from this aspect, is valid.

  • nonce: A 64-bit hash, which proves, combined with the mix-hash, that a sufficient amount of computation has been carried out on this block: the Proof-of-Work (PoW). The combination of nonce and mixhash must satisfy a mathematical condition described in the Yellowpaper, 4.3.4. Block Header Validity, (44), and allows to verify that the Block has really been cryptographically mined and thus, from this aspect, is valid. The nonce is the cryptographically secure mining proof-of-work that proves beyond reasonable doubt that a particular amount of computation has been expended in the determination of this token value. (Yellowpager, 11.5. Mining Proof-of-Work).

  • difficulty: A scalar value corresponding to the difficulty level applied during the nonce discovering of this block. It defines the mining Target, which can be calculated from the previous block’s difficulty level and the timestamp. The higher the difficulty, the statistically more calculations a Miner must perform to discover a valid block. This value is used to control the Block generation time of a Blockchain, keeping the Block generation frequency within a target range. On the test network, we keep this value low to avoid waiting during tests, since the discovery of a valid Block is required to execute a transaction on the Blockchain.

  • alloc: Allows defining a list of pre-filled wallets. That’s an Ethereum specific functionality to handle the “Ether pre-sale” period. Since we can mine local Ether quickly, we don’t use this option.

  • coinbase: The 160-bit address to which all rewards (in Ether) collected from the successful mining of this block have been transferred. They are a sum of the mining reward itself and the Contract transaction execution refunds. Often named “beneficiary” in the specifications, sometimes “etherbase” in the online documentation. This can be anything in the Genesis Block since the value is set by the setting of the Miner when a new Block is created.

  • timestamp: A scalar value equal to the reasonable output of Unix time() function at this block inception. This mechanism enforces a homeostasis in terms of the time between blocks. A smaller period between the last two blocks results in an increase in the difficulty level and thus additional computation required to find the next valid block. If the period is too large, the difficulty, and expected time to the next block, is reduced. The timestamp also allows verifying the order of block within the chain (Yellowpaper, 4.3.4. (43)).

  • parentHash: The Keccak 256-bit hash of the entire parent block header (including its nonce and mixhash). Pointer to the parent block, thus effectively building the chain of blocks. In the case of the Genesis block, and only in this case, it’s 0.

  • extraData: An optional free, but max. 32-byte long space to conserve smart things for ethernity. :)

  • gasLimit: A scalar value equal to the current chain-wide limit of Gas expenditure per block. High in our case to avoid being limited by this threshold during tests. Note: this does not indicate that we should not pay attention to the Gas consumption of our Contracts.

那網路上有人整理了常見的幾個錯誤, 我也列在這邊. (http://blog.csdn.net/loy_184548/article/details/78002074)

  • Fatal: invalid genesis file: missing 0x prefix for hex data:這個錯誤信息意思很明白,就是你的json文件中,對於16進制數據,需要加上0x前綴

  • Fatal: invalid genesis file: hex string has odd length:從v1.6開始,設置的十六進制數值,不能是奇數位,比如不能是0x0,而應該是0x00。

  • Fatal: failed to write genesis block: genesis has no chain configuration :這個錯誤信息,就是說,你的json文件中,缺少配置部分。看看這個信息,我們不需要把geth退到到v1.5版本,而是需要加上配置部分。

  • Error:invalid sender undefined:這個錯誤不會導致初始化失敗,但是會在以後的轉賬(eth.sendTransaction),或者部署智能合約的時候產生。解決方法就是chainId不能設置為0.如果你完全按照github上給的官方配置文件,就會產生這個錯誤。

啟動 node 並進入到 console

$ geth --rpc --rpcaddr 127.0.0.1 --rpcport 8545 --networkid 5566 --datadir privatechain console

應該會出現類似下面這樣的介面. 看到表示你成功啟動node&進入到console介面了. 如果你切换到 privatechain 文件夾中,你會看 到geth, geth.ipc, 和 keystore.


...

➜  go-ethereum git:(master) ✗ build/bin/geth attach ipc:/home/ubuntu/go-ethereum/privatechain/geth.ipc
Welcome to the Geth JavaScript console!

instance: Geth/v1.8.0-unstable-ec96216d/linux-amd64/go1.9.2
coinbase: 0x1c4750d78c23277e40bac02d47f4da8ad8ce1915
at block: 5926 (Tue, 23 Jan 2018 15:22:40 UTC)
 datadir: /home/ubuntu/go-ethereum/privatechain
 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

>

Console 操作

接著我們要操作 console, 首先先下personal.listAccounts, eth.getBalance來看看我們初始化有沒有成功

> personal.listAccounts
["0x9ba728aa745d0a71bd12f86a7a3dca7e50b7a0ad"]
> eth.getBalance(eth.accounts[0])
10000000000000000000
>

基本指令介紹

# 創建新賬號
personal.newAccount()

# 查看節點訊息
admin.nodeInfo

# 查看當前礦工賬號,默認為第一個賬戶
eth.coinbase

# 查看帳戶
personal.listAccounts

# 查看賬戶餘額
eth.getBalance(eth.accounts[0])

# 解鎖賬號
personal.unlockAccount(eth.accounts[0])

# 查看區塊數據相關指令
eth.blockNumber
eth.getTransaction("0x0c90831068937cbe9e230483bc90f58bd71532dc8fa5ec37fea6710a1dze937")
eth.getBlock(1)

# 開始/停止 挖礦
miner.start(1)
miner.stop()

交易

> personal.newAccount()
Passphrase:
Repeat passphrase:
"0xd35bfa71c69f7ccbb1941aeabdc72a1d0e599b80"
> personal.newAccount()
Passphrase:
Repeat passphrase:
"0x808f651ed4a3b120a3055912b6e276e3d1845685"
> var tx = {from: "0x9ba728aa745d0a71bd12f86a7a3dca7e50b7a0ad", to: "0xd35bfa71c69f7ccbb1941aeabdc72a1d0e599b80", value: web3.toWei(0.0000001, "ether")}
undefined
> personal.sendTransaction(tx, "passphrase")
INFO [02-05|01:21:55] Submitted transaction                    fullhash=0x9d43b8a243e6b33c7b15e29557072e6dc55817d4c3780cb9e154ab96995e2fe9 recipient=0x19a70C78bBD741F32f56A681e14bA9E6e7fFa084
"0x9d43b8a243e6b33c7b15e29557072e6dc55817d4c3780cb9e154ab96995e2fe9
> eth.getTransaction("0x9d43b8a243e6b33c7b15e29557072e6dc55817d4c3780cb9e154ab96995e2fe9")
{
  blockHash: "0x0000000000000000000000000000000000000000000000000000000000000000",
  blockNumber: null,
  from: "0xacff8d64ac6098462cd19115c6c58fe4a55e9390",
  gas: 90000,
  gasPrice: 18000000000,
  hash: "0x9d43b8a243e6b33c7b15e29557072e6dc55817d4c3780cb9e154ab96995e2fe9",
  input: "0x",
  nonce: 0,
  r: "0xc84df6760f3fdc7ee10e144314e8ff72b31a0dfa248429ecd43e93e3a89a47a7",
  s: "0x4b8cbb74803ebc5b148c731ad0f10eb7378355e5cb794f05b315d1838a837c49",
  to: "0x19a70c78bbd741f32f56a681e14ba9e6e7ffa084",
  transactionIndex: 0,
  v: "0x2ba0",
  value: 100000000000000000
}

完成交易時會吐給你一組 transaction id: 0x9d43b8a243e6b33c7b15e29557072e6dc55817d4c3780cb9e154ab96995e2fe9, 你可以用這筆id查詢目前交易的狀態.

這邊建議是自己多創幾組交易紀錄. 這樣之後方便之後挖礦查詢.

  • passphrase: 填入你新創account時輸入的密碼. 這是你之後轉帳交易都會用到的密碼.

挖礦

> miner.start(1)
null

接著切回之前那個視窗. 你會發現下列 Generating DAG in progres 資訊.

# start mining work
INFO [01-24|07:14:39] Generating DAG in progress               epoch=0 percentage=52 elapsed=2m17.808s
INFO [01-24|07:14:41] Generating DAG in progress               epoch=0 percentage=53 elapsed=2m20.307s

那這時候就要花點時間等待他執行好. (這等待時間也是蠻長的) 放著等通常過半小時~一小時左右你就有可能會挖到ether. 但只能在自己的private chain上使用而已.

Reference