Windows环境下,如何通过离线签名的方式在以太坊控制台中创建和调用智能合约

在Windows环境下,如何通过以太坊控制台console的方式创建和调用智能合约?具体步骤如下:

(1) 使用solc.exe编译智能合约

solc.exe是Windows环境下用来编译solidity智能合约的一个C ++实现的Solidity语言编译器。我们可以从https://github.com/ethereum/solidity/releases下载对应solidity语言版本的solc的Windows二进制文件。

这里使用的solc版本是0.4.25,对应使用的solidity语言版本也是0.4.25。在Windows上安装solc的过程很简单,直接下载solidity-windows_0.4.25.zip,然后解压就可以了,假设解压到E:\tools目录。

我们测试使用的智能合约内容如下:

pragma solidity >=0.4.22 <0.6.6;

contract Test{
    address creator;
    int i;
    constructor() public {
        creator = msg.sender;
        i =100;
    }
    
	function get() view public returns (int) {
        return i;
    }
	
	function set(int v) public returns (int){
        	i = v;
		return i;
    }
	
	function getCreator() view public returns (address) {
        return creator;
    }

}

是不是很简单

编译solidity智能合约test.sol
在Windows命令窗口中运行命令
E:\tools\solidity-windows_0.4.25\solc.exe test.sol --abi --bin -o ./

会在当前目录下生成Test.abi文件和Test.bin文件

Test.abi文件的内容:

[{“constant”:true,“inputs”:[],“name”:“getCreator”,“outputs”:[{“name”:"",“type”:“address”}],“payable”:false,“stateMutability”:“view”,“type”:“function”},{“constant”:true,“inputs”:[],“name”:“get”,“outputs”:[{“name”:"",“type”:“int256”}],“payable”:false,“stateMutability”:“view”,“type”:“function”},{“constant”:false,“inputs”:[{“name”:“v”,“type”:“int256”}],“name”:“set”,“outputs”:[{“name”:"",“type”:“int256”}],“payable”:false,“stateMutability”:“nonpayable”,“type”:“function”},{“inputs”:[],“payable”:false,“stateMutability”:“nonpayable”,“type”:“constructor”}]

Test.bin文件的内容:
608060405234801561001057600080fd5b50336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506064600181905550610191806100686000396000f300608060405260043610610057576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680630ee2cb101461005c5780636d4ce63c146100b3578063e5c19b2d146100de575b600080fd5b34801561006857600080fd5b5061007161011f565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b3480156100bf57600080fd5b506100c8610148565b6040518082815260200191505060405180910390f35b3480156100ea57600080fd5b5061010960048036038101908080359060200190929190505050610152565b6040518082815260200191505060405180910390f35b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6000600154905090565b60008160018190555060015490509190505600a165627a7a723058206b394cc395e0928a98ee6e2b64da40a21db6a189f9a2429f57536e25e50c6dbf0029

(2)在以太坊私链上部署智能合约

如何搭建以太坊私链,见本人的其它文章。这里不详述
打开以太坊控制台,在Windows命令窗口中运行命令:
geth attach ipc:\.\pipe\geth.ipc

这样就打开以太坊控制台,也就是以太坊的JavaScript console。

部署智能合约有多种方法,这里介绍通过接口signTransaction()和离线签名交易接口sendRawTransaction()来合约

a)通过离线签名接口signTransaction()对智能合约内容进行离线签名
eth.signTransaction({
nonce: 1,
gasPrice: ‘10000000000000’,
gas: ‘1000000’,
from:“0x815261DC4186502eC0D8CCFEf163785e1617b5A8”,
to: ‘0x0000000000000000000000000000000000000000’,
value: ‘0x00’,
data: ‘0x608060405234801561001057600080fd5b50336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506064600181905550610191806100686000396000f300608060405260043610610057576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680630ee2cb101461005c5780636d4ce63c146100b3578063e5c19b2d146100de575b600080fd5b34801561006857600080fd5b5061007161011f565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b3480156100bf57600080fd5b506100c8610148565b6040518082815260200191505060405180910390f35b3480156100ea57600080fd5b5061010960048036038101908080359060200190929190505050610152565b6040518082815260200191505060405180910390f35b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6000600154905090565b60008160018190555060015490509190505600a165627a7a723058206b394cc395e0928a98ee6e2b64da40a21db6a189f9a2429f57536e25e50c6dbf0029’
})

b)通过离线签名交易接口sendRawTransaction()发布智能合约

personal.unlockAccount(“0x815261DC4186502eC0D8CCFEf163785e1617b5A8”, “111”, 0)
true

eth.signTransaction({
… nonce: 8,
… gasPrice: ‘10000000000000’,
… gas: ‘1000000’,
… from:“0x815261DC4186502eC0D8CCFEf163785e1617b5A8”,
… data: ‘0x608060405234801561001057600080fd5b50336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506064600181905550610191806100686000396000f300608060405260043610610057576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680630ee2cb101461005c5780636d4ce63c146100b3578063e5c19b2d146100de575b600080fd5b34801561006857600080fd5b5061007161011f565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b3480156100bf57600080fd5b506100c8610148565b6040518082815260200191505060405180910390f35b3480156100ea57600080fd5b5061010960048036038101908080359060200190929190505050610152565b6040518082815260200191505060405180910390f35b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6000600154905090565b60008160018190555060015490509190505600a165627a7a723058206b394cc395e0928a98ee6e2b64da40a21db6a189f9a2429f57536e25e50c6dbf0029’
… })
{
raw: “0xf90291088609184e72a000830f42408080b901f9608060405234801561001057600080fd5b50336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506064600181905550610191806100686000396000f300608060405260043610610057576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680630ee2cb101461005c5780636d4ce63c146100b3578063e5c19b2d146100de575b600080fd5b34801561006857600080fd5b5061007161011f565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b3480156100bf57600080fd5b506100c8610148565b6040518082815260200191505060405180910390f35b3480156100ea57600080fd5b5061010960048036038101908080359060200190929190505050610152565b6040518082815260200191505060405180910390f35b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6000600154905090565b60008160018190555060015490509190505600a165627a7a723058206b394cc395e0928a98ee6e2b64da40a21db6a189f9a2429f57536e25e50c6dbf00298201dfa05d9c96842bf5dfdd243691dc7306b8820dc8d7d39b11cb8964a0106721ddc89aa0f423d4274d85dee9dbe2a8830b3e6bc4f363f67b1b5ba80ea7b07005fa387725a0a45a909bbbfe4ed27ec9ad98c41bac220e8cd6aac7e860ed23e2185128d6cf13a088642f0cc9f37afd8d0923871773f52ae314bdd060be7625a9c3f4793aac3557”,
tx: {
gas: “0xf4240”,
gasPrice: “0x9184e72a000”,
hash: “0xb78107043d9da7d037f37bf114986cb777a795082050645993c87742a764f0d5”,
input: “0x608060405234801561001057600080fd5b50336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506064600181905550610191806100686000396000f300608060405260043610610057576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680630ee2cb101461005c5780636d4ce63c146100b3578063e5c19b2d146100de575b600080fd5b34801561006857600080fd5b5061007161011f565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b3480156100bf57600080fd5b506100c8610148565b6040518082815260200191505060405180910390f35b3480156100ea57600080fd5b5061010960048036038101908080359060200190929190505050610152565b6040518082815260200191505060405180910390f35b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6000600154905090565b60008160018190555060015490509190505600a165627a7a723058206b394cc395e0928a98ee6e2b64da40a21db6a189f9a2429f57536e25e50c6dbf0029”,
nonce: “0x8”,
r: “0x5d9c96842bf5dfdd243691dc7306b8820dc8d7d39b11cb8964a0106721ddc89a”,
s: “0xf423d4274d85dee9dbe2a8830b3e6bc4f363f67b1b5ba80ea7b07005fa387725”,
to: null,
v: “0x1df”,
value: “0x0”
}
}
eth.sendRawTransaction(“0xf90291088609184e72a000830f42408080b901f9608060405234801561001057600080fd5b50336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506064600181905550610191806100686000396000f300608060405260043610610057576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680630ee2cb101461005c5780636d4ce63c146100b3578063e5c19b2d146100de575b600080fd5b34801561006857600080fd5b5061007161011f565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b3480156100bf57600080fd5b506100c8610148565b6040518082815260200191505060405180910390f35b3480156100ea57600080fd5b5061010960048036038101908080359060200190929190505050610152565b6040518082815260200191505060405180910390f35b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6000600154905090565b60008160018190555060015490509190505600a165627a7a723058206b394cc395e0928a98ee6e2b64da40a21db6a189f9a2429f57536e25e50c6dbf00298201dfa05d9c96842bf5dfdd243691dc7306b8820dc8d7d39b11cb8964a0106721ddc89aa0f423d4274d85dee9dbe2a8830b3e6bc4f363f67b1b5ba80ea7b07005fa387725a0a45a909bbbfe4ed27ec9ad98c41bac220e8cd6aac7e860ed23e2185128d6cf13a088642f0cc9f37afd8d0923871773f52ae314bdd060be7625a9c3f4793aac3557”)
“0xb78107043d9da7d037f37bf114986cb777a795082050645993c87742a764f0d5”

c)获取智能合约的地址

eth.getTransaction(“0xb78107043d9da7d037f37bf114986cb777a795082050645993c87742a764f0d5”)
{
blockHash: “0xb84da7abd9194577da60f2e6cba0097a9b806cda231ee61d383ee74bbcf31f54”,
blockNumber: 24842,
from: “0x815261dc4186502ec0d8ccfef163785e1617b5a8”,
gas: 1000000,
gasPrice: 10000000000000,
hash: “0xb78107043d9da7d037f37bf114986cb777a795082050645993c87742a764f0d5”,
input: “0x608060405234801561001057600080fd5b50336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506064600181905550610191806100686000396000f300608060405260043610610057576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680630ee2cb101461005c5780636d4ce63c146100b3578063e5c19b2d146100de575b600080fd5b34801561006857600080fd5b5061007161011f565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b3480156100bf57600080fd5b506100c8610148565b6040518082815260200191505060405180910390f35b3480156100ea57600080fd5b5061010960048036038101908080359060200190929190505050610152565b6040518082815260200191505060405180910390f35b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6000600154905090565b60008160018190555060015490509190505600a165627a7a723058206b394cc395e0928a98ee6e2b64da40a21db6a189f9a2429f57536e25e50c6dbf0029”,
nonce: 8,
r: “0x5d9c96842bf5dfdd243691dc7306b8820dc8d7d39b11cb8964a0106721ddc89a”,
s: “0xf423d4274d85dee9dbe2a8830b3e6bc4f363f67b1b5ba80ea7b07005fa387725”,
to: null,
transactionIndex: 0,
v: “0x1df”,
value: 0,
}

通过getTransaction()可以看到智能合约已经打包进区块链了

eth.getTransactionReceipt(“0xb78107043d9da7d037f37bf114986cb777a795082050645993c87742a764f0d5”)
{
blockHash: “0xb84da7abd9194577da60f2e6cba0097a9b806cda231ee61d383ee74bbcf31f54”,
blockNumber: 24842,
contractAddress: “0x25cd1b80e228b357c9c0cfa4730f088317d6bf2c”,
cumulativeGasUsed: 204301,
from: “0x815261dc4186502ec0d8ccfef163785e1617b5a8”,
gasUsed: 204301,
logs: [],
logsBloom: “0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000”,
status: “0x1”,
to: null,
transactionHash: “0xb78107043d9da7d037f37bf114986cb777a795082050645993c87742a764f0d5”,
transactionIndex: 0
}

通过getTransactionReceipt()可以看到智能合约的地址,上面红色部分就是合约地址

(3)在以太坊私链上调用智能合约

a)先在以太坊控制台定义abi接口,也就是Test.abi里的内容

abi=[{“constant”:true,“inputs”:[],“name”:“getCreator”,“outputs”:[{“name”:"",“type”:“address”}],“payable”:false,“stateMutability”:“view”,“type”:“function”},{“constant”:true,“inputs”:[],“name”:“get”,“outputs”:[{“name”:"",“type”:“int256”}],“payable”:false,“stateMutability”:“view”,“type”:“function”},{“constant”:false,“inputs”:[{“name”:“v”,“type”:“int256”}],“name”:“set”,“outputs”:[{“name”:"",“type”:“int256”}],“payable”:false,“stateMutability”:“nonpayable”,“type”:“function”},{“inputs”:[],“payable”:false,“stateMutability”:“nonpayable”,“type”:“constructor”}]
[{
constant: true,
inputs: [],
name: “getCreator”,
outputs: [{
name: “”,
type: “address”
}],
payable: false,
stateMutability: “view”,
type: “function”
}, {
constant: true,
inputs: [],
name: “get”,
outputs: [{
name: “”,
type: “int256”
}],
payable: false,
stateMutability: “view”,
type: “function”
}, {
constant: false,
inputs: [{
name: “v”,
type: “int256”
}],
name: “set”,
outputs: [{
name: “”,
type: “int256”
}],
payable: false,
stateMutability: “nonpayable”,
type: “function”
}, {
inputs: [],
payable: false,
stateMutability: “nonpayable”,
type: “constructor”
}]

b)指定合约地址

run=eth.contract(abi).at(“0x25cd1b80e228b357c9c0cfa4730f088317d6bf2c”)
{
abi: [{
constant: true,
inputs: [],
name: “getCreator”,
outputs: [{…}],
payable: false,
stateMutability: “view”,
type: “function”
}, {
constant: true,
inputs: [],
name: “get”,
outputs: [{…}],
payable: false,
stateMutability: “view”,
type: “function”
}, {
constant: false,
inputs: [{…}],
name: “set”,
outputs: [{…}],
payable: false,
stateMutability: “nonpayable”,
type: “function”
}, {
inputs: [],
payable: false,
stateMutability: “nonpayable”,
type: “constructor”
}],
address: “0x25cd1b80e228b357c9c0cfa4730f088317d6bf2c”,
transactionHash: null,
allEvents: function(),
get: function(),
getCreator: function(),
set: function()
}

c)调用合约里的函数
关于以太坊智能合约中函数的调用方法,可以参考这篇文章https://www.jianshu.com/p/f33df6fb3ce4

下面直接给出例子:

如调用合约里的get()函数

run.get()
100
run.get.call()
100

run.set.call(200)
200
这里调用set()函数调用虽然成功,但实际上i的值仍然是100。应该是需要发起交易写入区块链才能成功,因为需要改变存储变量的值。

以下这种方式调用不成功

run.set(200)
Error: invalid address
at web3.js:3930:11(47)
at web3.js:3756:41(16)
at web3.js:5025:37(8)
at web3.js:5024:12(13)
at web3.js:5050:34(20)
at web3.js:5075:39(15)
at web3.js:4137:41(57)
at web3.js:4223:75(24)
at :1:9(3)

要成功调用合约中函数,需要这样调用:

run.set.sendTransaction(200, {from:eth.accounts[0]})
“0x76d0aa03fde4698f72a79dc075d2ed2118173cb1880d98c6090c58782a9d7523”
run.get()
200

可以看到,合约中i的值已被成功赋值为200。{from:eth.accounts[0]}表示发起交易时由哪个账号支付手续费,这里是钱包列表里的第一个账号,前提当然是要拥有该账户的私钥并解锁该账户才行。

run.getCreator()
“0x815261dc4186502ec0d8ccfef163785e1617b5a8”

除了合约里自定义的函数外,我们还可以调用合约里默认的一些接口函数,如:

run.address
“0x25cd1b80e228b357c9c0cfa4730f088317d6bf2c”

我的csdn:https://blog.csdn.net/powervip
我的知乎: https://www.zhihu.com/people/powervip
我的腾讯微云网盘:https://share.weiyun.com/5qT0TvG

如果你觉得这篇文章写得还可以,请帮忙点个赞,谢谢!
你的鼓励,我的动力!

猜你喜欢

转载自blog.csdn.net/powervip/article/details/107234720