赞
踩
ERC20是以太坊上的一种代币标准,遵循该标准的代币合约,匀可以由一套以太坊代币钱包代码来调用,其带来了良好的兼容性。
ERC20定义的接口方法如下:
pragma solidity ^0.4.21;
contract ERC20 {
function name() public view returns (string);
function symbol() public view returns (string);
function decimals() public view returns (uint8);
function totalSupply() public view returns (uint);
function balanceOf(address _owner) public returns (uint);
function transfer(address _to, uint _value) public returns (bool);
function transferFrom(address _from, address _to, uint _value) public returns (bool);
function approve(address _spender, uint _value) public returns (bool);
function allowance(address _owner, address _spender) public returns (uint);
event Transfer(address indexed _from, address indexed _to, uint _value);
event Approval(address indexed _owner, address indexed _spender, uint _value);
}
ERC20代币的名字,例如”My test token”。
代币的简称,例如:MTT、EOS,这个是我们一般在代币交易所看到的名字。
token 精确到小数点后几位。比如如果设置为3,就是支持0.001表示。
token 总供应量。
某地址(账户)的账户余额。
从代币合约的调用者地址上转移 _value 数量的 token 到的地址 _to,并且必须触发 Transfer 事件。
从地址 _from 发送数量为 _value 的 token 到地址 _to,必须触发 Transfer 事件。transferFrom 方法用于允许合同代理某人转移 token。条件是 from 账户必须经过了approve。
允许 _spender 多次取回您的帐户,最高达 _value 金额。 如果再次调用此函数,它将以 _value 覆盖当前的余量。
返回 _spender 仍然被允许从 _owner 提取的金额。
这里给出一种 ERC20 代币合约的实现:
contract TokenDemo is ERC20 { string public name; // 名称,例如 "My test token" uint8 public decimals; // 返回 token 使用的小数点后几位。比如如果设置为 3,就是支持 0.001 表示. string public symbol; // token 简称,like MTT uint public totalSupply; mapping(address => uint256) balances; mapping(address => mapping(address => uint256)) allowed; constructor(uint256 _initialAmount, string _tokenName, uint8 _decimalUnits, string _tokenSymbol) public { totalSupply = _initialAmount * 10 ** uint256(_decimalUnits); // 设置初始总量 balances[msg.sender] = totalSupply; // 初始token数量给予消息发送者,因为是构造函数,所以这里也是合约的创建者 name = _tokenName; decimals = _decimalUnits; symbol = _tokenSymbol; } function transfer(address _to, uint256 _value) public returns (bool success) { // 默认 totalSupply 不会超过最大值 (2^256 - 1). // 如果随着时间的推移将会有新的 token 生成,则可以用下面这句避免溢出的异常 require(balances[msg.sender] >= _value && balances[_to] + _value > balances[_to]); require(_to != 0x0); balances[msg.sender] -= _value; // 从消息发送者账户中减去 _value 数量的 token balances[_to] += _value; // 往接收账户增加 _value 数量的 token emit Transfer(msg.sender, _to, _value); // 触发转币交易事件 return true; } function transferFrom(address _from, address _to, uint256 _value) public returns (bool) { require(balances[_from] >= _value && allowed[_from][msg.sender] >= _value); balances[_to] += _value; // 接收账户增加 _value 数量的 token balances[_from] -= _value; // 支出账户 _from 减去 _value 数量的 token allowed[_from][msg.sender] -= _value; // 消息发送者可以从账户 _from 中转出的数量减少 _value emit Transfer(_from, _to, _value); // 触发转币交易事件 return true; } function balanceOf(address _owner) public returns (uint256) { return balances[_owner]; } function approve(address _spender, uint256 _value) public returns (bool) { allowed[msg.sender][_spender] = _value; emit Approval(msg.sender, _spender, _value); return true; } function allowance(address _owner, address _spender) public returns (uint256 remaining) { return allowed[_owner][_spender]; // 允许 _spender 从 _owner 中转出的 token 数 } }
注:TokenDemo is ERC20 是声明实现某接口,这里实现了我们前面的 ERC20 接口。
zeppelin-solidity 之于 ERC20 智能合约就类似 Spring Boot 之于 JAVA 开发,是一个事实上的业界标准库,对于一些较通用的方法已经做了比较严谨的实现,而我们只需要做另外的部分。接下来我们使用 zeppelin-solidity 来开发一个智能合约。
sudo npm install -g truffle yarn
mkdir tutorial-token
cd tutorial-token
truffle unbox tutorialtoken
yarn add zeppelin-solidity dotenv
yarn install
解释一下,首先使用 npm 全局安装 truffle 及 yarn,前者是智能合约的开发框架,包含测试、部署等功能,前面的文章已经介绍过;后者是 facebook 开发的一款前端包管理器,相对于 npm 具有更好的版本控制及性能。后面使用 truffle 的 unbox 命令来使用 tutorialtoken 项目作为本次开发 ERC20 智能合约的骨架,之后安装 zeppelin-solidity;最后使用 yarn install 补全所有项目缺失的包。
使用 WebStorm 打开工程,在 contracts 目录下新建文件 TutorialToken.sol,内容如下:
pragma solidity ^0.4.21;
import 'zeppelin-solidity/contracts/token/ERC20/StandardToken.sol';
contract TutorialToken is StandardToken {
string public name = "TutorialToken";
string public symbol = "HT";
uint8 public decimals = 2;
uint public INITIAL_SUPPLY = 10 ** 12; // equal 10 ^ 12
constructor() public {
totalSupply_ = INITIAL_SUPPLY;
balances[msg.sender] = INITIAL_SUPPLY;
}
}
在 migrations 目录下新建 2_deploy_contracts.js
,内容如下:
var TutorialToken = artifacts.require("TutorialToken");
module.exports = function(deployer) {
deployer.deploy(TutorialToken);
}
修改 src/js/app.js 中 new Web3.providers.HttpProvider(‘http://127.0.0.1:8545’) 及 truffle.js 中 networks.development.host 及 port 为 127.0.0.1:8545。
命令行执行以下命令:
sudo yarn global add ganache-cli
ganache-cli
新建命令行进入到项目目录:
truffle migrate --reset
npm run dev
执行成功的话,会自动打开浏览器页面,在 Address 框输入 0xf17f52151EbEF6C7334FAD080c5704D77216b732,Amount 框输入1000,并点击 Transfer,会发现 Balance 余额减少了,说明本次 ERC20 合约编写、部署、功能匀没问题。
眼尖的小伙伴可能会发现,合约中 name,totalSupply 都没有编写对应的方法呢?这是因为 solidity 会自动给 public 变量生成同名的 getter 接口。
注:想直接看效果的小伙伴也可以直接下载笔者的合约代码: Gitee tutorial-token
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。