I have user's private key to sign a erc20-token transfer transaction in my DAPP. Now I want to send this transaction from different account so that 2nd account pay the gas fee. Is it possible through web3. Contract itself doesn't have any method to verify signature and call the transfer method, it has default transfer method. How can I achieve this?
Following the comments to your question, here is a working example (tested with web3.js v1.2.1):
async function run()
const web3 = new Web3(YOUR_NODE_URL);
const contract = new web3.eth.Contract(YOUR_CONTRACT_ABI, YOUR_CONTRACT_ADDR);
const account1 = web3.eth.accounts.privateKeyToAccount(ACCOUNT1_PRIVATE_KEY);
const account2 = web3.eth.accounts.privateKeyToAccount(ACCOUNT2_PRIVATE_KEY);
const transaction1 = contract.methods.approve(account2.address, TOKEN_AMOUNT);
const transaction2 = contract.methods.transferFrom(account1.address, DEST_ADDR, TOKEN_AMOUNT);
const receipt1 = await send(web3, account1, transaction1);
const receipt2 = await send(web3, account2, transaction2);
console.log(receipt1);
console.log(receipt2);
}
async function send(web3, account, transaction) {
const options = {
to : transaction._parent._address,
data : transaction.encodeABI(),
gas : await transaction.estimateGas({from: account.address}),
gasPrice: WHATEVER_GAS_PRICE_YOU_ARE_WILLING_TO_PAY
};
const signed = await web3.eth.accounts.signTransaction(options, account.privateKey);
const receipt = await web3.eth.sendSignedTransaction(signed.rawTransaction);
return receipt;
}
run();
Note that the first account will still need to pay gas for executing approve
, which is not much different than paying gas for executing transfer
to begin with.
The purpose of this ERC20 scheme, is not to allow someone else to pay for your gas, but to allow someone else to transfer a certain amount of tokens on your behalf.
This is a typical scenario when you register your account on an exchange, for example.
Generally speaking, you cannot have a transaction executed with one account and paid for with another account; the account executing the transaction will always be the one paying for it.
approve
way is a dead end imho. You should instead create a wrapper contract that can control user tokens based on signed users messages. It's something similar to a wallet for tokens. – Giuseppe Bertone Jun 12 '20 at 9:06