Search code examples
node.jsethereumweb3js

Web3js transfer token


I am trying to transfer tokens to other address. Before I call my transfer function, I call the estimateGas() to estimate the gas required.

The code is mentioned below:

var count = await web3Config.web3.eth.getTransactionCount(process.env.OWNER_ADDRESS);
        var data = web3Config.contractInstance.methods.transfer(req.body.address, req.body.amount*Math.pow(10,18)).encodeABI();

        var estimatedGasPrice = await web3Config.web3.eth.estimateGas({
          from : process.env.OWNER_ADDRESS,
          to:   process.env.CONTRACT_ADDRESS,
          data : data
        });

          logs.error(estimatedGasPrice)
          var rawTx = {
              from : process.env.OWNER_ADDRESS,
              to:   process.env.CONTRACT_ADDRESS,
              data : data,
              nonce: "0x" + count.toString(16),
              gasPrice: web3Config.gasPrice,
              value: '0x0',
              gasLimit: estimatedGasPrice,
              chainId: 3
          }

          var tx = new Tx(rawTx);
          tx.sign(web3Config.ownerPrivKey);
          var serializedTx = tx.serialize();

          var receipt = await web3Config.web3.eth.sendSignedTransaction('0x' + serializedTx.toString('hex'));
          res.send(receipt)
          logs.log(receipt)

The decimals in my contract is 18.

If I want to transfer 1 token so I need to convert it to 1000000000000000000 because of decimal points.

The issue is in this line req.body.amount*Math.pow(10,18). When I try to transfer tokens more than 100000 it gave an exception that is mentioned below:

Error: [number-to-bn] while converting number 1e+22 to BN.js instance, error: invalid number value. Value must be an integer, hex string, BN or BigNumber instance. Note, decimals are not supported. Given value: "1e+22"
warning.js:18
    at toBN (/home/akshay/WS/ethereum/node_modules/web3-utils/src/utils.js:64:15)
    at Object.toTwosComplement (/home/akshay/WS/ethereum/node_modules/web3-utils/src/utils.js:77:18)
    at SolidityTypeUInt.formatInputInt [as _inputFormatter] (/home/akshay/WS/ethereum/node_modules/web3-eth-abi/src/formatters.js:44:36)
    at SolidityTypeUInt.SolidityType.encode (/home/akshay/WS/ethereum/node_modules/web3-eth-abi/src/type.js:188:17)
    at /home/akshay/WS/ethereum/node_modules/web3-eth-abi/src/index.js:255:29
    at Array.map (<anonymous>)
    at ABICoder.encodeParameters (/home/akshay/WS/ethereum/node_modules/web3-eth-abi/src/index.js:254:34)
    at /home/akshay/WS/ethereum/node_modules/web3-eth-contract/src/index.js:420:24
    at Array.map (<anonymous>)
    at Object._encodeMethodABI (/home/akshay/WS/ethereum/node_modules/web3-eth-contract/src/index.js:419:12)
    at main (/home/akshay/WS/ethereum/routes/blockchain.js:55:116)
    at <anonymous>
    at process._tickCallback (internal/process/next_tick.js:188:7)

It exceeds the range of number.

Any help/suggestion would be appreciated.


Solution

  • If you type value in console, you'll see that the value is too big that javascript transform the value.

    > 1*Math.pow(10,18)
    
    1000000000000000000
    
    > 100000000000000*Math.pow(10,18)
    
    1e+32
    

    I think you can use web3 bn object to pow or caculate the token.

    Or you can use web3 toWei to do the same thing.

    If your token decimal is 18 (like ethereum to wei), so you can simply use toWei(1, 'ether') to get the token amount.