I have the requirement that in my smart contract certain functions cannot be called, if another function already has been called inside the same contract during the same transaction. Imagine I have the functions A, B and C. If function A or B is called, function C should not be callable inside the same transaction.

This is my approach so far: When A or B is called, store the following values with a modifier

  • tx.origin: I can't rely on msg.sender, as someone could deploy 2 smart contracts in one transaction, call A with one contract and C with the other
  • block.number

when C is called, check if tx.origin and block.number are the same as the stored values and revert if necessary.

This should ensure that C cannot be called if A or B were called in the same block by the same person. Is there a flaw in my logic here?

  • The title of the question says 'per block' and the body of the question says 'per transaction'. Those are two different requirements, which one is it that you actually need? – goodvibration Nov 30 '20 at 5:07
  • I need it per transaction, as I don't see how this is possible, I wanted to work this out for 'per block' first, as this is sufficient – Daniel Gretzke Nov 30 '20 at 11:33
  • It's actually harder per block than it is per transaction. See OZ (very simple) implementation. – goodvibration Nov 30 '20 at 11:35
  • The reentrancy guard only protects against calling another function again, while the function has not finished executing. An attacker could call A first and after A finished executing, they could call C without a problem – Daniel Gretzke Nov 30 '20 at 23:01

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.