Solidity智能合约开发测试环境搭建
以太坊合约开发工具非常多,但是功能上各有优缺点,因此如何选择搭配一套比较好用的开发和测试环境就非常重要。我在开发实践中摸索发现了一种方便快捷的开发和测试方法。
总结下来就是:
1、 使用https://ethfiddle.com/进行代码开发,调试
2、 使用testrpc和geth做发布前功能测试
3、 使用metamask进行发布
1、使用https://ethfiddle.com/进行代码开发,调试
打开网站https://ethfiddle.com/,这个工具使用非常简单,只需要在左边的编辑框内输入代码,下面的error就会同步编译并展示错误信息,代码编辑完成后,直接点击右边的deploy就可以发布合约,合约发布后,右边框内可以出现合约可以调用的函数,
点击call就可以调用合约对应的代码
注意:如果函数名称为空,我们可以先写个名字用来调试,发布的时候去除这个名称就可以了;同理对private的函数也可以先设置为public来调试
2、 使用testrpc和geth做发布前功能测试
本文在windows开发环境下,当然其他环境也验证了可以成功
我们需要安装testrpc和geth
A、安装testrpc
npm install -g ethereumjs-testrpc
运行testrpc后显示版本信息:EthereumJS TestRPC v6.0.3 (ganache-core: 2.0.2)
B、geth 下载:
https://geth.ethereum.org/downloads/
运行geth version后显示版本信息
Version: 1.8.1-stable
Git Commit: 1e67410e88d2685bc54611a7c9f75c327b553ccc
C、在cmd窗口启动testrpc
直接testrpc回车
D、在另外一个cmd窗口启动geth
输入:geth attach http://127.0.0.1:8545
E、在geth控制台创建帐号并转账
转账测试:
eth.accounts
personal.newAccount("123456")
eth.getBalance(eth.accounts[0])
eth.coinbase
eth.getBalance(eth.accounts[10])
eth.sendTransaction({from:eth.accounts[0],to:eth.accounts[10],value:web3.toWei(5,'ether')})
F、合约发布
https://ethfiddle.com/ 网站没有给我们生成web3脚本,我们这里使用remix来自动生成脚本
打开http://remix.ethereum.org,新增文件Token.sol,内容如下:
pragma solidity ^0.4.18;
contract Token {
address issuer;
mapping (address => uint) balances;
event Issue(address account, uint amount);
event Transfer(address from, address to, uint amount);
function Token() public payable{
issuer = msg.sender;
}
function issue(address account, uint amount) public {
assert(msg.sender == issuer);
balances[account] += amount;
}
function transfer(address to, uint amount) public {
assert (balances[msg.sender] >= amount);
balances[msg.sender] -= amount;
balances[to] += amount;
Transfer(msg.sender, to, amount);
}
function getBalance(address account) public constant returns (uint) {
return balances[account];
}
}
选择右边的编译,然后点击detail,选择WEB3DEPLOY,点击复制,把下面的内容放入geth console中
var tokenContract = web3.eth.contract([{"constant":false,"inputs":[{"name":"account","type":"address"},{"name":"amount","type":"uint256"}],"name":"issue","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"to","type":"address"},{"name":"amount","type":"uint256"}],"name":"transfer","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"account","type":"address"}],"name":"getBalance","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"inputs":[],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"name":"account","type":"address"},{"indexed":false,"name":"amount","type":"uint256"}],"name":"Issue","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"from","type":"address"},{"indexed":false,"name":"to","type":"address"},{"indexed":false,"name":"amount","type":"uint256"}],"name":"Transfer","type":"event"}]);
var token = tokenContract.new(
{
from: web3.eth.accounts[0],
data: '0x6060604052341561000f57600080fd5b336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506103d78061005e6000396000f300606060405260043610610057576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063867904b41461005c578063a9059cbb1461009e578063f8b2cb4f146100e0575b600080fd5b341561006757600080fd5b61009c600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803590602001909190505061012d565b005b34156100a957600080fd5b6100de600480803573ffffffffffffffffffffffffffffffffffffffff169060200190919080359060200190919050506101d9565b005b34156100eb57600080fd5b610117600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610362565b6040518082815260200191505060405180910390f35b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561018857600080fd5b80600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055505050565b80600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054101561022557600080fd5b80600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254039250508190555080600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055507fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef338383604051808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001828152602001935050505060405180910390a15050565b6000600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205490509190505600a165627a7a72305820fee6d10733c12d160654c96b4b873c8b909925a0a5900cdda3a44bf8a9bba03f0029',
gas: '4700000'
}, function (e, contract){
console.log(e, contract);
if (typeof contract.address !== 'undefined') {
console.log('Contract mined! address: ' + contract.address + ' transactionHash: ' + contract.transactionHash);
}
})
成功编译,显示:
Contract mined! address: 0xd481dea9b8e8399c263e7e77bb09d9e617da2a92 transactionH
ash: 0xec04e48ed031122d5fc57481aefa55c9bc79cd863ce6f364eec79e47d3608d0e
注意:上面是两行web3代码,我们分别复制到geth控制台,然后回车,否则可能看不到Contract mined! Address这些信息
G、合约测试
在geth控制台,测试充值:
token.issue(eth.accounts[0], 100, {from: eth.accounts[0]});
查看余额:
token.getBalance(eth.accounts[0])
转账:
token.transfer(eth.accounts[1], 30, {from: eth.accounts[0]})
查看余额:
token.getBalance(eth.accounts[0])
token.getBalance(eth.accounts[1])
3、使用metamask进行发布
这个参考http://liyuechun.org/2017/09/03/solidity-MetaMask/ ,使用remix和metamask搭配,在metamask里面选择main network就可以发布了,只是前提是要去买点eth。