【BlockChain】 调用智能合约的方法

前言

  本文主要讲调用已部署的智能合约的几种方法,以Capture The Ether网站为例,调用测试链为Ropsten。

使用remix-ide

  remix-ideBrowser-Only Solidity IDE and Runtime Environment。能够帮助我们调试合约代码。在本地搭建好后可以直接使用浏览器打开访问。

  这里以CTE里的一道题为例子




  代码如下:
1
2
3
4
5
6
7
8
9
pragma solidity ^0.4.21;

contract CallMeChallenge {
bool public isComplete = false;

function callme() public {
isComplete = true;
}
}

  目的是调用ropsten里的callme。

  点击开始后会得到一个合约地址:




  我们把代码放到remix-ide里,并进行编译




  在Run标签栏里,填好所需的信息,如环境,合约地址,最后能看到在ropsten里部署好的合约:




  点击callme,在console里会输出log信息,并给出是否成功。




  此时,回到题目,点击检查。即可通过这关。

  使用remix-ide只能满足简单的交互要求,如果交互频繁,则可以选择更为灵活的代码实现。

web3py

  web3py是web3.js在python上的实现,可以使用pip安装:

1
pip install web3

  一个使用web3py简单交互的代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68

# -*- coding:utf-8 -*-

from web3 import Web3, HTTPProvider
from web3.contract import ConciseContract
from web3.eth import Eth

false = False
true = True
config = {
"abi": [
{
"constant": false,
"inputs": [],
"name": "callme",
"outputs": [],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
},
{
"constant": true,
"inputs": [],
"name": "isComplete",
"outputs": [
{
"name": "",
"type": "bool"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
}
],
"address": "0x1933fEa88E2295e7b7A5523A86CE69742794DaA8" # 合约地址
}

INFURA_API_KEY="your_key"
ROPSTEN_URL = "https://ropsten.infura.io/%s" %INFURA_API_KEY

web3 = Web3(HTTPProvider(ROPSTEN_URL))

contract_instance = web3.eth.contract(address=config['address'], abi=config['abi'])

MY_ADDR = "0x901B1bDE..." # 你的地址
PRIV_KEY = "0x1dc7..." # 你的私钥

def SendTxn(txn):
signed_txn = web3.eth.account.signTransaction(txn, private_key=PRIV_KEY)
res = web3.eth.sendRawTransaction(signed_txn.rawTransaction).hex()
txn_receipt = web3.eth.waitForTransactionReceipt(res)
#
print(res)
return txn_receipt


txn = contract_instance.functions.callme().buildTransaction(
{
'chainId': 3, #ropsten, 1 for main
'nonce': web3.eth.getTransactionCount(MY_ADDR),
'gas': 7600000,
'value':Web3.toWei(0,'ether'),
'gasPrice': web3.eth.gasPrice,
}
)

print(SendTxn(txn))

  要实例化一个合约,需要abi合约地址两个参数,abi可以在remix-ide里获取到。




  另外,使用web3的过程中我们需要连接到以太坊节点,如HTTPProvider。如果自己本地没有搭建好节点,那么可以使用第三方提供的节点,如infura。注册好后可以得到一个app key,使用该key就能连入infura提供的节点。

  实例化contract以后我们可以使用contract_instance.functions.callme()的方法调用合约内的函数。因为我们需要实际改变ropsten链的值,所以我们需要创建一个交易,完成对ropsten的通信,所以还需调用buildTransaction方法。最后把签完名的交易块发送到ropsten链上。

web3.js

  web3.js是官方提供的库。其调用代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
let Web3 = require("web3");
let Tx = require('ethereumjs-tx');

// 合约地址
let contractAddress = "0x799Caa8d82d70296f1eA4992B76553ABD72da9B1";
// 创建web3对象
let web3 = new Web3();
// 连接到 ropsten 测试节点

let INFURA_API_KEY="************"
let ROPSTEN_URL = "https://ropsten.infura.io/" + INFURA_API_KEY
web3.setProvider(new Web3.providers.HttpProvider(ROPSTEN_URL))


let fromAddress = "0x901B1bDE...";

let count = web3.eth.getTransactionCount(fromAddress);
let gasPrice = web3.eth.gasPrice;
let gasLimit = 90000;


let rawTransaction = {
"from": fromAddress,
"nonce": web3.toHex(count),
"gasPrice": web3.toHex(gasPrice),
"gasLimit": web3.toHex(gasLimit),
"to": contractAddress,
"value": "0x0",
"data": "0xa3c8e393",
};

// 读取私钥,这里不包含‘0x’两个字符
let privKey = new Buffer.from('1dc72....', 'hex');
let tx = new Tx(rawTransaction);

// 用私钥签名交易信息
tx.sign(privKey);
let serializedTx = tx.serialize();

// 发送交易
web3.eth.sendRawTransaction('0x' + serializedTx.toString('hex'),
function(err, hash) {
if (!err)
console.log(hash);
else
console.log(err);
});

  如上,这里我们要重点关注rawTransaction里的data段。

  它是所调函数的函数声明做keccak256(即sha3)的哈希,并取前4个字节组成。如果需要传递参数,则把需要传递的参数转换成16进制,并在前面填满32字节(64位)。然后跟函数签名拼接而成。

  相关的说明我们可以参考:

  https://github.com/ethereum/wiki/wiki/Ethereum-Contract-ABI#examples

  https://github.com/linjie-1/guigulive-operation/wiki/Ethereum%E7%9A%84%E5%90%88%E7%BA%A6ABI%E6%8B%93%E5%B1%95#abi%E7%9A%84%E5%87%BD%E6%95%B0%E8%B0%83%E7%94%A8
  
  

评论

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×