Home > Enterprise >  web3.js: Estimate gas fee on usdt smart contract transfer
web3.js: Estimate gas fee on usdt smart contract transfer

Time:06-10

I'm trying to estimate gas value in eth, for USDT transfer, but we3.js gives me only IVALID OPCODE error...

code example

const Web3 = require('web3');

const web3 = new Web3('https://cloudflare-eth.com/');

const token = new web3.eth.Contract([{
    'constant': false,
    'inputs': [{
        'internalType': 'address',
        'name': 'recipient',
        'type': 'address',
    }, {
        'internalType': 'uint256',
        'name': 'amount',
        'type': 'uint256',
    }],
    'name': 'transfer',
    'outputs': [{
        'internalType': 'bool',
        'name': '',
        'type': 'bool',
    }],
    'payable': false,
    'stateMutability': 'nonpayable',
    'type': 'function',
}], '0xdac17f958d2ee523a2206206994597c13d831ec7');


const to = '0x....';
const from = '0x.....'
token
    .methods
    .transfer(to, web3.utils.toWei('1'))
    .estimateGas({from})
    .then(res=>{
        console.log(res);
    })
;

Error: enter image description here

can't find any working example for this. At the end i want to get near same value as metamask gives me...

UPDATE after Petr Hejda answer:

const Web3 = require('web3');

const web3 = new Web3('https://cloudflare-eth.com/');

const token = new web3.eth.Contract([{
    'constant': false,
    'inputs': [{
        'internalType': 'address',
        'name': 'recipient',
        'type': 'address',
    }, {
        'internalType': 'uint256',
        'name': 'amount',
        'type': 'uint256',
    }],
    'name': 'transfer',
    'outputs': [{
        'internalType': 'bool',
        'name': '',
        'type': 'bool',
    }],
    'payable': false,
    'stateMutability': 'nonpayable',
    'type': 'function',
}], '0xdac17f958d2ee523a2206206994597c13d831ec7');


const to = '0x..';
const from = '0x..'
const value = web3.utils.toWei('1', 'mwei');

web3.eth.getGasPrice()
    .then(gasPrice => {
        token
            .methods
            .transfer(to, value)
            .estimateGas({from})
            .then(estimatedGas=>{
                const txPriceWei = estimatedGas * gasPrice;
                const txPriceEth = web3.utils.fromWei(txPriceWei.toString(), 'ether');
                const txPriceUSD = txPriceEth * 1800;
                console.log({
                    estimatedGas, txPriceWei, txPriceEth, txPriceUSD
                });
            })
        ;
    })
;

Now it works, and estimates.. Something. It is near metamask value, but is about 30% less. Where could i miss this 30%? enter image description here enter image description here Thanks.

CodePudding user response:

Based on the values provided in the code, I'm assuming that you're trying to calculate gas fees for transfering 1 USDT on the Ethereum mainnet.

The web3js toWei() function convers a number to an EVM-compatible value with 18 decimal places. However, the USDT token uses only 6 decimals.

Because of this discrepancy, your code is effectively tying to calculate gas costs of transferring 1.000.000.000.000 tokens (10^18 / 10^6 = 10^12).

Since the from address doesn't have a trillion USDT, the transaction is expected to revert. And, in the underlying low-level EVM bytecode, a revert is triggered by the IVALID opcode.

  • Related