网上已有很多相关教程,但由于geth从1.6版本移除了编译Solidity的功能,如链接所述,许多教程中介绍的方法都失效了。本文综合了网上已有的一些教程,介绍了新的可行方法。
本文只介绍Ubuntu环境下的操作,其他环境下可以类比
# Install geth
sudo add-apt-repository -y ppa:ethereum/ethereum
sudo apt-get update
sudo apt-get install ethereum
Solc 是Solidity的编译器
# Install Solc
sudo add-apt-repository ppa:ethereum/ethereum
sudo apt-get update
sudo apt-get install solc
创世块主要根据genesis.json文件生成,其内容如下:
{
"config": {
"chainId": 123456,
"homesteadBlock": 0,
"eip155Block": 0,
"eip158Block": 0
},
"nonce": "0x0000000000000042",
"difficulty": "0x020000",
"mixhash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"coinbase": "0x0000000000000000000000000000000000000000",
"timestamp": "0x00",
"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"extraData": "0x11bbe8db4e347b4e8c937c1c8370e4b5ed33adb3db69cbdb7a38e1e50b1b82fa",
"gasLimit": "0x4c4b40",
"alloc": {}
}
创建data文件夹,并执行如下命令:
geth --datadir data init genesis.json
执行如下命令,其中--datadir的参数与上面命令相同,--networkid的参数与genesis.json中的参数相同:
geth --datadir data --networkid 123456 --rpc --rpccorsdomain "*" --nodiscover console
personal.newAccount() 或者 personal.newAccount("123456")admin.nodeInfominer.start(1)miner.stop()eth.coinbase(默认为第一个账户)miner.setEtherbase(eth.accounts[1])eth.accounts[0]eth.getBalance(eth.accounts[0])personal.unlockAccount(eth.accounts[0])eth.sendTransaction({from:eth.accounts[0],to:"address",value:web3.toWei(3,"ether")})eth.blockNumbereth.getBlock(1)eth.getTransaction("TxId")为下文智能合约的调用测试,需要提前生成两个账户,命令如下:
# Geth Console中 执行两次
personal.newAccount()
因为5.2节编译生成智能合约时,需要消耗一定的gas,因此我们先通过挖矿获得以太币
# Geth Console中
#第一次执行时会耗费较长时间,以构建DAG
miner.start(1)
采用solidity语言编写智能合约。命名该文件为Token.sol, 内容如下:
contract Token {
address issuer;
mapping (address => uint) balances;
event Issue(address account, uint amount);
event Transfer(address from, address to, uint amount);
function Token() {
issuer = msg.sender;
}
function issue(address account, uint amount) {
if (msg.sender != issuer) throw;
balances[account] += amount;
}
function transfer(address to, uint amount) {
if (balances[msg.sender] < amount) throw;
balances[msg.sender] -= amount;
balances[to] += amount;
Transfer(msg.sender, to, amount);
}
function getBalance(address account) constant returns (uint) {
return balances[account];
}
}
说明
Token合约功能issue 函数可以向充值以太到合约账户transfer 函数可以向其他账号发送tokengetBalance函数可以获取某个账号的token余额##5.2 编译智能合约
# 非Geth Console中
echo "var tokenOutput=`solc --optimize --combined-json abi,bin,interface Token.sol`" > token.js
# Geth Console中
loadScript('token.js')
var tokenContract = web3.eth.contract(JSON.parse(tokenOutput.contracts["Token.sol:Token"].abi))
var initializer = {from: web3.eth.accounts[0], data: "0x" + tokenOutput.contracts["Token.sol:Token"].bin, gas: 300000}
personal.unlockAccount(eth.accounts[0])
var token = tokenContract.new(initializer)
至此,token智能合约就编译完毕了。在Geth Console中输入命令token可以发现此时的token有transactionHash 但是没有address,这是因为此时的token还没有发布成功。
发布智能合约很简单,只需要生成新的区块,就可以把合约发布到链上。命令如下:
miner.start(1)
# Geth Console中
personal.unlockAccount(eth.accounts[0])
token.issue.sendTransaction(eth.accounts[0], 100, {from: eth.accounts[0]});
miner.start(1)
miner.stop()
# Geth Console中
token.transfer(eth.accounts[1], 30, {from: eth.accounts[0]})
miner.start(1)
miner.stop()
# 查看account0的余额
token.getBalance(eth.accounts[0])