I have one question about the "require function" of smart contract. Function is as following,

function set(uint currentTs) public {
    require(msg.sender == owner);
    ts = currentTs;

I'm not the owner but I call this function with parameter (for exmaple, 1567569109). So, the raw transaction contains contract's address, my EOA, gas, ...., and currentTs which is 1567569109.

However, my EOA doesn't match the condition in require function. At this time, is the transaction sent by me going to be mined successfully but with smart contract's status not changed. (If I scan all the transactions on the whole blockchain, I can find 1567569109, but when I query to the variable ts in smart contract, ts doesn't change.)

Does it correct? Or, if the condition in require doesn't match, the transaction will fail and it is not going to be mined.



Short answer: The transaction will fail and will be mined. You will be charged for gas cost, but smart contract's state will not change. Transaction status will be 0x0 (failed).

Long answer: Pseudo-function revert checks condition and, in case condition is false, reverts all changes made so far by current smart contract invocation. It also recursively reverts changes made by all smart contract invocations and all ether transfers performed by the current smart contract invocation. It also returns to the sender all the ether sent along with the current smart contract invocation. Though, in case this smart contract was invoked by another smart contract, require does not revert changes made by the invocation of that another smart contract. Also, gas is not refunded. So, even if condition is false, require does not necessary revert all the changes made by the current transaction, but only the changes made by the current invocation, does not refund gas cost, and does not prevent transaction from being mined. Transaction status only reflects the execution status of the topmost smart contract invocation within the transaction, and is not affected by the nested invocations, either successful or unsuccessful. Though, when smart contract is called from externally owned address, current transaction and current smart contract invocation are about the same thing.

  • If contract A's method setA() changes a variable 'a' value from 1 to 2 and then invokes contract B's method setB() and require inside setB() gets false, so according to your answer what will be the value of 'a' after this transaction (though it is a failed transaction)? Sep 4 '19 at 9:40
  • Yes, require inside setB will not revert the whole transaction, but only invocation of setB, and control will be returned to setA with error status. Then setA should handle this, either by reverting setA invocation or in some other way. Anyway, it is up to setA byte code, how to handle errors inside setB. Function setB cannot do anything about this. Sep 4 '19 at 11:51
  • But this given contract behaves not according to your explanation. After being failed, the value of variable 'a' is still 1. pragma solidity 0.5.11; contract A { uint public a = 1; function setA(address _b) public { a = 2; B b = B(_b); b.setB(a); } } contract B { function setB(uint _b) public { require(_b == 1, "Not Equal"); } } Sep 4 '19 at 12:38
  • In your example, author of contract A decided that setA should revert in case inner setB call failed. This was his free decision. Author of A was able to handle setB failure is any other way he likes, for example ignore it, or log event, or return false; and setB cannot to anything with this. Sep 4 '19 at 13:47
  • Thanks for your answer! Could you give an example of contract A that is not revert (value 'a' in contract A is changed to 2 successfully) in this case?
    – tyyen
    Sep 6 '19 at 1:32

When, the condition in require does not match, the transaction can be mined and inserted in the block but the transaction status will be 'failed'. All the state changes before the require statement will be reverted to the previous state. The remaining gas will be refunded if any.

So, what you have found in your case is correct. The transaction was added in the chain but, as require gets failed, the state was unchanged.

Further Explanation, See here

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.