Author: Chen Jinjian
personal blog: HTTPS: //jian1098.github.io
CSDN blog: https: //blog.csdn.net/c_jian
Jane book: https: //www.jianshu.com/u/8ba9ac5706b6
Contact: jian1098 @qq.com
Brief description
This tutorial is used for the construction of any BitShares ( bitshares
) chain, such as BAR, Gongxinbao and other copycat chains built through BitShares source code modification. The environment built in this article is a private environment, which is convenient for testing and development. The system is best used Ubuntu
, and CentOS
other dependencies may need to be installed.
Download program
Go github
to download the compiled program, or you can download the source code yourself and compile it according to the documentation, but the configuration required is very high (8G memory), otherwise the compilation will fail, and the compilation will take several hours.
BTS:https://github.com/bitshares/bitshares-core/releases
BAR:https://github.com/bar-chain/bar-core
I download the compiled binary program directly here
wget https://github.com/bitshares/bitshares-core/releases/download/3.3.2/bitshares-core-3.3.2-linux-amd64-bin.tar.bz2
Unzip
tar -xjf bitshares-core-3.3.2-linux-amd64-bin.tar.bz2
Get two application files
- witness_node: node program
- cli_wallet: Wallet command line program
Create genesis data file
If you are synchronizing public chain data, just skip this step
mkdir genesis
cd genesis
vi genesis.json
Copy and save the configuration information below
{
"initial_timestamp": "2019-02-14T20:32:55",
"max_core_supply": "1000000000000000",
"initial_parameters": {
"current_fees": {
"parameters": [[
0,{
"fee": 2000000,
"price_per_kbyte": 1000000
}
],[
1,{
"fee": 500000
}
],[
2,{
"fee": 0
}
],[
3,{
"fee": 2000000
}
],[
4,{}
],[
5,{
"basic_fee": 500000,
"premium_fee": 200000000,
"price_per_kbyte": 100000
}
],[
6,{
"fee": 2000000,
"price_per_kbyte": 100000
}
],[
7,{
"fee": 300000
}
],[
8,{
"membership_annual_fee": 200000000,
"membership_lifetime_fee": 1000000000
}
],[
9,{
"fee": 50000000
}
],[
10,{
"symbol3": "50000000000",
"symbol4": "30000000000",
"long_symbol": 500000000,
"price_per_kbyte": 10
}
],[
11,{
"fee": 50000000,
"price_per_kbyte": 10
}
],[
12,{
"fee": 50000000
}
],[
13,{
"fee": 50000000
}
],[
14,{
"fee": 2000000,
"price_per_kbyte": 100000
}
],[
15,{
"fee": 2000000
}
],[
16,{
"fee": 100000
}
],[
17,{
"fee": 10000000
}
],[
18,{
"fee": 50000000
}
],[
19,{
"fee": 100000
}
],[
20,{
"fee": 500000000
}
],[
21,{
"fee": 2000000
}
],[
22,{
"fee": 2000000,
"price_per_kbyte": 10
}
],[
23,{
"fee": 2000000,
"price_per_kbyte": 10
}
],[
24,{
"fee": 100000
}
],[
25,{
"fee": 100000
}
],[
26,{
"fee": 100000
}
],[
27,{
"fee": 2000000,
"price_per_kbyte": 10
}
],[
28,{
"fee": 0
}
],[
29,{
"fee": 500000000
}
],[
30,{
"fee": 2000000
}
],[
31,{
"fee": 100000
}
],[
32,{
"fee": 100000
}
],[
33,{
"fee": 2000000
}
],[
34,{
"fee": 500000000
}
],[
35,{
"fee": 100000,
"price_per_kbyte": 10
}
],[
36,{
"fee": 100000
}
],[
37,{}
],[
38,{
"fee": 2000000,
"price_per_kbyte": 10
}
],[
39,{
"fee": 500000,
"price_per_output": 500000
}
],[
40,{
"fee": 500000,
"price_per_output": 500000
}
],[
41,{
"fee": 500000
}
],[
42,{}
],[
43,{
"fee": 2000000
}
],[
44,{}
],[
45,{
"fee": 2000000
}
],[
46,{}
],[
47,{
"fee": 2000000
}
],[
48,{
"fee": 2000000
}
]
],
"scale": 10000
},
"block_interval": 5,
"maintenance_interval": 86400,
"maintenance_skip_slots": 3,
"committee_proposal_review_period": 1209600,
"maximum_transaction_size": 2048,
"maximum_block_size": 2000000,
"maximum_time_until_expiration": 86400,
"maximum_proposal_lifetime": 2419200,
"maximum_asset_whitelist_authorities": 10,
"maximum_asset_feed_publishers": 10,
"maximum_witness_count": 1001,
"maximum_committee_count": 1001,
"maximum_authority_membership": 10,
"reserve_percent_of_fee": 2000,
"network_percent_of_fee": 2000,
"lifetime_referrer_percent_of_fee": 3000,
"cashback_vesting_period_seconds": 31536000,
"cashback_vesting_threshold": 10000000,
"count_non_member_votes": true,
"allow_non_member_whitelists": false,
"witness_pay_per_block": 1000000,
"worker_budget_per_day": "50000000000",
"max_predicate_opcode": 1,
"fee_liquidation_threshold": 10000000,
"accounts_per_fee_scale": 1000,
"account_fee_scale_bitshifts": 4,
"max_authority_depth": 2,
"extensions": []
},
"initial_accounts": [{
"name": "init0",
"owner_key": "BTS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV",
"active_key": "BTS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV",
"is_lifetime_member": true
},{
"name": "init1",
"owner_key": "BTS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV",
"active_key": "BTS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV",
"is_lifetime_member": true
},{
"name": "init2",
"owner_key": "BTS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV",
"active_key": "BTS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV",
"is_lifetime_member": true
},{
"name": "init3",
"owner_key": "BTS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV",
"active_key": "BTS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV",
"is_lifetime_member": true
},{
"name": "init4",
"owner_key": "BTS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV",
"active_key": "BTS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV",
"is_lifetime_member": true
},{
"name": "init5",
"owner_key": "BTS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV",
"active_key": "BTS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV",
"is_lifetime_member": true
},{
"name": "init6",
"owner_key": "BTS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV",
"active_key": "BTS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV",
"is_lifetime_member": true
},{
"name": "init7",
"owner_key": "BTS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV",
"active_key": "BTS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV",
"is_lifetime_member": true
},{
"name": "init8",
"owner_key": "BTS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV",
"active_key": "BTS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV",
"is_lifetime_member": true
},{
"name": "init9",
"owner_key": "BTS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV",
"active_key": "BTS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV",
"is_lifetime_member": true
},{
"name": "init10",
"owner_key": "BTS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV",
"active_key": "BTS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV",
"is_lifetime_member": true
},{
"name": "nathan",
"owner_key": "BTS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV",
"active_key": "BTS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV",
"is_lifetime_member": false
}
],
"initial_assets": [],
"initial_balances": [{
"owner": "BTSFAbAx7yuxt725qSZvfwWqkdCwp9ZnUama",
"asset_symbol": "BTS",
"amount": "1000000000000000"
}
],
"initial_vesting_balances": [],
"initial_active_witnesses": 11,
"initial_witness_candidates": [{
"owner_name": "init0",
"block_signing_key": "BTS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV"
},{
"owner_name": "init1",
"block_signing_key": "BTS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV"
},{
"owner_name": "init2",
"block_signing_key": "BTS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV"
},{
"owner_name": "init3",
"block_signing_key": "BTS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV"
},{
"owner_name": "init4",
"block_signing_key": "BTS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV"
},{
"owner_name": "init5",
"block_signing_key": "BTS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV"
},{
"owner_name": "init6",
"block_signing_key": "BTS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV"
},{
"owner_name": "init7",
"block_signing_key": "BTS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV"
},{
"owner_name": "init8",
"block_signing_key": "BTS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV"
},{
"owner_name": "init9",
"block_signing_key": "BTS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV"
},{
"owner_name": "init10",
"block_signing_key": "BTS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV"
}
],
"initial_committee_candidates": [{
"owner_name": "init0"
},{
"owner_name": "init1"
},{
"owner_name": "init2"
},{
"owner_name": "init3"
},{
"owner_name": "init4"
},{
"owner_name": "init5"
},{
"owner_name": "init6"
},{
"owner_name": "init7"
},{
"owner_name": "init8"
},{
"owner_name": "init9"
},{
"owner_name": "init10"
}
],
"initial_worker_candidates": [],
"immutable_parameters": {
"min_committee_member_count": 11,
"min_witness_count": 11,
"num_special_accounts": 0,
"num_special_assets": 0
}
}
Initialize the node
Enter the directory where the program is located
[root@gamesrv bts]# ls
cli_wallet genesis witness_node
Execute the following command to create the genesis block data
./witness_node --data-dir data --genesis-json genesis/genesis.json --seed-nodes "[]"
430942ms th_a config_util.cpp:247 create_new_config_fi ] Writing new config file at /home/jian/bts/data/config.ini
430942ms th_a config_util.cpp:309 create_logging_confi ] Writing new config file at /home/jian/bts/data/logging.ini
430944ms th_a witness.cpp:121 plugin_initialize ] witness plugin: plugin_initialize() begin
430945ms th_a witness.cpp:114 add_private_key ] Public Key: BTS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV
430945ms th_a witness.cpp:167 plugin_initialize ] witness plugin: plugin_initialize() end
.........
plugin_startup() end
431033ms th_a application.cpp:1179 startup_plugins ] Plugin witness started
431033ms th_a main.cpp:183 main ] Started BitShares node on a chain with 0 blocks.
431034ms th_a main.cpp:184 main ] Chain ID is ced68e68d7e41258f6a2e71643e41c690edae19dbed8c5f525a0f5c74d322fa9
Chain ID
You can press Ctrl+C
exit when you see it
Configuration file
After performing the previous operation, a data
directory will be generated in the current directory , and the block and configuration files will be generated in the directory. We need to modify some configurations
cd data
vi config.ini
The configuration that needs to be modified is as follows
# 找到这一个配置,将值修改为true,这个配置是开启挖矿生成区块,主链的话不需要打开
enable-stale-production = true
# 在文件最后加入下面的配置
p2p-endpoint = 0.0.0.0:11010
checkpoint = []
rpc-endpoint = 127.0.0.1:11011
witness-id = "1.6.1"
witness-id = "1.6.2"
witness-id = "1.6.3"
witness-id = "1.6.4"
witness-id = "1.6.5"
witness-id = "1.6.6"
witness-id = "1.6.7"
witness-id = "1.6.8"
witness-id = "1.6.9"
witness-id = "1.6.10"
witness-id = "1.6.11"
Complete storage
Start and stop nodes
The start command is a bit long, in order to facilitate the start and stop, we have made a good start and stop script
vi start_witness.sh
# 将下面的脚本保存
#!/bin/bash
nohup ./witness_node --data-dir data --seed-nodes "[]" >> witness.log 2>&1 &
vi stop_witness.sh
# 将下面的脚本保存
#!/bin/bash
PIDS=`ps -ef |grep witness_node |grep -v grep | awk '{print $2}'`
if [ "$PIDS" != "" ]; then
kill -9 $PIDS
else
echo `date +%F" "%H:%M:%S` "witness_node is NOT runing!"
fi
Add execute permission
chmod u+x *.sh
Start node
./start_witness.sh
Check the log, you can see that the block is already being generated
tail -f witness.log
1770002ms th_a db_maint.cpp:952 process_hf_1465 ] Processing hard fork core-1465 at block 1
1770002ms th_a db_maint.cpp:854 update_call_orders_h ] Updating all call orders for hardfork core-343 at block 1
1770002ms th_a db_maint.cpp:872 update_call_orders_h ] Done updating all call orders for hardfork core-343 at block 1
1770002ms th_a db_maint.cpp:895 match_call_orders ] Matching call orders at block 1
1770002ms th_a db_maint.cpp:905 match_call_orders ] Done matching call orders at block 1
1770002ms th_a db_maint.cpp:880 update_call_orders_h ] Updating all call orders for hardfork core-1270 at block 1
1770002ms th_a db_maint.cpp:888 update_call_orders_h ] Done updating all call orders for hardfork core-1270 at block 1
1770003ms th_a db_maint.cpp:895 match_call_orders ] Matching call orders at block 1
1770003ms th_a db_maint.cpp:905 match_call_orders ] Done matching call orders at block 1
1770003ms th_a witness.cpp:277 block_production_loo ] Generated block #1 with 0 transaction(s) and timestamp 2019-10-18T07:29:30 at time 2019-10-18T07:29:30
1790000ms th_a witness.cpp:277 block_production_loo ] Generated block #2 with 0 transaction(s) and timestamp 2019-10-18T07:29:50 at time 2019-10-18T07:29:50
1795000ms th_a witness.cpp:277 block_production_loo ] Generated block #3 with 0 transaction(s) and timestamp 2019-10-18T07:29:55 at time 2019-10-18T07:29:55
1800001ms th_a witness.cpp:277 block_production_loo ] Generated block #4 with 0 transaction(s) and timestamp 2019-10-18T07:30:00 at time 2019-10-18T07:30:00
Execute the stop script to stop the node
./stop_witness.sh
Stop and start the wallet
To start the wallet, you need to specify RPC
the http
port and websocket
port, chain ID, and wallet file. It should be noted that the node must be started before it can be started, otherwise an error will be reported
./cli_wallet --wallet-file my-wallet.json --chain-id ced68e68d7e41258f6a2e71643e41c690edae19dbed8c5f525a0f5c74d322fa9 --server-rpc-endpoint ws://127.0.0.1:11011 -H 127.0.0.1:11012
Results of the
2094762ms th_a main.cpp:229 main ] wdata.ws_server: ws://127.0.0.1:11011
2094819ms th_a main.cpp:234 main ] wdata.ws_user: wdata.ws_password:
2094867ms th_a main.cpp:281 main ] Listening for incoming HTTP and WS RPC requests on 127.0.0.1:11012
Type "help" for a list of available commands.
Type "gethelp <command>" for info about individual commands.
Please use the "set_password" method to initialize a new wallet before continuing
new >>>
You can see the command line that will enter the wallet. This command line can be used to create wallets, transfer funds, etc., press Ctrl+C
to exit
In order to facilitate the start and stop, we can also make scripts to start and stop the wallet
vi start_wallet.sh
# 将下面的脚本保存
#!/bin/bash
nohup ./cli_wallet --wallet-file my-wallet.json --chain-id ced68e68d7e41258f6a2e71643e41c690edae19dbed8c5f525a0f5c74d322fa9 --server-rpc-endpoint ws://127.0.0.1:11011 -H 127.0.0.1:11012 -d >> wallet.log 2>&1 &
vi stop_wallet.sh
# 将下面的脚本保存
#!/bin/bash
PIDS=`ps -ef |grep cli_wallet |grep -v grep | awk '{print $2}'`
if [ "$PIDS" != "" ]; then
kill -9 $PIDS
else
echo `date +%F" "%H:%M:%S` "cli_wallet is NOT runing!"
fi
Add execute permission
chmod u+x *.sh
Start the wallet
./start_wallet.sh
View log
tail -f wallet.log
Stop wallet
./stop_wallet.sh
Wallet related commands
Create a wallet
Using the wallet for the first time will let you set the password of the default wallet, here is set to 123456
please use the set_password method to initialize a new wallet before continuing
new >>> set_password 123456
null
Unlock wallet
Many of the following commands need to unlock the wallet first, the unlock command is as follows
locked >>> unlock 123456
null
Import nathan account
unlocked >>> import_key nathan "5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3"
2768812ms th_a wallet.cpp:565 copy_wallet_file ] backing up wallet my-wallet.json to before-import-key-9407629b.wallet
2768826ms th_a wallet.cpp:983 save_wallet_file ] saving wallet to file my-wallet.json
2768828ms th_a wallet.cpp:1002 save_wallet_file ] saved successfully wallet to tmp file my-wallet.json.tmp
2768828ms th_a wallet.cpp:1008 save_wallet_file ] validated successfully tmp wallet file my-wallet.json.tmp
2768829ms th_a wallet.cpp:1012 save_wallet_file ] renamed successfully tmp wallet file my-wallet.json.tmp
2768829ms th_a wallet.cpp:1019 save_wallet_file ] successfully saved wallet to file my-wallet.json
2768829ms th_a wallet.cpp:565 copy_wallet_file ] backing up wallet my-wallet.json to after-import-key-9407629b.wallet
true
Import initial balance to this account
unlocked >>> import_balance nathan ["5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3"] true
null
Balance check
unlocked >>> list_account_balances nathan
10000000000 BTS
Create an account
Upgrade your account first, or you don’t have permission
unlocked >>> upgrade_account nathan true
Get mnemonic words
unlocked >>> suggest_brain_key
{
"brain_priv_key": "CHOW CAWQUAW SADE JILT VELUM WAYLAY SMITE FARAD CHASE YAWN BALL DECODE PHORIA PIKI JUNGLY MINGLER",
"wif_priv_key": "5J61N7xP7Y7zYgk1msafaYsRW1gAZ77SZdN3oxEX1Dxja4ZGFej",
"pub_key": "BTS6pbt37VPfBZcYtXpNk8iTwgDZhuw9ikteBudiX5BWXbGdxJcNf"
}
Use mnemonic phrase to create account account1
unlocked >>> create_account_with_brain_key "ETCH ZAYAT LARKY TRANSOM EOSIN ETHANE BRAVE RELATED COPIST SHRIVEN LIMPKIN STARE FOHAT SUCCENT MOUSY REEVE" account1 nathan nathan true
Transfer
unlocked >>> transfer nathan account1 1000 BTS "first transfer" true
Check the balance again
unlocked >>> list_account_balances account1
1000 BTS
More RPC
commands will be listed in detail in the next article.
Reference article
https://bitsharescn.github.io/bts-cn-docs/bts-exchange-single/