EOS Network Deployment

Table of Contents

1. 部署 EOS 网络

本文介绍如何部署多个 EOS 节点。在阅读本文前,你需要对单节点网络比较熟悉,如果你对此不熟悉,可以参考 Local Single-node Testnet

2. 单机器上部署多 EOS 节点

如果手头没有多余的机器资源,我们可以在同一个机器上部署多个节点(用不同端口区分)。

使用 EOS 源码中自带的脚本 bios-boot-tutorial.py 可以轻松完成这个任务,下面是在同一机器上部署 3 个 BP (Block Producer)节点的例子:

$ cd tutorials/bios-boot-tutorial
$ ./bios-boot-tutorial.py --symbol EOS --user-limit 20 --producer-limit 3 --num-producers-vote 3 -a

启动 EOS 网络有很多步骤要做, -a 表示执行所有必要的步骤。

参考:BIOS Boot Sequence

3. 不同机器上部署 EOS 节点

下面介绍如何在不同机器上部署 EOS 节点。(EOS 源码中的系统币默认为 SYS,编译节点时把 CORE_SYMBOL_NAME 改为 EOS 可以把系统币改为 EOS,下面例子使用节点的系统币已经改为了 EOS)。

下面是机器(3台机器,4个 EOS 节点,其中 eosio 节点在其它 BP 节点开始出块后不再出块)的基本设置:

  account        ip           p2p-listen-endpoint  http-server-address
eosio        172.16.60.146(A)           10100                  10180
accountbp1   172.16.60.146(A)           10101                  10181
accountbp2   172.16.60.147(B)           10101                  10181
accountbp3   172.16.60.148(C)           10101                  10181

3.1. 第一步:启动第一个 EOS 节点(Genesis Node)

下面是在机器 A 上启动第一个 EOS 节点(Genesis Node)的命令:

$ mywkdir=/app/eos-data
$ mkdir -p $mywkdir/nodes/00-eosio/blocks
$ nohup nodeos --max-transaction-time 30000 \
    --max-irreversible-block-age -1 \
    --verbose-http-errors \
    --contracts-console \
    --genesis-json $mywkdir/genesis.json \
    --blocks-dir $mywkdir/nodes/00-eosio/blocks \
    --config-dir $mywkdir/nodes/00-eosio \
    --data-dir $mywkdir/nodes/00-eosio \
    --chain-state-db-size-mb 20480 \
    --http-server-address 127.0.0.1:10180 \
    --p2p-listen-endpoint 172.16.60.146:10100 \
    --max-clients 13 \
    --p2p-max-nodes-per-host 13 \
    --enable-stale-production \
    --producer-name eosio \
    --signature-provider "EOS8Znrtgwt8TfpmbVpTKvA2oB8Nqey625CLN8bCN3TEbgx86Dsvr=KEY:5K463ynhZoCDDa4RDcr63cUwWLTnKqmdcoTKTHBjqoKfv4u5V7p" \
    --plugin eosio::http_plugin \
    --access-control-allow-origin '*' \
    --access-control-allow-headers '*' \
    --plugin eosio::chain_api_plugin \
    --plugin eosio::producer_plugin \
    --plugin eosio::history_plugin \
    --filter-on '*' \
    --plugin eosio::history_api_plugin >$mywkdir/nodes/00-eosio/stderr 2>&1 &

执行上面命令前,需要提前准备好文件$mywkdir/genesis.json(后文中启动其它 EOS 节点时都需要和它一模一样的 genesis.json 文件),你可以从./tutorials/bios-boot-tutorial/genesis.json 复制,本文例子中该文件的内容为:

{
  "initial_timestamp": "2018-03-02T12:00:00.000",
  "initial_key": "EOS8Znrtgwt8TfpmbVpTKvA2oB8Nqey625CLN8bCN3TEbgx86Dsvr",
  "initial_configuration": {
    "max_block_net_usage": 1048576,
    "target_block_net_usage_pct": 1000,
    "max_transaction_net_usage": 524288,
    "base_per_transaction_net_usage": 12,
    "net_usage_leeway": 500,
    "context_free_discount_net_usage_num": 20,
    "context_free_discount_net_usage_den": 100,
    "max_block_cpu_usage": 100000,
    "target_block_cpu_usage_pct": 500,
    "max_transaction_cpu_usage": 50000,
    "min_transaction_cpu_usage": 100,
    "max_transaction_lifetime": 3600,
    "deferred_trx_expiration_window": 600,
    "max_transaction_delay": 3888000,
    "max_inline_action_size": 4096,
    "max_inline_action_depth": 4,
    "max_authority_depth": 6
  },
  "initial_chain_id": "0000000000000000000000000000000000000000000000000000000000000000"
}

如果命令执行成功,查看文件 $mywkdir/nodes/00-eosio/stderr,你可以发现它已经在持续出块了(每 0.5 秒产生一个块)。

3.2. 第二步:启动 keosd,创建钱包,导入密钥

下面是在机器 A 上启动 keosd(监听在端口 6666)的命令:

$ mywkdir=/app/eos-data
$ mkdir -p $mywkdir/wallet
$ nohup keosd --unlock-timeout 999999999 \
    --http-server-address 127.0.0.1:6666 \
    --wallet-dir $mywkdir/wallet >$mywkdir/wallet/stderr 2>&1 &

创建默认钱包:

$ cleos --wallet-url http://127.0.0.1:6666 wallet create --to-console
Creating wallet: default
Save password to use in the future to unlock this wallet.
Without password imported keys will not be retrievable.
"PW5JeJgwoFskeyQbETdvV1BTRhuAdaywWffXKLumtWnTBXmrrSJNH"

导入 eosio 用户的密钥到默认钱包中:

$ cleos --wallet-url http://127.0.0.1:6666 wallet import
private key: 5K463ynhZoCDDa4RDcr63cUwWLTnKqmdcoTKTHBjqoKfv4u5V7p
imported private key for: EOS8Znrtgwt8TfpmbVpTKvA2oB8Nqey625CLN8bCN3TEbgx86Dsvr

生成 10 个密钥对放到钱包里:

$ for i in `seq 10`; do cleos --wallet-url http://127.0.0.1:6666 wallet create_key; done
Created new private key with a public key of: "EOS5saHMjjw48qfBPwBVmJWN9cPeAteGpJhAffMzA9ENjd4tjZBTJ"
Created new private key with a public key of: "EOS5TedaeaQwzNN6WNa4NoUNP4RVXpaky7eAokccxFbrHrZh32j25"
Created new private key with a public key of: "EOS7rmF4oWns6VqSUJy9DRP1TXypm4mgYRRb7y8xdbT6g8zsU7QFN"
Created new private key with a public key of: "EOS7EjS4r53iUHMnZvmcHg8nYG7VV9bCDxm52WrJ1vqsijLrNK8wc"
Created new private key with a public key of: "EOS7559wJG2kPcptAnDFjuXBcACNdZrEAyAN6DfYS65tbuUtPv2wF"
Created new private key with a public key of: "EOS7CxSzwWurxkn61P9VsZb7jbrTz6LxnhJHocDTxUHUYFuxP6meD"
Created new private key with a public key of: "EOS7ss5vkEWAKgjoYM96eTPg7ZYLmyLWWsggVLUYms72vBuvTVBXC"
Created new private key with a public key of: "EOS7f37i5cZZq1FC194VW3QquTaQ85nXMS9vfAfVM1HKkybiecLeA"
Created new private key with a public key of: "EOS5iF2Cpw36MEEFVzemUYjG7wu7MHWGAgc3cA25givgEZxY638DD"
Created new private key with a public key of: "EOS5RRvSEr526XnCeHx4CVzGpRpiyZgGqHKapun8LeWxn1JQ9c6iu"

这 10 个密钥的用途分配如下:
1、第 1 个密钥用作内置账号;
2、第 2-7 个密钥用作普通账号;
3、第 8-10 个密钥用作 BP 账号。

3.3. 第三步:创建内置账号(eosio.*)

创建下面这些内置账号(共 9 个):

eosio.bpay
eosio.msig
eosio.names
eosio.ram
eosio.ramfee
eosio.saving
eosio.stake
eosio.token
eosio.vpay

使用 cleos create account 创建上面账号:

$ users="eosio.bpay eosio.msig eosio.names eosio.ram eosio.ramfee eosio.saving eosio.stake eosio.token eosio.vpay"
$ for user in $users; do cleos --wallet-url http://127.0.0.1:6666 --url http://127.0.0.1:10180 create account eosio $user EOS5saHMjjw48qfBPwBVmJWN9cPeAteGpJhAffMzA9ENjd4tjZBTJ; done

关于这些账号的用途可参考:https://eosio.stackexchange.com/questions/963/what-is-the-purpose-for-each-of-the-eosio-system-accounts

3.4. 第四步:部署内置合约,发行代币

使用下面命令可以部署内置合约,发行代币:

$ cleos --wallet-url http://127.0.0.1:6666 --url http://127.0.0.1:10180 set contract eosio.token ~/eos/build/contracts/eosio.token/
$ cleos --wallet-url http://127.0.0.1:6666 --url http://127.0.0.1:10180 set contract eosio.msig ~/eos/build/contracts/eosio.msig/
$ cleos --wallet-url http://127.0.0.1:6666 --url http://127.0.0.1:10180 push action eosio.token create '["eosio", "1000000000.0000 EOS"]' -p eosio.token
$ cleos --wallet-url http://127.0.0.1:6666 --url http://127.0.0.1:10180 push action eosio.token issue '["eosio", "1000000000.0000 EOS", "memo"]' -p eosio
$ cleos --wallet-url http://127.0.0.1:6666 --url http://127.0.0.1:10180 set contract eosio ~/eos/build/contracts/eosio.system/
$ cleos --wallet-url http://127.0.0.1:6666 --url http://127.0.0.1:10180 push action eosio setpriv '["eosio.msig", 1]' -p eosio@active

完成上面操作后,eosio 用户里有 10 亿 EOS 代币。

3.5. 第五步:创建 BP 用户与普通用户

我们一共创建下面 9 个用户:

accountbp1
accountbp2
accountbp3
usera
userb
userc
userd
usere
userf

其中,accountbp1/accountbp2/accountbp3 为 BP 用户,其它的为普通用户。

使用下面命令可以创建这 9 个用户:

//create and transfer to producer
$ cleos --wallet-url http://127.0.0.1:6666 --url http://127.0.0.1:10180 system newaccount --transfer eosio accountbp1 EOS7f37i5cZZq1FC194VW3QquTaQ85nXMS9vfAfVM1HKkybiecLeA --stake-net "100000000.0000 EOS" --stake-cpu "100000000.0000 EOS" --buy-ram "20000.0000 EOS"
$ cleos --wallet-url http://127.0.0.1:6666 --url http://127.0.0.1:10180 transfer eosio accountbp1 "20000.0000 EOS"

$ cleos --wallet-url http://127.0.0.1:6666 --url http://127.0.0.1:10180 system newaccount --transfer eosio accountbp2 EOS5iF2Cpw36MEEFVzemUYjG7wu7MHWGAgc3cA25givgEZxY638DD --stake-net "100000000.0000 EOS" --stake-cpu "100000000.0000 EOS" --buy-ram "20000.0000 EOS"
$ cleos --wallet-url http://127.0.0.1:6666 --url http://127.0.0.1:10180 transfer eosio accountbp2 "20000.0000 EOS"

$ cleos --wallet-url http://127.0.0.1:6666 --url http://127.0.0.1:10180 system newaccount --transfer eosio accountbp3 EOS5RRvSEr526XnCeHx4CVzGpRpiyZgGqHKapun8LeWxn1JQ9c6iu --stake-net "100000000.0000 EOS" --stake-cpu "100000000.0000 EOS" --buy-ram "20000.0000 EOS"
$ cleos --wallet-url http://127.0.0.1:6666 --url http://127.0.0.1:10180 transfer eosio accountbp3 "20000.0000 EOS"

$ cleos --wallet-url http://127.0.0.1:6666 --url http://127.0.0.1:10180 system newaccount --transfer eosio usera EOS5TedaeaQwzNN6WNa4NoUNP4RVXpaky7eAokccxFbrHrZh32j25 --stake-net "20000000.0000 EOS" --stake-cpu "20000000.0000 EOS" --buy-ram "20000.0000 EOS"
$ cleos --wallet-url http://127.0.0.1:6666 --url http://127.0.0.1:10180 transfer eosio usera "20000.0000 EOS"

$ cleos --wallet-url http://127.0.0.1:6666 --url http://127.0.0.1:10180 system newaccount --transfer eosio userb EOS7rmF4oWns6VqSUJy9DRP1TXypm4mgYRRb7y8xdbT6g8zsU7QFN --stake-net "20000000.0000 EOS" --stake-cpu "20000000.0000 EOS" --buy-ram "20000.0000 EOS"
$ cleos --wallet-url http://127.0.0.1:6666 --url http://127.0.0.1:10180 transfer eosio userb "20000.0000 EOS"

$ cleos --wallet-url http://127.0.0.1:6666 --url http://127.0.0.1:10180 system newaccount --transfer eosio userc EOS7EjS4r53iUHMnZvmcHg8nYG7VV9bCDxm52WrJ1vqsijLrNK8wc --stake-net "20000000.0000 EOS" --stake-cpu "20000000.0000 EOS" --buy-ram "20000.0000 EOS"
$ cleos --wallet-url http://127.0.0.1:6666 --url http://127.0.0.1:10180 transfer eosio userc "20000.0000 EOS"

$ cleos --wallet-url http://127.0.0.1:6666 --url http://127.0.0.1:10180 system newaccount --transfer eosio userd EOS7559wJG2kPcptAnDFjuXBcACNdZrEAyAN6DfYS65tbuUtPv2wF --stake-net "20000000.0000 EOS" --stake-cpu "20000000.0000 EOS" --buy-ram "20000.0000 EOS"
$ cleos --wallet-url http://127.0.0.1:6666 --url http://127.0.0.1:10180 transfer eosio userd "20000.0000 EOS"

$ cleos --wallet-url http://127.0.0.1:6666 --url http://127.0.0.1:10180 system newaccount --transfer eosio usere EOS7CxSzwWurxkn61P9VsZb7jbrTz6LxnhJHocDTxUHUYFuxP6meD --stake-net "20000000.0000 EOS" --stake-cpu "20000000.0000 EOS" --buy-ram "20000.0000 EOS"
$ cleos --wallet-url http://127.0.0.1:6666 --url http://127.0.0.1:10180 transfer eosio usere "20000.0000 EOS"

$ cleos --wallet-url http://127.0.0.1:6666 --url http://127.0.0.1:10180 system newaccount --transfer eosio userf EOS7ss5vkEWAKgjoYM96eTPg7ZYLmyLWWsggVLUYms72vBuvTVBXC --stake-net "20000000.0000 EOS" --stake-cpu "20000000.0000 EOS" --buy-ram "20000.0000 EOS"
$ cleos --wallet-url http://127.0.0.1:6666 --url http://127.0.0.1:10180 transfer eosio userf "20000.0000 EOS"

3.6. 第六步:注册部分用户为 BP

下面命令把 accountbp1/accountbp2/accountbp3 注册为 BP:

$ cleos --wallet-url http://127.0.0.1:6666 --url http://127.0.0.1:10180 system regproducer accountbp1 EOS7f37i5cZZq1FC194VW3QquTaQ85nXMS9vfAfVM1HKkybiecLeA http://accountbp1.com/EOS7f37i5cZZq1FC194VW3QquTaQ85nXMS9vfAfVM1HKkybiecLeA
$ cleos --wallet-url http://127.0.0.1:6666 --url http://127.0.0.1:10180 system regproducer accountbp2 EOS5iF2Cpw36MEEFVzemUYjG7wu7MHWGAgc3cA25givgEZxY638DD http://accountbp2.com/EOS5iF2Cpw36MEEFVzemUYjG7wu7MHWGAgc3cA25givgEZxY638DD
$ cleos --wallet-url http://127.0.0.1:6666 --url http://127.0.0.1:10180 system regproducer accountbp3 EOS5RRvSEr526XnCeHx4CVzGpRpiyZgGqHKapun8LeWxn1JQ9c6iu http://accountbp3.com/EOS5RRvSEr526XnCeHx4CVzGpRpiyZgGqHKapun8LeWxn1JQ9c6iu

查看 BP 信息:

$ cleos --wallet-url http://127.0.0.1:6666 --url http://127.0.0.1:10180 system listproducers
Producer      Producer key                                              Url                                                         Scaled votes
accountbp1    EOS7f37i5cZZq1FC194VW3QquTaQ85nXMS9vfAfVM1HKkybiecLeA     http://accountbp1.com/EOS7f37i5cZZq1FC194VW3QquTaQ85nXMS9vf 0.0000
accountbp2    EOS5iF2Cpw36MEEFVzemUYjG7wu7MHWGAgc3cA25givgEZxY638DD     http://accountbp2.com/EOS5iF2Cpw36MEEFVzemUYjG7wu7MHWGAgc3c 0.0000
accountbp3    EOS5RRvSEr526XnCeHx4CVzGpRpiyZgGqHKapun8LeWxn1JQ9c6iu     http://accountbp3.com/EOS5RRvSEr526XnCeHx4CVzGpRpiyZgGqHKap 0.0000

3.7. 第七步:启动 BP 节点

下面命令可以在机器 A 上启动第一个 BP 节点:

$ mywkdir=/app/eos-data
$ mkdir -p $mywkdir/nodes/01-accountbp1/blocks
$ nohup nodeos --max-transaction-time 30000 \
    --max-irreversible-block-age -1 \
    --verbose-http-errors \
    --contracts-console \
    --genesis-json $mywkdir/genesis.json \
    --blocks-dir $mywkdir/nodes/01-accountbp1/blocks \
    --config-dir $mywkdir/nodes/01-accountbp1 \
    --data-dir $mywkdir/nodes/01-accountbp1 \
    --chain-state-db-size-mb 20480 \
    --http-server-address 127.0.0.1:10181 \
    --p2p-listen-endpoint 172.16.60.146:10101 \
    --max-clients 13 \
    --p2p-max-nodes-per-host 13 \
    --enable-stale-production \
    --producer-name accountbp1 \
    --signature-provider "EOS7f37i5cZZq1FC194VW3QquTaQ85nXMS9vfAfVM1HKkybiecLeA=KEY:5JugAoT6N6cGAzSqNhEsBTAVggusAYvsaj5YeEz9eEFuR3PXnFk" \
    --plugin eosio::http_plugin \
    --plugin eosio::chain_api_plugin \
    --plugin eosio::producer_plugin \
    --p2p-peer-address 172.16.60.146:10100 \
    --p2p-peer-address 172.16.60.147:10101 \
    --p2p-peer-address 172.16.60.148:10101 >$mywkdir/nodes/01-accountbp1/stderr 2>&1 &

由于其它两个节点还未启动,所以在$mywkdir/nodes/01-accountbp1/stderr 中会有下面日志:

connection failed to 172.16.60.148:10101: Connection refused
connection failed to 172.16.60.147:10101: Connection refused

复制文件$mywkdir/genesis.json 到另外两台机器。

登录机器 B,并执行:

$ mywkdir=/app/eos-data
$ mkdir -p $mywkdir/nodes/02-accountbp2/blocks
$ nohup nodeos --max-transaction-time 30000 \
    --max-irreversible-block-age -1 \
    --verbose-http-errors \
    --contracts-console \
    --genesis-json $mywkdir/genesis.json \
    --blocks-dir $mywkdir/nodes/02-accountbp2/blocks \
    --config-dir $mywkdir/nodes/02-accountbp2 \
    --data-dir $mywkdir/nodes/02-accountbp2 \
    --chain-state-db-size-mb 20480 \
    --http-server-address 127.0.0.1:10181 \
    --p2p-listen-endpoint 172.16.60.147:10101 \
    --max-clients 13 \
    --p2p-max-nodes-per-host 13 \
    --enable-stale-production \
    --producer-name accountbp2 \
    --signature-provider "EOS5iF2Cpw36MEEFVzemUYjG7wu7MHWGAgc3cA25givgEZxY638DD=KEY:5J1NJhq8yy35dFF6g5FL8jKXTBAqKNz9ZkdyqmQQuh7qaTEWvYG" \
    --plugin eosio::http_plugin \
    --plugin eosio::chain_api_plugin \
    --plugin eosio::producer_plugin \
    --p2p-peer-address 172.16.60.146:10100 \
    --p2p-peer-address 172.16.60.146:10101 \
    --p2p-peer-address 172.16.60.148:10101 >$mywkdir/nodes/02-accountbp2/stderr 2>&1 &

登录机器 C,并执行:

$ mywkdir=/app/eos-data
$ mkdir -p $mywkdir/nodes/03-accountbp3/blocks
$ nohup nodeos --max-transaction-time 30000 \
    --max-irreversible-block-age -1 \
    --verbose-http-errors \
    --contracts-console \
    --genesis-json $mywkdir/genesis.json \
    --blocks-dir $mywkdir/nodes/03-accountbp3/blocks \
    --config-dir $mywkdir/nodes/03-accountbp3 \
    --data-dir $mywkdir/nodes/03-accountbp3 \
    --chain-state-db-size-mb 20480 \
    --http-server-address 127.0.0.1:10181 \
    --p2p-listen-endpoint 172.16.60.148:10101 \
    --max-clients 13 \
    --p2p-max-nodes-per-host 13 \
    --enable-stale-production \
    --producer-name accountbp3 \
    --signature-provider "EOS5RRvSEr526XnCeHx4CVzGpRpiyZgGqHKapun8LeWxn1JQ9c6iu=KEY:5KVZvEMAck5AsWkLx8CCZqC2WCtggSAaJmzhhhhZXt9EW1c6wwx" \
    --plugin eosio::http_plugin \
    --plugin eosio::chain_api_plugin \
    --plugin eosio::producer_plugin \
    --p2p-peer-address 172.16.60.146:10100 \
    --p2p-peer-address 172.16.60.146:10101 \
    --p2p-peer-address 172.16.60.147:10101 >$mywkdir/nodes/03-accountbp3/stderr 2>&1 &

可以检查各个节点的 stderr 文件来确定当前的同步进度。

3.8. 第八步:用户投票

在 EOS 中,投票可以随时进行,并且随时更改。投票结果每 126 秒会记录一次,这也是完成一轮出块所需要的时间。每一轮出块中,每个超级节点都会生成 12 个区块,每个区块的生成时间是 0.5 秒。这意味着超级节点选举每 2 分 6 秒就会进行一次。每个 EOS token 最多可以投给 30 个不同的节点候选人。你所投的每个节点候选人都会一致获得你所拥有的选票(注:不能投给 A50 票,投给 B100 票,只能都是 50 票,或者都是 100 票),你的选票也不会被均分给所投节点候选人(票数都一致)。用户可以只用一部分 EOS token 来换选票(并不是有多少 token 就必须换多少票)。

回到机器 A 中,执行下面命令即可把用户 usera 的选票投给 accountbp1 和 accountbp2:

$ cleos --wallet-url http://127.0.0.1:6666 --url http://127.0.0.1:10180 system voteproducer prods usera accountbp1 accountbp2

检查投票信息:

$ cleos --wallet-url http://127.0.0.1:6666 --url http://127.0.0.1:10180 system listproducers
Producer      Producer key                                              Url                                                         Scaled votes
accountbp1    EOS7f37i5cZZq1FC194VW3QquTaQ85nXMS9vfAfVM1HKkybiecLeA     http://accountbp1.com/EOS7f37i5cZZq1FC194VW3QquTaQ85nXMS9vf 0.5000
accountbp2    EOS5iF2Cpw36MEEFVzemUYjG7wu7MHWGAgc3cA25givgEZxY638DD     http://accountbp2.com/EOS5iF2Cpw36MEEFVzemUYjG7wu7MHWGAgc3c 0.5000
accountbp3    EOS5RRvSEr526XnCeHx4CVzGpRpiyZgGqHKapun8LeWxn1JQ9c6iu     http://accountbp3.com/EOS5RRvSEr526XnCeHx4CVzGpRpiyZgGqHKap 0.0000

用户 userb 的选票投给 accountbp1 和 accountbp3:

$ cleos --wallet-url http://127.0.0.1:6666 --url http://127.0.0.1:10180 system voteproducer prods userb accountbp1 accountbp3

再次检查投票信息:

$ cleos --wallet-url http://127.0.0.1:6666 --url http://127.0.0.1:10180 system listproducers
Producer      Producer key                                              Url                                                         Scaled votes
accountbp1    EOS7f37i5cZZq1FC194VW3QquTaQ85nXMS9vfAfVM1HKkybiecLeA     http://accountbp1.com/EOS7f37i5cZZq1FC194VW3QquTaQ85nXMS9vf 0.5000
accountbp2    EOS5iF2Cpw36MEEFVzemUYjG7wu7MHWGAgc3cA25givgEZxY638DD     http://accountbp2.com/EOS5iF2Cpw36MEEFVzemUYjG7wu7MHWGAgc3c 0.2500
accountbp3    EOS5RRvSEr526XnCeHx4CVzGpRpiyZgGqHKapun8LeWxn1JQ9c6iu     http://accountbp3.com/EOS5RRvSEr526XnCeHx4CVzGpRpiyZgGqHKap 0.2500

下面命令可把 userc/userd/usere/userf 的选票分别投给 accountbp1/accountbp2/accountbp3/accountbp1:

$ cleos --wallet-url http://127.0.0.1:6666 --url http://127.0.0.1:10180 system voteproducer prods userc accountbp1
$ cleos --wallet-url http://127.0.0.1:6666 --url http://127.0.0.1:10180 system voteproducer prods userd accountbp2
$ cleos --wallet-url http://127.0.0.1:6666 --url http://127.0.0.1:10180 system voteproducer prods usere accountbp3
$ cleos --wallet-url http://127.0.0.1:6666 --url http://127.0.0.1:10180 system voteproducer prods userf accountbp1

3.8.1. 查看投票数

使用下面命令可以查看各个 BP 获得的投票数:

$ cleos --wallet-url http://127.0.0.1:6666 --url http://127.0.0.1:10180 get table eosio eosio producers
{
  "rows": [{
      "owner": "accountbp1",
      "total_votes": "696054688229721472.00000000000000000",
      "producer_key": "EOS7f37i5cZZq1FC194VW3QquTaQ85nXMS9vfAfVM1HKkybiecLeA",
      "is_active": 1,
      "url": "http://accountbp1.com/EOS7f37i5cZZq1FC194VW3QquTaQ85nXMS9vfAfVM1HKkybiecLeA",
      "unpaid_blocks": 60,
      "last_claim_time": 0,
      "location": 0
    },{
      "owner": "accountbp2",
      "total_votes": "348027344114860736.00000000000000000",
      "producer_key": "EOS5iF2Cpw36MEEFVzemUYjG7wu7MHWGAgc3cA25givgEZxY638DD",
      "is_active": 1,
      "url": "http://accountbp2.com/EOS5iF2Cpw36MEEFVzemUYjG7wu7MHWGAgc3cA25givgEZxY638DD",
      "unpaid_blocks": 66,
      "last_claim_time": 0,
      "location": 0
    },{
      "owner": "accountbp3",
      "total_votes": "348027344114860736.00000000000000000",
      "producer_key": "EOS5RRvSEr526XnCeHx4CVzGpRpiyZgGqHKapun8LeWxn1JQ9c6iu",
      "is_active": 1,
      "url": "http://accountbp3.com/EOS5RRvSEr526XnCeHx4CVzGpRpiyZgGqHKapun8LeWxn1JQ9c6iu",
      "unpaid_blocks": 63,
      "last_claim_time": 0,
      "location": 0
    }
  ],
  "more": false
}

所有代币的 15%进行投票后 eosio 会停止出块,主网会自动启动,BP 会轮流地生产区块。在这里我们的代币数据数量总共是 10 亿,那么我们的主网启动需要 1.5 亿质押的代币进行投票后才能启动。

4. Tips

4.1. Troubleshoot: Genesis state can only be set on a fresh blockchain

重启 nodeos 时请删除 --genesis-json 选项,否则会提示下面错误:

Genesis state can only be set on a fresh blockchain.
    {}
    thread-0  chain_plugin.cpp:519 plugin_initialize

4.2. Troubleshoot: /v1/chain/get_info, 400 bad request

如果访问“/v1/chain/get_info”时出现 400 bad request 错误:

$ curl -v -X POST http://your_server/v1/chain/get_info
......
< HTTP/1.1 400 Bad Request
< Connection: close
< Server: WebSocket++/0.7.0
<
 * Closing connection 0

可以尝试在启动 nodeos 时增加选项 --http-validate-host false

参考:https://github.com/EOSIO/eos/issues/4663

4.3. Troubleshoot: database dirty flag set

重启 nodeos 时,遇到错误“database dirty flag set”:

thread-0   chain_plugin.cpp:629          plugin_initialize    ] 13 St13runtime_error: database dirty flag set
rethrow database dirty flag set:
    {"what":"database dirty flag set"}
    thread-0  chain_plugin.cpp:629 plugin_initialize
thread-0   main.cpp:118                  main                 ] database dirty flag set (likely due to unclean shutdown): replay required

出现这个错误的原因往往是 nodeos 不正常地结束了。

kill -9 <nodeos-pid>       # 停止nodeos的不正确方式,nodeos没有机会优雅地停止
kill -15 <nodeos-pid>      # 停止nodeos的正确方式

解决办法是启动nodeos时,增加参数 --replay-blockchain --hard-replay-blockchain ,但这样会非常消耗时间,可能要等待几个小时才能replay完成。

Author: cig01

Created: <2018-08-14 Tue>

Last updated: <2019-11-30 Sat>

Creator: Emacs 27.1 (Org mode 9.4)