Writing smart contract using Ethereum

Comprehensive study notes, diagrams, and exam preparation for Writing smart contract using Ethereum.

Writing Smart Contract Using Ethereum

Definition

A smart contract is a program stored on the blockchain that automatically executes predefined actions when certain conditions are met. In Ethereum, smart contracts are usually written in Solidity, compiled into EVM bytecode, and deployed to a blockchain network where they can be called by users, wallets, or other contracts.

Important characteristics of Ethereum smart contracts include:

Deterministic execution

  • The same input always produces the same result.

Immutability after deployment

  • The deployed code cannot usually be changed, which increases trust but also requires careful testing.

Transparency

  • Contract code and transactions are publicly verifiable on the blockchain.

Automation

  • The contract performs actions automatically when invoked, reducing the need for intermediaries.

For example, a crowdfunding contract may automatically release funds to a project owner only if the funding goal is reached before the deadline. This removes the need for a third party to manually verify and enforce the agreement.


Main Content

1. Ethereum Smart Contract Basics

Ethereum and the EVM

Ethereum is a blockchain platform designed to support decentralized computation. The Ethereum Virtual Machine (EVM) is the runtime environment where smart contract bytecode executes. Every Ethereum node can verify contract execution, which ensures trustless processing. When a user interacts with a contract, the network processes the transaction and updates the blockchain state accordingly.

Solidity as the primary language

Most Ethereum smart contracts are written in Solidity, which looks similar to JavaScript, C++, and Python in some respects. Solidity supports variables, functions, mappings, inheritance, modifiers, events, and error handling. A simple example of a contract is a storage contract that stores and retrieves a number:

  // SPDX-License-Identifier: MIT
  pragma solidity ^0.8.0;

  contract SimpleStorage {
      uint256 private storedNumber;

      function setNumber(uint256 _number) public {
          storedNumber = _number;
      }

      function getNumber() public view returns (uint256) {
          return storedNumber;
      }
  }

In this example, setNumber changes blockchain state, while getNumber only reads it.

2. Contract Structure and Core Building Blocks

State variables, functions, and visibility

A smart contract typically contains state variables (data stored on-chain), functions (logic), and visibility modifiers such as public, private, internal, and external. Choosing the right visibility is important for security and clarity. For example, public functions can be called by anyone, while private data can only be used inside the contract.

Events, modifiers, and constructors

Events are used to log important actions so external applications can track activity efficiently. Modifiers allow reusable access-control or validation rules, such as restricting certain functions to the contract owner. A constructor runs once when the contract is deployed and is commonly used to initialize ownership or configuration values.

Example:

  contract OwnedCounter {
      address public owner;
      uint256 public count;

      event CountUpdated(uint256 newCount);

      modifier onlyOwner() {
          require(msg.sender == owner, "Not authorized");
          _;
      }

      constructor() {
          owner = msg.sender;
      }

      function increment() public onlyOwner {
          count += 1;
          emit CountUpdated(count);
      }
  }

This contract initializes the deployer as the owner and allows only that address to increment the counter.

3. Development, Testing, and Security Considerations

Development tools and workflow

Ethereum smart contract development commonly uses tools such as Remix, Hardhat, Foundry, and Truffle. These tools help with compiling, testing, deployment, debugging, and interacting with contracts. Developers often write tests in JavaScript, TypeScript, or Solidity to verify behavior before deploying to mainnet.

Security and best practices

Smart contracts handle real assets, so security is critical. Common risks include reentrancy attacks, integer overflow/underflow, unauthorized access, and poor input validation. Solidity versions 0.8+ include built-in overflow checks, but developers still need safe patterns. Best practices include:

  • Using access control properly
  • Following the checks-effects-interactions pattern
  • Validating inputs carefully
  • Avoiding unnecessary external calls
  • Using audited libraries like OpenZeppelin
  • Writing extensive unit and integration tests

Example of a secure withdrawal pattern:

  function withdraw(uint256 amount) public {
      require(balances[msg.sender] >= amount, "Insufficient balance");
      balances[msg.sender] -= amount;
      payable(msg.sender).transfer(amount);
  }

Here, the balance is reduced before the transfer, helping prevent reentrancy issues.


Working / Process

1. Design the contract logic and requirements

First, define the exact business rules the smart contract should enforce. Identify the parties involved, the conditions under which actions happen, the data that must be stored, and the expected outcomes. For example, in a token contract, you may need total supply, balances, transfers, approvals, and ownership control. Clear planning reduces bugs and makes the contract easier to verify.

2. Write, compile, and test the Solidity code

Next, implement the contract in Solidity using a development environment like Remix for simple projects or Hardhat/Foundry for professional workflows. Compile the code to check for syntax and type errors, then run tests to confirm that all functions behave as expected. Testing should cover normal cases, edge cases, failing cases, and security checks. Good tests are essential because deployed contracts are difficult or impossible to change later.

3. Deploy the contract and interact with it on Ethereum

After successful testing, deploy the compiled bytecode to an Ethereum network such as Sepolia for testing or Ethereum mainnet for live use. Deployment requires a wallet and gas fees paid in ETH. Once deployed, users can interact with the contract through a frontend application, wallet, or script using libraries like ethers.js or web3.js. After deployment, monitor contract activity, verify source code on block explorers, and ensure the contract is used safely and correctly.


Advantages / Applications

Automation and trust reduction

Smart contracts automatically execute agreements, reducing the need for intermediaries such as banks, brokers, or administrators. This increases efficiency, lowers costs, and reduces the possibility of manual error or manipulation.

Transparency and auditability

Because Ethereum transactions and contract code are publicly visible, users can verify how a contract works and trace its activity. This is valuable in financial systems, donation platforms, voting systems, and public record applications.

Wide range of practical use cases

Ethereum smart contracts are used in decentralized finance (DeFi), non-fungible tokens (NFTs), token creation, escrow services, insurance, governance, supply chain tracking, gaming, and digital identity systems. For example, an NFT contract can define ownership of unique digital items, while a DeFi contract can automate lending and borrowing.


Summary

  • Ethereum smart contracts are blockchain programs that execute automatically based on predefined conditions.
  • Solidity is the most common language used to write them.
  • Proper design, testing, and security practices are essential because deployed contracts are difficult to modify.
  • Important terms to remember

Smart contract development on Ethereum combines programming, blockchain logic, and security-focused engineering to create decentralized applications that are transparent, reliable, and automated.