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

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) )

相关文章和视频推荐

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

公开课地址:https://ke.qq.com/course/345101?flowToken=1007371

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

编辑于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏比原链

比原链Bytom错误码一览

1383
来自专栏吴伟祥

stellar 原

Actions that change things in Stellar, like sending payments, changing your acco...

1184
来自专栏微信公众号:Java团长

即将发布的 JDK 10 有 109 项新特性,你喜欢哪些?

按计划,JDK 10 将于 3 月 20 日正式发布。据前 Oracle 员工 Simon Ritter 的统计,JDK 10 总共包含 109 项新特性。当然...

662
来自专栏算法修养

HttpClient参观记:.net core 2.2 对HttpClient到底做了什么?

.net core 于 10月17日发布了 ASP.NET Core 2.2.0 -preview3,在这个版本中,我看到了一个很让我惊喜的新特性:HTTP C...

1691
来自专栏Java3y

【SSH测试整合Demo】企业人事管理系统

前言 前面我们已经学习了怎么整合SSH框架了。是时候拿一个小项目来练练手了….我们现在要设计一个企业人事管理系统… 需求: **要求对员工信息进行维护; ** ...

41913
来自专栏开发与安全

linux网络编程之进程间通信基础(二):死锁、信号量与PV原语简介

一、死锁 (1) 死锁是指多个进程之间相互等待对方的资源,而在得到对方资源之前又不释放自己的资源,这样,造成循环等待的一种现象。如果所有进程都在等待一个不可能发...

2560
来自专栏机器人网

一文教你从PLC编程菜鸟变成高手

PLC编程软件由系统程序和用户程序两部分组成。系统程序包括监控程序、编译程序、诊断程序等,主要用于管理全机、将程序语言翻译成机器语言,诊断机器故障。PLC编程软...

5615
来自专栏一个番茄说

Swift中防止ptrace依附

在移动开发中,安全是一个很重要的话题,当然安全是没有绝对的,只能说尽可能的提高安全性。在iOS的开发中,为了防止别人窥视我们的App,我们得采用一些手段来进行防...

1233
来自专栏圆方圆学院精选

【杨镇】【中译修订版】以太坊的分片技术官方介绍

本文的目的是为那些希望理解分片建议详情,乃至去实现它的朋友提供一份相对完整的细节说明和介绍。本文仅作为二次方分片(quadratic sharding)的第一阶...

1251
来自专栏比原链

比原链Bytom错误码一览

BTM103", "A peer core is operating on a different blockchain network"

1635

扫码关注云+社区

领取腾讯云代金券