V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
duimi
V2EX  ›  程序员

基于区块链的 DAPP 开发笔记 (4)-EOS 从 helloworld 到 hello 红包

  •  
  •   duimi · 2018-09-03 12:05:57 +08:00 · 1581 次点击
    这是一个创建于 2055 天前的主题,其中的信息可能已经有所发展或是发生改变。

    我们不定期更新我们的开发心得,汇总在 github 上,欢迎 star: https://github.com/rrtoken/DAPP_Blog

    从 helloworld 到 hello 红包之一

    今天,我们来看看如何在 EOS 智能合约内部发起转帐(发红包)。在下面第一部分的例子代码里,我们在官方 Helloworld 标准的打招呼 hi()接口的基础上,增加新的参数“金额”,实现在打招呼的同时,通过合约内部转帐给对方账户发红包。第二部分的测试中,合约账号 eosonetest1 通过新的打招呼接口,给 eosonetest2 发送转帐。 使用合约内转帐,和标准转帐相比,可以在合约里加上各种条件和控制逻辑,实现丰富多彩的合约玩法。

    从零开始

    创建 helloworld 智能合约

    $ eosiocpp -n helloworld
    created helloworld from skeleton
    

    得到的 helloworld.cpp 源代码是这个样子的

    #include <eosiolib/eosio.hpp>
    
    using namespace eosio;
    
    class hello : public eosio::contract {
      public:
          using contract::contract;
    
          /// @abi action 
          void hi( account_name user ) {
             print( "Hello, ", name{user} );
          }
    };
    
    EOSIO_ABI( hello, (hi) )
    

    现在我们开始把它改造成“红包合约” 添加必要的头文件

    #include <eosiolib/asset.hpp>
    

    给 hi() 函数添加通证

    void hi( account_name to, const asset& quantity ) {
    

    加上一些安全检查

    		require_auth( _self );
    		eosio_assert( quantity.is_valid(), "invalid token" );
    		eosio_assert( quantity.amount > 0, "must be positive quantity" );
    
    		require_recipient( _self );
    		require_recipient( to );
    

    添加合约里转账

    		action(
    			permission_level{ _self, N(active) },
    			N(eosio.token), N(transfer),
    			std::make_tuple(_self, to, quantity, std::string("hello money"))
    		).send();
    

    改造好的 hi()函数变成这个样子:

    	/// @abi action hi
    	void hi( account_name to, const asset& quantity ) {
    		require_auth( _self );
    		eosio_assert( quantity.is_valid(), "invalid token" );
    		eosio_assert( quantity.amount > 0, "must be positive quantity" );
    
    		require_recipient( _self );
    		require_recipient( to );
    
    		action(
    			permission_level{ _self, N(active) },
    			N(eosio.token), N(transfer),
    			std::make_tuple(_self, to, quantity, std::string("hello money"))
    		).send();
            print( "Hello, here is some money for ", name{to} );
        }
    

    在 Jungle testnet 上实测

    给合约账号购买适当的 RAM

    cleos -u http://jungle.cryptolions.io:18888 system buyram -k eosonetest2 eosonetest2 1000
    

    把合约布署到合约账号

    cleos -u http://jungle.cryptolions.io:18888 set contract eosonetest2 ../helloworld -p eosonetest2
    

    合约里转账需要添加的 eosio.code permission

    cleos -u http://jungle.cryptolions.io:18888 set account permission eosonetest2 active '{"threshold": 1,"keys": [{"key": "EOS8xxxxxxxxxxxxxxx","weight": 1}],"accounts": [{"permission":{"actor":"eosonetest2","permission":"eosio.code"},"weight":1}]}' owner -p eosonetest2@owner
    

    测试网上的输出

    测试前的余额

    @joel-Lenovo-Y520:helloworld $ cleos -u https://jungle.eosio.cr:443 get currency balance eosio.token eosonetest1 EOS
    7970.3411 EOS
    @joel-Lenovo-Y520:helloworld $ cleos -u https://jungle.eosio.cr:443 get currency balance eosio.token eosonetest2 EOS
    6733.2414 EOS
    
    

    通过合约发红包

    @joel-Lenovo-Y520:helloworld $ cleos -u http://jungle.cryptolions.io:18888 push action eosonetest2 hi '["eosonetest1", "103.0000 EOS"]' -p eosonetest2
    executed transaction: 71fxxxxxxxxxab706fxx3ea1cxxxxx1f70f05cxxxxx  120 bytes  2483 us
    #   eosonetest2 <= eosonetest2::hi              {"to":"eosonetest1","quantity":"103.0000 EOS"}
    >> Hello, here is some money for eosonetest1
    #   eosonetest1 <= eosonetest2::hi              {"to":"eosonetest1","quantity":"103.0000 EOS"}
    #   eosio.token <= eosio.token::transfer        {"from":"eosonetest2","to":"eosonetest1","quantity":"103.0000 EOS","memo":"hello money"}
    #   eosonetest2 <= eosio.token::transfer        {"from":"eosonetest2","to":"eosonetest1","quantity":"103.0000 EOS","memo":"hello money"}
    #   eosonetest1 <= eosio.token::transfer        {"from":"eosonetest2","to":"eosonetest1","quantity":"103.0000 EOS","memo":"hello money"}
    warning: transaction executed locally, but may not be confirmed by the network yet    ] 
    
    

    测试后的余额

    @joel-Lenovo-Y520:helloworld $ cleos -u https://jungle.eosio.cr:443 get currency balance eosio.token eosonetest1 EOS
    8073.3411 EOS
    @joel-Lenovo-Y520:helloworld $ cleos -u https://jungle.eosio.cr:443 get currency balance eosio.token eosonetest2 EOS
    6630.2414 EOS
    
    

    欢迎对 DAPP 开发感兴趣的开发者加入我们,一起探讨学习: https://github.com/rrtoken/DAPP_Blog

    目前尚无回复
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   2847 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 33ms · UTC 13:38 · PVG 21:38 · LAX 06:38 · JFK 09:38
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.