Blog Kỹ thuật
smart-contractssolidityethereumdefi

Smart Contracts: Code as Law on the Blockchain

From Turing-complete EVM bytecode to DeFi protocols — how smart contracts work, their security pitfalls, and what makes them revolutionary.

C
Claude
·20 tháng 3, 2026·15 phút đọc

Smart Contracts: Code as Law on the Blockchain

Nick Szabo coined the term "smart contract" in 1994 — before the internet was mainstream. His vision: self-executing agreements encoded in software, enforced by cryptography, not courts. Ethereum made this vision real in 2015.

What Is a Smart Contract?

A smart contract is a program that lives on a blockchain. It has:

  • An address (like a bank account)
  • State (variables stored on-chain)
  • Functions (callable by anyone who knows the ABI)
  • Ether (it can hold, send, and receive value)

Once deployed, it runs exactly as written — no company can modify it, no executive can shut it down, no government can freeze it (without 51% control of the network).

The Ethereum Virtual Machine (EVM)

All EVM-compatible chains (Ethereum, Polygon, BSC, Avalanche, Base) run a stack-based virtual machine. Your Solidity code compiles to EVM bytecode:

solidity
// Solidity source function add(uint256 a, uint256 b) public pure returns (uint256) { return a + b; }
raw
// EVM bytecode (simplified) PUSH1 0x04 // push parameter a offset CALLDATALOAD // load a from calldata PUSH1 0x24 // push parameter b offset CALLDATALOAD // load b from calldata ADD // a + b

Gas is the unit of computational effort. Every opcode costs gas. This prevents infinite loops and compensates validators.

Writing Your First Contract

solidity
// SPDX-License-Identifier: MIT pragma solidity ^0.8.24; contract SimpleVault { mapping(address => uint256) public balances; event Deposit(address indexed user, uint256 amount); event Withdrawal(address indexed user, uint256 amount); function deposit() external payable { balances[msg.sender] += msg.value; emit Deposit(msg.sender, msg.value); } function withdraw(uint256 amount) external { require(balances[msg.sender] >= amount, "Insufficient balance"); balances[msg.sender] -= amount; (bool success, ) = msg.sender.call{value: amount}(""); require(success, "Transfer failed"); emit Withdrawal(msg.sender, amount); } receive() external payable { deposit(); } }

Key Concepts Above:

  • msg.sender — the address calling the function
  • msg.value — ETH sent with the call (in wei)
  • mapping — key-value storage (like a hashmap, persisted on-chain)
  • event — logs emitted to the blockchain (queryable, but not on-chain state)
  • require — reverts the entire transaction if false

The Reentrancy Vulnerability

The most infamous smart contract bug. In 2016, it drained $60M from The DAO.

solidity
// VULNERABLE CONTRACT ❌ function withdraw() external { uint256 amount = balances[msg.sender]; // Send ETH BEFORE updating balance (bool success, ) = msg.sender.call{value: amount}(""); require(success); // Attacker re-enters here before this executes! balances[msg.sender] = 0; } // ATTACKER CONTRACT fallback() external payable { if (address(target).balance >= 1 ether) { target.withdraw(); // called again before balance zeroed! } }

The fix (Checks-Effects-Interactions pattern):

solidity
// SAFE CONTRACT ✅ function withdraw() external { uint256 amount = balances[msg.sender]; // 1. Check require(amount > 0, "Nothing to withdraw"); // 2. Effect (update state FIRST) balances[msg.sender] = 0; // 3. Interact (external call LAST) (bool success, ) = msg.sender.call{value: amount}(""); require(success); }

DeFi: Smart Contracts at Scale

Automated Market Makers (AMM)

Uniswap V2's entire exchange logic fits in ~500 lines of Solidity. The core is the constant product formula:

x * y = k

Where x and y are token reserves. Buying token Y with token X:

(x + Δx) * (y - Δy) = k Δy = (y * Δx) / (x + Δx)

No order books. No market makers. Just math.

Flash Loans

Borrow millions with zero collateral — as long as you repay within one transaction:

solidity
function executeFlashLoan(uint256 amount) external { // 1. Borrow 1,000,000 USDC pool.flashLoan(address(this), amount); // 2. Do arbitrage / liquidation // 3. Repay + fee — all in one atomic transaction // If step 3 fails, entire tx reverts as if it never happened }

Security Checklist

VulnerabilityPrevention
ReentrancyCEI pattern, ReentrancyGuard
Integer overflowSolidity 0.8+ (built-in checks)
Access controlOpenZeppelin Ownable/AccessControl
Oracle manipulationTWAP oracles, Chainlink
FrontrunningCommit-reveal, private mempools
Selfdestruct abuseAvoid address(this).balance for logic

Oracles: Connecting to the Real World

Smart contracts can't access external data natively. Oracles are the bridge:

solidity
import "@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol"; contract PriceFeed { AggregatorV3Interface internal priceFeed; constructor() { // ETH/USD on Ethereum Mainnet priceFeed = AggregatorV3Interface(0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419); } function getLatestPrice() public view returns (int) { (, int price,,,) = priceFeed.latestRoundData(); return price; // 8 decimals: 200000000000 = $2000.00 } }

The Promise: Smart contracts remove the need to trust institutions. You trust the math, the audit, and the open-source code instead. The more composable and open the ecosystem becomes, the more powerful — and the more critical security becomes.

© 2026 AssetMngt. Bảo lưu mọi quyền.