Fatskills
Practice. Master. Repeat.
Study Guide: Blockchain and Web3 Development: Blockchain Fundamentals What is Blockchain Distributed Ledger Immutability Consensus
Source: https://www.fatskills.com/cryptocurrency-bitcoin-blockchain-and-more/chapter/blockchain-and-web3-development-blockchain-and-web3-development-blockchain-fundamentals-what-is-blockchain-distributed-ledger-immutability-consensus

Blockchain and Web3 Development: Blockchain Fundamentals What is Blockchain Distributed Ledger Immutability Consensus

By Fatskills Exam Guides Team — the exam nerds behind 28,500+ quizzes and 2.1M practice questions across 500+ global exams.

⏱️ ~6 min read

Study Guide – What is Blockchain (Distributed Ledger, Immutability, Consensus)


What This Is

A blockchain is a distributed ledger that lives on many computers at once, where every new block of transactions is cryptographically linked to the previous one. Because the data is replicated, signed, and never overwritten, the system is immutable and its state is decided by a consensus algorithm rather than a single authority. In practice this lets anyone build trust‑less apps—e.g., a Uniswap swap that settles instantly without a central exchange, an NFT minting contract that guarantees provenance, or a DAO voting contract that records every vote on‑chain and can’t be tampered with.


Key Terms & Code Snippets

  • Distributed Ledger: A database spread across many nodes; each node stores the full chain, so no single point of failure.
  • Block: A batch of transactions plus a header (parentHash, timestamp, nonce, stateRoot).
  • Immutability: Once a block is finalized, its hash becomes part of the next block’s header, making retroactive changes computationally infeasible.
  • Consensus: The rule set (e.g., Proof‑of‑Work, Proof‑of‑Stake) that nodes follow to agree on the next block.
  • Hash Pointer: bytes32 public parentHash; – stores the hash of the previous block, creating the chain.
  • Merkle Tree: A binary tree of transaction hashes; the root (bytes32 public merkleRoot;) proves inclusion of any tx with a short proof.
  • Finality: The point after which a block is considered irreversible. In Ethereum’s PoS, finality is achieved when a supermajority of validators attest to a block.
  • EVM (Ethereum Virtual Machine): The sandboxed bytecode interpreter that executes Solidity contracts on every node, guaranteeing deterministic results.

Solidity snippet – a minimal immutable record contract


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

contract ImmutableLog {
event Log(address indexed sender, string data, uint256 timestamp);
// Anyone can write, but nothing can be deleted or altered
function write(string calldata _data) external {
emit Log(msg.sender, _data, block.timestamp);
} }
  • Block Header Fields (EIP‑1559 example)
    solidity struct Header {
    bytes32 parentHash;
    bytes32 stateRoot;
    bytes32 receiptsRoot;
    uint256 blockNumber;
    uint256 gasUsed;
    uint256 baseFeePerGas; // new after London fork }

  • Consensus Example – PoS validator set (pseudo‑JS)
    js const ethers = require('ethers'); const provider = new ethers.InfuraProvider('goerli', INFURA_KEY); const validator = new ethers.Wallet(PRIVATE_KEY, provider); // validator signs the block proposal const signature = await validator.signMessage(blockHash);

  • Merkle Proof Verification (Solidity)
    solidity function verifyProof(bytes32 leaf, bytes32[] calldata proof, bytes32 root) external pure returns (bool) {
    bytes32 computed = leaf;
    for (uint i = 0; i < proof.length; i++) {
    computed = keccak256(abi.encodePacked(computed < proof[i], computed, proof[i]));
    }
    return computed == root; }

  • Finality Gadget (Ethereum’s Casper FFG)
    Validators submit attestations; when >2/3 of total stake have attested, the block is finalized and cannot be reverted without slashing.


Step‑by‑Step / Process Flow

  1. Write the contract – Open Remix, paste the ImmutableLog contract (or your own ledger logic).
  2. Compile – Use Hardhat: npx hardhat compile (Solidity 0.8.24, optimizer enabled).
  3. Deploy – Run a deployment script targeting Goerli via Infura:
    js
    const ethers = require('ethers');
    const provider = new ethers.InfuraProvider('goerli', INFURA_KEY);
    const wallet = new ethers.Wallet(PRIVATE_KEY, provider);
    const factory = new ethers.ContractFactory(abi, bytecode, wallet);
    const contract = await factory.deploy(); // tx sent
    await contract.deployed(); // wait for receipt
    console.log('Deployed at', contract.address);
  4. Interact – Call write("first entry") from a front‑end using Ethers.js:
    js
    const tx = await contract.write("first entry");
    await tx.wait(); // block mined, immutable log entry created
  5. Verify Immutability – Pull the transaction receipt and Merkle proof from an archive node; run verifyProof on‑chain to confirm the entry is part of the canonical chain.

Common Mistakes

  • Mistake: Using tx.origin for access control.
    Correction: Use msg.sender (or role‑based AccessControl) because tx.origin can be spoofed through a malicious contract call chain.

  • Mistake: Assuming a block is final after 1 confirmation.
    Correction: Wait for the network’s finality threshold (e.g., 6 confirmations on Ethereum PoW, or a finalized checkpoint on PoS) to avoid reorg attacks.

  • Mistake: Hard‑coding gas limits (gas: 21000) for contract calls.
    Correction: Let the node estimate gas (estimateGas) or use gasLimit: ethers.constants.MaxUint256 and let the EVM cap it; over‑estimation wastes ETH, under‑estimation causes OOG failures.

  • Mistake: Storing large data (e.g., images) directly in contract storage.
    Correction: Store a hash/IPFS CID on‑chain and keep the heavy payload off‑chain; this preserves immutability while keeping gas low.

  • Mistake: Forgetting to enable the Solidity optimizer.
    Correction: In hardhat.config.js, set optimizer: { enabled: true, runs: 200 }; otherwise you’ll pay unnecessary gas for every operation.


Blockchain Developer Interview / Practical Insights

  1. Call vs. delegatecall: Interviewers love to ask why delegatecall is dangerous. delegatecall runs the callee’s code in the caller’s context, so a malicious library can overwrite the caller’s storage. Expect to discuss the “proxy pattern” and why you must whitelist the implementation address.

  2. ERC‑20 vs. ERC‑777: Be ready to compare the basic token interface (transfer/approve) with ERC‑777’s hooks (tokensReceived) and operator model, which mitigates the “approval race” problem.

  3. Optimistic vs. ZK Rollups: Explain that Optimistic Rollups assume transactions are valid and use fraud proofs (challenge window), while ZK Rollups generate succinct validity proofs on‑chain, offering instant finality but higher proving costs.

  4. Gas‑price vs. Base‑fee: Show you understand EIP‑1559: maxFeePerGas = baseFee + maxPriorityFee. Auditors will check that your dApp correctly caps maxFeePerGas to avoid over‑paying during spikes.


Quick Check Questions

  1. Scenario: A contract uses tx.origin to restrict withdrawals to the original sender.
    Answer: It’s unsafe because a malicious contract can trick a user into calling it, making tx.origin point to the user while the malicious contract executes the withdrawal.

  2. Scenario: After a hard fork, a block that was previously final becomes “orphaned”. What went wrong?
    Answer: The network’s consensus changed; you should rely on the finalized checkpoint (e.g., Casper FFG) rather than a simple confirmation count, because forks can reorganize non‑finalized blocks.

  3. Scenario: You see a contract that stores a 1 MB PNG in a bytes state variable.
    Answer: This is a gas‑inefficient anti‑pattern; store the file off‑chain (IPFS/S3) and keep only its hash or CID on‑chain.


Last‑Minute Cram Sheet (10 one‑liners)

  1. ⚠️ Never use tx.origin for auth – it can be hijacked through a contract call chain.
  2. EIP‑1559 splits gas price into baseFee (protocol‑set) + maxPriorityFee (miner tip).
  3. Merkle root = single 32‑byte hash that proves inclusion of any transaction with a logarithmic‑size proof.
  4. Finality on Ethereum PoS = ≥2/3 of total stake attesting a block; before that it’s only “probabilistic”.
  5. Gas optimizer: runs: 200 is a good default; higher runs favor read‑heavy contracts, lower runs favor write‑heavy contracts.
  6. ERC‑20 = 6‑function token; ERC‑777 adds hooks & operators, solving the approval race.
  7. Reentrancy guard pattern: uint256 private _status; modifier nonReentrant() { require(_status == 1); _status = 2; _; _status = 1; }.
  8. Hardhat default Solidity compiler version = 0.8.24 (as of 2024‑06); lock it in pragma solidity ^0.8.24;.
  9. Optimistic Rollup challenge window ≈ 7 days on Arbitrum; ZK Rollup finality is immediate after proof verification.
  10. Proxy upgradeability: Store implementation address in a dedicated storage slot (bytes32 constant IMPLEMENTATION_SLOT = keccak256("my.proxy.implementation")) to avoid slot collision.


ADVERTISEMENT