【許曉笛】49行代碼就能發幣?並且EOS連例子都給你了

Daniel Larimer 在他的博客介紹了EOS新的智能合約架構(EOS團隊的開發速度實在是太嚇人,根本追不上)。他給出了最簡單的一個新幣種的智能合約代碼,僅有49行就能完成一個新幣種的開發,一個新的「愛息歐」就誕生了。讓咱們一步一步實現吧。segmentfault

首先實現私有成員,創建一個 account 結構體,這個結構體裏保存的是全部持有咱們這種代幣的人的帳戶和餘額。架構

private:
      //account 結構體 
      struct account {
         //EOS 帳戶名
         account_name owner;
         //餘額
         uint64_t     balance;
         //主鍵
         uint64_t primary_key()const { return owner; }

下一步 咱們要利用 Boost 庫中的多索引列表,將上面聲明的結構體放入一個列表中,方便查詢和修改。app

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(發行)函數,要不從哪「印錢?」ui

void issue( account_name to, uint64_t quantity ) {
         //獲得合約主人的權限
         require_auth( _self );
         //直接印錢
         add_balance( _self, to, quantity );

最後一步,將咱們的 transfer 和 issue 函數接口提供給 EOS 系統,經過一個宏就能夠快速實現。this

EOSIO_ABI( simpletoken, (transfer)(issue) )

這個宏是咋回事?咱們看看 dispacher.hpp 文件中對這個宏的定義,實際上是替開發者實現了 apply 函數,使得開發者能夠專一於業務邏輯。spa

#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 智能合約架構仍是頗有意義的。code

#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://ke.qq.com/course/345101

相關文章
相關標籤/搜索