我必须承认,学习eosio一直没有闲庭信步的感觉,我可以看到为什么很多人说它有一个陡峭的学习曲线。随着eosio软件继续经历大量快速发展,文档数量有限,很少有工作实例可供参考。我已经被困了好几次,也希望帮助改善下一个开发人员的体验。在本文中,我将通过将其分解为单独的部分来讨论eosio.token
合约。
什么是eosio.token合约?
eosio.token合约允许创建许多不同的代币。这使任何人都能够创建和发送代币。每个代币必须由issuer
帐户发行。由于帐户可以包含多方,因此你可以使用具有所有者和活动权限的普通帐户或自定义配置帐户来创建和管理代币。每个代币都是asset
类型,如下所示:
1000000000.0000 SYS
1.0000 SYMBOL
0.10 SYS
asset
类型是一个数字(如果我没记错的话可以达到18位小数)和一个可以在1-7个大写字母之间的符号。此合约有三个操作可用于与之交互。它们是:创建,发布和转账。
创建用于定义新代币的特征。这包括代币asset
符号,最大供应量以及允许发出代币的帐户。创建还会将新代币配置保留在区块链上。这意味着新代币配置的存储必须由某人放置。正如你稍后将看到的,部署此合约的帐户(在我们的案例中为’eosio.token’)也将支付代币配置存储。
发布用于增加代币的有效供应。可以持续发出代币,直到达到最大供应量。在代币创建期间定义的issuer
必须批准此操作才能使其成功。
转账让一个帐户将代币转移到另一个帐户。
部署合约
你应该知道的第一件事是每个eosio智能合约都属于一个eosio帐户。合约基本上是其他帐户可以与之交互的对象。合约包含在区块链上执行代码的操作actions
。合约可以直接访问区块链上的存储,删除和更新数据。
将一个action推送到合约需要至少一个帐户的授权。根据合约的复杂性,可能需要进一步的帐户和权限。帐户可以由基于权限的配置中设置的单个或多个个人组成。智能合约只能由一个帐户运行,而一个帐户只能拥有一个智能合约。最佳做法是为帐户和合约提供相同(小写)的名称。
在你与eosio.token合约进行交互之前,你需要创建一个具有相同名称的帐户,并将合约部署到该帐户。
首先创建一个帐户
$cleos create account eosio eosio.token <OWNER-KEY> <ACTIVE-KEY>
然后编译合约
$cd eos/contract/eosio.token
$eosiocpp -o eosio.token.wast eosio.token.cpp
最后将合约部署到帐户上
$cleos set contract eosio.token ../eosio.token
你可以验证合约是否已部署
$cleos get code eosio.token
合约架构
合约分为两个文件eosio.token.cpp
和eosio.token.hpp
。.hpp
文件定义合约类,操作和表,而.cpp
文件实现操作逻辑。让我们首先看一下将用于实例化合约对象的合约类。(我从eosio.token.hpp
中删除了一些遗留代码)
/**
* @file
* @copyright defined in eos/LICENSE.txt
*/
#pragma once
#include <eosiolib/asset.hpp>
#include <eosiolib/eosio.hpp>
#include <string>
namespace eosiosystem {
class system_contract;
}
namespace eosio {
using std::string;
class token : public contract {
public:
token( account_name self ):contract(self){}
void create( account_name issuer,
asset maximum_supply);
void issue( account_name to, asset quantity, string memo );
void transfer( account_name from,
account_name to,
asset quantity,
string memo );
private:
friend eosiosystem::system_contract;
inline asset get_supply( symbol_name sym )const;
inline asset get_balance( account_name owner, symbol_name sym )const;
struct account {
asset balance;
uint64_t primary_key()const { return balance.symbol.name(); }
};
struct currency_stats {
asset supply;
asset max_supply;
account_name issuer;
uint64_t primary_key()const { return supply.symbol.name(); }
};
typedef eosio::multi_index<N(accounts), account> accounts;
typedef eosio::multi_index<N(stat), currency_s