Web3js – How to Send ERC20 Token from User to User with Server Paying Gas Fee

erc-20tokensweb3js

I am a newbie in this field.

Me and my team are trying to build an app that gives users an ERC20 token every time they write, and allows users to give their tokens to other users.

However, whenever a user gives a token to another user, a transaction occurs and a gas fee must be paid. Our team wants to pay this gas fee instead.

Is this possible? I tried using approve and transferFrom, but I get an error Error: Returned error: execution reverted: ERC20: transfer amount exceeds allowance.

This is the code I tried. The contract used the ERC20 standard.

export async function voteToOtherUser(senderAccount:String, senderPrivateKey:String, senderUserId:Number, receiverAccount:String, receiverUserId:Number) {
    const Web3 = require('web3');
    const web3 = new Web3(new Web3.providers.HttpProvider(process.env.INFURA_ENDPOINT)); 
    const contract = new web3.eth.Contract(SITokenABI, TOKEN_CONTRACT_ADDRESS, { from: TOKEN_CONTRACT_DEPLOYED_OWNER_ADDRESS, gas: GAS_FEE});
     //디코딩
    const decryptedPrivateKey = require('aes256').decrypt(process.env.PRIVATE_KEY_SECRET, senderPrivateKey)

    // web3.eth.accounts.wallet.add(decryptedPrivateKey);
    // console.log("result", await contract.methods.transfer(receiverAccount, VOTING_TOKEN_AMOUNT).call())


    console.log(await contract.methods.approve(senderAccount, VOTING_TOKEN_AMOUNT).call())
    console.log(await contract.methods.allowance(senderAccount, TOKEN_CONTRACT_ADDRESS).call())
   console.log( await contract.methods.transferFrom(senderAccount, receiverAccount, VOTING_TOKEN_AMOUNT).call())
    
    updateUserBalance(senderUserId, senderAccount)
    updateUserBalance(receiverUserId, receiverAccount)
}

If you have a solution to a similar question, please suggest it. I'm not a native English speaker, so I searched hard, but there may be limitations.

thanks!

Best Answer

To begin with, there is no trivial way to achieve this. All of the options are a bit advanced.

Using transferFrom requires the token owner to give allowance to withdraw the tokens, and usually giving this allowance requires a transaction.

If you control the ERC20 token code and can still change it (before deployment), you could add permit (https://docs.openzeppelin.com/contracts/4.x/api/token/erc20#ERC20Permit) functionality into it. This is the same as owner giving allowance, but it doesn't require a transaction - only a signature.

Another option is something like Gas Station Network (https://opengsn.org/).