更新系统合约的步骤:https://developers.eos.io/eosio-cpp/docs/upgrading-the-system-contract
eos的更新合约,使用的是set命令,这个命令会打包一个transaction。实际上,cleos执行某个步骤最终都是把这个步骤打包成transaction。每个transaction中包含一个或者多个action,比如set命令的transaction就会包含setcode和setabi两个action。
官方提供的系统合约更新需要15个主节点的签名,采用手动的方法。更新系统合约,需要eosio的权限:
cleos -u http://api.hkeos.com get account eosio
privileged: true
permissions:
owner 1: 1 eosio.prods@active,
active 1: 1 eosio.prods@active
Plain Text
cleos -u http://api.hkeos.com get account eosio.prods
permissions:
owner 1:
active 15: 1 argentinaeos@active, 1 bitfinexeos1@active, 1 cypherglasss@active, 1 eos42freedom@active, 1 eosasia11111@active, 1 eosauthority@active, 1 eoscanadacom@active, 1 eoscannonchn@active, 1 eosdacserver@active, 1 eosfishrocks@active, 1 eosflytomars@active, 1 eoshuobipool@active, 1 eoslaomaocom@active, 1 eosnewyorkio@active, 1 eosriobrazil@active, 1 eosswedenorg@active, 1 jedaaaaaaaaa@active, 1 libertyblock@active, 1 starteosiobp@active, 1 teamgreymass@active, 1 zbeosbp11111@active
从上文分析,既然transaction的原理都是一样的,那么,如果使用手动签名签署一笔多重签名的交易,在原理上和修改系统合约是一致的。
两个账户,hello.code 和 user,他们的原始状态如下:
cleos get account hello.code
permissions:
owner 1: 1 EOS8bD3vL8QjLuiaHg3ucZYfsYW8HabyFErSYdVmtSr5tQ4ahP3Kd
active 1: 1 EOS8bD3vL8QjLuiaHg3ucZYfsYW8HabyFErSYdVmtSr5tQ4ahP3Kd
.......
SYS balances:
liquid: 20.0000 SYS
staked: 0.0000 SYS
unstaking: 0.0000 SYS
total: 20.0000 SYS
cleos get account user
permissions:
owner 1: 1 EOS7MMGNnXmyuyXZh7cmZgU66rGrJ56AcyrWFzmc6zdi6VEpcRhCd
active 2: 1 EOS7MMGNnXmyuyXZh7cmZgU66rGrJ56AcyrWFzmc6zdi6VEpcRhCd1 hello.code@active,
.......
SYS balances:
liquid: 80.0000 SYS
staked: 0.0000 SYS
unstaking: 0.0000 SYS
total: 80.0000 SYS
hello.code使用单签,公钥是:EOS8bD3vL8QjLuiaHg3ucZYfsYW8HabyFErSYdVmtSr5tQ4ahP3Kd
user使用多重签名,active权限的权限权重是:
1 EOS7MMGNnXmyuyXZh7cmZgU66rGrJ56AcyrWFzmc6zdi6VEpcRhCd
1 hello.code@active
实验目标:从user账户转入hello.code账户10SYS
Plain Text
cleos transfer -j -d -s user hello.code '10 SYS' '' >tr.json
得到:
{
"expiration": "2018-09-03T06:47:07",
"ref_block_num": 46384,
"ref_block_prefix": 2713986768,
"max_net_usage_words": 0,
"max_cpu_usage_ms": 0,
"delay_sec": 0,
"context_free_actions": [],
"actions": [{
"account": "eosio.token",
"name": "transfer",
"authorization": [{
"actor": "user",
"permission": "active"
}
],
"data": "00000000007015d600804a14011aa36aa086010000000000045359530000000000"
}
],
"transaction_extensions": [],
"signatures": [],
"context_free_data": []
}
修改expiration字段: "expiration": "2018-09-03T07:47:07"
公私钥对为:
Private key1: 5K2pvJeJiGgqFQ2b7NhZNsphgUmyge1sEY8oA18zyRJBrDzXwm3
Public key1: EOS8bD3vL8QjLuiaHg3ucZYfsYW8HabyFErSYdVmtSr5tQ4ahP3Kd
Private key2: 5JVNQ8mwcF1qJcF9QsFfcrqYFbj785xAL2mXEnyN5fNYE56wwbC
Public key2: EOS7MMGNnXmyuyXZh7cmZgU66rGrJ56AcyrWFzmc6zdi6VEpcRhCd
使用Private key1签名:
cleos sign tr.json
得到:
{
"expiration": "2018-09-03T07:47:07",
"ref_block_num": 46384,
"ref_block_prefix": 2713986768,
"max_net_usage_words": 0,
"max_cpu_usage_ms": 0,
"delay_sec": 0,
"context_free_actions": [],
"actions": [{
"account": "eosio.token",
"name": "transfer",
"authorization": [{
"actor": "user",
"permission": "active"
}
],
"data": "00000000007015d600804a14011aa36aa086010000000000045359530000000000"
}
],
"transaction_extensions": [],
"signatures": [
"SIG_K1_K7PAA2JCbVEg2jxRQLiSTDF7wonXmNcewbTqq7EiEKv2e711FzteLBVG81R7NhKgZ2LSWGL5ruDUCXSXiZmo6yf9K6aM5D"
],
"context_free_data": []
}
提取signatures字段:
"SIG_K1_KdKWuceUCGVSgQcCdsztLJZGEuLzDabraL1Ck83cJ81jLkRM9nSi8YKA1dZ2LnVcN3DJco5ZWcJvnTkzdEDeTeifuVJT4w"
使用Private key2签名:
cleos sign tr.json
得到:
"SIG_K1_K7PAA2JCbVEg2jxRQLiSTDF7wonXmNcewbTqq7EiEKv2e711FzteLBVG81R7NhKgZ2LSWGL5ruDUCXSXiZmo6yf9K6aM5D"
将两个签名复制到tr.json中,更改signatures字段:
{
"expiration": "2018-09-03T07:47:07",
"ref_block_num": 46384,
"ref_block_prefix": 2713986768,
"max_net_usage_words": 0,
"max_cpu_usage_ms": 0,
"delay_sec": 0,
"context_free_actions": [],
"actions": [{
"account": "eosio.token",
"name": "transfer",
"authorization": [{
"actor": "user",
"permission": "active"
}
],
"data": "00000000007015d600804a14011aa36aa086010000000000045359530000000000"
}
],
"transaction_extensions": [],
"signatures": ["SIG_K1_KdKWuceUCGVSgQcCdsztLJZGEuLzDabraL1Ck83cJ81jLkRM9nSi8YKA1dZ2LnVcN3DJco5ZWcJvnTkzdEDeTeifuVJT4w" , "SIG_K1_K7PAA2JCbVEg2jxRQLiSTDF7wonXmNcewbTqq7EiEKv2e711FzteLBVG81R7NhKgZ2LSWGL5ruDUCXSXiZmo6yf9K6aM5D"],
"context_free_data": []
}
将交易发送给区块链:
cleos push transaction --skip-sign tr.json
-->Error 3080006: Transaction took too long
重复几次
-->
{
"transaction_id": "af082f5cdc4261cbbc113cea4d4f78270c3eff93b9672ac1f2fcc91ffc5e8bc1",
"processed": {
"id": "af082f5cdc4261cbbc113cea4d4f78270c3eff93b9672ac1f2fcc91ffc5e8bc1",
"receipt": {
"status": "executed",
"cpu_usage_us": 955,
"net_usage_words": 18
},
"elapsed": 955,
"net_usage": 144,
"scheduled": false,
"action_traces": [{
"receipt": {
"receiver": "eosio.token",
"act_digest": "6c35053af65c3921c72659794660bacf062706fd21fcb3e2373616958d09c4c6",
"global_sequence": 47921,
"recv_sequence": 6,
"auth_sequence": [[
"user",
8
]
],
"code_sequence": 1,
"abi_sequence": 1
},
"act": {
"account": "eosio.token",
"name": "transfer",
"authorization": [{
"actor": "user",
"permission": "active"
}
],
"data": {
"from": "user",
"to": "hello.code",
"quantity": "10.0000 SYS",
"memo": ""
},
"hex_data": "00000000007015d600804a14011aa36aa086010000000000045359530000000000"
},
"elapsed": 823,
"cpu_usage": 0,
"console": "",
"total_cpu_usage": 0,
"trx_id": "af082f5cdc4261cbbc113cea4d4f78270c3eff93b9672ac1f2fcc91ffc5e8bc1",
"inline_traces": [{
"receipt": {
"receiver": "user",
"act_digest": "6c35053af65c3921c72659794660bacf062706fd21fcb3e2373616958d09c4c6",
"global_sequence": 47922,
"recv_sequence": 4,
"auth_sequence": [[
"user",
9
]
],
"code_sequence": 1,
"abi_sequence": 1
},
"act": {
"account": "eosio.token",
"name": "transfer",
"authorization": [{
"actor": "user",
"permission": "active"
}
],
"data": {
"from": "user",
"to": "hello.code",
"quantity": "10.0000 SYS",
"memo": ""
},
"hex_data": "00000000007015d600804a14011aa36aa086010000000000045359530000000000"
},
"elapsed": 9,
"cpu_usage": 0,
"console": "",
"total_cpu_usage": 0,
"trx_id": "af082f5cdc4261cbbc113cea4d4f78270c3eff93b9672ac1f2fcc91ffc5e8bc1",
"inline_traces": []
},{
"receipt": {
"receiver": "hello.code",
"act_digest": "6c35053af65c3921c72659794660bacf062706fd21fcb3e2373616958d09c4c6",
"global_sequence": 47923,
"recv_sequence": 3,
"auth_sequence": [[
"user",
10
]
],
"code_sequence": 1,
"abi_sequence": 1
},
"act": {
"account": "eosio.token",
"name": "transfer",
"authorization": [{
"actor": "user",
"permission": "active"
}
],
"data": {
"from": "user",
"to": "hello.code",
"quantity": "10.0000 SYS",
"memo": ""
},
"hex_data": "00000000007015d600804a14011aa36aa086010000000000045359530000000000"
},
"elapsed": 9,
"cpu_usage": 0,
"console": "",
"total_cpu_usage": 0,
"trx_id": "af082f5cdc4261cbbc113cea4d4f78270c3eff93b9672ac1f2fcc91ffc5e8bc1",
"inline_traces": []
}
]
}
],
"except": null
}
}
然后cleos --url http://localhost:8888 get transaction af082f5cdc4261cbbc113cea4d4f78270c3eff93b9672ac1f2fcc91ffc5e8bc1
总是报错,不知为何,但从结果上看:
报错的原因是数据并没有存放进磁盘,在启动nodeos时加入--filter-on=*即可。此时数据库只会存放重新启动之后的交易,猜想应该强制重新播放块可以解决。
cleos get account hello.code
permissions:
owner 1: 1 EOS8bD3vL8QjLuiaHg3ucZYfsYW8HabyFErSYdVmtSr5tQ4ahP3Kd
active 1: 1 EOS8bD3vL8QjLuiaHg3ucZYfsYW8HabyFErSYdVmtSr5tQ4ahP3Kd
......
SYS balances:
liquid: 30.0000 SYS
staked: 0.0000 SYS
unstaking: 0.0000 SYS
total: 30.0000 S
hello.code的资金增加了10SYS
user的资金减少了10SYS
结果是正确的