4

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?

4

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;
  }

}
  • Yes, unless the portions shift around by other factors (time) then I would do all the math on receipt so funds are allocated so you always have an accounting of liabilities and users can see how much is in their account. – Rob Hitchens - B9lab Mar 28 '17 at 3:41
  • For now I'm just concerned with the basic code. I don't care so much About Other factors. I wonder how that would look like in code. Is there an example maybe? – Wil K Mar 28 '17 at 8:53
  • In fact I must know this, would it work the other way around? Could you help one more time please Rob? – Wil K Mar 28 '17 at 20:45
  • 1
    Added another exampled of a "not recommended" structure. It depends what you call "work". It doesn't work in all scenarios ("doesn't work"). It will seem to work but it will fail a security audit. I can't explain the security issues in any depth in a small space. It's an airplane that seems to fly but no one should want to get in. Not sure if this is decipherable, but ... github.com/ConsenSys/… The "Simple" example observes these recommendations. The "Naive" example does not. – Rob Hitchens - B9lab Mar 29 '17 at 0:40
  • So more like a crowd-fund than a splitter. This comment thread is getting too long for SE. Can you post as separate question and clarify the rules? Are the payments in a fixed amount or variable? Does payout wait for all four to pitch in or happen when a goal is reached? Is there a deadline. What happens if someone doesn't pay? – Rob Hitchens - B9lab Mar 29 '17 at 9:21
0

Handling of multiple transaction as one (commit or rollback) is a serious drawback, particularly with respect to chaining of contract beyond just exchanging tokens (or numbers). If/when multiple contracts are touched by more than one transactions, each could be mined by separate entities at different point of times. Effectively, multiple transaction handling as one has to be done from the client side (DApp or elsewhere) to emulate completion or rollback.

0

If you are looking to send tokens/bal to mutiple adressess you can check this out send to multiple address

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.