I have a global variable foo that I'd like people to be able to increment in a shared fashion.

int foo;
function addToFoo(int value) public {
   foo += value

Im concerned that if this function could fail due to reentracy.

for example: lets assume foo is currently equal to 1, then if user A calls addToFoo(1) and user B calls addToFoo(2) then ideally I'd like foo to be 3. However, if user A and B make their calls at almost the exact same time then I'm concerned that foo could equal 1 or 2 instead of 3, due to both grabbing the same starting value of foo.

So my question is what is the best practice to ensure that the foo is always 3?

Can I use a mutex and loop while the mutex is in use or will this burn too much gas?

Should I just revert when foo is in use? That doest seem great.

Or should I have a queue where people add their values to the queue and then later I can loop through the whole queue and do all the summations? If I go with this solution then I'd have to break up the loop some how to ensure that it can scale to millions of additions.

None of these solutions seem great...

Any help would be great thanks!


Transactions are fully serialized, so there's no issue here. Either A or B will go first, and the second transaction will use the resulting state from the first transaction.

  • How did the DAO attack work if transactions were synchronous? I thought someone was able to call the function mid execution somehow?
    – mark
    Mar 26 '18 at 18:21
  • 1
    They called a function twice during the same transaction through reentrancy. A calls B which calls A again.
    – user19510
    Mar 26 '18 at 18:22

Use of mutex is needed only in a concurrent environment and there is no concurrency related with evm where your solidity code get executed.

Transactions are mined into blocks in an order and transaction A and transaction B will be executed in the order of they were mined.

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