一个简单的智能合约发布与调用(以太坊)
geth版本 1.5.4
首先进入控制台
geth --datadir data console
1.定义合约
source='contract demo{function hellworld()constant returns (string){return "helloworld";}}'回车
"contract demo{function hellworld()constant returns (string){return \"helloworld\";}}"
2.编译合约
compiled=web3.eth.compile.solidity(source);
回车
{ demo: { code: "0x606060405260ce8060106000396000f3606060405260e060020a60003504636992e1048114601c575b6002565b34600257604080516020808201835260009091528151808301909252600a82527f68656c6c6f776f726c64000000000000000000000000000000000000000000009082015260405180806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600302600f01f150905090810190601f16801560c05780820380516001836020036101000a031916815260200191505b509250505060405180910390f3", info: { abiDefinition: [{...}],!!!!!应用程序二进制接口定义 compilerOptions: "--combined-json bin,abi,userdoc,devdoc --add-std --optimize", compilerVersion: "0.4.4", developerDoc: { methods: {} }, language: "Solidity", languageVersion: "0.4.4", source: "contract demo{function hellworld()constant returns (string){return \"helloworld\";}}", userDoc: { methods: {} } } } }
3.部署合约
(1)contract=web3.eth.contract(compiled.demo.info.abiDefinition);
回车
{ abi: [{ constant: true, inputs: [], name: "hellworld", outputs: [{...}], payable: false, type: "function" }], eth: { accounts: ["0xc37ef8ef496ab16f406705ed5b22db40dbafb43a", "0x18016fbcafb6c430c6f0620bc40288748325f5e6", "0xf302f246c4f3bac89c197caaa7135c73b95d223e"], blockNumber: 57, coinbase: "0xc37ef8ef496ab16f406705ed5b22db40dbafb43a", compile: { lll: function(), serpent: function(), solidity: function() }, defaultAccount: undefined, defaultBlock: "latest", gasPrice: 20000000000, hashrate: 0, mining: false, pendingTransactions: [], syncing: false, call: function(), contract: function(abi), estimateGas: function(), filter: function(fil, callback), getAccounts: function(callback), getBalance: function(), getBlock: function(), getBlockNumber: function(callback), getBlockTransactionCount: function(), getBlockUncleCount: function(), getCode: function(), getCoinbase: function(callback), getCompilers: function(), getGasPrice: function(callback), getHashrate: function(callback), getMining: function(callback), getNatSpec: function(), getPendingTransactions: function(callback), getRawTransaction: function(), getRawTransactionFromBlock: function(), getStorageAt: function(), getSyncing: function(callback), getTransaction: function(), getTransactionCount: function(), getTransactionFromBlock: function(), getTransactionReceipt: function(), getUncle: function(), getWork: function(), iban: function(iban), icapNamereg: function(), isSyncing: function(callback), namereg: function(), resend: function(), sendIBANTransaction: function(), sendRawTransaction: function(), sendTransaction: function(), sign: function(), signTransaction: function(), submitTransaction: function(), submitWork: function() }, at: function(address, callback), getData: function(), new: function() }
要在区块链上创建一个合约,要把以太坊虚拟机代码作为数据给空地址发送交易。需要准备一个有余额并激活的以太坊账户。
(2)解锁账户
1.address=eth.accounts[0]
回车
"0xc37ef8ef496ab16f406705ed5b22db40dbafb43a"
2.personal.unlockAccount(address)
回车
Unlock account 0xc37ef8ef496ab16f406705ed5b22db40dbafb43a Passphrase: true
(3) demo=contract.new({from:web3.eth.accounts[0],data:compiled.demo.code, gas:1000000});
回车
I1208 10:21:06.949018 internal/ethapi/api.go:1045] Tx(0x678f09c4574956594a8121e82086a7968c5500ba3fad6be84ea9d8aeadcd7de9) created: !!!!!!!!!!!!!!!!这个是合约部署的交易地址) 0x33f6aab95fa3f799fcf9770adb496214868cf50b { abi: [{ constant: true, inputs: [], name: "hellworld", outputs: [{...}], payable: false, type: "function" }], address: undefined, transactionHash: "0x678f09c4574956594a8121e82086a7968c5500ba3fad6be84ea9d8aeadcd7de9" }
4.查看合约
demo
回车
{ abi: [{ constant: true, inputs: [], name: "hellworld", outputs: [{...}], payable: false, type: "function" }], address: undefined,!!!!!!没有挖矿之前这里是空的 transactionHash: "0x678f09c4574956594a8121e82086a7968c5500ba3fad6be84ea9d8aeadcd7de9" !!!!!!这个就是上边那个tx }
5.启动挖矿
miner.start()
回车
I1208 10:22:39.958538 eth/backend.go:473] Automatic pregeneration of ethash DAG ON (ethash dir: /Users/zhangyunlong/.ethash) I1208 10:22:39.958595 miner/miner.go:137] Starting mining operation (CPU=4 TOT=5) I1208 10:22:39.958666 eth/backend.go:480] checking DAG (ethash dir: /Users/zhangyunlong/.ethash) true
I1208 10:22:39.962889 miner/worker.go:548] commit new work on block 58 with 1 txs & 0 uncles. !!!!!!!!!!!在第58块区块上进行了一笔交易
Took 4.232035ms
I1208 10:22:39.963042
vendor/github.com/ethereum/ethash/ethash.go:259] Generating DAG for epoch 0 (size 1073739904) (0000000000000000000000000000000000000000000000000000000000000000)
I1208 10:22:41.040059 vendor/github.com/ethereum/ethash/ethash.go:276] Done generating DAG for epoch 0, it took 1.077030202s
I1208 10:22:51.893403 miner/worker.go:347] 🔨 Mined block (#58 / 0c497722). Wait 5 blocks for confirmation
I1208 10:22:51.894392 miner/worker.go:548] commit new work on block 59 with 0 txs & 0 uncles. Took 180.071µs
I1208 10:22:51.898869 miner/worker.go:347] 🔨 Mined block (#58 / 66c3a6cc). Wait 5 blocks for confirmation
I1208 10:22:51.903851 miner/worker.go:347] 🔨 Mined stale block (#58 / bab1ae53).
I1208 10:22:51.904707 miner/worker.go:548] commit new work on block 59 with 0 txs & 1 uncles. Took 192.952µs
I1208 10:22:52.477529 miner/worker.go:347] 🔨 Mined block (#59 / 4f08eef3). Wait 5 blocks for confirmation
I1208 10:22:52.477902 miner/worker.go:548] commit new work on block 60 with 0 txs & 0 uncles. Took 230.781µs
6.停止挖矿
miner.stop()
回车
true
备注:挖矿的输出会一直跑,可能来不及输入完miner.stop(),不用担心,只要完全输入miner.stop()后,就会停止
7.合约被写进区块链之后就可以去调用这个合约了
console.log(demo.hellworld());
回车
helloworld undefined
或者
demo.hellworld()
回车
"helloworld"
也可以通过abi来调用
g=eth.contract(abi).at(address)
abi等于demo里面abi里面的信息
address是demo里面的
address: "0x33f6aab95fa3f799fcf9770adb496214868cf50b",
g.hellworld()
回车
"helloworld"
理论上是这样子呀,,但是我没有成功(ps 看我的另外一个代币合约发布的文章,里面写了怎么调用函数,这个我就不弄啦)
`
var avi=[{contant:true,inputs:[],name:"hellworld",outputs:[{name:"helloworld",type:"string"}],payable:false,type:"function"}];
输出undefined
var address= "0x33f6aab95fa3f799fcf9770adb496214868cf50b";
输出undefined
var g=eth.contract(avi).at(address);
undefined
g.hellworld()
Error: invalid address
at web3.js:3887:15
at web3.js:3713:20
at web3.js:4939:28
at map (<native code>)
at web3.js:4938:12
at web3.js:4964:18
at web3.js:4989:23
at web3.js:4055:16
at apply (<native code>)
at web3.js:4141:16
`
8.看一下合约附加在交易上是什么样的
eth.getTransaction("0x678f09c4574956594a8121e82086a7968c5500ba3fad6be84ea9d8aeadcd7de9");
回车
{ blockHash: "0x66c3a6cc00425ed554b5e75b67bd3dfdb623fa48ed4520f8c5aa07f10f062bab", blockNumber: 58, from: "0xc37ef8ef496ab16f406705ed5b22db40dbafb43a", gas: 1000000, gasPrice: 20000000000, hash: "0x678f09c4574956594a8121e82086a7968c5500ba3fad6be84ea9d8aeadcd7de9", input: "0x606060405260ce8060106000396000f3606060405260e060020a60003504636992e1048114601c575b6002565b34600257604080516020808201835260009091528151808301909252600a82527f68656c6c6f776f726c64000000000000000000000000000000000000000000009082015260405180806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600302600f01f150905090810190601f16801560c05780820380516001836020036101000a031916815260200191505b509250505060405180910390f3", nonce: 1, r: "0x708ec2e734557e8b4a74b23713fe7748e909bd204a5077940a487199e5d1fa5c", s: "0x5123e3e53ea8014ad10892289c34f5e8d910f413ee04afa045e61137eb6d35", to: null,!!!! transactionIndex: 0,!!!!!!这一条交易没有接收方和转账金额,只是为了更清楚的理解合约是以什么样的方式部署到区块链网络上的 v: "0x1b", value: 0 }