node.js - 发送 ERC-20 令牌失败。交易成功,但没有发送令牌
问题描述
当我运行以下代码时,它准确地获取了两个地址的代币余额,并且交易甚至通过了(我可以在测试网上看到它),尽管没有发送代币。
我尝试了很多方法,包括用这个替换签名的交易部分:
await contract.methods.transfer(toAddress, 100000).send({
from: fromAddress
});
但这失败并出现unknown account
错误。
我发送令牌的代码:
const Web3 = require("web3");
const { hdkey } = require("ethereumjs-wallet");
const bip39 = require("bip39");
const token = require("./token.json");
const mnemonic = "12 word phrase";
const provider = "https://apis.ankr.com/.../binance/full/test";
(async() => {
try {
const seed = await bip39.mnemonicToSeed(mnemonic);
const root = hdkey.fromMasterSeed(seed);
const web3 = new Web3(provider);
const addrNode = root.derivePath(`m/44'/60'/0'/0/0`);
const wallet = addrNode.getWallet();
// #0 in the hdwallet, the owner of the tokens
const fromAddress = wallet.getAddressString();
// #1 in the hdwallet, already has a token balance
const toAddress = "0x...";
const contract = new web3.eth.Contract(token.abi, token.contract_address);
let fromAddressBalance = await contract.methods.balanceOf(fromAddress).call();
let toAddressBalance = await contract.methods.balanceOf(toAddress).call();
console.log(`Pre Transaction: Sender: ${fromAddressBalance} TOKENS / Wallet: ${toAddressBalance} TOKENS`);
// token has 3 decimal places, this is 100.000
const encodedABI = contract.methods.transfer(toAddress, 100000).encodeABI();
const tx = {
from: fromAddress,
to: toAddress,
gas: 2000000,
value: 0x0,
data: encodedABI
};
const signed = await web3.eth.accounts.signTransaction(tx, wallet.privateKey.toString("hex"));
const trans = await web3.eth.sendSignedTransaction(signed.rawTransaction);
fromAddressBalance = await contract.methods.balanceOf(fromAddress).call();
toAddressBalance = await contract.methods.balanceOf(toAddress).call();
console.log(`Post Transaction: Sender: ${fromAddressBalance} TOKENS / Wallet: ${toAddressBalance} TOKENS`);
} catch (err) {
console.error(err.stack);
}
process.exit();
})();
解决方案
有一些问题一旦解决就解决了我的问题。我还没有回过头来测试是哪个做到了,或者是否所有都需要,但想把它留给未来的探索者。
- 我正在使用 ethereum-js-wallet 创建一个钱包,然后将它与 web3 一起使用。你必须让 web3 知道钱包。
const account = web3.eth.accounts.privateKeyToAccount(privateKey);
web3.eth.accounts.wallet.create();
web3.eth.accounts.wallet.add(account);
- 私钥地址需要以 0x 开头。来源:https ://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#privatekeytoaccount
const privateKey = `0x${wallet.privateKey.toString("hex")}`;
- 这最终无关紧要,也不是正确的转移方式,但仍然需要注意的是,我将签署的交易发送给第 3 方,而不是合同,发送交易的正确方式应该是
const tx = {
from: fromAddress,
to: token.contract_address,
gas: 2000000,
value: 0x0,
data: encodedABI
};
最终,我需要利用合同的转移方法与签署/发送交易
const result = await contract.methods.transfer(toAddress, 100).send({
from: fromAddress,
gas: 2000000
});
推荐阅读
- ckeditor - Magnolia CkEditor InternalLink 未在工具栏中列出
- react-native - 为什么我的键盘失去了对每个水龙头的关注
- angular - 订阅中的多个请求问题
- css - 使图像适合网格,以便占用所有可用空间
- javascript - 带有每个可变参数的 if 语句
- node.js - 如何在 MongoDB 2.2 中使用 $count 聚合运算符(或解决方法)?
- asp.net - 向 IdentityUser 添加数据注释
- macos - 为选项卡切换器添加 IntelliJ 快捷方式不会复制默认行为
- excel - 日期自动修改为其他内容
- jquery - 如何在页面重新加载时删除类/添加类