Web3.js - 如何签署批准交易以进行掉期交易?
Web3.js - How to sign an approve transaction for a swap?
我想以编程方式交换两个令牌。我必须先批准金额。我如何批准使用 web3.js?
这是我到目前为止的想法,但我收到错误 Error: Returned error: nonce too low
const myAddress = "my-wallet-address"
const privateKey = Buffer.from('my-private-key', 'hex');
const test = async () => {
const allowed = await tokenContract.methods.allowance(myAddress, 'UniswapV2Router02ContractAddress').call()
const encodedABI = tokenContract.methods.approve('UniswapV2Router02ContractAddress', amountIn).encodeABI();
const tx = {
from: myAddress,
to: 'UniswapV2Router02ContractAddress',
gas: 2000000,
data: encodedABI
};
const customCommon = Common.default.forCustomChain(
'mainnet',
{
name: 'SAMPLE testnet',
networkId: custom-testnet-id,
chainId: custom-testnet-id,
},
'petersburg',
)
const txTx = new Tx(tx, {common: customCommon});
txTx.sign(privateKey);
// below gives true, true
console.log(txTx.validate(), ethUtil.bufferToHex(txTx.getSenderAddress()) === ethUtil.bufferToHex(ethUtil.privateToAddress(privateKey)))
const serializedTx = txTx.serialize();
// below line results in error
await web3.eth.sendSignedTransaction('0x' + serializedTx.toString('hex'))
// await uniswapV2Router02Contract.methods.swapExactTokensForTokensSupportingFeeOnTransferTokens(amountIn, amountOutMin, path, myAddress, deadline).send({from: myAddress})
}
test()
这个post的最后一个答案讨论了Error: Returned error: nonce too low
错误:但是我已经验证我的私钥属于交易的发送者(我)所以我一无所知
我们先了解一下以太坊中的Nonce是什么
基于Ethereum paper:Nonce 是标量值,等于从地址(钱包)发送的交易数量...
交易包括:转账、创建合约...
当您在不同的地方使用您的帐户时,可能会出现 Nonce too low
错误。特别是当你使用私钥签署交易时。
示例:
- 一个地址有5笔交易,发自MM(PC1)。 Nonce 为 5.
- 您使用私钥 (PC2) 在另一个地方执行交易。 Nonce是6。但是MM不知道这个。
- 回到PC1,在MM上再做一笔交易,Nonce应该是7,MM却说是6,这就导致了Nonce太低的问题。
为了修复,我们可以简单地重置 MM 钱包:
从 MM 菜单中选择设置 => 高级设置 => 重置。
为什么重置MM可以解决nonce问题?
- 通过重置,MM可以同步地址的交易数量。所以随机数增加得很好。
代码如下:
var Web3 = require('web3');
var web3 = new Web3("rpc-node-link");
var Tx = require('ethereumjs-tx').Transaction;
var Common = require('ethereumjs-common');
var ethUtil = require('ethereumjs-util')
web3.eth.getTransactionCount(myAddress, async (err, txCount) => {
const encodedABI = contractWhichisApproving.methods.approve(contractThatWantsToSpendContractWhichisApprovingsToken, amountIn).encodeABI();
const tx = {
nonce: web3.utils.toHex(txCount),
from: myAddress,
to: contractWhichisApprovingAddress,
gas: 2000000,
data: encodedABI
};
const customCommon = Common.default.forCustomChain(
'mainnet',
{
name: 'Example testnet',
networkId: custom-testnet-id,
chainId: custom-testnet-id,
},
'petersburg',
)
const txTx = new Tx(tx, {common: customCommon});
txTx.sign(privateKey);
// following line logs true, true
console.log(txTx.validate(), ethUtil.bufferToHex(txTx.getSenderAddress()) === ethUtil.bufferToHex(ethUtil.privateToAddress(privateKey)))
const serializedTx = txTx.serialize();
console.log('sending')
await web3.eth.sendSignedTransaction('0x' + serializedTx.toString('hex')).on('receipt', console.log);
console.log('done')
});
使用自定义链的引用:https://github.com/ethereumjs/ethereumjs-tx/blob/master/examples/custom-chain-tx.ts
我想以编程方式交换两个令牌。我必须先批准金额。我如何批准使用 web3.js?
这是我到目前为止的想法,但我收到错误 Error: Returned error: nonce too low
const myAddress = "my-wallet-address"
const privateKey = Buffer.from('my-private-key', 'hex');
const test = async () => {
const allowed = await tokenContract.methods.allowance(myAddress, 'UniswapV2Router02ContractAddress').call()
const encodedABI = tokenContract.methods.approve('UniswapV2Router02ContractAddress', amountIn).encodeABI();
const tx = {
from: myAddress,
to: 'UniswapV2Router02ContractAddress',
gas: 2000000,
data: encodedABI
};
const customCommon = Common.default.forCustomChain(
'mainnet',
{
name: 'SAMPLE testnet',
networkId: custom-testnet-id,
chainId: custom-testnet-id,
},
'petersburg',
)
const txTx = new Tx(tx, {common: customCommon});
txTx.sign(privateKey);
// below gives true, true
console.log(txTx.validate(), ethUtil.bufferToHex(txTx.getSenderAddress()) === ethUtil.bufferToHex(ethUtil.privateToAddress(privateKey)))
const serializedTx = txTx.serialize();
// below line results in error
await web3.eth.sendSignedTransaction('0x' + serializedTx.toString('hex'))
// await uniswapV2Router02Contract.methods.swapExactTokensForTokensSupportingFeeOnTransferTokens(amountIn, amountOutMin, path, myAddress, deadline).send({from: myAddress})
}
test()
这个post的最后一个答案讨论了Error: Returned error: nonce too low
错误:
我们先了解一下以太坊中的Nonce是什么
基于Ethereum paper:Nonce 是标量值,等于从地址(钱包)发送的交易数量...
交易包括:转账、创建合约...
当您在不同的地方使用您的帐户时,可能会出现 Nonce too low
错误。特别是当你使用私钥签署交易时。
示例:
- 一个地址有5笔交易,发自MM(PC1)。 Nonce 为 5.
- 您使用私钥 (PC2) 在另一个地方执行交易。 Nonce是6。但是MM不知道这个。
- 回到PC1,在MM上再做一笔交易,Nonce应该是7,MM却说是6,这就导致了Nonce太低的问题。
为了修复,我们可以简单地重置 MM 钱包:
从 MM 菜单中选择设置 => 高级设置 => 重置。
为什么重置MM可以解决nonce问题?
- 通过重置,MM可以同步地址的交易数量。所以随机数增加得很好。
代码如下:
var Web3 = require('web3');
var web3 = new Web3("rpc-node-link");
var Tx = require('ethereumjs-tx').Transaction;
var Common = require('ethereumjs-common');
var ethUtil = require('ethereumjs-util')
web3.eth.getTransactionCount(myAddress, async (err, txCount) => {
const encodedABI = contractWhichisApproving.methods.approve(contractThatWantsToSpendContractWhichisApprovingsToken, amountIn).encodeABI();
const tx = {
nonce: web3.utils.toHex(txCount),
from: myAddress,
to: contractWhichisApprovingAddress,
gas: 2000000,
data: encodedABI
};
const customCommon = Common.default.forCustomChain(
'mainnet',
{
name: 'Example testnet',
networkId: custom-testnet-id,
chainId: custom-testnet-id,
},
'petersburg',
)
const txTx = new Tx(tx, {common: customCommon});
txTx.sign(privateKey);
// following line logs true, true
console.log(txTx.validate(), ethUtil.bufferToHex(txTx.getSenderAddress()) === ethUtil.bufferToHex(ethUtil.privateToAddress(privateKey)))
const serializedTx = txTx.serialize();
console.log('sending')
await web3.eth.sendSignedTransaction('0x' + serializedTx.toString('hex')).on('receipt', console.log);
console.log('done')
});
使用自定义链的引用:https://github.com/ethereumjs/ethereumjs-tx/blob/master/examples/custom-chain-tx.ts