BCSkill (Block chain skill )
区块链中文技术社区

只讨论区块链底层技术
遵守一切相关法律政策!

eos系统合约介绍 — 提案合约eosio.msig (上)

简介

本篇将为大家介绍eos另一个系统合约eos.msig的主要功能和源码实现细节。eos.msig是eos的提案合约,同样也是cleos multisig命令调用的系统合约,可用于提案、通过/不通提案、执行多重签名交易等功能。由于涉及内容较多,介绍将分为上下两篇,上篇将围绕eos账户权限、cleos multisig命令的使用这几个方面进行介绍,下篇则会为大家介绍eosio.msig的源码实现

Eos账户权限

回顾一下之前的文章,一个账户最基本的权限owner和active是由公私钥对控制的,然而,eos丰富的权限控制方式,还允许我们将一个账户的权限,下放给其他的账户。比如下面的经典例子:
账户popo的权限情况

permissio account weight threshold
owner 2
@user1 1
@user2 1
active 1
@user1 1
@user2 1

我们将一步一步,通过命令行操作的方式来为大家介绍eos权限的应用。

1.我们分别创建三个账户popo11111111、zoin11111111、zoin22222222,每个账户使用不同的公私钥对。
分别创建6对公私钥,分别用于三个账号的owner和active权限

cleos create key --to-console

| 账号 | 权限|公钥 |私钥 |
| ------------ | ------------ | ------------ |
| popo11111111 | owner | EOS81WjiHefR6c5VKYjvdSat68RDJ3qGPgCckJqG3pXbDbVjZR5QB | 5JAxr3bM6DwwtcKJ7aVydpoaSA2oyiZ94PjqTpW6uXDZ41VuK22|
| popo11111111 | active | EOS7ob62mdBfiRt1a8tQrQGbhnU1gEAvWyQDFHs99HzYEh8wxeQ9T |5KRCeqsHAx1UNTtz7BH5N4SSMe75XMCj3j93TqQRDrYCwbjccoP |
| zoin11111111 | owner | EOS5N3qMPXjtwZpMyPeiYXSmBQbr7Lt5Ro2W8pLqyAzFYQPknoUvZ |5KWYcdZcJ1E8mWtg1Qoq5s1fYXJxMQkLupozfZEUEiu6vn6QNzx |
| zoin11111111 | active | EOS6BAfK8mZZjMaa74zxkT3evWEtWo4AnRQYmnpGWkNJYKVjcrpao | 5Jwy6VbCwpkmczjYgMNVtr9Nd77aenZcPE8DtvPwtYqztbgMzu4|
| zoin22222222 | owner | EOS6hBy5yioHpcH4SxSe91aH8vCGAhhEifKtp1jZEy7PS2rhJFSER |5Hz3u44Avpf4NCVDQdwZGSVXpbpEdRFczo2Wm9FC14pqcx8mUwM |
| zoin22222222 | active | EOS5TeY2C9bdewrbS58SZnrp5azF5Cq7AXraNJihxaW4hbGeWSaeE |5JFoGdAc6zPG9KdHCHPHFL5XbpEnFmDq61y53Bw3Hm3VuFy7Stk |

2.下面开始创建三个账号

cleos system newaccount 已有账号 将要创建的账号 ownerkey  activekey  --stake-net '0.1 EOS' --stake-cpu '0.1 EOS'  --buy-ram-kbytes 4000

利用我们上面文章《以传统的WEB开发方式,来举例理解Dapp开发》中已经在麒麟测试网创建的账号cryptokylinq,并在麒麟测试网来创建其他账号。

suroudeMacBook-Pro:~ surou$ cleos -u http://kylin.fn.eosbixin.com system newaccount cryptokylinq popo11111111 EOS81WjiHefR6c5VKYjvdSat68RDJ3qGPgCckJqG3pXbDbVjZR5QB  EOS7ob62mdBfiRt1a8tQrQGbhnU1gEAvWyQDFHs99HzYEh8wxeQ9T  --stake-net '0.1 EOS' --stake-cpu '0.1 EOS'  --buy-ram-kbytes 4000
executed transaction: ada14edaa2dc356f02f8f19515f3227669887a5a840601d28f8d59238e1c7890  336 bytes  4284 us
#         eosio <= eosio::newaccount            {"creator":"cryptokylinq","name":"popo11111111","owner":{"threshold":1,"keys":[{"key":"EOS81WjiHefR6...
#         eosio <= eosio::buyrambytes           {"payer":"cryptokylinq","receiver":"popo11111111","bytes":4096000}
#   eosio.token <= eosio.token::transfer        {"from":"cryptokylinq","to":"eosio.ram","quantity":"99.8497 EOS","memo":"buy ram"}
#  cryptokylinq <= eosio.token::transfer        {"from":"cryptokylinq","to":"eosio.ram","quantity":"99.8497 EOS","memo":"buy ram"}
#     eosio.ram <= eosio.token::transfer        {"from":"cryptokylinq","to":"eosio.ram","quantity":"99.8497 EOS","memo":"buy ram"}
#   eosio.token <= eosio.token::transfer        {"from":"cryptokylinq","to":"eosio.ramfee","quantity":"0.5018 EOS","memo":"ram fee"}
#  cryptokylinq <= eosio.token::transfer        {"from":"cryptokylinq","to":"eosio.ramfee","quantity":"0.5018 EOS","memo":"ram fee"}
#  eosio.ramfee <= eosio.token::transfer        {"from":"cryptokylinq","to":"eosio.ramfee","quantity":"0.5018 EOS","memo":"ram fee"}
#         eosio <= eosio::delegatebw            {"from":"cryptokylinq","receiver":"popo11111111","stake_net_quantity":"0.1000 EOS","stake_cpu_quanti...
#   eosio.token <= eosio.token::transfer        {"from":"cryptokylinq","to":"eosio.stake","quantity":"0.2000 EOS","memo":"stake bandwidth"}
#  cryptokylinq <= eosio.token::transfer        {"from":"cryptokylinq","to":"eosio.stake","quantity":"0.2000 EOS","memo":"stake bandwidth"}
#   eosio.stake <= eosio.token::transfer        {"from":"cryptokylinq","to":"eosio.stake","quantity":"0.2000 EOS","memo":"stake bandwidth"}
2018-09-25T04:07:44.999 thread-0   main.cpp:458                  print_result   warning: transaction executed locally, but may not be confirmed by the network yet
suroudeMacBook-Pro:~ surou$ cleos -u http://kylin.fn.eosbixin.com system newaccount cryptokylinq zoin11111111 EOS5N3qMPXjtwZpMyPeiYXSmBQbr7Lt5Ro2W8pLqyAzFYQPknoUvZ  EOS6BAfK8mZZjMaa74zxkT3evWEtWo4AnRQYmnpGWkNJYKVjcrpao  --stake-net '0.1 EOS' --stake-cpu '0.1 EOS'  --buy-ram-kbytes 4000
executed transaction: daf4b102f68d7161022c0ac8635d91137a0d2d24072d49fdad13a608e2e03072  336 bytes  5102 us
#         eosio <= eosio::newaccount            {"creator":"cryptokylinq","name":"zoin11111111","owner":{"threshold":1,"keys":[{"key":"EOS5N3qMPXjtw...
#         eosio <= eosio::buyrambytes           {"payer":"cryptokylinq","receiver":"zoin11111111","bytes":4096000}
#   eosio.token <= eosio.token::transfer        {"from":"cryptokylinq","to":"eosio.ram","quantity":"99.8589 EOS","memo":"buy ram"}
#  cryptokylinq <= eosio.token::transfer        {"from":"cryptokylinq","to":"eosio.ram","quantity":"99.8589 EOS","memo":"buy ram"}
#     eosio.ram <= eosio.token::transfer        {"from":"cryptokylinq","to":"eosio.ram","quantity":"99.8589 EOS","memo":"buy ram"}
#   eosio.token <= eosio.token::transfer        {"from":"cryptokylinq","to":"eosio.ramfee","quantity":"0.5019 EOS","memo":"ram fee"}
#  cryptokylinq <= eosio.token::transfer        {"from":"cryptokylinq","to":"eosio.ramfee","quantity":"0.5019 EOS","memo":"ram fee"}
#  eosio.ramfee <= eosio.token::transfer        {"from":"cryptokylinq","to":"eosio.ramfee","quantity":"0.5019 EOS","memo":"ram fee"}
#         eosio <= eosio::delegatebw            {"from":"cryptokylinq","receiver":"zoin11111111","stake_net_quantity":"0.1000 EOS","stake_cpu_quanti...
#   eosio.token <= eosio.token::transfer        {"from":"cryptokylinq","to":"eosio.stake","quantity":"0.2000 EOS","memo":"stake bandwidth"}
#  cryptokylinq <= eosio.token::transfer        {"from":"cryptokylinq","to":"eosio.stake","quantity":"0.2000 EOS","memo":"stake bandwidth"}
#   eosio.stake <= eosio.token::transfer        {"from":"cryptokylinq","to":"eosio.stake","quantity":"0.2000 EOS","memo":"stake bandwidth"}
2018-09-25T04:11:22.091 thread-0   main.cpp:458                  print_result   warning: transaction executed locally, but may not be confirmed by the network yet
suroudeMacBook-Pro:~ surou$ cleos -u http://kylin.fn.eosbixin.com system newaccount cryptokylinq zoin22222222 EOS6hBy5yioHpcH4SxSe91aH8vCGAhhEifKtp1jZEy7PS2rhJFSER  EOS5TeY2C9bdewrbS58SZnrp5azF5Cq7AXraNJihxaW4hbGeWSaeE  --stake-net '0.1 EOS' --stake-cpu '0.1 EOS'  --buy-ram-kbytes 4000
executed transaction: 7b184ccebaeb2cd2b6cece49ec46abd86b20a1d20b29722d21029dd1abc958f0  336 bytes  2667 us
#         eosio <= eosio::newaccount            {"creator":"cryptokylinq","name":"zoin22222222","owner":{"threshold":1,"keys":[{"key":"EOS6hBy5yioHp...
#         eosio <= eosio::buyrambytes           {"payer":"cryptokylinq","receiver":"zoin22222222","bytes":4096000}
#   eosio.token <= eosio.token::transfer        {"from":"cryptokylinq","to":"eosio.ram","quantity":"99.8723 EOS","memo":"buy ram"}
#  cryptokylinq <= eosio.token::transfer        {"from":"cryptokylinq","to":"eosio.ram","quantity":"99.8723 EOS","memo":"buy ram"}
#     eosio.ram <= eosio.token::transfer        {"from":"cryptokylinq","to":"eosio.ram","quantity":"99.8723 EOS","memo":"buy ram"}
#   eosio.token <= eosio.token::transfer        {"from":"cryptokylinq","to":"eosio.ramfee","quantity":"0.5019 EOS","memo":"ram fee"}
#  cryptokylinq <= eosio.token::transfer        {"from":"cryptokylinq","to":"eosio.ramfee","quantity":"0.5019 EOS","memo":"ram fee"}
#  eosio.ramfee <= eosio.token::transfer        {"from":"cryptokylinq","to":"eosio.ramfee","quantity":"0.5019 EOS","memo":"ram fee"}
#         eosio <= eosio::delegatebw            {"from":"cryptokylinq","receiver":"zoin22222222","stake_net_quantity":"0.1000 EOS","stake_cpu_quanti...
#   eosio.token <= eosio.token::transfer        {"from":"cryptokylinq","to":"eosio.stake","quantity":"0.2000 EOS","memo":"stake bandwidth"}
#  cryptokylinq <= eosio.token::transfer        {"from":"cryptokylinq","to":"eosio.stake","quantity":"0.2000 EOS","memo":"stake bandwidth"}
#   eosio.stake <= eosio.token::transfer        {"from":"cryptokylinq","to":"eosio.stake","quantity":"0.2000 EOS","memo":"stake bandwidth"}
2018-09-25T04:13:52.457 thread-0   main.cpp:458                  print_result   warning: transaction executed locally, but may not be confirmed by the network yet

3.将popo11111111的owner权限交出,由zoin11111111和zoin22222222的owner权限控制。每个权限的权重weight是1,而门槛threshold是2,即使用popo11111111的owner权限发送交易,需要zoin11111111和zoin22222222进行多重签名才行
先将popo11111111的owner私钥导入钱包

suroudeMacBook-Pro:~ surou$ cleos wallet import
private key: imported private key for: EOS81WjiHefR6c5VKYjvdSat68RDJ3qGPgCckJqG3pXbDbVjZR5QB

查看下popo11111111信息

suroudeMacBook-Pro:~ surou$ cleos -u http://kylin.fn.eosbixin.com get account popo11111111
permissions: 
     owner     1:    1 EOS81WjiHefR6c5VKYjvdSat68RDJ3qGPgCckJqG3pXbDbVjZR5QB
        active     1:    1 EOS7ob62mdBfiRt1a8tQrQGbhnU1gEAvWyQDFHs99HzYEh8wxeQ9T

将popo11111111的owner权限交出

suroudeMacBook-Pro:~ surou$ cleos -u http://kylin.fn.eosbixin.com set account permission popo11111111 owner '{"threshold":2, "keys":[{"key": "EOS81WjiHefR6c5VKYjvdSat68RDJ3qGPgCckJqG3pXbDbVjZR5QB"}], "accounts": [{"permission": {"actor": "zoin11111111", "permission": "owner"}, "weight": 1}, {"permission": {"actor": "zoin22222222", "permission": "owner"}, "weight": 1}]}' -p popo11111111@owner
executed transaction: 38317f76ad1eb90601ad9bd2c6720e322196aebbb8bed5afacfd4f7c5098b111  200 bytes  759 us
#         eosio <= eosio::updateauth            {"account":"popo11111111","permission":"owner","parent":"","auth":{"threshold":2,"keys":[{"key":"EOS...

再次查看popo11111111账户

suroudeMacBook-Pro:~ surou$ cleos -u http://kylin.fn.eosbixin.com get account popo11111111
permissions: 
     owner     2:    60450 EOS81WjiHefR6c5VKYjvdSat68RDJ3qGPgCckJqG3pXbDbVjZR5QB1 zoin11111111@owner, 1 zoin22222222@owner, 
        active     1:    1 EOS7ob62mdBfiRt1a8tQrQGbhnU1gEAvWyQDFHs99HzYEh8wxeQ9T

已将权限owner转交给了 zoin11111111@owner, 1 zoin22222222@owner

4.将popo11111111的active权限交出,由zoin11111111和zoin22222222的active权限控制。每个权限的权重weight是1,而门槛threshold是1,即使用popo11111111的active权限发送交易,zoin11111111和zoin22222222任意一个账户签名即可
先将popo11111111的owner私钥导入钱包

suroudeMacBook-Pro:~ surou$ cleos wallet import
private key: imported private key for: EOS7ob62mdBfiRt1a8tQrQGbhnU1gEAvWyQDFHs99HzYEh8wxeQ9T

将popo11111111的active权限交出

suroudeMacBook-Pro:~ surou$ cleos -u http://kylin.fn.eosbixin.com set account permission popo11111111 active '{"threshold":1, "keys":[{"key": "EOS6L7pr3AaKekTs1dbratDq1PutoSdmBWJFwbLcStsnKBbJtNUws"}], "accounts": [{"permission": {"actor": "zoin11111111", "permission": "active"}, "weight": 1}, {"permission": {"actor": "zoin22222222", "permission": "active"}, "weight": 1}]}' -p popo11111111@active
executed transaction: c51dede340204a6561b9ad511efcf1f194075319a97f54e7fce1dbee8b20eb18  200 bytes  748 us
#         eosio <= eosio::updateauth            {"account":"popo11111111","permission":"active","parent":"owner","auth":{"threshold":1,"keys":[{"key...

再次查看popo11111111账户

suroudeMacBook-Pro:~ surou$ cleos -u http://kylin.fn.eosbixin.com get account popo11111111
permissions: 
     owner     2:    60450 EOS81WjiHefR6c5VKYjvdSat68RDJ3qGPgCckJqG3pXbDbVjZR5QB1 zoin11111111@owner, 1 zoin22222222@owner, 
        active     1:    31778 EOS6L7pr3AaKekTs1dbratDq1PutoSdmBWJFwbLcStsnKBbJtNUws1 zoin11111111@active, 1 zoin22222222@active, 

已经权限active转交给1 zoin11111111@active, 1 zoin22222222@active

cleos multisig命令

EOS账户这一节,我们将popo11111111账户的owner和active权限交给了zoin11111111和zoin22222222账户,则popo11111111账户原来的公私钥对就失效了,交易的发送需要zoin11111111和zoin22222222账户授权。

额外提一句,主网启动后,超级节点们会将eosio账户的权限交给eosio.prods账户,而eosio.prods账户是由21个超级节点的账户联合控制的,需要15个节点联合签名才能使用eosio账户,可以避免拿管理员权限作恶的现象

  • 主网eosio账户权限
    suroudeMacBook-Pro:~ surou$ cleos -u http://kylin.fn.eosbixin.com get account eosio
    privileged: true
    permissions: 
       owner     1:    1 eosio.prods@active, 
          active     1:    1 eosio.prods@active,
  • 主网eosio.prods账户权限
    suroudeMacBook-Pro:~ surou$ cleos -u http://kylin.fn.eosbixin.com get account eosio.prods
    permissions: 
       owner     1:    
          active    15:    1 acryptotitan@active, 1 alohaeostest@active, 1 blockmatrix2@active, 1 eosargentina@active, 1 eosasia11111@active, 1 eosbeijingbp@active, 1 eoscanadacom@active, 1 eosecoeoseco@active, 1 eoshuobipool@active, 1 eosiomeetone@active, 1 eosiosg11111@active, 1 eoslaomaocom@active, 1 eosnodeonebp@active, 1 eospaceioeos@active, 1 eosriobrazil@active, 1 eosstorebest@active, 1 eossv12eossv@active, 1 eosswedenorg@active, 1 eoszb1111111@active, 1 helloeoschbp@active, 1 superoneiobp@active, 
             prod.major    11:    1 acryptotitan@active, 1 alohaeostest@active, 1 blockmatrix2@active, 1 eosargentina@active, 1 eosasia11111@active, 1 eosbeijingbp@active, 1 eoscanadacom@active, 1 eosecoeoseco@active, 1 eoshuobipool@active, 1 eosiomeetone@active, 1 eosiosg11111@active, 1 eoslaomaocom@active, 1 eosnodeonebp@active, 1 eospaceioeos@active, 1 eosriobrazil@active, 1 eosstorebest@active, 1 eossv12eossv@active, 1 eosswedenorg@active, 1 eoszb1111111@active, 1 helloeoschbp@active, 1 superoneiobp@active, 
                prod.minor     8:    1 acryptotitan@active, 1 alohaeostest@active, 1 blockmatrix2@active, 1 eosargentina@active, 1 eosasia11111@active, 1 eosbeijingbp@active, 1 eoscanadacom@active, 1 eosecoeoseco@active, 1 eoshuobipool@active, 1 eosiomeetone@active, 1 eosiosg11111@active, 1 eoslaomaocom@active, 1 eosnodeonebp@active, 1 eospaceioeos@active, 1 eosriobrazil@active, 1 eosstorebest@active, 1 eossv12eossv@active, 1 eosswedenorg@active, 1 eoszb1111111@active, 1 helloeoschbp@active, 1 superoneiobp@active, 

下面,我们就要介绍cleos multisig命令如何调用eosio.msig合约进行提案、发送多重签名的交易。

1.zoin11111111发起一个转账提案,提案名是transferpopo,将popo11111111账户中的10EOS转给cryptokylinq账户,这之前需要保证popo11111111账户有币。
先给popo11111111转入点EOS

cleos -u http://kylin.fn.eosbixin.com push action eosio.token transfer '["cryptokylinq", "popo11111111","10.0000 EOS","test"]' -p cryptokylinq

再导入zoin11111111的active的私钥

suroudeMacBook-Pro:~ surou$ cleos wallet import
private key: imported private key for: EOS6BAfK8mZZjMaa74zxkT3evWEtWo4AnRQYmnpGWkNJYKVjcrpao

发起提案

suroudeMacBook-Pro:~ surou$ cleos -u http://kylin.fn.eosbixin.com multisig propose transferpopo '[{"actor": "zoin11111111", "permission": "active"}, {"actor": "zoin22222222", "permission": "active"}]'  '[{"actor": "popo11111111", "permission":"active"}]'  eosio.token transfer '{"from": "popo11111111", "to": "cryptokylinq", "quantity":"10.0000 EOS", "memo": "test multisig"}' -p zoin11111111@active
executed transaction: 83cde06310cd6cd74dfb180aa38fa4f0a5d950b6f39a4f963237a5ea6d2c39aa  240 bytes  810 us
#    eosio.msig <= eosio.msig::propose          {"proposer":"zoin11111111","proposal_name":"transferpopo","requested":[{"actor":"zoin11111111","perm...

详细分析下cleos multisig propose命令参数
- proposal_name:提案名

  • requested_permissions:提案审批通过需要的权限,这里需要zoin11111111和zoin22222222的active权限
  • trx_permission:提案执行需要的权限,需要popo11111111的active权限就能发起转账
  • contract:提案调用的合约账户,转账使用eosio.token账户合约
  • action:提案调用的合约方法,转账使用transfer方法
  • data:具体数据
  • proposer:提案发起人,zoin11111111发起
    - proposal_expiration:提案的有效时间

2.查看提案交易cleos multisig review <proposer> <proposal_name>

suroudeMacBook-Pro:~ surou$ cleos -u http://kylin.fn.eosbixin.com multisig review zoin11111111 transferpopo
{
  "proposal_name": "transferpopo",
  "packed_transaction": "4224ab5b000000000000000000000100a6823403ea3055000000572d3ccdcd011042082184402bad00000000a8ed32322e1042082184402bad60a78b1ed25cfd45a08601000000000004454f53000000000d74657374206d756c746973696700",
  "transaction": {
    "expiration": "2018-09-26T06:16:34",
    "ref_block_num": 0,
    "ref_block_prefix": 0,
    "max_net_usage_words": 0,
    "max_cpu_usage_ms": 0,
    "delay_sec": 0,
    "context_free_actions": [],
    "actions": [{
        "account": "eosio.token",
        "name": "transfer",
        "authorization": [{
            "actor": "popo11111111",
            "permission": "active"
          }
        ],
        "data": {
          "from": "popo11111111",
          "to": "cryptokylinq",
          "quantity": "10.0000 EOS",
          "memo": "test multisig"
        },
        "hex_data": "1042082184402bad60a78b1ed25cfd45a08601000000000004454f53000000000d74657374206d756c7469736967"
      }
    ],
    "transaction_extensions": []
  }
}

3.查看提案审批情况,provided_approvals为空表示尚未审批,request_approvals表示需要哪些权限进行审批
cleos get table eosio.msig <proposer> approvals

suroudeMacBook-Pro:~ surou$ cleos -u http://kylin.fn.eosbixin.com get table eosio.msig zoin11111111 approvals
{
  "rows": [{
      "proposal_name": "transferpopo",
      "requested_approvals": [{
          "actor": "zoin11111111",
          "permission": "active"
        },{
          "actor": "zoin22222222",
          "permission": "active"
        }
      ],
      "provided_approvals": []
    }
  ],
  "more": false
}

4.通过提案 cleos multisig approve 提案人 提案 权限

  • zoin11111111通过提案
    suroudeMacBook-Pro:~ surou$ cleos -u http://kylin.fn.eosbixin.com multisig approve zoin11111111 transferpopo '{"actor": "zoin11111111", "permission": "active"}'  -p zoin11111111@active
    executed transaction: bcc0495b88d7b897853af11ace59029a32f16f1727de04e4c1fa7fc85e7df1dc  128 bytes  1091 us
    #    eosio.msig <= eosio.msig::approve          {"proposer":"zoin11111111","proposal_name":"transferpopo","level":{"actor":"zoin11111111","permissio...

    查看提案审批情况

    suroudeMacBook-Pro:~ surou$ cleos -u http://kylin.fn.eosbixin.com get table eosio.msig zoin11111111 approvals
    {
    "rows": [{
        "proposal_name": "transferpopo",
        "requested_approvals": [{
            "actor": "zoin22222222",
            "permission": "active"
          }
        ],
        "provided_approvals": [{
            "actor": "zoin11111111",
            "permission": "active"
          }
        ]
      }
    ],
    "more": false
    }
  • zoin22222222通过提案
    suroudeMacBook-Pro:~ surou$ cleos -u http://kylin.fn.eosbixin.com multisig approve zoin11111111 transferpopo '{"actor": "zoin22222222", "permission": "active"}'  -p zoin22222222@active
    executed transaction: 62ef04a0ee345ac604ca9fe7be034a0cb69524b1ed146e22c44a806a03337919  128 bytes  633 us
    #    eosio.msig <= eosio.msig::approve          {"proposer":"zoin11111111","proposal_name":"transferpopo","level":{"actor":"zoin22222222","permissio...

    查看提案审批情况

    suroudeMacBook-Pro:~ surou$ cleos -u http://kylin.fn.eosbixin.com get table eosio.msig zoin11111111 approvals
    {
    "rows": [{
        "proposal_name": "transferpopo",
        "requested_approvals": [],
        "provided_approvals": [{
            "actor": "zoin11111111",
            "permission": "active"
          },{
            "actor": "zoin22222222",
            "permission": "active"
          }
        ]
      }
    ],
    "more": false
    }

5.执行提案cleos multisig exec <proposer> <proposal_name> -p 谁想执行都可以
执行前查看账户

  • cryptokylinq 余额4,148.3135 EOS
  • popo11111111 余额 10 EOS
suroudeMacBook-Pro:~ surou$ cleos -u http://kylin.fn.eosbixin.com multisig exec zoin11111111 transferpopo -p zoin11111111
executed transaction: caaa900536463207713f6af031ee315125d993f0af56ea91aafff3dcdf8b1353  160 bytes  1098 us
#    eosio.msig <= eosio.msig::exec             {"proposer":"zoin11111111","proposal_name":"transferpopo","executer":"zoin11111111"}

执行完成后查看账户

  • cryptokylinq 余额4,158.3135 EOS
  • popo11111111 余额 0 EOS

且提案将被自动删除

suroudeMacBook-Pro:~ surou$ cleos -u http://kylin.fn.eosbixin.com get table eosio.msig zoin11111111 approvals
{
  "rows": [],
  "more": false
}

并注意到,该笔转账没有交易记录actions 额,是不是在某些情况,需要隐藏交易记录时,可以通过此方法。。。


使用场景

某个账户发起一个提案后,需事先明确指定哪些账户/权限,必须全部通过审核后,合约动作才能被执行。

常见问题

  • 提案操作很消耗CPU Error 3080004: Transaction exceeded the current CPU usage limit imposed on the transaction

    cleos -u http://kylin.fn.eosbixin.com system delegatebw cryptokylinq zoin11111111 "0 EOS" "10 EOS"
  • 执行提案时,可能出现下面未知错误

    需要部署eosio.system系统合约,并开启提案合约的功能即可解决(具体原理会在介绍eos.system合约的时候介绍)

    cleos push action eosio setpriv '["eosio.msig", 1]' -p eosio

    后记

    本篇为大家介绍了eos的账户权限,以及eosio.msig提案合约如何通过cleos multisig调用使用,如何发起提案、审批提案等。别走开,下一篇将深入源码,分析eosio.msig提案合约是怎么写的。
    参考自简书

Error 3050003: eosio_assert_message assertion failure

创建账号时Error 3050003

suroudeMacBook-Pro:~ surou$ cleos -u http://kylin.fn.eosbixin.com system newaccount cryptokylinq popo EOS81WjiHefR6c5VKYjvdSat68RDJ3qGPgCckJqG3pXbDbVjZR5QB  EOS7ob62mdBfiRt1a8tQrQGbhnU1gEAvWyQDFHs99HzYEh8wxeQ9T  --stake-net '0.1 EOS' --stake-cpu '0.1 EOS'  --buy-ram-kbytes 4000
Error 3050003: eosio_assert_message assertion failure

如果nodeos启动时开始错误显示

nodeos --verbose-http-errors
Error 3050003: eosio_assert_message assertion failure
Error Details:
assertion failure with message: no active bid for name

根据Details就能看出,由于创建的账户名不属于常规的账户名“1-5,a-z”12位。是需要事先投标购买成功的。

DApp接入最新版本Scatter.js支持,以及ScatterDesktop的使用

我们知道目前EOS DApp运行,目前分为两种方式

  • App提供DApp运行环境。App内置浏览器控件,注入js,DApp运行时用注入的js与App内置的钱包交互,DApp需要私钥签名时,将需要签名的数据通过注入的js将数据传给外部的钱包,使用钱包当前选中的私钥将数据签名,然后将数据返回给DApp。
  • 浏览器扩展提供支持。目前支持EOS链的扩展主要是以Scatter,或者基于此二次开发为主。

本篇我们主要讲下DApp对Scatter的接入,大多的App提供的运行环境也是支持Scatter的,比如tp钱包等,并且Scatter在EOS链的绝对地位(不低于Metamask对于以太坊),所以我们开发DApp最少要支持Scatter的支持。

先来个主角Scatter介绍

Scatter 是一个去中心化的签名、身份、私人数据与身份验证解决方案。它在用户的计算机本地运行,采用非对称加密技术,令用户可以在不访问集中式服务器的情况下通过网站进行身份验证。Scatter 主要包含两个部分:钱包与 RIDL (Reputation & Identity Layer) 系统。

Scatter 钱包目前支持 EOS 和 ETH 钱包,未来会支持更多钱包。Scatter 已推出 Chrome 浏览器插件版本和桌面 Beta 版本,之后会推出移动端版本,其中浏览器插件版与以太坊轻钱包 MetaMask 类似。Scatter 钱包作为 EOS 应用程序与用户信息之间的桥梁,能让用户安全地向应用程序签名和提供私人数据,并保证在与EOS 区块链通信的 Web 应用程序进行交互时不会暴露密钥和其他不必要的信息。Scatter 不需要用户提交私钥,只需对交易签名,它是本地的应用,不会给用户发送需要解密或加密私钥的请求。而用户如果使用直接手动将私钥输入到应用程序的网页表单中,会存在资产被盗取的严重风险。

Scatter 的 RIDL (Reputation & Identity Layer) 系统包含了声望与身份系统。用户可以创建多个身份,每个身份都包含用户身份名称、EOS 账户/密钥对、姓名、电话和地址等个人信息。用户只需设置一次身份, Dapp 就可以经过用户授权后从 Scatter 接入用户身份信息。因此用户不必在多个 Dapp 重复填写个人信息,并避免个人信息泄漏。而在 Scatter 声望系统当中,用户和 Dapp 可以互相对彼此的声望进行评分。这一系统允许应用程序评估用户做出某种行为的可能性,比如偿还贷款。反之,它也允许用户衡量应用程序的质量,例如安全性与可用性。

Scatter 项目代码

现在Scatter 分为ScatterWebExtension(浏览器扩展)和ScatterDesktop(桌面客户端)两个版本。

编写一个支持Scatter的DApp例子

//TODO

ScatterDesktop使用步骤,并与上面例子交互

//TODO

中秋快乐,稍后继续完善本文。节后会紧跟几篇,详细针对Scatter接口方面的讲解。

EOSIO cleos命令汇总

version返回版本信息

返回EOS客户端版本信息

$cleos version client
Build version: cc9decff

create在区块链上和区域外创建数据

create key 创建密钥

命令格式:$ cleos create key
为了创建一个帐户,你需要两个新的密钥:所有者和激活密钥。你可以要求cleos为你创建一些钥匙:
这将是你的Owner Key,

$ cleos create key --to-console
Private key: 5HtimtY36YN8mB5MRKh2FDkdtUg98dZ5HrnC9hhCkf5KsZvXR11
Public key: EOS86qf6z2CuNfYDADMMysy2Gfs6p3GVK5k71BbGovmtmkBwvMxPq

再次执行,生成active key

$ cleos create key --to-console
Private key: 5K4SVxGkSrUWJVSsxtyJx7nqwVoNwgEZ77KxwVXaB2yzCf2ri3q
Public key: EOS5aC4xP3rf1sJVfNudJaa4CikUpmAYqXuiCxfL8nQT3tFDys9X1

注意:cleos不会把生成的私钥自动导入钱包,需手动导入cleos wallet import

create account 创建账号

命令格式:$ cleos create account ${control_account} ${account_name} ${owner_public_key} ${active_public_key}

Usage: ./cleos create account [OPTIONS] creator name OwnerKey ActiveKey

Positionals:
  creator TEXT                创建新帐户的帐户的名称
  name TEXT                   新帐户的名称
  OwnerKey TEXT               新帐户的所有者公钥
  ActiveKey TEXT              新帐户的激活公钥

Options:
  -x,--expiration             在交易到期之前以秒为单位设置时间,默认值为30s。
  -f,--force-unique           强制使交易独一无二,这将消耗额外的带宽,并消除对多次发布同一交易的任何保护。
  -s,--skip-sign              指定未锁定钱包密钥是否用于签署交易。即跳过签署直接交易。
  -d,--dont-broadcast         不要向网络广播交易(只需打印到stdout)。
  -p,--permission TEXT ...    授权的帐户和权限级别,如“帐户@权限”(默认值'creator@active')

待续

怎么给超级节点发工资:EOS的奖励分配规则

最近几篇文章,持续在聊EOS的资源分配模型。今天节后上班第一天,我们来聊个五块钱的天,看看EOS节点的收入问题:收益有多少,是怎么计算出的。

当下一次有人问你,EOS的通胀比率是多少,节点的奖励比例是多少,怎么分配的时候,也许这篇文章可以帮你回答这些问题。

主要用到的网站:

超级节点/备用节点/BP是什么?

在许多文章里面你会看到BP这一缩写。这是Block Producer的简称,即出块节点。

实际上,超级节点,这是中文里面才会有的称呼,似乎不加上超级,就显得不够霸气似的。英文语境里面,只是称呼EOS的节点为BP(Block Producer)。

节点分为两类:出块节点,跟备用节点(Block Producer Candidate)。在EOS主网之中,现在是设定为前21个节点为出块节点,其他的节点为备用节点。

备用节点也有另外的名称,叫做候选节点,两个名字都是说的同一回事。

你如果愿意,也可以调用EOS的命令,将自己启动的节点注册为节点,只是,未必有收益罢了。

节点收益知多少?

通过https://eos.host/mainnet这一网络,可以非常直观的查看各个节点的收益情况。

上图列出了前30个节点的得票率占比,橙色为出块节点,灰色为备用节点。

21个出块节点的收益


通过第二张图,可以看到,有一栏是列出来了节点的预估收益。

我们再仔细看一下。排名第一的佳能节点(恭喜佳能!),总计出块34895,预估得到收益为: 1,248.86 EOS

备用节点的收益


除了出块节点之外,也有部分备用节点是有收益的。从图中可以看出来,排名59的备选节点hexlantttttt,预计也能够得到100多的EOS作为回报。

你可能会好奇:出块节点的收益跟备用节点的收益是怎么算的呢?我们从EOS的增发开始说起。

算算节点的收益分配

分配的流程
每次有节点发起指令要领取奖励的时候,系统会计算:

  • 新增发的EOS总数有多少;
  • 按照比例,将新增发的EOS分配到不同的奖励池之中(下文会详述);
  • 按照节点的实际情况,计算节点应该得到的收益,并分配这部分收益给节点;
  • 对于备用节点来说,如果领取的奖励不足100个EOS,则无法领取奖励。
    简单概括就是,先计算各部分奖励池应该分配多少EOS,即新注入多少EOS;然后,根据规则,分配这部分新增的奖励,分配给对应的人节点。

EOS通胀率为5%

EOS是温和通胀设计的系统,每年增发的EOS比率为5%左右,按照总供应量10亿来计算,就是五千万EOS。
而节点得到的奖励,只是通胀的一小部分,只是总EOS数量的1%。

新增EOS的用途

实际上,EOS的增发,是持续进行的,而并非是每年一次性新增加EOS。每次EOS的节点发起领取奖励的命令,就会计算新增EOS的量。

通胀的EOS,有两个用途:

  • 通胀EOS的20%, 用于给节点的奖励,即,如果新增了五千万EOS,那么会有1千万EOS分配给节点作为奖励,包括给出块节点和备用节点;
  • 通胀EOS的80%, 用于EOS基金池,这部分会在未来用于Worker Proposal的奖励发放。所谓的Worker Proposal,是指的社区福利应用或者对EOS系统有所帮助的项目。

Worker Proposal这部分的奖励,现在已经开始累积,但是没有发放。

后续会部署新的智能合约到系统之中,经过持票人投票选出来认为对社区有益的DAPP,来获得这部分奖金。

可以看得出来,EOS设计之中对于生态的重视,Worker Proposal(可以称为:工作提案?)这部分每年足足有四千万左右的EOS奖励。(此处进行了简化,实际上随着EOS通胀,奖励的EOS数量会越来越多,比率为总流通量的4%)

如果你觉得自己的创意够牛逼,对于推动社区进步有贡献,那后续,光凭藉Worker Proposal的这部分奖励,应该就足够你赚到钱的了。

出块节点和备用节点的收益

具体的节点奖励的这1%,分为两部分:出块奖励(0.25%)和得票奖励(0.75%)。

出块奖励只是分配给出块的前21个节点,而得票奖励呢,则是用作所有节点(包括出块节点和备用节点)的奖励。

  • 出块奖励占据EOS总量的0.25%,这部分前21个节点平分。
    假设总量是10亿,那么,出块奖励部分,则是两百五十万 EOS,这部分21个节点平分。
  • 得票奖励, 占0.75%,这部分由所有节点按照投票权重占比来分配的。

例如,在某个时刻,如果未分配的得票奖励部分是一万2千个EOS,那么,假设 EOS Cannon节点的投票权重比例为10%,则佳能可以分得10%的奖励,即两千五百个EOS。

另外,佳能作为出块节点,还可以因为出块得到奖励。
假设未分配的出块奖励为两千一百个EOS,那么,佳能得到的奖励就是一百个,因为出块奖励是21个节点平分的。

总结

  • 如果某个节点是前21个节点之一,那么,其奖励分为:出块奖励部分 + 得票奖励部分;
  • 如果某个节点是备用节点,那么,它可能得到的收益属于得票奖励之中的一部分,比如总共投票权重为100,该节点所得到的投票权重为5,则可以分到得票奖励的5%。
  • 如果某个备用节点的得票奖励不足100个EOS,则无法得到奖励。

转载自:https://www.jianshu.com/p/8fb3531d055c