Bird
Raised Fist0
Blockchain / Solidityprogramming~5 mins

Accounts (EOA vs contract accounts) in Blockchain / Solidity

Choose your learning style10 modes available
Introduction

Accounts are how we identify who owns or controls assets on a blockchain. There are two main types: Externally Owned Accounts (EOA) controlled by people, and Contract Accounts controlled by code.

When sending cryptocurrency from your wallet to a friend (EOA).
When deploying a smart contract to automate tasks (Contract Account).
When interacting with a decentralized app that runs code on the blockchain (Contract Account).
When checking who owns certain tokens or assets (EOA).
When creating a new feature that needs automatic rules, like a voting system (Contract Account).
Syntax
Blockchain / Solidity
EOA: Controlled by a private key, can send transactions.
Contract Account: Has code, executes functions when called.

EOAs require a private key to sign transactions.

Contract accounts cannot initiate transactions themselves; they respond to calls.

Examples
This shows a user (EOA) sending cryptocurrency to another address.
Blockchain / Solidity
// Example of an EOA sending Ether
web3.eth.sendTransaction({from: eoaAddress, to: recipientAddress, value: amount});
This deploys a smart contract to the blockchain, creating a contract account.
Blockchain / Solidity
// Deploying a contract account
const contract = new web3.eth.Contract(abi);
contract.deploy({data: bytecode}).send({from: eoaAddress});
An EOA calls a function on a contract account to execute code.
Blockchain / Solidity
// Calling a function on a contract account
contract.methods.myFunction().send({from: eoaAddress});
Sample Program

This program connects to the Ethereum blockchain, checks the balance of an EOA, and detects if a contract account exists at another address by checking for code.

Blockchain / Solidity
// Simple example in JavaScript using web3.js
async function example() {
  const Web3 = require('web3');
  const web3 = new Web3('https://mainnet.infura.io/v3/YOUR_PROJECT_ID');

  // EOA address example
  const eoaAddress = '0xYourEOAAddress';

  // Contract account address example
  const contractAddress = '0xYourContractAddress';

  // Check balance of EOA
  const eoaBalance = await web3.eth.getBalance(eoaAddress);
  console.log(`EOA balance: ${web3.utils.fromWei(eoaBalance, 'ether')} ETH`);

  // Check if contract code exists at contract address
  const code = await web3.eth.getCode(contractAddress);
  if (code === '0x' || code === '0x0') {
    console.log('No contract found at this address.');
  } else {
    console.log('Contract account detected at this address.');
  }
}

example();
OutputSuccess
Important Notes

EOAs are controlled by private keys and can send transactions directly.

Contract accounts contain code and can only act when triggered by transactions from EOAs or other contracts.

Checking if an address is a contract can be done by checking if code exists at that address.

Summary

There are two main account types: EOAs (people) and contract accounts (code).

EOAs send transactions; contract accounts run code when called.

Understanding the difference helps you interact correctly with blockchain applications.

Practice

(1/5)
1. Which of the following best describes an Externally Owned Account (EOA) on a blockchain?
easy
A. An account that can only receive tokens but not send them.
B. An account that only stores data but cannot send transactions.
C. An account that automatically executes code when called.
D. An account controlled by a private key, used by people to send transactions.

Solution

  1. Step 1: Understand what an EOA is

    An EOA is controlled by a private key and represents a user or person on the blockchain.
  2. Step 2: Identify EOA capabilities

    EOAs can send transactions and initiate actions, unlike contract accounts which run code.
  3. Final Answer:

    An account controlled by a private key, used by people to send transactions. -> Option D
  4. Quick Check:

    EOA = user-controlled account [OK]
Hint: EOAs are user accounts with private keys [OK]
Common Mistakes:
  • Confusing EOAs with contract accounts
  • Thinking EOAs run code automatically
  • Believing EOAs cannot send transactions
2. Which syntax correctly represents a contract account address in Solidity?
easy
A. address payable contractAddr = 0x1234567890abcdef1234567890abcdef12345678;
B. contractAddr = '0x1234567890abcdef1234567890abcdef12345678';
C. address contractAddr = 1234567890abcdef1234567890abcdef12345678;
D. address contractAddr = 0xGHIJKL7890abcdef1234567890abcdef12345678;

Solution

  1. Step 1: Check Solidity address syntax

    Addresses must be hexadecimal starting with 0x and enclosed in proper type declaration.
  2. Step 2: Validate each option

    The declaration 'address payable contractAddr = 0x1234567890abcdef1234567890abcdef12345678;' uses correct type and hex format. String assignments without type declaration are invalid, missing 0x prefix fails, and invalid hex characters like 'GHI' are not allowed.
  3. Final Answer:

    address payable contractAddr = 0x1234567890abcdef1234567890abcdef12345678; -> Option A
  4. Quick Check:

    Valid Solidity address syntax = address payable contractAddr = 0x1234567890abcdef1234567890abcdef12345678; [OK]
Hint: Solidity addresses start with 0x and use 'address' type [OK]
Common Mistakes:
  • Omitting 0x prefix
  • Using invalid hex characters
  • Assigning address as a plain string without type
3. Consider the following Solidity code snippet:
address sender = msg.sender;
bool isContract = sender.code.length > 0;

What does isContract indicate?
medium
A. True if sender is an EOA, false if contract.
B. True if sender is a contract account, false if EOA.
C. Always true because msg.sender is a contract.
D. Always false because msg.sender has no code.

Solution

  1. Step 1: Understand msg.sender.code.length

    This checks the length of the code at the sender's address; contracts have code, EOAs do not.
  2. Step 2: Interpret the boolean value

    If code length > 0, sender is a contract account; otherwise, it's an EOA.
  3. Final Answer:

    True if sender is a contract account, false if EOA. -> Option B
  4. Quick Check:

    Code length > 0 means contract [OK]
Hint: Check code length to distinguish contract vs EOA [OK]
Common Mistakes:
  • Assuming msg.sender is always EOA
  • Confusing code length meaning
  • Thinking EOAs have code
4. You have this Solidity function:
function sendEther(address recipient) public {
    recipient.transfer(1 ether);
}

When calling this function with an EOA address, it fails with an error. What is the likely cause?
medium
A. The recipient address is not payable, so transfer fails.
B. EOA addresses cannot receive ether.
C. The function lacks the payable modifier.
D. transfer() only works with contract accounts.

Solution

  1. Step 1: Understand transfer() requirements

    transfer() requires the recipient address to be payable to receive ether.
  2. Step 2: Analyze recipient type

    If recipient is declared as address (not address payable), transfer will fail even if it's an EOA.
  3. Final Answer:

    The recipient address is not payable, so transfer fails. -> Option A
  4. Quick Check:

    Use address payable for ether transfers [OK]
Hint: Use address payable to send ether [OK]
Common Mistakes:
  • Thinking EOAs can't receive ether
  • Missing payable keyword on function
  • Assuming transfer only works with contracts
5. You want to write a Solidity function that sends 1 ether only if the recipient is an EOA (not a contract). Which code snippet correctly implements this check?
hard
A. require(recipient.balance > 0, "Recipient must have balance"); recipient.transfer(1 ether);
B. require(recipient.code.length > 0, "Recipient must be contract"); payable(recipient).transfer(1 ether);
C. require(recipient.code.length == 0, "Recipient must be EOA"); payable(recipient).transfer(1 ether);
D. require(msg.sender == recipient, "Sender must be recipient"); recipient.transfer(1 ether);

Solution

  1. Step 1: Check recipient code length to identify EOA

    EOAs have no code, so recipient.code.length == 0 confirms EOA.
  2. Step 2: Use require to enforce condition and transfer ether

    If recipient is EOA, convert to payable and transfer 1 ether safely.
  3. Final Answer:

    require(recipient.code.length == 0, "Recipient must be EOA"); payable(recipient).transfer(1 ether); -> Option C
  4. Quick Check:

    Code length 0 means EOA, then transfer [OK]
Hint: Check code length == 0 to confirm EOA before sending [OK]
Common Mistakes:
  • Checking for code length > 0 to find EOAs
  • Not converting address to payable before transfer
  • Using balance check instead of code length
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard