Transfer Ether from Contracts to User Addresses – Step-by-Step Guide

gasgas-limitgas-priceinternal-transactionssolidity

I have code to transfer Ether to an address, as follows:

addr.transfer(amount);

Unfortunately, when I execute this statement for two transfers, the money never arrives in the addr addresses. I do see the Etherscan output on Ropsten:

enter image description here

I have a suspicion the transfers (call_1_0 and call_1_1 below) are never fulfilled, because the GasLimit is set to 2300. Is this possible?

Is there a way to increase the GasLimit? I tried using:

  uint GAS_LIMIT = 4000000;
  addr.transfer.gas(GAS_LIMIT)(amount);

but then the solc compiler says:

TypeError: Member "gas" not found or not visible after argument-dependent lookup in function (uint256)
addr.transfer.gas(GAS_LIMIT)(amount);
^—————^

This is the full code of the contract (beneficiaries are added during construction by a "manager" contract that instantiates it.

contract SimpleSmartAsset is Mortal {

  uint usagePrice;
  Beneficiary[] beneficiaries;
  uint totalWeight; // to calculate percentage the beneficiaries receive

  event AssetCreated(uint _usagePrice,
                     address[] addresses,
                     uint[] weights);

  function SimpleSmartAsset(uint _usagePrice,
                            address[] addresses,
                            uint[] weights) {
    owner = msg.sender;
    usagePrice = _usagePrice;

    uint beneficiaryCount = addresses.length;
    for (uint i = 0; i < beneficiaryCount; i++) {

      uint weight = weights[i];

      addBeneficiary(addresses[i], weight);
      totalWeight += weight;
    }

    AssetCreated(_usagePrice, addresses, weights);
  }

  function getUsagePrice() constant returns (uint) {
    return usagePrice;
  }

  event BeneficiaryPaid(address addr, uint amount);

  function pay() payable onlyOwner {
    require(msg.value >= usagePrice);

    uint beneficiaryCount = beneficiaries.length;
    for (uint i = 0; i < beneficiaryCount; i++) {

      Beneficiary memory beneficiary = beneficiaries[i];

      uint weight = beneficiary.weight;
      address addr = beneficiary.addr;

      uint amount = (weight * usagePrice) / totalWeight;

      uint GAS_LIMIT = 4000000;
      addr.transfer.gas(GAS_LIMIT)(amount);
      BeneficiaryPaid(addr, amount);
    }
  }

  struct Beneficiary {
    address addr;
    uint weight;
  }

  function addBeneficiary(address addr, uint weight) onlyOwner {
    beneficiaries.push(Beneficiary({
        addr: addr,
        weight: weight
    }));
  }

}

How can I transfer money to the user addresses from the contract?

Best Answer

Looking at your transaction 0xdd6c0059b330dc... both transfer were done correctly.

For example the second transfer is to address 0xbc965738eabb38..., you should look at the "Internal Transaction" tab, there's a line where "Parent Hash" is 0xdd6c0059b330dc... and block is 1287872 for an amount of 0.05402... Ether.

Usually "internal transactions" are not tracked by most wallets because it requires processing each transaction, and there's no public api to access them.

Related Topic