What is the difference between a transaction and a call?

  • What is the difference between a transaction and a call? In some interfaces, I can interact with contracts via calls or via transactions. What is the difference between the two, and can contracts also do transactions and calls?

    **NOTE** for avoiding confusion: `call` in this question is neither _EVM_ `CALL` opcode nor _Solidity_ `

    .call()`, which make changes in contract states, but _Web3.js_ API `web3.eth.call()`, which does not make any state changes.
  • eth

    eth Correct answer

    5 years ago

    Call

    A call is a local invocation of a contract function that does not broadcast or publish anything on the blockchain.

    It is a read-only operation and will not consume any Ether. It simulates what would happen in a transaction, but discards all the state changes when it is done.

    It is synchronous and the return value of the contract function is returned immediately.

    Its web3.js API is web3.eth.call and is what's used for Solidity view, pure, constant functions.

    Its underlying JSON-RPC is eth_call

    Transaction

    A transaction is broadcasted to the network, processed by miners, and if valid, is published on the blockchain.

    It is a write-operation that will affect other accounts, update the state of the blockchain, and consume Ether (unless a miner accepts it with a gas price of zero).

    It is asynchronous, because it is possible that no miners will include the transaction in a block (for example, the gas price for the transaction may be too low). Since it is asynchronous, the immediate return value of a transaction is always the transaction's hash. To get the "return value" of a transaction to a function, Events need to be used (unless it's Case4 discussed below). For ethers.js an example: listening to contract events using ethers.js?

    Its web3.js API is web3.eth.sendTransaction and is used if a Solidity function is not marked constant.

    Its underlying JSON-RPC is eth_sendTransaction

    sendTransaction will be used when a verb is needed, since it is clearer than simply transaction.

    Recommendation to Call first, then sendTransaction

    Since a sendTransaction costs Ether, it is a good practice to "test the waters" by issuing a call first, before the sendTransaction. This is a free way to debug and estimate if there will be any problems with the sendTransaction, for example if an Out of Gas exception will be encountered.

    This "dry-run" usually works well, but in some cases be aware that call is an estimate, for example a contract function that returns the previous blockhash, will return different results based on when the call was performed, and when the transaction is actually mined.

    Finally, note that even though a call does not consume any Ether, sometimes it may be necessary to specify the actual gas amount for the call: the default gas for call in clients such as Geth, may still be insufficient and can still lead to Out of Gas.

    Case4: can contracts create transactions?

    There are 4 cases for how a contract function can be invoked.

    Here are the 4 cases, and the first 3 have been covered above:

    1. direct invocation of a contract function, originated with call

    2. direct invocation of a contract function, originated with sendTransaction

    3. contract invocation of a contract function, originated with call

    4. contract invocation of a contract function, originated with sendTransaction

    Although Case4 sounds like a contract can "also do transactions", because it's within a transaction, the definition of a transaction is data signed by an External Actor. Thus Case4 is not a transaction.

    From the Yellow Paper:

    Transaction: A piece of data, signed by an External Actor. It represents either a Message or a new Autonomous Object. Transactions are recorded into each block of the blockchain.

    Earlier above, it was stated that Events had to be used to get the return value of a contract function, originated with sendTransaction. That pertains and is true for Case2. For Case4, the contract obtains the return value of a contract function directly and can use it. Here's how the Yellow Paper says it in bold:

    Message Call: The act of passing a message from one Account to another. If the destination account is associated with non-empty EVM Code, then the VM will be started with the state of said Object and the Message acted upon. If the message sender is an Autonomous Object, then the Call passes any data returned from the VM operation

    With these definitions from the Yellow Paper, it can be seen that Case4 is a Message Call within a transaction (thus state changes), there is no nesting of transactions, and that a unit of activity on the Ethereum blockchain is all within a single transaction that may contain multiple Message Calls.

    Update: Since calling a function can be ambiguous (is it an eth_call or an eth_sendTransaction?), there is a proposal for eth_simulateTransaction.

    I would just add some final clarification/conclusion on the potential ambiguity between a web3 call() and a message call() between two contracts? The syntax would look very similar and thus it might be seen that if a contract calls another contract that it works similar to a web3 call, which is not the case. It doesn't simulate it in that environment. It results in state changes.

    Thanks, upvoted and was able to tweak the very last paragraph.

    I nominate this answer as tag wiki for contract-invocation. Feel free to review and contribute the wiki and excerpt.

    Does any of this change with the "Abstraction" coming in Metropolis?

    I see a message for a view function call in Remix that states "(Cost only applies when called by a contract)". I have an address balance checking function, which makes a call to an external token contract using the Erc20 `balanceOf` method. So in this case, the token contract is in fact called by my smart contract. Will this cost gas as stated, even though the entire process is read-only?

    @GViz A transaction that invokes a `view` or `pure` function will never require payment for gas. You're correct that a simple way to tell is that an entire process that is read-only will not cost gas. Note that gas is still used by `view` functions.

    @eth great point, gas is used temporarily–but not paid–when running view functions to prevent arbitrarily large routines (e.g. infinite loops) from executing.

    is `call` an atomic operation ? other words if the `call` fails somewhere in middle does it rollback?

    @user1870400 `eth_call` does not persist anything: "rollback" is its default behavior.

    @eth when does state updates get written(persisted) into storage? from my understanding reading through code base it looks like state updates get written to storage when the block gets appended to Blockchain until then its all memory. is that correct?

License under CC-BY-SA with attribution


Content dated before 7/24/2021 11:53 AM