1

Long story short I am curious how a contract stores variables in memory, so is it possible to spam say 100 transactions at once and the values to be changed afterwards...I am sure I am giving bad description so here is the code to better illustrate my point:

contract thiscontract
{

uint256 balancer = 3000;

function something() public payable
{
if(balancer > 0)
{
balancer -= 1000;
msg.sender.transfer(1000);
//event Transfer(msg.sender, balancer);
}

}
}

Basically: The function should send no more than 3000 wei, each time sending 1000 wei - if 4th msg.sender calls it after the first 3 calls it will not send anything since the value is 0 and the "if" statement prevents it.

But what will happen if 100 or more transactions call the "if" simultaneously? Does the contract 'freeze' and processes every single check one after another? Or does the contract allow some sort of parallelism like a web server and many people can call it and do this exact operation in parallel?

Because if the case is as described in "parallel" what happens is:

// it takes 0.05 seconds or so to check "if" statement... // however 10000000 calls are made to cause denial of service/parallel check:

if (balancer > 0)

// let's say 5000 pass the check and continue to sending... If someone calls it an hour later it will surely fail but still way many succeed.

I am sure this isn't possible, the only thing I know is "if" check or "Require" takes some computational time and you can read a contract without any blockchain interaction, however this is so basic that it can't be possible. Maybe someone should send 200 transactions via loop statement in web3 js/python on ropsten and see if they all obey the if rule above or more succeed or better yet pass them to aws instances who execute transactions in parallel.

Final note for now: From purely programming point of view this may be impossible since the transaction will be sent to bytecode assembly LIFO which will obey the "last in, first out" rule causing indeed freeze/slowdown and impossibility of parallel execution (so no: solidity seems far simpler than java/c# or webservers with asynchronous calls and so on). I am not 100% sure and maybe the many nodes can make it possible but I admit I have limited understanding of how exactly the transaction flow occurs between Ethereum nodes.

  • 1
    Consider the simple scenario of Double Spending - I have 100 Ether, and a send them "simultaneously to two different friends of mine. Each transaction by itself is legal. But when these two transactions are added to the blockchain, the blockchain network (i.e., nodes on the blockchain network) will reject this new state, because it violates a rule (of your account having a balance of minus 100 Ether). Does that answer your question? – goodvibration Dec 13 '19 at 9:52
  • Yes but my point was that balance occurs before transaction hits the blockchain or not? I mean how could this happen when "balancer" isn't yet written? Unless ethereum transactions occur at 100000 per second...which was my point. – Robert Ggg Dec 13 '19 at 10:41
0

tl;dr: Your transactions will be executed in a sequential order.

You cannot determine the order beforehand, because the miners decide which transactions will be added to the block. When you create let's say 4 transactions calling your something() function at the same time, you create those while the Smart Contract has the state "balancer = 3000". If you simulate their execution on the current state, all of them will pass. You send them to the ethereum network, the nodes within the network verify them regarding the common consensus rules and store and relay them to other nodes if they are okay. Miners who continiously create blocks will eventually include them in blocks (assuming your supplied gas is attractive enough for them). You cannot determine in which blocks those transactions will be included (but you can reduce the average time by supplying an attractive amount of gas). Each transaction is put in a sequential order within a block and each block is put in a sequential order within the blockchain. When a block is "executed" (verified, stored and relayed), the transactions within are executed one after another, depending on the order the miner has specified. After the execution of a transaction, the state is updated accordingly and every following transaction will be executed upon that new state.

One sidenote: Use require(...) within your something(...) function if the conditions are not met. This way you ensure that the smart contract reverts in case the conditions are not met and that the sender therefore receives the funds (the remaining gas and the ethereum supplied to the "payable" function) back.

| improve this answer | |
  • thanks...but about the 2nd point: isn't "revert" included in transfer? I mean with call/delegatecall if/require seem obligatory but aren't send/transfer sort of "tuned up" functions that both prevent renntrancy and check if receiver gets ether? I usually put require though just in case but here the point was alternative. – Robert Ggg Dec 13 '19 at 10:38
  • @RobertGgg I just realised that your function does not accept incoming ether, it sends ether to the caller. You should remove the "payable" attribute in that case, because it is only required if the smart contract can receive ether through that function. In that case (receiving funds), a require(...) would be mandatory in case of an error because otherwise the received funds would not be sent back to the caller and the state might be inconsistent. The if statement should still be replaced by a require to send the remaining gas, which was not consumed during the execution, back to the caller. – sea212 Dec 13 '19 at 10:54

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.