0%

eth | web3.js 合约调用

我将用几个案例来描述。

其实,真正懂了 abi 之后,就会发现,erc20 转账其实和合约调用是一样的,毕竟转账就是一次合约调用。


支票兑换


这个是我为 gps 写的一个开源工具。

支票兑换是其中的一个小功能。直接看代码。

  • “ethereumjs-tx”: “^1.3.7”,
  • “ethereumjs-util”: “^7.1.0”,
  • “web3”: “^1.3.6”
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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
import "@pages/common/common"
import "./index.css"
import Web3 from "web3"
import axios from "axios";
import Tx from "ethereumjs-tx"

let w3 = new Web3(new Web3.providers.HttpProvider("https://bsc-dataseed4.binance.org"));
let contractAddr = "0x5e772acf0f20b0315391021e0884cb1f1aa4545c";
let tokenContractABI = [
{
"constant": true,
"inputs": [{"name": "who", "type": "address"}],
"name": "balanceOf",
"outputs": [{"name": "", "type": "uint256"}],
"payable": false,
"stateMutability": "view",
"type": "function"
}, {
"inputs": [
{"internalType": "uint256", "name": "cumulativePayout", "type": "uint256"},
{"internalType": "bytes", "name": "issuerSig", "type": "bytes"}],
"name": "cashCheque",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
}]
let tokenContract = new w3.eth.Contract(tokenContractABI, contractAddr);

const cash_pay = (address, private_key) => {
tokenContract.methods.balanceOf(address).call().then((balance) => {
console.log(balance);
})
}

$("#submit").click(() => {
$("#hex").empty();
let addresses_vals = $("#addresses").val();
let addresses = addresses_vals.split(/\s+/)
let privates_vals = $("#privates").val();
let privates = privates_vals.split(/\s+/)
let threshold = parseFloat($("#threshold").val())
console.log(threshold)
if (isNaN(threshold) || threshold === 0) {
alert("请输入正确的阈值")
return
}

if (addresses.length !== privates.length || addresses[0] === null || addresses[0] === "" || privates[0] === "" || privates[0] === null) {
alert("地址和私钥数量对应不对")
return
}

for (let i = 0; i < addresses.length; i++) {
let address = addresses[i]
let private_key = privates[i]
if (private_key.startsWith("0x")) {
private_key = private_key.substr(2);
}
if (!w3.utils.isAddress(address)) {
...
}
w3.eth.getBalance(address, (error, balance) => {
console.log(balance)
if (error) {
...
}
let bnb = w3.utils.fromWei(balance, "ether")
console.log(bnb)
if (bnb < 0.0005) {
...
}
let url = "https://api.gpfs.xyz/v1/cheque?address=" + address
axios.get(url).then((response) => {
let info = response.data
if (response.status === 200 && info.msg === "success") {
let data = info.data;
let amount = data['amount'];
let amount_16 = w3.utils.toHex(amount)
let paidout = data['paid_out']
let paidin = (parseFloat(amount) - parseFloat(paidout)) / 10000
let signature = data['signature']
let signature_16 = "0x" + signature


if (threshold > paidin) {
...
}

w3.eth.getTransactionCount(address, ((error, count) => {
if (error) {
...
}

let rawTx = {
from: address,
to: '0x5e772acf0f20b0315391021e0884cb1f1aa4545c',
value: w3.utils.toHex(w3.utils.toWei('0', 'ether')),
nonce: w3.utils.toHex(count),
gasLimit: w3.utils.toHex(100000),
gasPrice: w3.utils.toHex(w3.utils.toWei('5', 'gwei')),
data: tokenContract.methods.cashCheque(amount_16, signature_16).encodeABI()
}


let tx = new Tx(rawTx);
tx.sign(new Buffer(private_key, 'hex'));
let serializedTx = tx.serialize();
let raw = '0x' + serializedTx.toString('hex')
w3.eth.sendSignedTransaction(raw, (err, txHash) => {
...
}
})

}))

}
})
})
}
})

具体的代码解析,请看下面。

请我喝杯咖啡吧~