基于区块链的 DAPP 开发笔记 (5)-EOS 从 helloworld 到 hello 红包之二 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时复制粘贴 AI 生成的内容
duimi
V2EX    程序员

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

  •  
  •   duimi 2018-09-18 16:30:49 +08:00 1820 次点击
    这是一个创建于 2584 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

    另,我们建了一个 DAPP 开发者群,平常大家一起交流开发心得,感兴趣的开发者请加微信:mindflow2017,我拉你入群。


    从 helloworld 到 hello 红包之二

    上次我们学会了用 EOS 智能合约发红包,发红包时需要合约方知道对方的 EOS 账号,并通过合约账号授权发定向红包(转账送钱)。今天我们要实现的是多人“领红包”的功能,固定金额,见者有份,分完为止,不需要通过合约的 EOS 账号授权。(有人问,为什么不做拼手气红包呢?因为智能合约的随机数比较特殊,有机会再单独讲。)

    数据存储

    只要我记得你,你就永远不会消失的啊 ----《寻梦幻游记》 CoCo

    首先,我们需要让合约记住已经领过红包的账号,机会均等,每人只能领一次。在 EOS 上,最简单的办法就是用 table 保存合约的状态和数据。

    创建表格

    首先,我们在 helloworld.cpp 里加上两个表格。其中 primary_key 是主键,bonustable 是表名,bonus_t 是表结构。

    红包表:

    struct bonus_t { uint64_t id; asset balance; uint64_t primary_key() const { return id;} EOSLIB_SERIALIZE( bonus_t, (id)(balance) ) }; multi_index<N(bonustable), bonus_t > _bonus; 

    领红包的用户表:

    struct user_t { uint64_t id; account_name user; uint64_t primary_key() const { return user;} EOSLIB_SERIALIZE( user_t, (id)(user) ) }; multi_index<N(usertable), user_t> _users; 

    初始化表格

    加上 default constructor,把红包金额初始化为 10 EOS。

     hello( account_name self ) :contract(self),_bonus( _self, _self),_users( _self, _self) { asset quantity; quantity.set_amount(100000); // 10 EOS if ( _bonus.begin() == _bonus.end() ) _bonus.emplace( self, [&](auto& a) { a.id = 1; a.balance = quantity; }); } } 

    检查用户状态

    我们增加一个检查用户的函数 checkuser,检查用户是否领过红包。如果用户没领过红包,就把用户的账号加到表格里。

    bool checkuser( account_name user ) { bool found = true; auto itr = _users.find(user); if( itr == _users.end() ) { found = false; itr = _users.emplace(_self, [&](auto& acnt){ acnt.id = _users.available_primary_key(); acnt.user = user; }); } return found; } 

    更新红包金额

    再把取红包金额的功能放到一个函数里:

    asset getbonus() { asset quantity; auto itr = _bonus.begin(); auto balance = itr->balance; eosio_assert( balance.amount > 0, "must be positive quantity" ); if (balance.amount > 10000){ quantity.set_amount(10000); // 1 EOS _bonus.modify(itr, _self, [&](auto& p) { eosio_assert( p.balance.amount > quantity.amount, "we're out of bonus!" ); p.balance.amount -= quantity.amount; }); } else { quantity = balance; itr = _bonus.erase(itr); } return quantity; } 

    新的红包接口

    最后,我们把用户检查和取红包金额的功能加到领红包的接口上,改造后的 hi()接口不再传入金额。

    /// @abi action hi void hi( account_name to ) { if ( checkuser(to) ) return; asset bOnus= getbonus(); eosio_assert( bonus.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, bonus, std::string("hello money")) ).send(); print( "Hello, here is some money for ", name{to} ); } 

    具体的测试方法,请参考《从 helloworld 到 hello 红包 part1 》

    知识点总结

    创建表格

    struct user_t { uint64_t id; account_name user; asset balance; uint64_t primary_key() const { return user;} EOSLIB_SERIALIZE( user_t, (id)(user)(balance) ) }; multi_index<N(usertable), user_t> _users; 

    查询表格:

     auto itr = _users.find(user); 

    给表格添加元素:

     auto itr = _users.find(user); if( itr == _users.end() ) { itr = _users.emplace(_self, [&](auto& acnt){ acnt.id = _users.available_primary_key(); acnt.user = user; }); } 

    更新表格:

     auto itr = _users.find(user); if( itr != _users.end() ) { _users.modify( itr, _self, [&]( auto& acnt ){ acnt.user = user; acnt.balance.amount = new_amount; }); } 

    清空表格:

     for (auto itr = _users.begin(); itr != _users.end();) itr = _users.erase(itr); 
    目前尚无回复
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     5075 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 25ms UTC 03:53 PVG 11:53 LAX 20:53 JFK 23:53
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86