Smart Contract Execution – Understanding Ethereum Smart Contract Execution

contract-invocation

I have a question that might sound really dumb, but its understanding is crucial for me.

Say, I have a Smart Contract, which has a public variable, and a setter to change that variable. If a Smart Contract is executed by 2 addresses simultaneously, how the Ethereum Blockchain behaves? Will it execute the first contract for the first address, and then execute it for the second one, or will it make a "copy" of the contract, to execute it for the second address? Can there be a case, when the setter function for the second address will fail to change the variable, since the variable will be already "in use" by the first address?

Best Answer

It's not a dumb question.

It will never make sense while thinking about the contracts as separate instances running on different nodes. The EVM is modeled as a distributed state machine. There is an EVM state that is logical, and separate and apart from the nodes. The protocol ensures (nearly) that the nodes will eventually agree on the canonical state at a given point.

A crucial concern to sort out is the order of transactions. All nodes must agree on this as a prerequisite for agreement about the effect of those transactions. There is ambiguity about transaction order due to network latency. This is resolved by the mining process. Mining produces blocks of transactions in a specific order. When nodes hear about a block, they process the contained transactions and then will reach agreement with other nodes at that block number, also known as block height.

If a Smart Contract is executed by 2 addresses simultaneously, how the Ethereum Blockchain behaves?

This is not possible. Everything is kicked off by an externally owned account (a wallet) signing a transaction and addressing it to a smart contract, normally to a specific function. The contract isn't "running", but the transaction is proposed.

The transaction will be mined. There is no assurance about the mined order of two transactions signed by two different accounts that are broadcast more or less simultaneously. What we can be sure of is the mining process will ensure that one or the other proceeds first. It will be evaluated entirely before work on the next transaction starts.

Will it execute the first contract for the first address, and then execute it for the second one

It will execute the one that got mined first, and then the one that got mined second.

or will it make a "copy" of the contract, to execute it for the second address

a "copy of the contract" exists on every full node. Contracts are part of the state and are used to process the transactions in the blocks (how can a node process the transaction against a contract if they don't have a copy of the contract?). Every full node runs every transaction. The "state" of the virtual machine is known to all full nodes. The state is the only logical conclusion given well-ordered transactions described in the blockchain about which they all agree.

Can there be a case, when the setter function for the second address will fail to change the variable, since the variable will be already "in use" by the first address?

No. However, the state of the contract at the beginning of the second transaction will be the result of the first transaction. It will execute in the context the first transaction left behind when it was done.

Here's a simple example I cobbled together. Imagine a coordinated burst from multiple senders all trying to be first. It will only work for the first transaction mined, which is not the same as first sent. Indeed, the contestants can compete with each other by bidding for priority using the gasPrice.

pragma solidity 0.4.25;

contract WorksOnce {

    bool isUsed;

    event LogLuckyWinner(address sender);

    function pickMe() public {
        require(!isUsed);
        isUsed = true;
        emit LogLuckyWinner(msg.sender);
    }
}

Hope it helps.

Related Topic