什么是标准代币合约
2017年,ICO异常火爆,催生了大量的以太坊代币。这些代币,基本上都是ERC20标准代币。ERC20是标准Token接口,规定了Token的基本功能(查询余额、转账交易等),方便第三方使用(如钱包和交易所),极大地降低了代币的发行和交易成本。
其实,除了ERC20,还有其它一些标准接口规范,如ERC223、ERC721等。如2017年很火爆的以太坊养猫,其实用的就是ERC721标准。以太坊养猫中的猫都是ERC721的Token,每只猫拥有不一样基因,归根到底也就是拥有不一样属性的Token。猫的编号其实也就是Token的编号, 猫的基因也就是Token的属性。
接下来我们要学习的,就是如何创建和部署自己的ERC20标准代币合约。
创建和部署建ERC20标准合约
1. 初始化合约工程
新建工程目录,如笔者创建的工程名为“SeaCoin”(海洋币,很俗的名字),然后用truffle初始化工程:
truffle init
2. 安装Zeppelin-Solidity
Zeppelin-Solidity是一个开源的第三方库,使用该库可以既快速又安全地开发ERC20标准代币合约。相反,如果完全靠我们自己编写合约代码,难免会有考虑不全的地方。而一旦代码出现漏洞,被攻击者利用,那整个代币将完全失去价值!
在工程的根目录,执行以下命令:
npm install zeppelin-solidity
安装完成后,我们用Sublime Text打开工程,会发现node_modules目录下已经导入有zepplin-solidity的代码库。
image3. 通过继承Zepplin StandardToken编写合约
- 在contracts目录下新建文件SeaCoin.sol,复制以下内容:
pragma solidity ^0.4.4;
import "zeppelin-solidity/contracts/token/ERC20/StandardToken.sol";
contract SeaCoin is StandardToken {
string public name = "SeaCoin";
string public symbol = "SEC"; //token的代号
uint8 public decimals = 4; //小数位
uint256 public INITIAL_SUPPLY = 2000000; //初始化代币总量,如这里200万
function BloggerCoin() {
totalSupply_ = INITIAL_SUPPLY;
balances[msg.sender] = INITIAL_SUPPLY;
}
}
- 在migrations文件夹下新建文件“2_deploy_contract.js”,并输入以下内容
var SeaCoin = artifacts.require("SeaCoin")
module.exports = function(deployer){
deployer.deploy(SeaCoin);
};
- 修改配置文件
打开位于根目录的truffle.js文件,改成以下内容。
module.exports = {
networks: {
development: {
host: "localhost",
port: 8545,
network_id: "*" // 匹配任何network id
}
}
};
4. 编译智能合约
truffle compile
5. 运行私链网络
- 启动私链
geth --datadir "E:\Ether\private" --networkid 15 --port 61910 --rpc --rpcport 8545 --rpcapi "db,eth,net,web3" console
打开一个新的命令行窗口,启动私链网络后保持窗口不关闭,等待合约部署。
- 解锁账户
personal.unlockAccount(eth.accounts[0],"123456")
6. 部署智能合约
打开另一个PowerShell窗口(注意这时打开了两个命令行窗口,私链所在的命令行不需管它)。
在命令行cd到工程的根目录,执行以下命令:
truffle migrate
执行命令后,会输出“Deploying Migrations...”,表示正在进行部署,需要通过挖矿打包部署。
miner.start()
回到私链所在的命令行窗口,执行挖矿,挖出一定的区块后,合约部署成功!
image与ERC20代币合约交互
前面我们已经成功把SeaCoin部署到了私链网络下,下面我们通过执行一些操作进行验证。在上一个章节中,我们学习到有两种交互方法,现在我们采用truffle提供的控制台进行交互。
- 打开控制台
truffle console
- 实例赋值
SeaCoin.deployed().then(instance => contract = instance)
- 查询余额
contract.balanceOf(eth.coinbase)
- 交易
从第1个账户转十五万个SeaCoin到第二个账户。
contract.transfer(web3.eth.accounts[1], 150000)
需要说明的是,转账前,需要先解锁账户。转账之后,控制台会卡住,是因为在等待挖矿,因此你需要在私链网络运行挖矿以打包交易。
验证没问题,代表我们的SeaCoin已成功流转在以太坊的网络里。虽然现在仍然是私链,但下一个章节,我们将学习如何部署到以太坊主网!
下面是笔者的操作记录:
truffle(development)> contract.balanceOf(web3.eth.accounts[0])
BigNumber { s: 1, e: 6, c: [ 2000000 ] }
truffle(development)> contract.balanceOf(web3.eth.accounts[1])
BigNumber { s: 1, e: 0, c: [ 0 ] }
truffle(development)> contract.transfer(web3.eth.accounts[1], 150000)
{ tx: '0xd88ef1c6cbba03ce67e81d7eb5c9a62c2dd17b86603517f98a52ed0466b1d9ae',
receipt:
{ blockHash: '0x66b1e3cc7154548695de3ba7fa705514fa5bb8dabf0a60dc8a50c46c287f1b73',
blockNumber: 205,
contractAddress: null,
cumulativeGasUsed: 51697,
from: '0x61b7c76de24861f00efddd4b5873c4d188dd88a9',
gasUsed: 51697,
logs: [ [Object] ],
logsBloom: '0x00000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000008000000000000002000040000000000000000000000000000000000000000000000000
000000000000040000000000010000000000000000000000000000000000000000000008000000000000000000000000000001000000000000000000
000000000100000000000000000000000000000000000000002000000000000000000000000000000000000000000001000000000000000000000000
000000000000000000000000000000000000004000000000000',
root: '0x8c0ab5305f4ec98656d5dd2cd5af384f7b852133a2649ca27efdbdfd9535a2f2',
to: '0x08e6b912a61da948d064f20e166089c2c7459c4d',
transactionHash: '0xd88ef1c6cbba03ce67e81d7eb5c9a62c2dd17b86603517f98a52ed0466b1d9ae',
transactionIndex: 0 },
logs:
[ { address: '0x08e6b912a61da948d064f20e166089c2c7459c4d',
blockNumber: 205,
transactionHash: '0xd88ef1c6cbba03ce67e81d7eb5c9a62c2dd17b86603517f98a52ed0466b1d9ae',
transactionIndex: 0,
blockHash: '0x66b1e3cc7154548695de3ba7fa705514fa5bb8dabf0a60dc8a50c46c287f1b73',
logIndex: 0,
removed: false,
event: 'Transfer',
args: [Object] } ] }
truffle(development)> contract.balanceOf(web3.eth.accounts[0])
BigNumber { s: 1, e: 6, c: [ 1850000 ] }
truffle(development)> contract.balanceOf(web3.eth.accounts[1])
BigNumber { s: 1, e: 5, c: [ 150000 ] }
网友评论