7

I have created a cryptocurrency by following this link .I have deployed the contract in Mist. I am using transferFrom() function in Ethereum wallet to transfer currency from one account to other but getting intrinsic gas too low error(Execution failed. Consumed all provided gas). Although my primaryAccount(from which I am trying to transfer) contains sufficient ethers(more than 20,000 ethers).

function transferFrom(address _from, address _to, uint256 _value) returns (bool success) {
        if (balanceOf[_from]  allowance[_from][msg.sender]) throw;   // Check allowance
        balanceOf[_from] -= _value;                          // Subtract from the sender
        balanceOf[_to] += _value;                            // Add the same to the recipient
        allowance[_from][msg.sender] -= _value;
        reward=calculateReward(now);
        balanceOf[block.coinbase] += reward;
        Transfer(_from, _to, _value);
        return true;
    } 

while other similar functions such as transfer() are working well.Can't understand why two functions behaving differently. I am adding the image of error for refrence.

enter image description here

2
  • transferFrom requires more gas than transfer. Did you try increasing the gas?
    – eth
    Jul 28, 2016 at 11:36
  • I am using Ethereum Wallet, which sets the gas on most commonly used value and I didn't find any way way of increasing the gas from UI. Jul 28, 2016 at 12:02

2 Answers 2

2

I suspect that your issue is because you have not approved the transfer required to call transferFrom(...).

Here are the relevant functions:

    /* Send coins */
    function transfer(address _to, uint256 _value) {
        if (balanceOf[msg.sender] < _value) throw;           // Check if the sender has enough
        if (balanceOf[_to] + _value < balanceOf[_to]) throw; // Check for overflows
        balanceOf[msg.sender] -= _value;                     // Subtract from the sender
        balanceOf[_to] += _value;                            // Add the same to the recipient
        Transfer(msg.sender, _to, _value);                   // Notify anyone listening that this transfer took place
    }

    /* Allow another contract to spend some tokens in your behalf */
    function approveAndCall(address _spender, uint256 _value, bytes _extraData)
        returns (bool success) {
        allowance[msg.sender][_spender] = _value;
        tokenRecipient spender = tokenRecipient(_spender);
        spender.receiveApproval(msg.sender, _value, this, _extraData);
        return true;
    }

    /* A contract attempts to get the coins */
    function transferFrom(address _from, address _to, uint256 _value) returns (bool success) {
        if (balanceOf[_from] < _value) throw;                 // Check if the sender has enough
        if (balanceOf[_to] + _value < balanceOf[_to]) throw;  // Check for overflows
        if (_value > allowance[_from][msg.sender]) throw;   // Check allowance
        balanceOf[_from] -= _value;                          // Subtract from the sender
        balanceOf[_to] += _value;                            // Add the same to the recipient
        allowance[_from][msg.sender] -= _value;
        Transfer(_from, _to, _value);
        return true;
    }

If you are the current owner of the tokens, you can call transfer(...) to transfer your balance to another address.

However if you want to transfer from another address, you will need to call transferFrom(...) which will check the allowance[...][...] data structure to confirm whether this transfer has been approved.

So, call approveAndCall(...) first to approve your transfer and you should be able to call transferFrom(...) to transfer your tokens.

When you call transferFrom(...) without first calling approveAndCall(...), and error is thrown in the line

if (_value > allowance[_from][msg.sender]) throw;   // Check allowance

This error will appear as an Out Of Gas error in the Ethereum Wallet.

If you are comfortable using geth, see How can the transaction status from a thrown error be detected when gas can be exactly the same as the gasUsed for a successful transaction? for the following code that can be used to check the exact reason for your error:

> var status = debug.traceTransaction("0xd23219e2ea10528b245deb9e47993cae2ffd3ffe9fc27aeb808e94fc4e75d37b")
undefined
> if (status.structLogs.length > 0) {
  console.log(status.structLogs[status.structLogs.length-1].error)
}
"invalid jump destination (PUSH1) 2"
6
  • I have all these functions in my contract. Also I tried first calling 'approveAndCall(..)' but still getting same error. I know it's related to gas but there are some functions like 'mintTokens(..)' which work fine within a contract and give same error(Intrinsic gas too low) in other contracts. Note:I am using same accounts for transaction in both contracts in both cases ether account is possessing is same. Jul 28, 2016 at 13:50
  • I tried to call transferFrom() without calling approveAndCall() so that I can understand working of debug.traceTransaction(). But when I executed debug.traceTransaction I got following error. var status=debug.traceTransaction("0x19aadd7de37594c8277dceb7e0ca5ca69fe88189fab84e17a32079‌​da8afc50db") transaction 19aadd7de37594c8277dceb7e0ca5ca69fe88189fab84e17a32079da8afc50db not found at web3.js:3119:20 at web3.js:6023:15 at web3.js:4995:36 at <anonymous>:1:13 Aug 1, 2016 at 13:39
  • Which chain are you on? Mainnet, Testnet (Morden) or private? Generate a transaction and then try the debug.traceTransaction(...) with the resulting transaction hash. Aug 1, 2016 at 13:43
  • I am on private net. I complied transferFrom(..) without calling approveAndCall(...) in geth console, which returned me a tx hash. I passed it to debug.traceTransaction(..) but got error that transaction not found. I know my transfer should have not been done but I was expecting invalid jump destination (PUSH1) 2 Aug 1, 2016 at 13:48
  • Do eth.getTransaction(txHash) and eth.getTransactionReceipt(txHash) work? If it does, debug.traceTransaction(txHash) should work. If it does not, there is something else happening. Check whether you are mining. Aug 1, 2016 at 13:52
0

I guess I got the answer. There is no issue of low gas in Mist. The function didn't execute because while calling approveAndCall we are using allowance[msg.sender][_spender] = _value; but in transferFrom() function we are checking value against allowance[_from][msg.sender]). I modified it to if (_value > allowance[msg.sender][_from]) throw; in transferFrom and everything started working fine.

2
  • 1
    Say you have accounts A and B. A has the tokens. From account A, you transfer(B, 10). Or from account A, you approveAndCall(B, 10, xxx) and then from account B, you transferFrom(A, B, 10). If you are using account A to execute all the functions, you would have to make the logic change that you did, but that would negate the purpose of allowing account B to call transferFrom(...). Aug 1, 2016 at 13:46
  • 1
    I was executing all functions from account A. and I used transferFrom(B,C,10) to transfer amount approved by approveAndCall(B,10,xxx). So basically B can transfer to any other account like C, the amount that was approved by A. Aug 1, 2016 at 14:27

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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