网上已有很多相关教程,但由于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.nodeInfo
miner.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.blockNumber
eth.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
函数可以向其他账号发送token
getBalance
函数可以获取某个账号的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])