Blockchain Basics

Chapter 8
Smart Contracts and Decentralized Applications

Diploma in Blockchain
Blockchain Basics   •   Diploma

Smart Contracts and Decentralized Applications

Introduction

A blockchain becomes an application platform when it can execute rules, store state, and allow users to interact without relying on a single controlling server. Smart contracts are programs deployed to a blockchain. They define state-changing rules that are executed by network participants according to the blockchain’s consensus mechanism. A decentralized application (DApp) combines one or more smart contracts with a user interface, wallets, blockchain infrastructure, and—when necessary—external data services.

Smart contracts are not legally “smart” by definition, nor are they necessarily contracts in the legal sense. They are deterministic computer programs. Their importance arises from their ability to enforce agreed rules transparently and automatically, provided that the required inputs are available on-chain.

Learning Objectives

By the end of this chapter, you should be able to:

  • explain smart-contract deployment and execution;
  • describe the role of a blockchain virtual machine;
  • calculate and interpret transaction gas costs;
  • distinguish on-chain data from oracle-provided data;
  • describe the architecture of a DApp;
  • create and test a simple Solidity contract;
  • evaluate security, technical, governance, and regulatory limitations.

1. Smart Contracts as Deterministic Programs

A smart contract has persistent state, executable functions, and an address on the blockchain. For example, a token contract may store balances and provide functions for transferring tokens. A voting contract may store proposals and voting records.

A typical transaction follows this sequence:

  1. A user or another contract creates a transaction containing the target contract address, function call, parameters, and a fee limit.
  2. The transaction is signed by the sender’s private key.
  3. Nodes validate the signature, account balance, and transaction format.
  4. A block producer includes the transaction in a candidate block.
  5. The virtual machine executes the contract code.
  6. If execution succeeds, the resulting state changes and event logs become part of the blockchain state. If execution fails, state changes are normally reverted, although the transaction fee used for computation is still charged.

Execution must be deterministic. If two honest nodes process the same valid transaction against the same prior state, they must obtain the same result. Consequently, contracts should not directly use local clocks with arbitrary precision, random local files, internet requests, or other information that differs between nodes.

Contract lifecycle

A contract normally passes through four stages:

  • Development: requirements are translated into code.
  • Testing and audit: behavior and security assumptions are examined.
  • Deployment: compiled bytecode is recorded on the blockchain.
  • Interaction and maintenance: users call functions; upgrades, if supported, follow predefined governance rules.

Deployment is itself a blockchain transaction. After deployment, the contract has an address and its code is generally publicly inspectable. Immutability provides assurance that deployed logic cannot be silently changed, but it also makes programming errors difficult to correct.

2. Virtual Machines and Execution Models

A blockchain virtual machine (VM) is the execution environment that interprets or runs contract bytecode. Ethereum-compatible systems use the Ethereum Virtual Machine (EVM), a stack-based VM with persistent storage, memory, a program counter, and a restricted instruction set called opcodes.

The VM separates several types of data:

Data areaTypical purposePersistence
StackTemporary operation valuesDuring execution
MemoryTemporary byte arraysDuring execution
StorageContract state such as balancesBetween transactions
CalldataFunction input supplied by callerRead-only for the call
Logs/eventsSearchable records for applicationsRecorded in transaction receipt

A contract call may be a transaction, which changes state and requires authorization and a fee, or a read-only call, often called a query, which can be executed locally without submitting a state-changing transaction. A read-only call can still be computationally expensive for a node, but it does not normally consume the caller’s on-chain gas because it is not included in a block.

Contracts can call other contracts. This composability supports decentralized finance, gaming, identity, and supply-chain applications. It also creates risk: a contract may depend on another contract whose behavior, availability, or security is not fully controlled by the calling developer.

3. Gas and Transaction Economics

Blockchains limit computation to prevent infinite loops and denial-of-service attacks. In EVM-based networks, each operation consumes a specified amount of gas. The transaction specifies a gas limit, which is the maximum amount of gas the sender authorizes for that transaction.

The basic fee relationship is:

Transaction fee = Gas used × Gas price

Gas used is measured in gas units; gas price is commonly expressed in gwei, where 1 gwei = 10⁻⁹ of the network’s native currency. Therefore, if a transaction uses 50,000 gas at 20 gwei:

Fee = 50,000 × 20 gwei = 1,000,000 gwei = 0.001 native currency units

This calculation assumes the stated gas price applies to all gas used and ignores network-specific fee components or refunds. Some modern fee markets divide the fee into a base fee and a priority fee:

Effective gas price = Base fee + Priority fee

The total payment is still based on actual gas used, subject to the transaction’s limit and the network’s fee rules. A transaction that reaches its gas limit may fail because execution cannot continue. In many systems, gas already consumed is not refunded after failure.

Gas performs three functions:

  1. Resource pricing: computation and storage have an economic cost.
  2. Abuse resistance: unlimited computation is prevented.
  3. Fee allocation: validators or block producers receive compensation according to the network’s protocol.

Developers reduce gas costs by avoiding unnecessary storage writes, choosing appropriate data structures, batching operations where safe, and minimizing redundant computation. Optimization must not compromise correctness or security.

4. Oracles and the On-Chain Boundary

A blockchain can securely calculate from its own state, but it does not automatically know the current weather, a bank exchange rate, a shipment location, or the outcome of a sporting event. An oracle supplies external data to a contract.

The oracle problem is not simply a technical data-feed problem; it is a trust and incentive problem. A contract can verify that an oracle transaction was signed by an approved address, but it cannot independently prove that the reported off-chain fact is true unless the data source and verification process are trustworthy.

Common oracle approaches include:

  • single-source oracle: simple but dependent on one provider;
  • decentralized oracle network: several data providers report values and an aggregation method is used;
  • consensus oracles: data is accepted only when a threshold of authorized reporters agrees;
  • proof-based systems: cryptographic evidence connects an external fact to the reported result, where technically possible.

Important design questions include data freshness, precision, update frequency, failure handling, manipulation resistance, and the authority to replace an oracle. A financial contract should specify what happens if a price is stale or unavailable. It may pause, use a fallback source, or reject the transaction.

5. Architecture of a Decentralized Application

A DApp is usually a hybrid system rather than a completely serverless system. Its blockchain component provides shared state and rule execution, while other components provide usability, indexing, storage, and external integration.

Decentralized application architecture User interfaceWeb or mobile app WalletKeys and signing Smart contractsRules and state Blockchain nodesConsensus and data Oracles /storage
Decentralized application architecture
Figure: Decentralized application architecture

Figure: Main components of a decentralized application and their interactions.

Main components

  • Frontend: presents data and requests actions. It should clearly distinguish confirmed, pending, and failed transactions.
  • Wallet: manages or connects to private keys and asks the user to approve signatures. A DApp should never request a user’s private key directly.
  • Provider or RPC endpoint: carries requests between the frontend and blockchain nodes. A DApp may depend on public or commercial infrastructure providers.
  • Smart-contract layer: enforces business rules and stores critical state.
  • Indexing layer: organizes events and transactions for efficient search. It improves usability but may introduce delays or data-dependency risks.
  • Off-chain storage: stores large files such as images or documents. A blockchain may store only a content identifier or hash.
  • Oracle layer: supplies selected external facts.

A useful design principle is to keep the minimum necessary trust-critical logic on-chain and place large, private, or high-throughput operations off-chain, while documenting the resulting trust assumptions.

6. Creating a Simple Contract

The following illustrative Solidity contract records a message and restricts updates to its owner. It is educational code, not production-ready code.

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

contract MessageBoard {
    address public owner;
    string public message;

    event MessageChanged(address indexed editor, string newMessage);

    constructor(string memory initialMessage) {
        owner = msg.sender;
        message = initialMessage;
    }

    function setMessage(string calldata newMessage) external {
        require(msg.sender == owner, "Only owner");
        message = newMessage;
        emit MessageChanged(msg.sender, newMessage);
    }
}

owner and message are persistent state variables. The constructor executes once during deployment. msg.sender identifies the immediate caller. The require statement reverts the call if the caller is not the owner. The event creates a searchable log for interfaces and indexing services.

Testing workflow

A practical workflow is:

  1. Compile with a specified Solidity compiler version.
  2. Test deployment with an initial message.
  3. Confirm that the deployer is recorded as owner.
  4. Read message through a read-only call.
  5. Change the message from the owner account.
  6. Attempt the same change from a second account and confirm that it reverts.
  7. Inspect the emitted event and transaction receipt.
  8. Test boundary cases, such as an empty message, and decide whether the specification should allow them.
  9. Use static analysis, unit tests, and—before production—independent security review.

Testing should verify both expected behavior and rejected behavior. A test that only demonstrates successful calls provides weak evidence of security.

7. Applied Case: Illustrative Agricultural Insurance DApp

Background and problem

Suppose a cooperative wants crop insurance based on rainfall. Manual claims are slow and expensive, while a smart contract could release payment when rainfall falls below an agreed threshold. This is an illustrative case, not a recommendation for deployment.

Analysis

The contract can store policy terms, premiums, insured parties, and payment status. However, rainfall is not naturally on-chain. An oracle must provide measurements from an agreed weather service. The design must address late data, conflicting reports, sensor failure, privacy, and the possibility that a weather station does not represent every farm equally.

Approach

A cautious design could:

  • identify the insured farm without publishing unnecessary personal data;
  • store a policy identifier and cryptographic reference to full documents;
  • accept rainfall data only from an authorized oracle network;
  • require two or more consistent reports;
  • reject data older than a defined observation period;
  • include a dispute or pause mechanism;
  • emit events for policy creation, data submission, and payment;
  • use a stable-value payment method where legally and technically appropriate.

Outcome

The DApp could reduce administrative delay and make policy rules auditable. It would not eliminate trust: users would still trust the oracle methodology, the contract code, the wallet, the payment asset, and the governance process. An incorrect threshold or unreliable sensor could produce a technically valid but economically unfair result.

Learning points

The case demonstrates that blockchain is strongest when several parties need a shared, tamper-resistant record and when rules can be stated precisely. It is weaker when the key fact is subjective, private, rapidly changing, or controlled by a single data provider.

8. Limitations, Security, and Governance

Technical limitations

  • Irreversibility: an erroneous transfer may be impossible to recover.
  • Code defects: bugs can cause permanent loss or unauthorized behavior.
  • Scalability: demand may increase confirmation times and fees.
  • Privacy: public ledgers can expose transaction relationships and metadata.
  • Oracle dependence: external inputs can be delayed, manipulated, or unavailable.
  • Key loss: loss of a private key may mean loss of control.
  • Upgrade complexity: upgradeable contracts introduce administrators, proxy risks, and governance dependence.

Common vulnerabilities include reentrancy, improper access control, unchecked external calls, arithmetic or accounting errors, denial of service, oracle manipulation, and inadequate initialization. Solidity’s compiler checks do not replace security analysis. Developers should follow least privilege, validate assumptions, use established libraries carefully, apply checks-effects-interactions where relevant, and avoid unnecessary complexity.

Governance and legal considerations

A project should define who may pause a contract, upgrade code, change an oracle, or resolve disputes. Centralized emergency powers may improve safety but reduce decentralization. Governance tokens do not automatically create fair or legally recognized governance.

Legal classification varies by jurisdiction. Tokens, automated payments, financial products, consumer services, data processing, and digital identity systems may trigger licensing, consumer-protection, tax, anti-money-laundering, securities, or privacy obligations. Technical decentralization does not remove accountability. Organizations should obtain jurisdiction-specific legal advice and document risk controls.

Responsible design

A professional DApp should provide understandable transaction descriptions, avoid dark patterns, disclose risks, protect personal information, publish contract addresses and compiler information, communicate upgrade authority, and maintain incident-response procedures. AI may assist with code review or test generation, but generated code must be independently tested and audited; plausible-looking code is not evidence of correctness.

9. Contemporary Development Directions

Current blockchain engineering increasingly uses layer-2 networks, account abstraction, zero-knowledge techniques, cross-chain messaging, decentralized identity, and modular data-availability systems. These developments can improve cost, privacy, and user experience, but they add assumptions about bridges, sequencers, provers, relayers, or service operators. The correct evaluation question is not whether a system is labelled “decentralized,” but which actors can change outcomes, censor activity, access data, or recover assets.

Best-Practice Checklist

Before deployment, a team should:

  • write a precise specification and threat model;
  • minimize on-chain data and clearly identify trust boundaries;
  • test successful, failed, and adversarial cases;
  • use compiler warnings and independent analysis tools;
  • control administrative keys with suitable operational security;
  • document gas behavior and failure modes;
  • verify oracle sources, freshness, and fallback procedures;
  • disclose upgrade and pause powers;
  • conduct legal, privacy, and accessibility reviews;
  • deploy in stages, beginning with a limited-value environment.

Chapter Summary

Smart contracts are deterministic programs that maintain blockchain state and enforce coded rules. Their execution occurs in a virtual machine, where gas prices computation and limits abuse. Transactions may succeed or revert, and failed execution can still consume fees. Because blockchains cannot directly observe most external facts, oracles introduce essential but significant trust assumptions. A DApp combines a frontend, wallet, provider, smart contracts, blockchain nodes, indexing or storage services, and sometimes oracle networks. The illustrative Solidity contract demonstrates state, access control, deployment, function calls, events, and testing. Smart contracts can improve transparency and automation, but they remain vulnerable to coding errors, key loss, privacy problems, oracle failure, governance disputes, legal uncertainty, and scalability constraints. Professional development therefore requires specification, testing, security review, explicit trust analysis, and responsible governance.

Key Terms

Smart contract: A program deployed on a blockchain that executes coded rules.

Decentralized application (DApp): An application combining blockchain contracts with user and infrastructure components.

Virtual machine: The deterministic execution environment for contract bytecode.

EVM: Ethereum Virtual Machine, an execution environment for Ethereum-compatible contracts.

State: Persistent information maintained by a contract or blockchain.

Bytecode: Compiled machine-readable instructions executed by a virtual machine.

Transaction: A signed request that may change blockchain state.

Gas: A unit measuring computational work in an execution environment.

Gas limit: Maximum gas a sender authorizes for a transaction.

Gas price: Amount paid per unit of gas.

Oracle: A mechanism that supplies external information to a blockchain contract.

Event: A contract log intended for off-chain monitoring and indexing.

Calldata: Read-only input data supplied to a contract call.

Reentrancy: An attack in which control returns to a contract before an earlier operation is complete.

Access control: Rules determining which accounts may perform actions.

Upgradeability: Ability to alter or redirect contract logic after deployment.

RPC provider: A service or node interface through which applications communicate with a blockchain.

Consensus: Agreement by network participants on valid transactions and state.

Review Questions

5 Short Answer Questions

  1. Why must smart-contract execution be deterministic?
  2. Distinguish a transaction from a read-only contract call.
  3. What are gas units used to measure?
  4. Why does a contract need an oracle for an external exchange rate?
  5. What purpose does an event serve in the sample contract?

5 Long Answer Questions

  1. Explain the lifecycle of a smart contract from development to interaction.
  2. Describe the main components of a DApp and the trust assumptions associated with each.
  3. Explain how gas limits protect a blockchain and affect users and developers.
  4. Compare single-source and decentralized oracle designs.
  5. Discuss the security and governance implications of upgradeable contracts.

3 Analytical / Application Questions

  1. Design a DApp for issuing digital certificates. Identify what belongs on-chain, what belongs off-chain, and how certificates should be verified.
  2. A contract depends on a price feed that has become stale. Analyze at least three possible responses and recommend one.
  3. Review the sample MessageBoard contract as a production proposal. Identify its assumptions, missing controls, privacy implications, and testing requirements.

Multiple Choice Questions with Answers

Question 1

What is the primary reason smart-contract execution must be deterministic?

A. To ensure honest nodes calculate the same resulting state

B. To allow contracts to access arbitrary local files

C. To eliminate the need for transaction signatures

D. To guarantee that every transaction is free

Correct Answer: A. To ensure honest nodes calculate the same resulting state

Question 2

Which data area normally persists between transactions in an EVM contract?

A. Stack

B. Memory

C. Storage

D. Calldata

Correct Answer: C. Storage

Question 3

A transaction uses 50,000 gas at 20 gwei per gas. Ignoring other fee components, what is the fee?

A. 0.000001 native currency units

B. 0.0001 native currency units

C. 0.001 native currency units

D. 1 native currency unit

Correct Answer: C. 0.001 native currency units

Question 4

What happens when a contract transaction executes a failing require statement?

A. The failure is ignored and all state changes remain

B. The call reverts, although gas already consumed may still be charged

C. The contract is permanently deleted

D. The sender’s private key is published

Correct Answer: B. The call reverts, although gas already consumed may still be charged

Question 5

What is the main function of an oracle?

A. To compile Solidity code

B. To create a user’s private key

C. To supply external information to a contract

D. To replace blockchain consensus

Correct Answer: C. To supply external information to a contract

Question 6

Which DApp component normally asks a user to approve and sign a transaction?

A. Wallet

B. Indexer

C. Oracle sensor

D. Block explorer database

Correct Answer: A. Wallet

Question 7

Why can an event be useful in a DApp?

A. It makes contract code invisible

B. It provides a searchable record for applications and monitoring

C. It guarantees that an oracle is truthful

D. It removes all gas costs

Correct Answer: B. It provides a searchable record for applications and monitoring

Question 8

In the sample MessageBoard contract, who may call setMessage successfully?

A. Any account that knows the contract address

B. Only the account stored as owner

C. Only a blockchain validator

D. Only the compiler

Correct Answer: B. Only the account stored as owner

Question 9

Which is a central limitation of using an oracle?

A. The blockchain cannot store numbers

B. The contract must trust the data source and reporting process

C. Oracles prevent all contract calls

D. Oracle data is always private

Correct Answer: B. The contract must trust the data source and reporting process

Question 10

Which practice is most appropriate before deploying a high-value smart contract?

A. Skip failure testing to reduce gas costs

B. Publish private keys for transparency

C. Perform adversarial testing and independent security review

D. Allow unrestricted external calls by default

Correct Answer: C. Perform adversarial testing and independent security review

Blockchain Basics
Chapter 8 of 14