multiply_test.sol
,内容如下:pragma solidity 0.4.24;
contract multiply_test {
function mul(uint a) pure public returns (uint) {
return a*12;
}
}
Test.sol
,内容如下:pragma solidity 0.4.24;
contract Test{
string public name;
constructor() public {
name = "lucy";
}
function getName() public view returns (string) {
return name;
}
function setName(string _name) public {
name = _name;
}
}
details
,查看两个智能合约对应的web3 deploy
的内容。multiply_test.sol
的web3 deploy
的内容:var multiply_testContract = web3.eth.contract([{"constant":true,"inputs":[{"name":"a","type":"uint256"}],"name":"mul","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"pure","type":"function"}]);
var multiply_test = multiply_testContract.new(
{
from: web3.eth.accounts[0],
data: '0x608060405234801561001057600080fd5b5060bb8061001f6000396000f300608060405260043610603f576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063131e2f18146044575b600080fd5b348015604f57600080fd5b50606c600480360381019080803590602001909291905050506082565b6040518082815260200191505060405180910390f35b6000600c820290509190505600a165627a7a723058202e8291b99896a921cc82fde46202082fa88f7c1e2bf326d5c368cd4f0f9ce76c0029',
gas: '4700000'
}, function (e, contract){
console.log(e, contract);
if (typeof contract.address !== 'undefined') {
console.log('Contract mined! address: ' + contract.address + ' transactionHash: ' + contract.transactionHash);
}
})
Test.sol
的web3 deploy
的内容:
var testContract = web3.eth.contract([{"constant":true,"inputs":[],"name":"name","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getName","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_name","type":"string"}],"name":"setName","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"inputs":[],"payable":false,"stateMutability":"nonpayable","type":"constructor"}]);
var test = testContract.new(
{
from: web3.eth.accounts[0],
data: '0x608060405234801561001057600080fd5b506040805190810160405280600481526020017f6c756379000000000000000000000000000000000000000000000000000000008152506000908051906020019061005c929190610062565b50610107565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106100a357805160ff19168380011785556100d1565b828001600101855582156100d1579182015b828111156100d05782518255916020019190600101906100b5565b5b5090506100de91906100e2565b5090565b61010491905b808211156101005760008160009055506001016100e8565b5090565b90565b610410806101166000396000f300608060405260043610610057576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806306fdde031461005c57806317d7de7c146100ec578063c47f00271461017c575b600080fd5b34801561006857600080fd5b506100716101e5565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156100b1578082015181840152602081019050610096565b50505050905090810190601f1680156100de5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156100f857600080fd5b50610101610283565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015610141578082015181840152602081019050610126565b50505050905090810190601f16801561016e5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561018857600080fd5b506101e3600480360381019080803590602001908201803590602001908080601f0160208091040260200160405190810160405280939291908181526020018383808284378201915050505050509192919290505050610325565b005b60008054600181600116156101000203166002900480601f01602080910402602001604051908101604052809291908181526020018280546001816001161561010002031660029004801561027b5780601f106102505761010080835404028352916020019161027b565b820191906000526020600020905b81548152906001019060200180831161025e57829003601f168201915b505050505081565b606060008054600181600116156101000203166002900480601f01602080910402602001604051908101604052809291908181526020018280546001816001161561010002031660029004801561031b5780601f106102f05761010080835404028352916020019161031b565b820191906000526020600020905b8154815290600101906020018083116102fe57829003601f168201915b5050505050905090565b806000908051906020019061033b92919061033f565b5050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061038057805160ff19168380011785556103ae565b828001600101855582156103ae579182015b828111156103ad578251825591602001919060010190610392565b5b5090506103bb91906103bf565b5090565b6103e191905b808211156103dd5760008160009055506001016103c5565b5090565b905600a165627a7a723058203ee99201eee4e947f71128a9e8a8f4149ad48ca0d230419e31abb3712f983cf90029',
gas: '4700000'
}, function (e, contract){
console.log(e, contract);
if (typeof contract.address !== 'undefined') {
console.log('Contract mined! address: ' + contract.address + ' transactionHash: ' + contract.transactionHash);
}
})
编译命令如下:
$ solc /home/hadoop/solidity/MyTest.sol --bin --abi --optimize -o ~/solidity
Compiler run successful. Artifact(s) can be found in directory /home/hadoop/solidity.
multiply_test.sol
为例)abi
的内容,即web3 deploy
中web3.eth.contract(xxxx)
中的xxxx
。建议: 不要直接粘贴上图中ABI
的内容,这个内容粘贴出来有换行,需要自己整理,比较麻烦。> abi_mul = [{"constant":true,"inputs":[{"name":"a","type":"uint256"}],"name":"mul","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"pure","type":"function"}]
[{
constant: true,
inputs: [{
name: "a",
type: "uint256"
}],
name: "mul",
outputs: [{
name: "",
type: "uint256"
}],
payable: false,
stateMutability: "pure",
type: "function"
}]
abi
的内容放到web3.eth.contract()
中去,创建合约。可以直接粘贴web3 deploy
中的内容,将具体的abi
改为abi_mul
:> multiply_testContract = web3.eth.contract(abi_mul)
{
abi: [{
constant: true,
inputs: [{...}],
name: "mul",
outputs: [{...}],
payable: false,
stateMutability: "pure",
type: "function"
}],
eth: {
accounts: ["0x4161514855682c94e3cbcb4808eb8766cf889e17", "0xa070a468bfb29e807fa09b2876b543dc2e9f9424", "0xd4c057bbda47d12229f71c474be330d0b1a37780"],
blockNumber: 302,
...
},
at: function(address, callback),
getData: function(),
new: function()
}
bytecode
,也就是web3 deploy
中multiply_testContract.new()
中的data:> mul_data = '0x608060405234801561001057600080fd5b5060bb8061001f6000396000f300608060405260043610603f576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063131e2f18146044575b600080fd5b348015604f57600080fd5b50606c600480360381019080803590602001909291905050506082565b6040518082815260200191505060405180910390f35b6000600c820290509190505600a165627a7a723058202e8291b99896a921cc82fde46202082fa88f7c1e2bf326d5c368cd4f0f9ce76c0029'
"0x608060405234801561001057600080fd5b5060bb8061001f6000396000f300608060405260043610603f576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063131e2f18146044575b600080fd5b348015604f57600080fd5b50606c600480360381019080803590602001909291905050506082565b6040518082815260200191505060405180910390f35b6000600c820290509190505600a165627a7a723058202e8291b99896a921cc82fde46202082fa88f7c1e2bf326d5c368cd4f0f9ce76c0029"
> mul_gasValue = eth.estimateGas({data:mul_data})
102751
web3 deploy
中第二个var的内容,只需要将gas
改为我们计算出来的 mul_gasValue
的值 :> multiply_test = multiply_testContract.new(
{
from: web3.eth.accounts[0],
data: '0x608060405234801561001057600080fd5b5060bb8061001f6000396000f300608060405260043610603f576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063131e2f18146044575b600080fd5b348015604f57600080fd5b50606c600480360381019080803590602001909291905050506082565b6040518082815260200191505060405180910390f35b6000600c820290509190505600a165627a7a723058202e8291b99896a921cc82fde46202082fa88f7c1e2bf326d5c368cd4f0f9ce76c0029',
gas: '102751'
}, function (e, contract){
console.log(e, contract);
if (typeof contract.address !== 'undefined') {
console.log('Contract mined! address: ' + contract.address + ' transactionHash: ' + contract.transactionHash);
}
})
INFO [03-26|10:14:34.627] Setting new local account address=0x4161514855682C94e3CBcb4808eb8766cf889e17
INFO [03-26|10:14:34.627] Submitted contract creation fullhash=0xbeff6afbc46ba3e0a9d7259437359f3a3eb1d462f000604fcf82f6282a113384 contract=0xe2715bcf75AdaF302C0DE53A4beBB5bB9e5FB3e7
null [object Object]
{
abi: [{
constant: true,
inputs: [{...}],
name: "mul",
outputs: [{...}],
payable: false,
stateMutability: "pure",
type: "function"
}],
address: undefined,
transactionHash: "0xbeff6afbc46ba3e0a9d7259437359f3a3eb1d462f000604fcf82f6282a113384"
}
Error: authentication needed: password or unlock undefined
解决办法: 解锁账户
> personal.unlockAccount(eth.accounts[0],"123456",0)
true
② 账户余额不足
Error: insufficient funds for gas * price + value undefined
解决办法: 挖矿
txpool
中有待确认的交易。部署合约的过程实际也是由创建合约的账户发送的一笔交易(即eth.coinbase
账户),需要挖矿进行确认,否则合约实例multiply_test
的address
是undefined
。> txpool.status
{
pending: 1,
queued: 0
}
> miner.start(1)
...
//发现有以下信息,说明合约已经成功部署。
Contract mined! address: 0xe2715bcf75adaf302c0de53a4bebb5bb9e5fb3e7 transactionHash: 0xbeff6afbc46ba3e0a9d7259437359f3a3eb1d462f000604fcf82f6282a113384
multiply_test.address
属性,发现就是合约部署成功的提示信息中address
。这个合约地址可以记录到你的文件夹中,方便以后使用智能合约时,输入对应的合约地址!eth.accounts[0]
去调用已经部署好的智能合约,搞了一个晚上,人家说地址不会自己都没反应过来。。。。> multiply_test.address
"0xe2715bcf75adaf302c0de53a4bebb5bb9e5fb3e7"
multiply_test
去调用智能合约> multiply_test.mul(12)
144
abi
去调用智能合约(在另外一个节点上测试)//abi_mul的定义如上,不再赘述
//使用eth.contract(abi_mul)获取合约对象,at(multiply_test.address)实例化合约
> mul_contract = eth.contract(abi_mul).at("0xe2715bcf75adaf302c0de53a4bebb5bb9e5fb3e7")
{
abi: [{
constant: true,
inputs: [{...}],
name: "mul",
outputs: [{...}],
payable: false,
stateMutability: "pure",
type: "function"
}],
address: "0xe2715bcf75adaf302c0de53a4bebb5bb9e5fb3e7",
transactionHash: null,
allEvents: function(),
mul: function()
}
//调用合约实现乘法计算
> mul_contract.mul(5)
60
合约地址
!!!!不然报错如下:Error: new BigNumber() not a base 16 number:
...
参考链接:
【区块链】记录合约开发中遇到的坑
Error: new BigNumber() not a base 16 number
What does the Web3 “BigNumber not a base 16 number Error” mean
multiply_test.sol
一样,不再赘述。> abi_test=[{"constant":true,"inputs":[],"name":"name","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getName","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_name","type":"string"}],"name":"setName","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"inputs":[],"payable":false,"stateMutability":"nonpayable","type":"constructor"}]
> testContract = web3.eth.contract(abi_test)
> test_data='0x608060405234801561001057600080fd5b506040805190810160405280600481526020017f6c756379000000000000000000000000000000000000000000000000000000008152506000908051906020019061005c929190610062565b50610107565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106100a357805160ff19168380011785556100d1565b828001600101855582156100d1579182015b828111156100d05782518255916020019190600101906100b5565b5b5090506100de91906100e2565b5090565b61010491905b808211156101005760008160009055506001016100e8565b5090565b90565b610410806101166000396000f300608060405260043610610057576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806306fdde031461005c57806317d7de7c146100ec578063c47f00271461017c575b600080fd5b34801561006857600080fd5b506100716101e5565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156100b1578082015181840152602081019050610096565b50505050905090810190601f1680156100de5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156100f857600080fd5b50610101610283565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015610141578082015181840152602081019050610126565b50505050905090810190601f16801561016e5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561018857600080fd5b506101e3600480360381019080803590602001908201803590602001908080601f0160208091040260200160405190810160405280939291908181526020018383808284378201915050505050509192919290505050610325565b005b60008054600181600116156101000203166002900480601f01602080910402602001604051908101604052809291908181526020018280546001816001161561010002031660029004801561027b5780601f106102505761010080835404028352916020019161027b565b820191906000526020600020905b81548152906001019060200180831161025e57829003601f168201915b505050505081565b606060008054600181600116156101000203166002900480601f01602080910402602001604051908101604052809291908181526020018280546001816001161561010002031660029004801561031b5780601f106102f05761010080835404028352916020019161031b565b820191906000526020600020905b8154815290600101906020018083116102fe57829003601f168201915b5050505050905090565b806000908051906020019061033b92919061033f565b5050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061038057805160ff19168380011785556103ae565b828001600101855582156103ae579182015b828111156103ad578251825591602001919060010190610392565b5b5090506103bb91906103bf565b5090565b6103e191905b808211156103dd5760008160009055506001016103c5565b5090565b905600a165627a7a723058203ee99201eee4e947f71128a9e8a8f4149ad48ca0d230419e31abb3712f983cf90029'
> test_gasValue = eth.estimateGas({data:test_data})
363932
> test = testContract.new(
... {
...... from: web3.eth.accounts[0],
...... data: '0x608060405234801561001057600080fd5b506040805190810160405280600481526020017f6c756379000000000000000000000000000000000000000000000000000000008152506000908051906020019061005c929190610062565b50610107565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106100a357805160ff19168380011785556100d1565b828001600101855582156100d1579182015b828111156100d05782518255916020019190600101906100b5565b5b5090506100de91906100e2565b5090565b61010491905b808211156101005760008160009055506001016100e8565b5090565b90565b610410806101166000396000f300608060405260043610610057576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806306fdde031461005c57806317d7de7c146100ec578063c47f00271461017c575b600080fd5b34801561006857600080fd5b506100716101e5565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156100b1578082015181840152602081019050610096565b50505050905090810190601f1680156100de5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156100f857600080fd5b50610101610283565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015610141578082015181840152602081019050610126565b50505050905090810190601f16801561016e5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561018857600080fd5b506101e3600480360381019080803590602001908201803590602001908080601f0160208091040260200160405190810160405280939291908181526020018383808284378201915050505050509192919290505050610325565b005b60008054600181600116156101000203166002900480601f01602080910402602001604051908101604052809291908181526020018280546001816001161561010002031660029004801561027b5780601f106102505761010080835404028352916020019161027b565b820191906000526020600020905b81548152906001019060200180831161025e57829003601f168201915b505050505081565b606060008054600181600116156101000203166002900480601f01602080910402602001604051908101604052809291908181526020018280546001816001161561010002031660029004801561031b5780601f106102f05761010080835404028352916020019161031b565b820191906000526020600020905b8154815290600101906020018083116102fe57829003601f168201915b5050505050905090565b806000908051906020019061033b92919061033f565b5050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061038057805160ff19168380011785556103ae565b828001600101855582156103ae579182015b828111156103ad578251825591602001919060010190610392565b5b5090506103bb91906103bf565b5090565b6103e191905b808211156103dd5760008160009055506001016103c5565b5090565b905600a165627a7a723058203ee99201eee4e947f71128a9e8a8f4149ad48ca0d230419e31abb3712f983cf90029',
...... gas: '363932'
...... }, function (e, contract){
...... console.log(e, contract);
...... if (typeof contract.address !== 'undefined') {
......... console.log('Contract mined! address: ' + contract.address + ' transactionHash: ' + contract.transactionHash);
......... }
...... })
Contract mined! address: 0x172afbdc1ff6ffbd985501240aa319178547fc01 transactionHash: 0xa0ea14ca8be7bfefbce2d50116f5d701e7ed911b32f811a782deeb484c21d94e
写操作要消耗gas,读操作不用
。因为写操作需要通过矿工对链做出更改和同步,有代价。这就是为什么getName()
可以直接得到结果,而setName()
需要指定付款账户并挖矿确认。> test.getName()
"lucy"
//每次调用set时顺便指定付款账户,这种方法适用于每个账户都经常使用的多账户节点。
> test.setName("john",{from:eth.accounts[0]})
INFO [03-26|11:26:55.527] Submitted transaction fullhash=0x8a8b1f254de9e96383d845b2da7009e1c62248e84fb2ff3317471dd2a3176cc3 recipient=0x50ce18662C13d61EA3e10709A896124E6a1A13D7
"0x8a8b1f254de9e96383d845b2da7009e1c62248e84fb2ff3317471dd2a3176cc3"
//通过挖矿让写操作生效
> miner.start(1)
...
> test.getName()
"john"
如果不指定付款账户,报错:
> test.setName("tiger")
Error: invalid address
at web3.js:3930:15
at web3.js:3756:20
at web3.js:5025:28
at map (<native code>)
at web3.js:5024:12
at web3.js:5050:18
at web3.js:5075:23
at web3.js:4137:16
at apply (<native code>)
at web3.js:4223:16
参考链接:
6分钟以太坊实战系列-以太坊私有链搭建及智能合约部署——gas的估计
区块链学习(2) 智能合约部署到以太坊私有链并交互(mac版)
以太坊搭建私有链和部署智能合约