[Ethereum] transfer ERC20 Tokens by web3

erc-20tokenstransactionsweb3js

I'm a beginner of ethereum.
I have seen some solutions.
I can use sendRawTransaction to transfer costumed tokens from one account to another account.
But my boss asked me to use ERC-20 "transfer" method.(not to use"web3.eth.sendRawTransaction")
I'm using infura & Web3 0.20 version & ropsten testnet, running in the back-end(node.js).(I don't want to run in the front-end)

pragma solidity ^0.4.24;
function transfer(address _to, uint256 _value) returns (bool) {
  balances[msg.sender] = balances[msg.sender].sub(_value);
  balances[_to] = balances[_to].add(_value);
  Transfer(msg.sender, _to, _value);
  return true;
}

Blockquote

var Web3 = require('web3');
const testnet = 'https://ropsten.infura.io/';
const web3 = new Web3(new Web3.providers.HttpProvider(testnet));

var contractABI = [.....{"constant":false,"inputs": 
[{"name":"_to","type":"address"}, 
{"name":"_value","type":"uint256"}],"name":"transfer","outputs" 
 [{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable",
 "type":"function"}.....]

 var contractAddress = '0x9A6...';
 var contract = web3.eth.contract(contractABI).at(contractAddress);

 // transfer 100 tokens form 0xD0A88... to 0x36c90...
 contract.transfer.call("0x36C90...", 
 100*Math.pow(10, 18),{from: "0xD0A88..."}, 
 function(error, txHash){
 console.log(txHash);
 });

Running and "console.log(txHash)" return "true".
But I saw etherscan didn't have this transaction, and tokens also didn't be transferred.
How can I revise it?(Web3 0.20 version)

Best Answer

You should use send instead of call, because token transfer does modify blockchain state:

// transfer 100 tokens form 0xD0A88... to 0x36c90...
contract.transfer.send(
  "0x36C90...", 
  100 * Math.pow (10, 18),
  {
    from: "0xD0A88..."
  }, 
  function(error, txHash) {
    console.log(txHash);
  });

Though, this will not work with Infura, because Infura does not have your private key. You will need to do contract.transfer.getData("0x36C90...", 100 * Math.pow (10, 18)) to get encoded transaction data, and then use this data to construct and sign raw transaction.

BTW, you use floating point arithmetic to calculate number of tokens to be transferred. This way you will loose precision. You should use BigNumber instead.

Related Topic