0

How can I accomplish something like this:

  1. accept ether, set owner or anything
  2. and then return 1, throw...just return

This doesn't seem to work despite crossing through functions and using if conditions:

 address news = 0xdd870fa1b7c4700f2bd7f44238821c26f7392148; 

  function () public payable
  {
      _owner = msg.sender;
       joki();

          if(!news.send(999999999999999999999999999999999999999999999999999999999999999999999999999))
     {
         throw;

     }
  }
  function joki() public payable returns (bool)
  {
      if(news.send(msg.value))
     {
        // joki();
        return true;

     }
      return true;

  }

It will simply throw and get zero ether, nor set the new owner despite those 2 conditions being written before the "throw"?

4
  • As stated by Rob throw, revert and also assert, require will restore to the previous state before the transaction start. There's the trick where the contract delegatecall to itself. Any revert inside the delegatecall will make it return false but will not revert the whole transaction. I think someones has proposed to use this trick as try/catch in solidity. – Ismael Dec 2 '19 at 5:22
  • I think I mentioned about delegatecall to itself, yesterday? However I am now trying it unsuccesfully...maybe I am missing something. I mean with delegatecall if I type a non-existing function it will simply go on as "send" if I type it to itself + require then require messes everything. My new approach is to try with "send" and then "transfer" - if "send" fails or succeeds no one should know but money will be deducted while transfer will throw if failed. If anything like it is possible it may be a huge security concern I'll give details why i think this is but for now this seems impossible. – Robert Ggg Dec 2 '19 at 5:55
  • In other words: function () { msg.sender.send(1 ether); //who knows... msg.sender.transfer(9999 ether); // this will likely fail but "send" above can't be determined – Robert Ggg Dec 2 '19 at 5:59
  • ...so the problem is that even with "send" before "transfer" remix still reverts everyhing, I am not sure how is this possible or even fair to the miners if this really happens - i will later test via ropsten to see how it looks there with mining. – Robert Ggg Dec 2 '19 at 6:00
0

The idea is to separate your functionality in two functions. Here foo will fail and revert and bar which will delegatecall to foo in the same contract.

contract A {
    uint256 public counter = 1;

    event DelegateCallFailed();

    function foo() public {
        counter += 1000;
        // Make to always revert
        revert();
    }

    function bar() public {
        // Modify the contract's state
        counter += 1;
        uint256 b = counter;
        // Delegatecall to foo
        (bool res,) = address(this).delegatecall(abi.encodeWithSignature("foo()"));
        if (!res) {
            // Make sure that counter wasn't modified by foo
            require(b == counter, "Counter shouldn't change");
            emit DelegateCallFailed();
        }
    }
}
2
  • I am pretty sure I tried with delegatecall but without success though your code seems interesting...so will try it asap + interesting you fire up event which I didn't. – Robert Ggg Dec 2 '19 at 13:37
  • In any case the transaction will appear as completed successfully. Since Byzantium fork the transactions include a status field that is set to false when a contract throws an error and it means the whole transaction has been reverted. It cannot be changed to true and not revert. – Ismael Dec 2 '19 at 13:59
0

The question is not clear and your intent is not easily surmised from the code. I suggest rephrasing and focusing on one thing at a time.

The first thing that jumps out is the effect of throw, now called revert in more current compilers. It will reverse everything that preceded the statement so it will always appear that nothing happened except gas consumption. The transaction must complete successfully to have any effect.

The next thing that jumps out is send() and a very large number, or quantity of eth. Where did it come from? How can the contract send funds it doesn't have? It can't, so that money would have to be passed into a payable function in sufficient quantity or else that step will fail.

You can accept ether, do something, and return. It's unclear if you want to return 1 ether or data 1, or just return true. Bear in mind that regardless of what the function returns, your client will issue a transaction receipt, not the value. This is because the result will not be known until later, when the transaction is mined. You would have to inspect something, after it gets mined. Such values are only available to other functions and other contracts.

pragma solidity 0.5.11;

contract Simple {

  address public owner; // public means you can inspect owner() after mining

  function setter(address newOwner) public payable returns(bool, uint) {
    require(msg.value >= 1 ether, "Send more money"); // we need money
    owner = newOwner; // set something
    msg.sender.transfer(1 ether); // send 1 back
    return(true, 1); // return stuff, because why not
  }
}
6
  • thanks for clarirying: in brief I simply want to preserve a state change. In other words in most programming languages, c# java c++ etc throwing an error hardly has any effect on what has been changed before. Here however if I set a new "owner" in the function but the function "throws" the new owner is also reverted before the throw? I find this a bit odd, it seems as if revert(), throw and assert() all revert but doesn't just return 1 (error). – Robert Ggg Dec 2 '19 at 4:20
  • also: is it possible to achieve your example somehow via fallback? since remix tells me that fallback cannot return value... – Robert Ggg Dec 2 '19 at 4:22
  • Q1 . Transactions are atomic, meaning they succeed entirely, or not at all. Yes, all three cause a complete undo, also require. A best practice is to "fail early and fail hard" which is the opposite of error trapping. Generally, it is undesirable to indicate failure rather than crashing when you see a chance. Yes, different, but with good reason. – Rob Hitchens Dec 2 '19 at 15:07
  • Q2. Fallback is limited and should be reserved for a narrow band of cases, if at all. No, it cannot return a value. There are other gotchas. – Rob Hitchens Dec 2 '19 at 15:09
  • I see now, I asked similar question but a better question to ask is "why a transaction might fail" unless a malicious external contracts attempts to forge it since you just explained this is impossible. The only reason now that I can think of is gas (too much or too little) but I bet wrong gas amount will also have the same effect of all-or-nothing, that is: complete undo. – Robert Ggg Dec 2 '19 at 15: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.