承接前文重要提醒
这是以太坊介绍指南系列的第二部分。如果你之前没读过第一部分,那就建议马上查看。在第一部分里,你可以对以太坊有个基本的认识,也能知道与以太坊节点交互以及在账户间发送交易等方面的知识。只有先把前面的基础搭建好,才能够更好地理解这篇文章。
智能合约基础认知
智能合约实际上是在以太坊虚拟机(EVM)上运行的程序。在以太坊的范围内,它就像是一个能做各种事情的万能工具箱。目前,大部分智能合约被应用于众筹领域,像 I-COs 或者代币销售这类活动都非常依赖它。有了智能合约,实现带有智能合约的 I-CO 不再困难,关键在于要实现数字资产交易以及赋予其价值的逻辑。
pragma solidity ^0.4.0;
contract MyToken {
address public creator;
uint256 public totalSupply;
mapping (address => uint256) public balances;
function MyToken() public {
creator = msg.sender;
totalSupply = 10000;
balances[creator] = totalSupply;
}
function balanceOf(address owner) public constant returns(uint256){
return balances[owner];
}
function sendTokens(address receiver, uint256 amount)
public returns(bool){
address owner = msg.sender;
require(amount > 0);
require(balances[owner] >= amount);
balances[owner] -= amount;
balances[receiver] += amount;
return true;
}
}
代币智能合约需求
开展 I - CO 很有必要开发代币智能合约。该合约能为每个贡献者储存相应数量的代币。就像举办聚会,先准备了一些沙拉,再通过发放代币来兑换沙拉。一周后,客人数量增多,沙拉供应却有限,此时客人们会将代币当作资产交易,使代币市场价值提升。以太坊让几乎任何人都能创建可交易的数字资产,且这在现实中确实在发生。
...
require(amount > 0);
require(balances[owner] >= amount);
...
合约定义与初始化
...
balances[owner] -= amount;
balances[receiver] += amount;
return true;
}
合约定义初始化时需用到合约的名字。像例子中的 MyToken,它是一个与合约同名的函数。每当有新的合约实例被部署到网络里,此函数就会被调用一次。因为函数调用属于交易,所以能够通过 msg.sender 来获取合约所有者的信息。这是一个非常量函数,要改变余额就必须借助它来进行操作。
npm install -g solc
代币转移函数要求
solcjs MyToken.sol --bin
代币转移函数的参数包含接收者地址和欲转移的代币数量,它会返回一个布尔类型的数据,用于表明交易是否成功。在具体例子中,有两个要求:一是被转移的代币数量需大于零;二是发送者的余额要能支付这笔代币转移。只有当这些条件都满足时,代币转移才能顺利完成,这也是保障交易安全合理的重要举措。
合约部署与交互
solcjs MyToken.sol --abi
首先创建一个名为 MyToken.sol 的文件,然后把合约代码粘贴进去。接着在该文件所在的路径下打开终端。之后利用 solc 来构建 ABI,ABI 作为合约的接口和模板,能够让你了解可用的方法。随后使用后台运行的 testrpc 以及 node.js 控制台来部署合约,通过字节码把合约的新实例部署到 testrpc 上,并把地址保存好,以便后续与合约进行交互。你还能看到一个类似的 app.js 文件,这个文件中包含了发送代币以及展示账户余额信息的逻辑。不过,对于 ERC20 协议代币,将会在下一篇文章中进行介绍。
//instance web3
Web3 = require('web3')
provider = new Web3.providers.HttpProvider("http://localhost:8545")
web3 = new Web3(provider)
大家读完这篇以太坊介绍指南的第二部分后,对于以太坊中的智能合约以及 ICO 的实践过程,是否有了更清晰的认识?如果有任何疑问,欢迎在评论区留言。同时,不要忘记点赞,并且把它分享给身边对以太坊感兴趣的朋友。
// load files
myTokenABIFile = fs.readFileSync('MyToken_sol_MyToken.abi')
myTokenABI = JSON.parse(myTokenABIFile.toString())
myTokenBINFile = fs.readFileSync('MyToken_sol_MyToken.bin')
myTokenByteCode = myTokenBINFile.toString()
//deploy
account = web3.eth.accounts[0]
MyTokenContract = web3.eth.contract(myTokenABI)
contractData = { data: myTokenByteCode, from: account, gas: 999999 }
deployedContract = MyTokenContract.new(contractData)