I have a simple contract:
pragma solidity ^0.4.0;
contract Festival {
address owner;
uint8 max;
address[] entered;
function Festival(uint8 _max) {
max = _max;
owner = msg.sender;
}
function joinFestival()
{
if(entered.length < max)
entered.push(msg.sender);
}
}
For example we set max=3
.
So let's say we call this function from some web page using web3.js
Festival.deployed().then(function(fest){
return fest.joinFestival({from:web3.eth.accounts[0], gas: 100000});
});
Okay, great. When first guy calls the function we get something like that:
if(entered.length < max) // yes, length == 0, success, we can join!
entered.push(msg.sender) //joined
After a while, when the transaction has been confirmed, second guy call the function:
if(entered.length < max) // yes, length == 1, success, we can join!
entered.push(msg.sender) //joined
And now the interesting part. 3rd and 4th guys are trying to join at the same time.
3rd guy:
if(entered.length < max) // yes, length == 2, success, we can join!
entered.push(msg.sender) //joined
And now his transaction is pending. At the moment the 4th guy is calling this function the 3rd guy transaction is still pending:
if(entered.length < max) // yes, length == 2, success, we can join!
entered.push(msg.sender) //joined
And so, the problem is in the last call. The thing is that this guy will get TX error and all gas will be spend. Since gas=ether, it is a very bad situation. My question is: how can we prevent this situation? I have only one way in my mind: check in web page .js file for pending blocks and if there is a transaction sent to our contract and the state of a contract is 'entered.length == 2' just throw an error to the 4th guy. If you have any suggestions it would be great. Thank you.