1 环境搭建
1.1 安装Substrate节点
$ git clone git@github.com:paritytech/substrate.git$ cd substrate(master)$ git checkout -b v2.0.0-rc4 v2.0.0-rc4切换到一个新分支 'v2.0.0-rc4'(v2.0.0-rc4)$ cargo build --release
1.2 安装cargo contract插件
•安装命令
$ cargo install cargo-contract --vers 0.6.1 --force
•帮助手册
$ cargo contract --helpcargo-contract 0.6.1Utilities to develop Wasm smart contractsUSAGE: cargo contract OPTIONS: -h, --help Prints help information -V, --version Prints version informationSUBCOMMANDS: new Setup and create a new smart contract project build Compiles the smart contract generate-metadata Generate contract metadata artifacts test Test the smart contract off-chain help Prints this message or the help of the given subcommand(s)
2 ERC20合约介绍
2.1 什么是ERC20标准
ERC20 通证标准(ERC20 Token Standard)是通过以太坊创建通证时的一种规范。按照 ERC20 的规范可以编写一个智能合约,创建“可互换通证”。它并非强制要求,但遵循这个标准,所创建的通证可以与众多交易所、钱包等进行交互,它现在已被行业普遍接受。
ERC20定义了一些标准的接口函数:balanceOf
、 totalSupply
、transfer
、transferFrom
、approve
和allowance
。以及一些可选的字段,例如通证名称、符号以及小数保留位数等。
详见:https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20.md
2.2 ERC20接口
contract ERC20 {
function totalSupply() constant returns (uint theTotalSupply); function balanceOf(address _owner) constant returns (uint balance); function transfer(address _to, uint _value) returns (bool success); function transferFrom(address _from, address _to, uint _value) returns (bool success); function approve(address _spender, uint _value) returns (bool success); function allowance(address _owner, address _spender) constant returns (uint remaining); event Transfer(address indexed _from, address indexed _to, uint _value); event Approval(address indexed _owner, address indexed _spender, uint _value);}
•功能介绍:
函数名 | 功能 |
totalSupply | 返回存在于流通中的通证(Token)总量 |
balanceOf | 返回指定账户地址的通证余额 |
transfer | 让调用方将指定数量的通证发送到另一个地址,即转账 |
transferFrom | 允许智能合约自动执行转账流程并代表所有者发送给定数量的通证 |
approve | 调用方授权给定的地址可以从其地址中提款 |
allowance | 返回被允许转移的余额数量 |
event Transfer | 事件通知,当token被转移时,必须调用触发,类似回调,当事件发生时,会得到通知 |
event Approval | 事件通知,当任何成功调用approve 后,必须调用触发 |
3 ERC20合约开发
3.1 创建合约工程
执行命令后,会生成2个文件,其中lib.rs
会包括一些基础框架,我们可以在此基础上开发我们的合约。
$ cargo contract new erc20 Created contract erc20$ tree erc20/erc20/├── Cargo.toml└── lib.rs
3.2 合约存储创建
#[ink(storage)] struct Erc20 {
/// 代币发行总量 total_supply: storage::Value, /// 用户及余额映射 balances: storage::HashMap, }
3.3 合约构造方法创建
#[ink(constructor)] fn new(&mut self, initial_supply: Balance) {
// 获取合约创建者 let caller = self.env().caller(); // 设置发行总量 self.total_supply.set(initial_supply); // 合约创建者拥有所有发行代币 self.balances.insert(caller, initial_supply); }
3.4 合约接口方法创建
(1)查询代币发行总量接口
#[ink(message)] fn total_supply(&self) -> Balance {
*self.total_supply }
(2)查询用户代币余额接口
#[ink(message)] fn balance_of(&self, owner: AccountId) -> Balance {
self.balance_of_or_zero(&owner) } // 工具方法:若用户未被初始化,代币余额置为0 fn balance_of_or_zero(&self, owner: &AccountId) -> Balance {
*self.balances.get