I'm sending a token from account A to B. The account who issues transaction is C. Surprisingly, the transaction is valid and works fine. Why?

This means that I, being the transaction issuer, can make arbitrary account A give tokens to arbitrary account B? Does this not mean that I can literally steal tokens this way, given B is some other address of mine.

I'm pretty sure I'm missing some fundamental thing here.

The JSON RPC payload to depict the question is this:

  "jsonrpc": "2.0",
  "method": "eth_sendTransaction",
  "params": [
      "to": "0x5928ead021bd523e6d3531de920d78b7a02efa60",
      "from": "0xef2b050377007e45ba43d9c2bf0d7acc2039c112",
      "data": "0x23b872dd000000000000000000000000d8e05701eFf33acfDA0A8e24C04070347703c72C000000000000000000000000ad9c9b5085bec8e8013296dc12bd9cecad102356000000000000000000000000000000000000000000000000000000005a9187bf",
      "gas": "0x3d0900",
      "gasPrice": "0x51f4d5c00"
  "id": 1

The transaction happened on a ropsten network, and can be seen here: https://ropsten.etherscan.io/tx/0x3a1d9800565e93a7ff0e85958dcf49a9e7752d099f4b061598e8b73f1e453814


  • 0x5928ead021bd523e6d3531de920d78b7a02efa60 – contract address,
  • 0xef2b050377007e45ba43d9c2bf0d7acc2039c112 – transaction issuer (the one who will pay the transaction fee),
  • 0xd8e05701eFf33acfDA0A8e24C04070347703c72C – user A, actually, contract creator who holds all the tokens; the one whos tokens are being stolen,
  • 0xad9c9b5085bec8e8013296dc12bd9cecad102356 – user B, the one who is being gifted some tokens.

How come this transaction is valid?


Take a look at that token contract at https://ropsten.etherscan.io/address/0x5928ead021bd523e6d3531de920d78b7a02efa60#code

function transferFrom(address _from, address _to, uint _value) returns (bool success) {
    if (_from == 0x0 && _to == 0x0) throw;
    if (balanceOf[_from] >= _value && _value > 0) {
      balanceOf[_from] -= _value;
      balanceOf[_to] += _value;
      Transfer(_from, _to, _value);
      return true;
    return false;

The transferFrom function doesn't check who is the initiator of the transaction thus anyone can transfer from anybody.

This token only implements two methods from ERC20, and it implements them incorrectly. For correct implementation, either use zeppelin-solitidy library or take a look at https://theethereum.wiki/w/index.php/ERC20_Token_Standard


In ERC20 standard, a sender can approve a 3rd party to transfer on his behalf. This is called allowance and done via approve() method. Use cases like decentralized exchange need this to operate.

Following is a well-written article on ERC20 and a good explanation of allowance. https://medium.com/@jgm.orinoco/understanding-erc-20-token-contracts-a809a7310aa5

  • Thank you for the comment, @Sumanth. That article was insightful! – gmile Feb 26 '18 at 13:52

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.