3

I Wrote a contract which contains a function that allows ether to be sent from the contract to the another contract. Everytime I call the function however I am notified that there is not enough gas for the transaction as shown below:

My Code is as follows:

contract bankPlus {
/* Define variable owner of the type address*/
address public owner;
uint256 fifty = 500000000000000000;
address public taxContract = 0x29a02cd0f340efb6492c535a951fb33270ad1ef7;

mapping (address => uint) balances;

/* this function is executed at initialization and sets the owner of the contract */
function mortal() { owner = msg.sender; }

/* Function to recover the funds on the contract */
function kill() { if (msg.sender == owner) selfdestruct(owner); }

function cashOut() { owner.send(this.balance / 2 ) ;}//pays out half the contract with the other half taxed

function deposit(address customer){
  uint value = msg.value;
  balances[customer] += value;
}

function withdraw50(address customer){
  if(balances[customer] > fifty){
    customer.send(fifty); //sends a 0.5 of an ether
    balances[customer] -= fifty;
  }
  else return;
}

function sendMoney(address customer, address recipient, uint256 amount) {
  if(balances[customer] > amount){
    customer.send(amount);
    balances[customer] -= amount;
  }
  else return;
}

function refund(address recipient, uint amount) returns (string) {
  if(amount < this.balance){
    recipient.send(amount);
    return "refund processed";
  }
  else return "Refund amount too large";
}

function payBankTax(){
  taxContract.call.gas(240000).value(this.balance / 3)(); //calls another contract initiated by the owner
}

}

contract bankInfo is bankPlus{
  function getBalanceOf(address customer) constant returns(uint){
    return balances[customer];
}

  function getBankBalance() returns (uint256){
    return this.balance;
  }

}
  • how much gas are you sending in the transactions? can you paste an example of a transaction? are you using geth or an other tool? – Roland Kofler Jul 11 '16 at 8:37
2

If your receiving contract fallback function is writing to storage or just doing everything but log the transaction, your first contract send() will fail due to a 2300 gas limit on send(). Maybe that's the cause of the failure.

However, keep in mind that your sendMoney function is insecure: if send() fails, it just return false, doesn't throw anything, so in the case of a send fail your function:

function sendMoney(address customer, address recipient, uint256 amount) {
if(balances[customer] > amount){
customer.send(amount);
balances[customer] -= amount;
}
 else return;
}

would deplete balances[customer] with no actual ether being sent at all. Instead,

if( customer.send(amount) ) {
    balances[customer] -= amount;
}

(or just throw when send returns false)

Would be more secure. Just check this to check for security issues.

Actaully, if the receiving contract must do write something to storage, you can replace

address.send();

with

address.call.gas(xxx).value(amount)();

to manually set up the gas limit. However, you must be careful since this allow the receiving contract to set up all sorts of reentrancy attacks. (Your sendMoney() function as is write right now, and even the version I provided before, are both vulenrable to reentrancy attack if send() is changed to call ).

  • there is no fallback func... – Roland Kofler Jul 11 '16 at 11:50
  • Thanks for taking the time to answer, my contract actually has specified the gas limit as above with: taxContract.call.gas(240000).value(this.balance / 3)(); – Jim Jul 11 '16 at 23:17
  • Ok, so is that method that fails, and not refund(). What does taxContract fallback function? – Sergeon Jul 11 '16 at 23:24

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.