学习目的:
1.了解智能合约
2.环境搭建
3.利用solidity编写hello world合约
4.合约部署和互动
5.编写发行代币的合约
了解智能合约:
1.智能合约是一套以数字形式定义的的承诺,包括合约参与方可以在上面执行这些承诺的协议。
2.以太坊中具体定义,它是运行在可复制,共享账本上的计算机程序,可以处理信息,接收、储存和发送价值。
3.以太坊中使用Solidity编写智能合约程序。
环境安装:
1.开发框架使用 truffle
2.测试框架使用testrpc(包含以太坊区块链测试环境以及JavaScript版本的Ethereum虚拟机)
安装命令:npm install -g ethereumjs-testrpc truffle
版本:Truffle v4.1.3 (core: 4.1.3) Solidity v0.4.19 (solc-js)
EthereumJS TestRPC v6.0.3 (ganache-core: 2.0.2)
3.IDE atom,使用etheratom插件来调试编写solidity
版本: atom 1.24.1 x64 mac版本
4.geth客户端
版本: 1.8.2-stable-b8b9f7f4 amd64
5.nodejs
版本:node-v8.10.0.pkg
合约编写:
➜ /Users/lion/my_project/_eth >mkdir test_truffle
➜ /Users/lion/my_project/_eth >cd test_truffle
➜ /Users/lion/my_project/_eth/test_truffle >truffle init
完成后,你将拥有如下目录:
* contracts 智能合约目录
* migrations 发布脚本目录
* test 存放测试文件
* truffle.js Truffle的配置文件
合约内容:
合约编译:
> truffle compile
命令返回:
Compiling ./contracts/HelloWorld.sol...
Writing artifacts to ./build/contracts
同时在项目目录下会生成一个build的目录,里面的内容是编译后的结果文件.
合约部署:
编写部署文件:
在migrations目录,1_initial_migration.js文件中添加两行代码:
var Migrations = artifacts.require("./Migrations.sol");
var HelloWorld = artifacts.require("./HelloWorld.sol");
module.exports = function(deployer) {
deployer.deploy(Migrations);
deployer.deploy(HelloWorld);
};
编写链接以太坊客户端的配置文件:
module.exports = {
networks: {
development: {
host: "localhost", port: 8545, network_id: '*', // 匹配任何network id gas:5000000 } } };
启动testrpc:
> testrpc
部署命令:
>truffle migrate --reset
返回结果:
Using network 'development'.
Running migration: 1_initial_migration.js Replacing Migrations... ... 0x088bbc083c39d1a8b9ff33943257b1f87c50c5937584c24488a0b74bf77d2af3 Migrations: 0xae9d2511c50958863dd30a374ebc1783a4349232 Deploying HelloWorld... ... 0x49fd087ea9c1da6d3453193e79bcdbeec54595874423bc23267008d4240bf731 HelloWorld: 0x0d400f2540406a86c3a725b118aaab5ef54e705f Saving successful migration to network... ... 0xa3a7cc28a0ef03c473cbaf3d6d2892fa5c441798b06ea6dcb5143862ae8b6099 Saving artifacts...
合约调用:
> truffle console
truffle(development)> var contract
undefined
HelloWorld.detectNetwork truffle(development)> HelloWorld.deployed().then(function(instance){ contract = instance })
undefined
truffle(development)> contract.setContent("123")
{ tx: '0x8b17186c45e31502537828b6a439260d1889e76279807d62fb539fe6faeeb5f9', receipt: { transactionHash: '0x8b17186c45e31502537828b6a439260d1889e76279807d62fb539fe6faeeb5f9', transactionIndex: 0, blockHash: '0x431aa934dff9d539462d02b3f84e7f60380ceb815f40f0ddb3cf230aa0a63d45', blockNumber: 11, gasUsed: 42847, cumulativeGasUsed: 42847, contractAddress: null, logs: [], status: 1 }, logs: [] }
truffle(development)> contract.sayContent();
'123'
成功^_^!
编写代币的合约:
以太坊的上发行代币,需遵循ERC20协议,才能在mist 等客户端发布。
以下是简略版本,发布到geth客户端中使用。
pragma solidity ^0.4.19;
contract MyToken
{
string public name;
string public symbol;
uint8 public decimals;
mapping (address => uint256) public balancesOf;
address public owner;
event Transfer(address indexed from, address indexed to, uint256 value);
function MyToken(uint256 _supply, string _name, string _symbol, uint8 _decimals) public
{
if(_supply == 0) _supply = 1000000;
owner = msg.sender;
balancesOf[msg.sender] = _supply;
name = _name;
symbol = _symbol;
decimals = _decimals;
}
function transfer(address _to, uint _value) public
{
// require(balancesOf[msg.sender] < _value); //避免转移出去的代币超过当前的存货
// require(balancesOf[_to] + _value < balancesOf[_to]); //避免自己调用自己,或者递归调用
balancesOf[msg.sender] -= _value;
balancesOf[_to] += _value;
Transfer(msg.sender, _to, _value);
}
function mint(uint _amount) public
{
balancesOf[owner] += _amount;
}
}
部署合约:
//truffle框架部署代码
var MyToken = artifacts.require("./MyToken.sol");
module.exports = function(deployer) {
deployer.deploy(MyToken, 1000000, "太平币", "TBB", 18);
};
//部署操作命令和步骤
>geth --datadir "chain" --rpc --rpcaddr localhost --rpcport 8545 --nodiscover console --vmdebug 2>> eth.log //本地启用私有链测试
> miner.start() && personal.unclockAccount() 启动挖矿和解锁账户
//再第二个终端,合约目录下使用以下命令
> truffle migrate --reset //部署命令,同时结果会返回合约地址,注意观察
Running migration: 1520850885_my_token.js
Replacing MyToken...0x281ec1591b90387e50922aac7cc8383ab6549eaf30b735a688b7d811b7f4111b
MyToken: 0x414d2fd5357f63b22fa0be50d2f4c61c4e68097e //合约地址
Saving successful migration to network... ... 0x94737295782072187b4466e72b5e6c4ea43bde0b64ee43be553ef3da788cff12 Saving artifacts...
//再从build/contract/MyToken.jso文件中拷贝abi:字段的值,值需要转义和压缩
//回到geth命令行中
> var my_token = eth.contract(JSON.parse('转义后的abi值')).at("合约地址");
然后可以调用这个合约里面的方法做一些具体操作,比如交易等等
网友评论