准备工作:
1.编译器 solc
2.Geth
3.区块数据存储位置变更(windows ,非必要)
4.合约 (诸如: A 、B )
备注:
solc 我是用的本地node.js 安装的solcjs 。网络版的时常大姨妈。
对应的编译命令:
solcjs --bin question.sol // 二进制
solcjs --abi question.sol // abi
---
Geth 需要在系统环境变量中
开始干活:
1.打开任意位置命令行
2. 配置私链 可参考 翻译
geth init init.json
{
"nonce": "0x0000000000000042",
"mixhash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"difficulty": "0x20000",
"alloc": {},
"coinbase": "0x0000000000000000000000000000000000000000",
"timestamp": "0x00",
"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"extraData": "blossom",
"gasLimit": "0xffffffff"
}
-- 并将日志打入指定文件 -- 2这里可能代表模式表示 后台运行日志?
geth console 2>> D:/EthereumData/Ethereum/devnet/logs/geth.log --dev --rpc
这时候就进入geth的console了
3.合约这里用的是 上面的 A (我把 question 属性类型改成 bytes了 之前的是String)
pragma solidity ^0.4.0;
contract Questions {
//global variables that aren't in a struct
mapping(address => uint) public answers; //integer where 0 means hasn't answered, 1 means yes, 2 means no
bytes question;
address asker;
uint trues;
uint falses;
/// __init__
function questions(bytes _question) public {
asker = msg.sender;
question = _question;
}
//We need a way to validate whether or not they've answered before.
//The default of a mapping is
function answerQuestion (bool _answer) public {
if (answers[msg.sender] == 0 && _answer) { //haven't answered yet
answers[msg.sender] = 1; //they vote true
trues += 1;
}
else if (answers[msg.sender] == 0 && !_answer) {
answers[msg.sender] = 2; //falsity
falses += 1;
}
else if (answers[msg.sender] == 2 && _answer) { // false switching to true
answers[msg.sender] = 1; //true
trues += 1;
falses -= 1;
}
else if (answers[msg.sender] == 1 && !_answer) { // true switching to false
answers[msg.sender] = 2; //falsity
trues -= 1;
falses += 1;
}
}
function getQuestion() public constant returns (bytes, uint, uint, uint) {
return (question, trues, falses, answers[msg.sender]);
}
}
对应的abi 为:
[{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"answers","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_question","type":"bytes"}],"name":"questions","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getQuestion","outputs":[{"name":"","type":"bytes"},{"name":"","type":"uint256"},{"name":"","type":"uint256"},{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_answer","type":"bool"}],"name":"answerQuestion","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"}]
对应的bin为
608060405234801561001057600080fd5b50610705806100206000396000f300608060405260043610610062576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680635e9618e714610067578063a869765a146100be578063eff38f9214610127578063f9e04961146101cc575b600080fd5b34801561007357600080fd5b506100a8600480360381019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506101fb565b6040518082815260200191505060405180910390f35b3480156100ca57600080fd5b50610125600480360381019080803590602001908201803590602001908080601f0160208091040260200160405190810160405280939291908181526020018383808284378201915050505050509192919290505050610213565b005b34801561013357600080fd5b5061013c61026e565b6040518080602001858152602001848152602001838152602001828103825286818151815260200191508051906020019080838360005b8381101561018e578082015181840152602081019050610173565b50505050905090810190601f1680156101bb5780820380516001836020036101000a031916815260200191505b509550505050505060405180910390f35b3480156101d857600080fd5b506101f9600480360381019080803515159060200190929190505050610366565b005b60006020528060005260406000206000915090505481565b33600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550806001908051906020019061026a929190610634565b5050565b6060600080600060016003546004546000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054838054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156103515780601f1061032657610100808354040283529160200191610351565b820191906000526020600020905b81548152906001019060200180831161033457829003601f168201915b50505050509350935093509350935090919293565b60008060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541480156103b15750805b156104105760016000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506001600360008282540192505081905550610631565b60008060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205414801561045c575080155b156104bb5760026000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506001600460008282540192505081905550610630565b60026000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541480156105065750805b156105765760016000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506001600360008282540192505081905550600160046000828254039250508190555061062f565b60016000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541480156105c2575080155b1561062e5760026000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550600160036000828254039250508190555060016004600082825401925050819055505b5b5b5b50565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061067557805160ff19168380011785556106a3565b828001600101855582156106a3579182015b828111156106a2578251825591602001919060010190610687565b5b5090506106b091906106b4565b5090565b6106d691905b808211156106d25760008160009055506001016106ba565b5090565b905600a165627a7a7230582088bb66279f826e4efd502bbbfc2acbac3b299054775e7fff4464485d43b473000029
4.定义合约
abi=[{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"answers","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_question","type":"bytes"}],"name":"questions","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getQuestion","outputs":[{"name":"","type":"bytes"},{"name":"","type":"uint256"},{"name":"","type":"uint256"},{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_answer","type":"bool"}],"name":"answerQuestion","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"}]
contractQ=eth.contract(abi)
5.解锁账户
personal.unlockAccount(eth.coinbase)
默认私链的coinbase 是有点钱的,默认密码为空 直接回车就行了
6.创建并发起合约
transQ=contractQ.new({from:eth.coinbase,data:'0x608060405234801561001057600080fd5b50610705806100206000396000f300608060405260043610610062576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680635e9618e714610067578063a869765a146100be578063eff38f9214610127578063f9e04961146101cc575b600080fd5b34801561007357600080fd5b506100a8600480360381019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506101fb565b6040518082815260200191505060405180910390f35b3480156100ca57600080fd5b50610125600480360381019080803590602001908201803590602001908080601f0160208091040260200160405190810160405280939291908181526020018383808284378201915050505050509192919290505050610213565b005b34801561013357600080fd5b5061013c61026e565b6040518080602001858152602001848152602001838152602001828103825286818151815260200191508051906020019080838360005b8381101561018e578082015181840152602081019050610173565b50505050905090810190601f1680156101bb5780820380516001836020036101000a031916815260200191505b509550505050505060405180910390f35b3480156101d857600080fd5b506101f9600480360381019080803515159060200190929190505050610366565b005b60006020528060005260406000206000915090505481565b33600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550806001908051906020019061026a929190610634565b5050565b6060600080600060016003546004546000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054838054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156103515780601f1061032657610100808354040283529160200191610351565b820191906000526020600020905b81548152906001019060200180831161033457829003601f168201915b50505050509350935093509350935090919293565b60008060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541480156103b15750805b156104105760016000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506001600360008282540192505081905550610631565b60008060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205414801561045c575080155b156104bb5760026000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506001600460008282540192505081905550610630565b60026000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541480156105065750805b156105765760016000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506001600360008282540192505081905550600160046000828254039250508190555061062f565b60016000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541480156105c2575080155b1561062e5760026000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550600160036000828254039250508190555060016004600082825401925050819055505b5b5b5b50565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061067557805160ff19168380011785556106a3565b828001600101855582156106a3579182015b828111156106a2578251825591602001919060010190610687565b5b5090506106b091906106b4565b5090565b6106d691905b808211156106d25760008160009055506001016106ba565b5090565b905600a165627a7a7230582088bb66279f826e4efd502bbbfc2acbac3b299054775e7fff4464485d43b473000029',gas:'4700000'})
data内容就是合约的二进制bin
这时候日志里会有条记录
这时候等待矿工挖矿就行了
7.查询合约发布情况
transReceipt=eth.getTransactionReceipt(transQ.transactionHash)
status 0x1 表示成功 0x0 表示失败 contractAddress就是合约地址
8.通过合约地址获取合约对象
entityQ = contractQ.at(transReceipt.contractAddress)
9.调用合约的查询方法getQuestion()
entityQ.getQuestion()
第一次调用question属性应该为空字节0x 其他都是0
10.通过交易transaction调用合约方法questions
txSend=eth.sendTransaction({"from": eth.coinbase, "to": transReceipt.contractAddress, "data": "0xa869765a00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000014697320636f6e747261637420737563636573733f000000000000000000000000"})
这里说明下简单说下data数据的组成,比较复杂。。0x后面 开始
前4个字节--即前8位 为方法+参数类型的sha3值 questions(bytes)的前八位
后面参数根据参数类型是否是动态或者静态 做不同处理 。动态的先搞个占位符,然后填具体内容。静态的直接填写就行了详见文档
note:
这东西自己搞比较累,不如直接调用方法将结果返回出来。。
获取到合约对象,选择对应的方法questions,调用getData,填写参数 会直接生成需要的data 二进制参数
entityQ.questions.getData("is contract success?")
11.查询交易情况
eth.getTransaction(txSend)
12.查询合约的getQuestion()检查是否变化
entityQ.getQuestion()
这里question属性已经变了,内容就是"is contract success?"的16进制内容。
这表示合约已经调用成功。。
参考文献:
合约文档
solidity文档
示例A 示例B
Geth命令文档
end