美文网首页
【许晓笛】49行代码就能发币?而且EOS连例子都给你了

【许晓笛】49行代码就能发币?而且EOS连例子都给你了

作者: 6bca7c813977 | 来源:发表于2018-05-30 09:13 被阅读0次

    Daniel Larimer 在他的博客介绍了EOS新的智能合约架构(EOS团队的开发速度实在是太吓人,根本追不上)。他给出了最简单的一个新币种的智能合约代码,仅有49行就能完成一个新币种的开发,一个新的“爱息欧”就诞生了。让我们一步一步实现吧。

    首先实现私有成员,建立一个 account 结构体,这个结构体里保存的是所有持有我们这种代币的人的账户和余额。

       private:
          //account 结构体 
          struct account {
             //EOS 账户名
             account_name owner;
             //余额
             uint64_t     balance;
             //主键
             uint64_t primary_key()const { return owner; }
    
    

    下一步 我们要利用 Boost 库中的多索引列表,将上面声明的结构体放入一个列表中,方便查询和修改。

          eosio::multi_index<N(accounts), account> _accounts;
    

    接着,实现 add_balance() 函数,这个私有函数的目的是给特定的 EOS 账户增加特定的代币。

          void add_balance( account_name payer, account_name to, uint64_t q ) {
             //在列表中查询,看要收币的用户是否已经在列表中。
             auto toitr = _accounts.find( to );
             //如果不在列表中,说明用户从未持有过这种币,要将用户加入列表
             if( toitr == _accounts.end() ) {
                //增加一个用户
               _accounts.emplace( payer, [&]( auto& a ) {
                  a.owner = to;
                  //因为之前没有这种币,用户名下的余额为要接收的数量
                  a.balance = q;
               });
               //如果用户在列表中,说明已经持有或持有过这种币
             } else {
               _accounts.modify( toitr, 0, [&]( auto& a ) {
                   //直接将余额增加要转入的数量
                  a.balance += q;
                  //判断用户余额是否溢出(余额增加了q,之后数量应该大于q)
                  eosio_assert( a.balance >= q, "overflow detected" );
               });
             }
          }
    
    

    之后就要实现公有方法了,首先是构造函数,别忘了初始化 _accounts 列表。

      public:
          simpletoken( account_name self )
          :contract(self),_accounts( _self, _self){}
    

    实现公有的 transfer(转账)函数,将代币从一个账户转移到另一个账户。

          void transfer( account_name from, account_name to, uint64_t quantity ) {
             //从付款方获取权限
             require_auth( from );
             //从列表中搜索发币方账户
             const auto& fromacnt = _accounts.get( from );
             //验证付款方余额,是否透支
             eosio_assert( fromacnt.balance >= quantity, "overdrawn balance" );
             //从付款方减去代币
             _accounts.modify( fromacnt, from, [&]( auto& a ){ a.balance -= quantity; } );
             //收款方增加代币(之前实现的私有函数)
             add_balance( from, to, quantity );
          }
    

    OK,是不是以为大功告成了?还有最重要的 issue(发行)函数,要不从哪“印钱?”

          void issue( account_name to, uint64_t quantity ) {
             //得到合约主人的权限
             require_auth( _self );
             //直接印钱
             add_balance( _self, to, quantity );
    
    

    最后一步,将我们的 transfer 和 issue 函数接口提供给 EOS 系统,通过一个宏就可以快速实现。

    EOSIO_ABI( simpletoken, (transfer)(issue) )
    

    这个宏是咋回事?我们看看 dispacher.hpp 文件中对这个宏的定义,其实是替开发者实现了 apply 函数,使得开发者可以专注于业务逻辑。

    #define EOSIO_ABI( TYPE, MEMBERS ) \
    extern "C" { \
       void apply( uint64_t receiver, uint64_t code, uint64_t action ) { \
          auto self = receiver; \
          if( code == self ) { \
             TYPE thiscontract( self ); \
             switch( action ) { \
                EOSIO_API( TYPE, MEMBERS ) \
             } \
             eosio_exit(0); \
          } \
       } \
    } \
    

    大功告成,看看全部的代码吧,是不是49行就搞定了?不过 EOS 表示以后会有系统的标准代币,连以上的具体逻辑都不用我们实现了,不过这段代码对系统学习 EOS 智能合约架构还是很有意义的。

    #include <eosiolib/eosio.hpp>
    
    class simpletoken : public eosio::contract {
       public:
          simpletoken( account_name self )
          :contract(self),_accounts( _self, _self){}
    
          void transfer( account_name from, account_name to, uint64_t quantity ) {
             require_auth( from );
    
             const auto& fromacnt = _accounts.get( from );
             eosio_assert( fromacnt.balance >= quantity, "overdrawn balance" );
             _accounts.modify( fromacnt, from, [&]( auto& a ){ a.balance -= quantity; } );
    
             add_balance( from, to, quantity );
          }
    
          void issue( account_name to, uint64_t quantity ) {
             require_auth( _self );
             add_balance( _self, to, quantity );
          }
    
       private:
          struct account {
             account_name owner;
             uint64_t     balance;
    
             uint64_t primary_key()const { return owner; }
          };
    
          eosio::multi_index<N(accounts), account> _accounts;
    
          void add_balance( account_name payer, account_name to, uint64_t q ) {
             auto toitr = _accounts.find( to );
             if( toitr == _accounts.end() ) {
               _accounts.emplace( payer, [&]( auto& a ) {
                  a.owner = to;
                  a.balance = q;
               });
             } else {
               _accounts.modify( toitr, 0, [&]( auto& a ) {
                  a.balance += q;
                  eosio_assert( a.balance >= q, "overflow detected" );
               });
             }
          }
    };
    
    EOSIO_ABI( simpletoken, (transfer)(issue) )
    

    相关文章和视频推荐

    【许晓笛】 EOS智能合约案例解析(1)
    https://www.jianshu.com/p/04be0bcbb7d0

    【许晓笛】 EOS智能合约案例解析(2)
    https://www.jianshu.com/p/277c3c572b1d

    【许晓笛】 EOS智能合约案例解析(3)
    https://www.jianshu.com/p/4d86a7d037c0

    圆方圆学院汇集大批区块链名师,打造精品的区块链技术课程。 在各大平台都长期有优质免费公开课,欢迎报名收看。

    公开课地址:https://ke.qq.com/course/345101

    相关文章

      网友评论

          本文标题:【许晓笛】49行代码就能发币?而且EOS连例子都给你了

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