Fatskills
Practice. Master. Repeat.
Study Guide: Blockchain and Web3 Development: Blockchain Fundamentals Decentralization and Trustless Systems
Source: https://www.fatskills.com/cryptocurrency-bitcoin-blockchain-and-more/chapter/blockchain-and-web3-development-blockchain-and-web3-development-blockchain-fundamentals-decentralization-and-trustless-systems

Blockchain and Web3 Development: Blockchain Fundamentals Decentralization and Trustless Systems

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

⏱️ ~5 min read

What This Is

Decentralization and trust‑less systems are the backbone of Web3: they let participants exchange value, vote, or run code without needing a central authority or “middle‑man.” By moving logic onto the blockchain (the EVM) and using cryptographic guarantees, anyone can verify that the rules were followed. Real‑world example: a user swaps ETH for DAI on Uniswap – the trade is executed by a smart contract that enforces the AMM formula, and no exchange operator can intervene or steal the funds.


Key Terms & Code Snippets

  • Trustless: No party needs to trust another; the protocol enforces the rules.
  • Decentralized Autonomous Organization (DAO): A contract‑based entity where token holders vote on proposals.

solidity // Minimal DAO proposal execution function execute(uint256 proposalId) external {
require(proposals[proposalId].passed, "not passed");
(bool ok,) = proposals[proposalId].target.call{value:0}(proposals[proposalId].data);
require(ok, "execution failed"); }


  • Reentrancy Attack: A malicious contract repeatedly calls back into a vulnerable function before state changes are recorded.

solidity // ❌ vulnerable function withdraw() external {
uint256 bal = balances[msg.sender];
(bool ok,) = msg.sender.call{value: bal}("");
require(ok);
balances[msg.sender] = 0; } // ✅ fixed with Checks‑Effects‑Interactions


  • Check‑Effects‑Interactions (CEI) Pattern: Update state before sending external calls to stop re‑entrancy.

solidity balances[msg.sender] = 0; // effect (bool ok,) = msg.sender.call{value: bal}(""); // interaction require(ok);


  • AMM (x * y = k): Constant‑product market maker formula used by Uniswap V2. k stays constant, guaranteeing liquidity.

solidity uint256 amountOut = (reserveOut * amountIn * 997) / (reserveIn * 1000 + amountIn * 997);


  • EIP‑2535 Diamond Standard: A modular contract architecture that lets you add/replace functions without redeploying the whole contract.

solidity // facet selector → implementation mapping stored in a central Diamond


  • Delegatecall: Executes code from another contract in the context of the caller, preserving msg.sender and storage. Use only with trusted libraries.

solidity (bool ok,) = libraryAddress.delegatecall(abi.encodeWithSignature("setX(uint256)", 42));


  • Tx.origin vs. msg.sender: tx.origin is the original external account that started the transaction; msg.sender is the immediate caller. Using tx.origin for auth is unsafe because a malicious contract can forward calls.

  • Optimistic Rollup: Batches transactions off‑chain, assumes they’re valid, and posts a fraud proof window (e.g., Optimism).

  • ZK‑Rollup: Posts a succinct zero‑knowledge proof that the batch is correct (e.g., zkSync).

  • ERC‑20 vs. ERC‑777: ERC‑777 adds hooks (tokensReceived) and allows operators, but is backward‑compatible with ERC‑20.

  • Gas‑Refund (SSTORE2): Storing data in a separate contract and reading via extcodecopy can be cheaper than many SSTORE writes.


Step‑by‑Step / Process Flow

  1. Write the contract – Open Remix or VS Code, create TrustlessSwap.sol implementing the AMM logic and CEI pattern.
  2. Compile & test – Run npx hardhat compile and write unit tests in JavaScript/TypeScript (test/Swap.test.js).
  3. Deploy to a testnet – Use Hardhat + Infura:

bash
npx hardhat run scripts/deploy.js --network goerli


  1. Verify on Etherscannpx hardhat etherscan-verify --network goerli <contract-address> so anyone can read the source.
  2. Interact from the front‑end – Connect MetaMask with ethers.js:

js
const contract = new ethers.Contract(address, abi, signer);
await contract.swapExactETHForTokens(…);


  1. Monitor & upgrade – If you used the Diamond pattern, add a new facet with npx hardhat run scripts/upgrade.js … without losing state.

Common Mistakes

  • Mistake: Using tx.origin for access control.
    Correction: Always check msg.sender; tx.origin can be spoofed through a malicious contract, breaking the trustless guarantee.

  • Mistake: Forgetting to set the receive()/fallback() function payable when the contract should accept ETH.
    Correction: Add receive() external payable {}; otherwise the transaction reverts and users lose gas.

  • Mistake: Deploying a contract with the default Solidity optimizer disabled.
    Correction: Enable optimizer: { enabled: true, runs: 200 } in hardhat.config.js to cut gas by 10‑30 %.

  • Mistake: Hard‑coding addresses (e.g., Uniswap router) for mainnet while testing on Goerli.
    Correction: Use a network‑aware config file (addresses[network.name]) to avoid “address not found” errors.

  • Mistake: Ignoring the “unchecked” overflow in Solidity 0.8+ when deliberately using it for gas savings.
    Correction: Wrap the arithmetic in unchecked { … } only after confirming the values can’t overflow; otherwise you expose a classic bug.


Blockchain Developer Interview / Practical Insights

  1. Call vs. Delegatecall: Interviewers love to ask why you’d choose one over the other. Call runs code in the callee’s storage; delegatecall runs it in the caller’s storage. Use delegatecall for library patterns, but always audit the target contract.
  2. ERC‑20 vs. ERC‑777: Be ready to explain the extra hooks (tokensReceived, tokensToSend) and why they matter for composability (e.g., preventing “lost tokens” in a contract that only implements ERC‑20.
  3. Optimistic vs. ZK Rollups: Know the trade‑off: Optimistic rollups rely on fraud proofs (cheaper but slower finality), while ZK rollups give instant finality at higher proof‑generation cost.
  4. Upgradeability Safety: If you mention a proxy pattern, also discuss storage‑slot collisions and the need for an initialize() function instead of a constructor.

Quick Check Questions

  1. Scenario: A contract uses tx.origin == owner to restrict withdrawals.
    Answer: Dangerous – a phishing contract can call the vulnerable contract on behalf of the owner, and tx.origin will still be the owner’s address, allowing theft.

  2. Scenario: You see a function that writes to a storage slot, then immediately calls an external contract.
    Answer: Likely a reentrancy risk; the correct order is effects first, interactions later (CEI pattern).

  3. Scenario: A DeFi protocol advertises “zero‑fee swaps” but charges a hidden 0.3 % on the token’s transfer.
    Answer: That’s a transfer tax (ERC‑20 extension) – the protocol must account for it in the AMM formula, otherwise users receive less than expected.


Last‑Minute Cram Sheet (10 one‑liners)

  1. ⚠️ Never use tx.origin for auth – it can be hijacked through a malicious contract.
  2. CEI (Checks‑Effects‑Interactions) stops re‑entrancy; always update state before external calls.
  3. Gas tip: Pack uint128 variables together; each 32‑byte slot costs 20 k gas when written.
  4. Solidity ≥0.8 has built‑in overflow checks; use unchecked {} only when you’re certain it’s safe.
  5. ERC‑20 = fungible token; ERC‑777 adds hooks and operator support, but still works with ERC‑20 wallets.
  6. Optimistic Rollup → fraud proof window (usually 1 week); ZK Rollup → instant finality, heavier proof generation.
  7. Delegatecall runs code in the caller’s storage; only call trusted libraries.
  8. EIP‑2535 Diamond lets you add/replace functions without redeploying the whole contract.
  9. Hardhat optimizer runs: runs: 200 is a good default; higher numbers favor read‑heavy contracts, lower numbers favor write‑heavy contracts.
  10. Common attack vector: Flash loan exploits – always validate that a user’s balance is sufficient after the loan is repaid.


ADVERTISEMENT