How to call an EOAs in a smart contract

How to call an EOAs in a smart contract

Introduction to externally owns account (EOAs)

EOA stands for "Externally Owned Account" in Ethereum, which is a type of account in the Ethereum blockchain that is controlled by a private key and owned by an individual or an entity outside of the Ethereum network. An EOA can be used to send transactions, store and transfer Ether (ETH), and interact with smart contracts. These transactions are signed by the private key of the EOA, allowing it to prove its identity and authorize changes to the state of the contract. EOAs are in contrast to "Contract Accounts," which are controlled by code stored in the Ethereum blockchain and can only be interacted with through the execution of its functions by other accounts.

Basic Types of EOAs

  1. Externally Owned Accounts - All transactions originate from an EOA, they are controlled by a private key which signs off on the transaction.

  2. Smart Contract - This is code deployed to the blockchain. It is programmed to respond to different inputs sent by EOAs or other contracts.

OK, great! Let's focus on calling EOAs first.

Here is an example of how an EOA might be used in the Ethereum network:

  1. An individual wants to send 1 ETH to another EOA. They use their private key to sign a transaction that specifies the recipient EOA's address and the amount of ETH to be sent. This transaction is broadcast to the Ethereum network and included in the next block.

  2. An EOA wants to store some assets in a smart contract. The owner of the EOA signs a transaction that invokes the smart contract's "store assets" function and includes the necessary data and arguments. This transaction is broadcast to the Ethereum network and executed on the blockchain.

  3. An EOA wants to interact with a decentralized exchange (DEX) and trade some ETH for a different cryptocurrency. The owner of the EOA signs a transaction that invokes the DEX smart contract's "trade" function and includes the necessary data and arguments. This transaction is broadcast to the Ethereum network and executed on the blockchain, resulting in the exchange of ETH for the desired cryptocurrency.

In all of these cases, the EOA acts as the initiator of the action, providing authorization through the use of its private key and allowing it to interact with other accounts and smart contracts on the Ethereum network.

EOAs in a Smart Contract

Let's imagine we have two authors of a smart contract:

contract SpecialNumber {
    address author1;
    address author2;
}

What's something we can do with EOAs? We can pay for them! Let's do that. Any time this contract receives ether, let's send half to author1 and half to author2.

contract SpecialNumber {
    address author1;
    address author2;

    receive() external payable {
        // msg.value is passed to this contract
        uint totalValue = msg.value;

        // make a call to author1 sending half of the ether
        (bool success1, ) = author1.call{ value: totalValue / 2 }("");
        require(success1);

        // make a call to author2 sending half of the ether
        (bool success2, ) = author2.call{ value: totalValue / 2 }("");
        require(success2);
    }
}

A payable function can receive ether. The receive the function is a special function that will be invoked when a smart contract receives ether. We'll touch on this further later on.

Let's take a look at that call syntax, specifically:

(bool success1, ) = author1.call{ value: totalValue / 2 }("");
require(success1);

What is happening in these two lines? Let's break this syntax up into four parts:

  1. The .call method

  2. The curly brace {} syntax

  3. The empty string argument passed in ("")

  4. The return value (bool success1, )

Call

First, let's talk about call. The call method is something you'll find on every address type when you want to send input data or ether to an address. When you do this, you'll be making something called a message call. You'll often hear this terminology used to describe a call to a smart contract. We differentiate this from a transaction, which is an object signed by the EOA sent to the blockchain.

Curly Braces

The curly braces which comes after call {} provides an opportunity to override the value and gas parameters on the message call. The gas parameter will be relevant when we start calling smart contract addresses. When you leave it unspecified it will forward along all the gas remaining that the transaction sender designated (through the gasLimit parameter on the front-end, remember?).

The Empty String Argument

You can see where passing in an empty string here. If you were trying to target a function on a smart contract this is where your calldata would go. The calldata will specify the function you're trying to call as well as the arguments you are sending. In this case, we're just trying to send ether to an EOA, so we pass an "" to indicate there is no calldata.

Return Value

The (bool success1, ) part probably looks a bit confusing! Remember how in the previous lesson we wrote a contract that can return multiple values? The call method returns multiple values. Solidity will warn you if you don't use the first value returned, which indicates if the message call was successful or not. In most cases, we will want the transaction to fail if a message call fails. The code require(success1) will do just that. We'll take about require further very shortly!

In the meantime, let's get some practice on our solidity address type. Jump into the next coding lesson to begin!