启动
启动geth
./geth --datadir ./ethdev --networkid 15 --rpc --rpcport "7545" --rpccorsdomain "*" --port "30303" --nodiscover --rpcapi "db,eth,net,web3" console 2>>console.log
开启账户
不解锁账号,truffle没法部署,表现是打印:
Error: authentication needed: password or unlock
方法:
> my = eth.accounts[0]
"0x1c02d85723be55413a0009d2a813ea51849b35e7"
> personal.unlockAccount(my)
Unlock account 0x1c02d85723be55413a0009d2a813ea51849b35e7
Passphrase:
111
true
personal.newAccount()
personal.newAccount()
eth.getBalance(eth.accounts[1])
eth.sendTransaction({from:my2,to:my1,value:500050000000000000})
##预估部署合约的gas消耗,to地址,应该为全0
eth.estimateGas({from:my,data:"0x00111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111"})
## 以下可以看到,部署的合约越长(data),gas消耗越多,gas字段不影响,另外,每多一个字节,增加 68 gas
> eth.estimateGas({from:my,data:"0x00111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111",gas:11})
56268
> eth.estimateGas({from:my,data:"0x00111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111",gas:111})
56268
> eth.estimateGas({from:my,data:"0x0011111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111122",gas:111})
56336
> eth.estimateGas({from:my,data:"0x001111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111112233",gas:111})
56404
开启挖矿
不开启挖矿,truffle没法部署,表现是一直不动
miner.start(1)
部署失败仍然会消耗gas
部署
truffle migrate --reset
Compiling ./contracts/ownable.sol...
Compiling ./contracts/safemath.sol...
Compiling ./contracts/zombiefactory_bak.sol...
Writing artifacts to ./build/contracts
Using network 'development'.
Running migration: 1_initial_migration.js
Replacing Migrations...
... 0xfb9174d44de5608e3934be7e321cde2860a6491960fcc747b3195ffbd3e8fd70
Migrations: 0xe8c49a9600fa886224a160a503652b832e094c01
Saving successful migration to network...
... 0x8331d1611900ee094f4b38b1b01294099f8c6c6bdd6484b18d18d9c6a1951029
Saving artifacts...
Running migration: 2_deploy_contracts.js
Replacing Ownable...
... 0xaf702e52ab9ea1fa818a3fed1042505069058f0b7c187b4bd41a730e2dcc54c2
Ownable: 0x27f29eb20691f27c8cb19d4921ffeaef0fbe3abd
Replacing ZombieFactory...
... 0xc8d1fe108f0d487d909550ce0e11f4c6c30d3b0ac69d324d42f79e8f4c98938c
ZombieFactory: 0x330318833a083da513dd5a658c42156485e49fe3
Saving successful migration to network...
... 0xc2e52ec4e4b11b05544151bea6ae043243627480b6f10701f887b96d9fafcf08
交互
需要abi,可以通过solc
solc -o . --bin --abi --overwrite zombiefactory.sol
vi zombiefactory.abi
改为:
var zfContract = eth.contract([{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"zombies","outputs":[{"name":"name","type":"string"},{"name":"dna","type":"uint256"},{"name":"level","type":"uint32"},{"name":"readyTime","type":"uint32"},{"name":"winCount","type":"uint16"},{"name":"lossCount","type":"uint16"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"}],"name":"getZombiesByOwner","outputs":[{"name":"","type":"uint256[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"zombieToOwner","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_name","type":"string"}],"name":"createRandomZombie","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"anonymous":false,"inputs":[{"indexed":false,"name":"zombieId","type":"uint256"},{"indexed":false,"name":"name","type":"string"},{"indexed":false,"name":"dna","type":"uint256"}],"name":"NewZombie","type":"event"}]);
然后Loadscript:
loadscript('./zombiefactory.abi')
zf = zfContract.at('0x65101af39e7dc60f1d3badf1be801e7f75ca000a')
> zf.greet()
"hello lex"
> zf.greet.call()
"hello lex"
zf.createRandomZombie.call('lex')
注意,通过call方法进行的调用,智能查看区块链上的信息,但如果要调用合约的方法来改变状态,那么需要通过sendTransaction函数。注意,要同时开启挖矿
zf.setGreeting.sendTransaction('hello sally',{from: my})
zf.greet.call()
"hello sally"
部署合约对gas对消耗
> var simpleContract = eth.contract([{"constant":false,"inputs":[{"name":"_a","type":"uint256"},{"name":"_b","type":"uint256"}],"name":"multiply","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_a","type":"uint256"},{"name":"_b","type":"uint256"}],"name":"arithmetics","outputs":[{"name":"o_sum","type":"uint256"},{"name":"o_product","type":"uint256"}],"payable":false,"type":"function"}])
undefined
> eth.estimateGas({ from: eth.accounts[0],
...... data: "0x6060604052341561000f57600080fd5b5b6101178061001f6000396000f30060606040526000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063165c4a161460475780638c12d8f0146084575b600080fd5b3415605157600080fd5b606e600480803590602001909190803590602001909190505060c8565b6040518082815260200191505060405180910390f35b3415608e57600080fd5b60ab600480803590602001909190803590602001909190505060d6565b604051808381526020018281526020019250505060405180910390f35b600081830290505b92915050565b600080828401915082840290505b92509290505600a165627a7a72305820389009d0e8aec0e9007e8551ca12061194d624aaaf623e9e7e981da7e69b2e090029",
...... gas: 500000
...... })
127229
> eth.getBalance(my1)
1000100000000000000
> eth.gasPrice
18000000000
> 127229 * 18000000000
2290122000000000
> 1000100000000000000 - 2290122000000000
997809878000000000
> personal.unlockAccount(my1)
Unlock account 0x02ada2b218f5dfce2f443cba076f1eed7862db00
Passphrase:
true
> var simple = simpleContract.new(
{ from: eth.accounts[0],
data: "0x6060604052341561000f57600080fd5b5b6101178061001f6000396000f30060606040526000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063165c4a161460475780638c12d8f0146084575b600080fd5b3415605157600080fd5b606e600480803590602001909190803590602001909190505060c8565b6040518082815260200191505060405180910390f35b3415608e57600080fd5b60ab600480803590602001909190803590602001909190505060d6565b604051808381526020018281526020019250505060405180910390f35b600081830290505b92915050565b600080828401915082840290505b92509290505600a165627a7a72305820389009d0e8aec0e9007e8551ca12061194d624aaaf623e9e7e981da7e69b2e090029",
gas: 500000
}
)
undefined
> eth.getBalance(my1)
997809878000000000
> eth.getTransactionReceipt('0xc7890332667e99a8ef58d23d4a8091d66f75cc706dac5ac3bc6083d769f0a83f')
{
blockHash: "0x713d0a980a340894044a3f9a95cfa59740e34e411dcfa056965a81142befe225",
blockNumber: 3767,
contractAddress: "0xc086fb217e3c46a36aaa3c49006eeb37e7aa01a8",
cumulativeGasUsed: 127229,
from: "0x02ada2b218f5dfce2f443cba076f1eed7862db00",
gasUsed: 127229,
logs: [],
logsBloom: "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
root: "0x1243b7d3468d78c73d0e513f3592c827f7ad51013fe2ed281809606e6f8d2b78",
to: null,
transactionHash: "0xc7890332667e99a8ef58d23d4a8091d66f75cc706dac5ac3bc6083d769f0a83f",
transactionIndex: 0
}
>
单位的转换
web3.fromWei('2758428000000000','ether')
"0.002758428"
web3.toWei('1', 'ether');
"1000000000000000000"
web3.toBigNumber('200000000000000000000001');
2.00000000000000000000001e+23
> web3.eth.getBalance(eth.coinbase)
267999999999999999999
> web3.fromWei(web3.eth.getBalance(eth.coinbase),"ether")
267.999999999999999999
查看函数内容
geth里面的语言和javascript很像。并且可以通过toString函数查看函数代码,比如,Contract的new函数是用来部署的:
> simpleContract.new.toString()
"function () {\n /*jshint maxcomplexity: 7 */\n \n var contract = new Contract(this.eth, this.abi);\n\n // parse arguments\n var options = {}; // required!\n var callback;\n\n var args = Array.prototype.slice.call(arguments);\n if (utils.isFunction(args[args.length - 1])) {\n callback = args.pop();\n }\n\n var last = args[args.length - 1];\n if (utils.isObject(last) && !utils.isArray(last)) {\n options = args.pop();\n }\n\n if (options.value > 0) {\n var constructorAbi = abi.filter(function (json) {\n return json.type === 'constructor' && json.inputs.length === args.length;\n })[0] || {};\n\n if (!constructorAbi.payable) {\n throw new Error('Cannot send value to non-payable constructor');\n }\n }\n\n var bytes = encodeConstructorParams(this.abi, args);\n options.data += bytes;\n\n if (callback) {\n\n // wait for the contract address adn check if the code was deployed\n this.eth.sendTransaction(options, function (err, hash) {\n if (err) {\n callback(err);\n } else {\n // add the transaction hash\n contract.transactionHash = hash;\n\n // call callback for the first time\n callback(null, contract);\n\n checkForContractAddress(contract, callback);\n }\n });\n } else {\n var hash = this.eth.sendTransaction(options);\n // add the transaction hash\n contract.transactionHash = hash;\n checkForContractAddress(contract);\n }\n\n return contract;\n }"
部署的回调函数
在使用geth进行智能合约的部署的时,可以放置一个回调函数。注意,这里有个坑,当你使用回调函数的时候,必须先解锁账户。(不使用回调函数时,geth在你执行new函数后,会提示你解锁账户,但使用了回调函数则不会有提示)
> personal.unlockAccount(eth.accounts[1])
Unlock account 0x02ada2b218f5dfce2f443cba076f1eed7862db00
Passphrase:
true
> var myfb = function(e, contract){ if(!e) {
...... if(!contract.address) {
......... console.log("Contract transaction send: TransactionHash: " + contract.transactionHash + " waiting to be mined...");
.........
......... } else {
......... console.log("Contract mined! Address: " + contract.address);
......... console.log(contract);
......... }
......
...... }}
undefined
>
>
>
> var simple = simpleContract.new({from: eth.accounts[1],
data: "0x6060604052341561000f57600080fd5b5b6101178061001f6000396000f30060606040526000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063165c4a161460475780638c12d8f0146084575b600080fd5b3415605157600080fd5b606e600480803590602001909190803590602001909190505060c8565b6040518082815260200191505060405180910390f35b3415608e57600080fd5b60ab600480803590602001909190803590602001909190505060d6565b604051808381526020018281526020019250505060405180910390f35b600081830290505b92915050565b600080828401915082840290505b92509290505600a165627a7a72305820389009d0e8aec0e9007e8551ca12061194d624aaaf623e9e7e981da7e69b2e090029",
gas: 0x100000
}, myfb)
Contract transaction send: TransactionHash: 0x5ea1fd175dc05da1764eebe676c192ee8c78c223ad66159e742bd923349090d6 waiting to be mined...
undefined
> Contract mined! Address: 0x9c951b854d530549423ba10ede4fa83f8fd6f200
[object Object]