2

Here is the code confusing me:

function createRelay () returns (bool success) {
    relay = new Relay()
    bool success = Relay(relay).setRelay(someInt, someAddress);

    if (success) {
        msg.sender.send(fee);
    }
}

I'm trying to send a predetermined fee to the new instance of a Relay contract.

Who is msg.sender? How do I point to the Relay I want to send the fee to?

2

msg.sender is the account (external or another contract) that called createRelay().

If you want to send to your Relay, you write: relay.send(fee) or if you want it to be part of the setRelay call you do:

bool success = relay.setRelay.value(fee)(someInt, someAddress);
  • Thank you! And the value of fee coming from msg.sender in that case? Or is it coming from "self"? – Michael O'Rourke Jan 18 '17 at 16:50
  • It is coming from the contract's balance. If the contract does not have enough to cover the fee, the call fails. – Xavier Leprêtre B9lab Jan 18 '17 at 17:12
  • "...the call fails" and will cause an exception. This is good, whereas send needs to propagate the exception manually: if (!relay.send(fee)) { throw; } – eth Jan 20 '17 at 2:21
2

There are a few things that are a good reminder and can help minimize debugging. Here's an example and answer to the question.

contract Relay {
    function bal() constant returns (uint) {
        return this.balance;
    }

    function setRelay() payable {
        //...
    }

    function() payable {
    }
}

contract Bar {
    uint public x = 0;
    function foo(Relay contractRelay)  {
        x = 2;
        contractRelay.setRelay.value(100)();  // this is how to send a fee along with setRelay
    }
}
  1. Reminder to add payable modifier to setRelay if you want it to get a fee.

  2. contractRelay.setRelay.value(100)() is the syntax for sending a fee as part of setRelay. I changed the example so that setRelay doesn't have arguments, to highlight that the last () is important to avoid debugging headaches.

  3. If Bar has less than 100 wei, than setRelay will cause an exception and the transaction will be reverted (x will remain 0).

Here are reminders if instead foo just uses contractRelay.send(100):

  • The fallback function should have the payable modifier.

  • If Bar has less than 100 wei, then contractRelay.send(100) will not cause an exception: x will be set to 2. A general recommendation is to always check the return value of send, and in this case

the following is probably desired:

if (!contractRelay.send(100)) {
    throw;
}
  • This was incredibly helpful. Thank you for expanding on my question. – Michael O'Rourke Jan 20 '17 at 14:37
  • 1
    Glad it's helpful: don't want others to spend much time with unnecessary debugging or writing less secure contracts. – eth Jan 21 '17 at 1:42

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.