EOS开发入门3 -- 合约部署与调用

作者: luohuayong | 来源:发表于2018-05-13 18:53 被阅读79次

    在开始所有之前,先确定已经完成了上两篇文章的内容。

    EOS开发入门1 -- 环境搭建
    EOS开发入门2 -- 钱包与账户

    创建一个新账户

    创建账户命令格式为:

    cleos create account [OPTIONS] creator name OwnerKey ActiveKey
    
    • cleos create account 命令
    • creator 用于创建新帐号的帐号名
    • name 新帐号名
    • OwnerKey 所有权的key,是这个帐号的最高权限,可以用来设置active权限
    • ActiveKey 操作权的key
    $ cleos create account eosio eosio.token EOS7ijWCBmoXBi3CgtK7DJxentZZeTkeUnaSDvyro9dq7Sd1C3dC4 EOS7ijWCBmoXBi3CgtK7DJxentZZeTkeUnaSDvyro9dq7Sd1C3dC4
    ...
    

    我们使用eosio这个系统默认账户创建了eosio.token账户

    部署合约

    我们准备部署eosio.token这个合约,这个合约名和我们刚创建的账户名相同,这个合约也是eosio源码自带的。位置在eosio源码/build/contracts/eosio.token

    部署合约的命令形式为:

    cleos set contract [OPTIONS] account contract-dir [wast-file] [abi-file]
    
    • cleos set contract 命令
    • acount 用于部署的帐号名称
    • contract-dir 合约所在目录
    • -p 可选参数,使用指定的账户和权限进行合约部署,默认值为account@active
    $ cleos set contract eosio.token build/contracts/eosio.token -p eosio.token
    Reading WAST...
    Assembling WASM...
    Publishing contract...
    executed transaction: 528bdbce1181dc5fd72a24e4181e6587dace8ab43b2d7ac9b22b2017992a07ad  8708 bytes  10000 cycles
    #         eosio <= eosio::setcode               {"account":"eosio.token","vmtype":0,"vmversion":0,"code":"0061736d0100000001ce011d60067f7e7f7f7f7f00...
    #         eosio <= eosio::setabi                {"account":"eosio.token","abi":{"types":[],"structs":[{"name":"transfer","base":"","fields":[{"name"...
    

    对照命令参数应该容易理解命令的含义

    创建EOS的token

    我们先看下eosio.token合约的接口文件:eosio源码下contracts/eosio.token/eosio.token.hpp

       void create( account_name issuer,
                    asset        maximum_supply,
                    uint8_t      can_freeze,
                    uint8_t      can_recall,
                    uint8_t      can_whitelist );
    
    
       void issue( account_name to, asset quantity, string memo );
    
       void transfer( account_name from,
                      account_name to,
                      asset        quantity,
                      string       memo );
    

    我们看到这里的三个公有方法:

    • create用于创建token,参数包括token的发布账户,最大供应量,是否可冻结,是否可召回,是否包含白名单。
    • issue用于从当前账户向指定账户发送token,参数包括目标账户,发送数量,备注
    • transfer用于从一个账户向另一个账户转移token,除了多一个源账户外,其它参数同issue

    调用合约方法的命令

    cleos push action [OPTIONS] contract action data
    
    • cleos push action 命令
    • contract 合约名
    • action 合约的方法名
    • data 给方法传参
    $ cleos push action eosio.token create '[ "eosio", "1000000000.0000 EOS", 0, 0, 0]' -p eosio.token
    executed transaction: 0e49a421f6e75f4c5e09dd738a02d3f51bd18a0cf31894f68d335cd70d9c0e12  260 bytes  1000 cycles
    #   eosio.token <= eosio.token::create          {"issuer":"eosio","maximum_supply":"1000000000.0000 EOS","can_freeze":0,"can_recall":0,"can_whitelis...
    

    或者使用更明确的命名参数的方式调用方法

    $ cleos push action eosio.token create '{"issuer":"eosio", "maximum_supply":"1000000000.0000 EOS", "can_freeze":0, "can_recall":0, "can_whitelist":0}' -p eosio.token
    executed transaction: 0e49a421f6e75f4c5e09dd738a02d3f51bd18a0cf31894f68d335cd70d9c0e12  260 bytes  1000 cycles
    #   eosio.token <= eosio.token::create          {"issuer":"eosio","maximum_supply":"1000000000.0000 EOS","can_freeze":0,"can_recall":0,"can_whitelis...
    

    通过这个命令我们创建了一个新的token,名称为EOS,这个token包含4位小数,最大供应量为1000000000.0000 EOS
    调用这个命令创建token,我们必须拥有eosio.token合约的所有权,因为它是'EOS'命名空间的拥有者.
    因为这个原因,我们必须在命令中加入参数 -p eosio.token 来授权本次调用

    将token发放给user账户

    现在我们已经创建了token,可以向之前创建的user账户发送token了:

    $ cleos push action eosio.token issue '[ "user", "100.0000 EOS", "memo" ]' -p eosio
    executed transaction: 822a607a9196112831ecc2dc14ffb1722634f1749f3ac18b73ffacd41160b019  268 bytes  1000 cycles
    #   eosio.token <= eosio.token::issue           {"to":"user","quantity":"100.0000 EOS","memo":"memo"}
    >> issue
    #   eosio.token <= eosio.token::transfer        {"from":"eosio","to":"user","quantity":"100.0000 EOS","memo":"memo"}
    >> transfer
    #         eosio <= eosio.token::transfer        {"from":"eosio","to":"user","quantity":"100.0000 EOS","memo":"memo"}
    #          user <= eosio.token::transfer        {"from":"eosio","to":"user","quantity":"100.0000 EOS","memo":"memo"}
    

    这次输出包括几个不同的操作:一个发送(issue)和三个转移(transfer),虽然我们仅签名了issue操作。issue执行了一个内联转移(inline transfer),该内联转移通知发送账户和接收账户。命令行的输出显示了所有被调用的操作处理程序,调用的顺序,以及这些操作产生的输出。
    从技术上来说,eosio.token合约可以跳过内联转移而直接修改账户余额。但是这里的处理方式是更好的实践方式。即所有账户余额可以通过转移行为来推导出。这里还通知了token的发送账户和收款账户,以便触发其相应的自动操作,处理存款和提款。
    我们再次进行相同的操作,但是添加两个参数:

    • -d 不在网络中广播交易,仅将其输出到标准输出设备
    • -j 以json格式输出结果
    $ cleos push action eosio.token issue '["user", "100.0000 EOS", "memo"]' -p eosio -d -j
    {
      "expiration": "2018-04-01T15:20:44",
      "region": 0,
      "ref_block_num": 42580,
      "ref_block_prefix": 3987474256,
      "net_usage_words": 21,
      "kcpu_usage": 1000,
      "delay_sec": 0,
      "context_free_actions": [],
      "actions": [{
          "account": "eosio.token",
          "name": "issue",
          "authorization": [{
              "actor": "eosio",
              "permission": "active"
            }
          ],
          "data": "00000000007015d640420f000000000004454f5300000000046d656d6f"
        }
      ],
      "signatures": [
        "EOSJzPywCKsgBitRh9kxFNeMJc8BeD6QZLagtXzmdS2ib5gKTeELiVxXvcnrdRUiY3ExP9saVkdkzvUNyRZSXj2CLJnj7U42H"
      ],
      "context_free_data": []
    }
    

    向tester账户转移token

    现在user账户已经拥有了token,我们将user账户的token转移一部分至tester账户。因为这次是对user账户做转出操作,所以需要使用user的账户对操作进行授权。 -p user

    $ cleos push action eosio.token transfer '[ "user", "tester", "25.0000 EOS", "m" ]' -p user
    executed transaction: 06d0a99652c11637230d08a207520bf38066b8817ef7cafaab2f0344aafd7018  268 bytes  1000 cycles
    #   eosio.token <= eosio.token::transfer        {"from":"user","to":"tester","quantity":"25.0000 EOS","memo":"m"}
    >> transfer
    #          user <= eosio.token::transfer        {"from":"user","to":"tester","quantity":"25.0000 EOS","memo":"m"}
    #        tester <= eosio.token::transfer        {"from":"user","to":"tester","quantity":"25.0000 EOS","memo":"m"}
    

    部署Exchange合约

    与之前的部署方式相同,我们来部署exchange合约,可以理解为交易所合约。该合约提供了创建和交易token的功能。下面的命令假定当前处于eos源码的根目录:

    $ cleos create account eosio exchange  EOS7ijWCBmoXBi3CgtK7DJxentZZeTkeUnaSDvyro9dq7Sd1C3dC4 EOS7ijWCBmoXBi3CgtK7DJxentZZeTkeUnaSDvyro9dq7Sd1C3dC4
    executed transaction: 4d38de16631a2dc698f1d433f7eb30982d855219e7c7314a888efbbba04e571c  364 bytes  1000 cycles
    #         eosio <= eosio::newaccount            {"creator":"eosio","name":"exchange","owner":{"threshold":1,"keys":[{"key":"EOS7ijWCBmoXBi3CgtK7DJxe...
    
    $ cleos set contract exchange build/contracts/exchange -p exchange
    Reading WAST...
    Assembling WASM...
    Publishing contract...
    executed transaction: 5a63b4de8a1da415590778f163c5ed26dc164c960185b20fd834c297cf7fa8f4  35172 bytes  10000 cycles
    #         eosio <= eosio::setcode               {"account":"exchange","vmtype":0,"vmversion":0,"code":"0061736d0100000001f0023460067f7e7f7f7f7f00600...
    #         eosio <= eosio::setabi                {"account":"exchange","abi":{"types":[{"new_type_name":"account_name","type":"name"}],"structs":[{"n...
    

    这里的命令做了两件事情:

    • 第一是创建了一个新的账户exchange。
    • 第二是用新创建的exchange账户部署了exchange合约。
      这个合约是eos源码自带的,位置在build/contracts/exchange。
      我觉得这里有些不好的地方,就是账户名和合约名都使用了完全相同的名称,容易弄混淆,但是这是官方教程提供的,我也是照做。
      另外需要注意的地方是,生成账户的秘钥是使用的秘钥对中的公钥,不要弄错了。这里的秘钥是官方教程里的,实际上生成的秘钥跟这个不一样,用自己的秘钥替换这里的示例。

    部署Eosio.msig合约

    eosio.msig合约允许对单个交易进行异步方式的多重签名。EOSIO框架本身也提供了对多重签名(multisig)的支持。但是需要一个同步的侧通道(side channel),对在这个通道中传输的数据进行签名。Eosio.msig合约则是一个对用户更加友好的多重签名方式,可以异步对交易进行多重签名并发布。
    以下步骤用来部署eosio.msig合约:

    $ cleos create account eosio eosio.msig  EOS7ijWCBmoXBi3CgtK7DJxentZZeTkeUnaSDvyro9dq7Sd1C3dC4 EOS7ijWCBmoXBi3CgtK7DJxentZZeTkeUnaSDvyro9dq7Sd1C3dC4
    #         eosio <= eosio::newaccount            {"creator":"eosio","name":"eosio.msig","owner":{"threshold":1,"keys":[{"key":"EOS7ijWCBmoXBi3CgtK7DJ...
      
    $ cleos set contract eosio.msig build/contracts/eosio.msig -p eosio.msig
    Reading WAST...
    Assembling WASM...
    Publishing contract...
    executed transaction: a113a7db8c878dfd894671792770b59a04efb3aa8295f5b3d585daf89c314ec9  8964 bytes  10000 cycles
    #         eosio <= eosio::setcode               {"account":"eosio.msig","vmtype":0,"vmversion":0,"code":"0061736d0100000001bd011b60047f7e7e7f0060047...
    #         eosio <= eosio::setabi                {"account":"eosio.msig","abi":{"types":[{"new_type_name":"account_name","type":"name"},{"new_type_na...
    

    这里的部署与前面相同,创建帐号eosio.msig,并部署位于build/contracts/eosio.msig目录下的eosio.msig合约

    相关文章

      网友评论

      • 8337ea5e8883:您好,看到您的文章质量非常高,想邀请您成为虫洞社区的首批优质内容签约作者。虫洞社区是专业的区块链技术学习社区。虫洞社区鼓励内容生产者产生高质量内容,并给予合理的回报,也希望能帮助内容消费者获得高质量的区块链内容,并让数字货币投资者获得有价值的投资洞见。同时,虫洞社区已经积累了大量的区块链深度从业者,便于作者建立个人品牌。不知道是否方便加您微信细聊?
      • 蓝浩:cleos push action 的参数应该是账户名,不是合约名

      本文标题:EOS开发入门3 -- 合约部署与调用

      本文链接:https://www.haomeiwen.com/subject/zenldftx.html