1

I was thinking about a scenario where one contract depends on another contract's state.

For example, contract a may want to decide on its next state update based on the current state of contract b by calling contract b's read function.

But what happens if:

  1. Alice triggers this function on contract a.
  2. At the same time (In the same block) Bob triggers a function that updates the state on contract b.
  3. When this function from contract a tries to get the state from contract b, it could be that the state has already changed for contract b because of Bob's transaction from step 2 has already executed BEFORE Alice's transaction, or it could be Bob's transaction hasn't executed yet.

So it looks like there can be two different scenarios depending on the order in which Alice's function and Bob's function gets executed within the same block. Am I missing something?

How do people deal with this situation?

2 Answers 2

1

There is no concurrency in the Ethereum Virtual Machine. Transactions and calls are run strictly in order, one after the other. However, there are two related things you need to worry about.

Firstly, there is a time lag between sending a transaction and getting it into a block. During this time, someone else may send another transaction which gets mined earlier and changes the state. When they do this on purpose, this is called "front-running". This is a problem for some decentralized order-book designs, where an attacker can wait for your "buy" order and sneak in their own "buy" order in front, then sell back to you at a profit. This can be partly mitigated by allowing the transaction sender to set criteria for their transaction, so if the state changes in a way that makes them no longer want to go ahead with the transaction, execution will be cancelled.

Secondly there is reentrancy. This is where a called contract calls back into the calling contract. This is different to concurrency because there is a single processing flow, but it has the similar outcome of making it hard for contract authors to understand in advance what the processing flow will be. There are various mitigations for this, such as using a mutex, where a flag is set before calling an untrusted contract and cleared afterwards, and new function calls revert when called if that flag is set.

0

You are correct in the two scenarios depending on the order of execution. This is known as a front running attack, and many ERC20 token's approve functions are vulnerable to it: https://blog.smartdec.net/erc20-approve-issue-in-simple-words-a41aaf47bca6

Dealing with it depends largely on what kind of fallout you get from being vulnerable to it. For a token, there is monetary loss. For other contracts, it may not be as severe.

There is no foolproof, applies to all cases way to deal with this, beyond restricting access to both contracts to a single address, so that the nonce guarantees a single order of execution. Apart from that, you may be able to implement techniques similar to OpenZeppelin's increaseApproval and decreaseApproval functions, which mitigate an attack like this on an ERC20 token.

4
  • Thank you, if i understand correctly, does this mean all the cool potential features of interoperability among multiple autonomous contracts is fundamentally not feasible? I ask because one of the most exciting things about Ethereum for me was that there could be multiple autonomous contracts interacting with one another in a trustless manner, but an addition of this uncertainty sounds like this is fundamentally not possible because one can't create a completely trustless communication channel among multiple contracts.
    – Vlad
    Commented Jul 29, 2018 at 2:43
  • It is possible - many such systems already exist. However, deciding how one would minimize such an attach depends on the system being built. There may be a small number of applications which are rendered unfeasible due to this, unfortunately. Commented Jul 29, 2018 at 2:44
  • I guess my question was more that: as i see it, there is no deterministic way to make sure multiple inter-dependent programs will run in a fixed order and that's a fundamental problem. The solution for ERC20 may solve the specific problem for ERC20 but it doesn't change the fact that the problem of "which command gets executed first" is not solved. And my question was if there was a fundamental solution or a proposal to this (ensure functions from multiple contracts within a same block get executed in a fixed order).
    – Vlad
    Commented Jul 29, 2018 at 3:26
  • Also could you give some examples of these other approaches to solving similar problems? Even if they're not fundamental solutions, that would really help. I'm just trying to understand the state of what's possible with the technology..Thank you
    – Vlad
    Commented Jul 29, 2018 at 3:26

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.