MOAC实战 - 12. 调用合约-需要Gas

前言

调用合约需要 Gas 分为两种。

  • 调用写入方法,消耗基础gas
  • 调用合约转账,向合约内部转账,消耗gas和转账的 Token 数

我们下面直接用代码的方式来介绍这两种方式

调用合约内方法

1. 建立连接

这部分可以参照之前的文章

2. 声明自己的地址

1
2
3
4
5
// 自己的地址
const initWallet = {
address: "0x3E7F188981bb007CFF261d6E0Fb1A6cedBc4cfAd",
secret: "0xddfde37799e3582e2938cbd85d0b65df830fd5ed294a2888a32e4819b62300be"
}

3. 读取合约ABI文件

1
2
3
// 读取ABI
const abiPath = path.join(__dirname, 'xxx/Test.abi');
const abiFile = JSON.parse(fs.readFileSync(abiPath, 'utf8'));

4. 使用 Chain3 连接合约

合约地址的计算可参考之前的文章

1
2
3
4
const MyContract = chain3.mc.contract(abiFile);
// 合约地址
const contractAddress='0x06efa91fbaf9d20930f461684b92573bf8fb8042';
const myContractInstance = MyContract.at(contractAddress);

5. 编码调用方法

这一步要把你需要调用的哪个具体方法给编码出来

1
2
3
4
5
6
7
// transfer 代表合约内部的一个方法,这个变量可以替换其他方法

// 没有参数的
var tcalldata = myContractInstance.transfer.getData();

// 带有参数的
var tcalldata = myContractInstance.transfer.getData('ABC', 888);

6. 计算燃料和构建参数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
let gasEstimate = chain3.mc.estimateGas({data: tcalldata});
gasEstimate = 4000000; // 这里可以写固定的,最大不能超过区块燃料限制
var networkid = chain3.version.network;

// 计算序号
var txcount = chain3.mc.getTransactionCount(initWallet.address);

var rawTx = {
from: initWallet.address,
to: contractAddress,
nonce: chain3.intToHex(txcount),
gasPrice: chain3.intToHex(30000000000),
gasLimit: chain3.intToHex(gasEstimate),
value: '0x', // 转账金额为 0x 代表不转账
data: tcalldata,
chainId: chain3.intToHex(networkid)
}

7. 离线签名

1
var cmd1 = chain3.signTransaction(rawTx, initWallet.secret);

8. 上链

1
2
3
4
5
const { err, hash } = await new Promise(resolve => {
chain3.mc.sendRawTransaction(cmd1, function(err, hash) {
resolve({ err, hash });
});
});

合约转账

合约转账和上面需要gas的操作很相似,有几处不同,其他的很相似。

5. 编码调用方法

这一步需要调用合约内部带有 payable 关键字的函数

6. 计算燃料和构建参数

1
2
3
4
5
6
7
8
9
10
var rawTx = {
from: initWallet.address,
to: contractAddress,
nonce: chain3.intToHex(txcount),
gasPrice: chain3.intToHex(30000000000),
gasLimit: chain3.intToHex(gasEstimate),
value: chain3.toHex(chain3.toSha(value, 'mc')),
data: tcalldata,
chainId: chain3.intToHex(networkid)
}

这一步的 value 值需要有特定的金额,代表发送了特定的 MOAC 到合约地址中去。

结语

我们调用完合约之后,可以去查询 HASH ,看合约是否调用成功了。

如下图:

补充说明:

合约调用具有原子性,如果支付的燃料不足,或者是其他异常,合约中的数据更改到一半的会全部回滚。

  • 版权声明: 本博客所有文章,未经许可,任何单位及个人不得做营利性使用!转载请标明出处!如有侵权请联系作者。
  • Copyrights © 2015-2020 翟天野

请我喝杯咖啡吧~