[Ethereum] Sending multiple transactions at once

contract-developmentsolidity

How do I create an Ethereum contract which itself create multiple transactions as a result of a single invocation.

Can anyone help me out here?

Best Answer

You make a Splitter contract to handle the rules and get A to send to the contract.

I wouldn't be especially hard to code, but for security reasons, you don't want to do it all at once.

Instead, have A send 20 to a contract. Have the contract calculate four equal parts and record amounts owed to B, C, D and E.

Have another function to facilitate on-demand withdrawals. B, C, D and E claim their allocations when they wish. Each withdrawal transaction is kept separate from the others.

Question rhymes with this (splitter with different rules): https://stackoverflow.com/questions/42990292/smart-contract-limitations-in-ethereum-fabric

Hope it helps.

Update:

Naive Example:

This contract doesn't conform to recommendations for the safe handling of funds. It will seem to work for a while. Edge cases (deliberate accidental) will cause serious problems.

pragma solidity ^0.4.6;

// This contract contains hidden security risks. 
// it is vulnerable to known attack types. 
// For illustration only. Do not use. 

contract NaiveSplit {

  address[4] public beneficiaryList;

  // emit events for real-time listeners and state history

  event LogReceived(address sender, uint amount);
  event LogSent(address beneficiary, uint amount);

  // give the constructor four addresses for the split

  function FourWaySplit(address addressA, address addressB, address addressC, address addressD) {
    beneficiaryList[0]=addressA;
    beneficiaryList[1]=addressB;
    beneficiaryList[2]=addressC;
    beneficiaryList[3]=addressD;
  }

  function pay() 
    public
    payable
    returns(bool success)
  {
    if(msg.value==0) throw;

    uint forth = msg.value / 4;

    beneficiaryList[0].send(forth);
    beneficiaryList[1].send(forth);
    beneficiaryList[2].send(forth);
    beneficiaryList[3].send(forth);
    LogReceived(msg.sender, msg.value);
    LogSent(beneficiaryList[0], forth);
    LogSent(beneficiaryList[1], forth);
    LogSent(beneficiaryList[2], forth);
    LogSent(beneficiaryList[3], forth);
    return true;
  }
}

Very simplistic example:

pragma solidity ^0.4.6;

contract FourWaySplit {

  // balances and account list are publicly visible

  mapping(address => uint) public beneficiaryBalance;
  address[4] public beneficiaryList;

  // emit events for real-time listeners and state history

  event LogReceived(address sender, uint amount);
  event LogWithdrawal(address beneficiary, uint amount);

  // give the constructor four addresses for the split

  function FourWaySplit(address addressA, address addressB, address addressC, address addressD) {
    beneficiaryList[0]=addressA;
    beneficiaryList[1]=addressB;
    beneficiaryList[2]=addressC;
    beneficiaryList[3]=addressD;
  }

  // send ETH

  function pay() 
    public
    payable
    returns(bool success)
  {
    if(msg.value==0) throw;

    // ignoring values not evenly divisible by 4. We round down and keep the change.
    // (No way to remove the loose change, so it's effectively destroyed.)

    uint forth = msg.value / 4;

    beneficiaryBalance[beneficiaryList[0]] += forth;
    beneficiaryBalance[beneficiaryList[1]] += forth;
    beneficiaryBalance[beneficiaryList[2]] += forth;
    beneficiaryBalance[beneficiaryList[3]] += forth;
    LogReceived(msg.sender, msg.value);
    return true;
  }

  function withdraw(uint amount)
    public
    returns(bool success)
  {
    if(beneficiaryBalance[msg.sender] < amount) throw; // insufficient funds
    beneficiaryBalance[msg.sender] -= amount;          // Optimistic accounting.
    if(!msg.sender.send(amount)) throw;                // failed to transfer funds
    LogWithdrawal(msg.sender, amount);
    return true;
  }

}
Related Topic