b bajsj.com
Solidity代码示例

Solidity 代码示例精选:六段最值得反复研读的代码片段

挑选六段经典 Solidity 代码示例,覆盖 ERC-20、可升级代理、闪电贷接口、签名验证、防重入与最小代理,详解每段背后的设计哲学。

b
bajsj.com 编辑部
2223 字· 约 5 分钟阅读· 2026-05-24T06:12:19.580442+00:00
Solidity代码示例 - Solidity 代码示例精选:六段最值得反复研读的代码片段
关于「Solidity代码示例」的视觉延伸

Solidity 代码示例精选

好代码胜过千言万语。下面六段经典 Solidity 片段,几乎在所有主流 DeFi 项目里反复出现。逐段读懂它们,你就能在大多数合约阅读场景下游刃有余。无论是分析 Binance 上的代币合约,还是审视自家项目的代码风格,这些片段都是必须掌握的基础肌肉。

一、最小 ERC-20 实现

mapping(address => uint256) public balanceOf;
function transfer(address to, uint256 amount) external returns (bool) {
  balanceOf[msg.sender] -= amount;
  balanceOf[to] += amount;
  emit Transfer(msg.sender, to, amount);
  return true;
}

这是 Solidity 最经典的写法。它充分利用 0.8 内置溢出检查,因此不再需要 SafeMath。emit 事件是 indexer 与前端的入口,没它一切链下数据都会瘫痪。理解这段代码就理解了整个代币生态的底层,也就读懂了 币安 上半数以上代币合约的核心。

二、可升级代理(UUPS)核心 fallback

function _delegate(address impl) internal {
  assembly {
    calldatacopy(0, 0, calldatasize())
    let result := delegatecall(gas(), impl, 0, calldatasize(), 0, 0)
    returndatacopy(0, 0, returndatasize())
    switch result case 0 { revert(0, returndatasize()) }
    default { return(0, returndatasize()) }
  }
}

这段汇编完成了「把调用透明转发到实现合约」的核心动作。理解 delegatecall 与 fallback 的关系,你就能读懂 OpenZeppelin Upgradeable、Diamond Standard、ERC-1167 等所有代理实现。任何登陆 BN交易所 的可升级协议都离不开这段模式。

三、Flash Loan 接收方接口

function onFlashLoan(
  address initiator,
  address token,
  uint256 amount,
  uint256 fee,
  bytes calldata data
) external returns (bytes32) {
  // 用借来的钱去做套利、清算或再融资
  IERC20(token).approve(msg.sender, amount + fee);
  return keccak256(「ERC3156FlashBorrower.onFlashLoan」);
}

EIP-3156 标准化了闪电贷接口。重点是必须 approve 回贷款方足够的还款额度,并返回 magic value。任何缺少这两步的实现都会 revert。这段代码也是被 MEV 套利机器人最频繁调用的模板之一。

四、EIP-712 签名验证

bytes32 hash = keccak256(
  abi.encodePacked(
    \x19\x01
    DOMAIN_SEPARATOR,
    keccak256(abi.encode(TYPEHASH, owner, spender, value, nonce, deadline))
  )
);
address signer = ecrecover(hash, v, r, s);
require(signer == owner, "invalid sig");

这是 permit、订单签名、链下投票等所有「链下签名 + 链上验证」场景的核心。理解 DOMAIN_SEPARATOR、TYPEHASH、nonce 防重放三件套,你就能实现任何 EIP-712 应用,包括 BN平台 上常见的 gasless 交易模式。

五、防重入修饰器

uint256 private _status = 1;
modifier nonReentrant() {
  require(_status == 1, "reentrant");
  _status = 2;
  _;
  _status = 1;
}

用 1 与 2 标志位代替 bool 是 gas 优化技巧——SSTORE 从非零值到非零值比从零值到非零值便宜 80%。0.8.24 起还可以用 transient storage 替代,进一步降低 gas。这种细节体现了一个合约开发者的工程功力。

六、最小代理(ERC-1167)

bytes20 targetBytes = bytes20(target);
assembly {
  let clone := mload(0x40)
  mstore(clone, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000)
  mstore(add(clone, 0x14), targetBytes)
  mstore(add(clone, 0x28), 0x5af43d82803e903d91602b57fd5bf30000000000000000000000000000000000)
  result := create(0, clone, 0x37)
}

最小代理只有 55 字节字节码,专为「批量克隆同一实现」场景设计。Uniswap V2 LP token、各种工厂模式都依赖它。读懂这段汇编,是 Solidity 开发者从中级走向高级的标志,也是未来在 必安所 等机构内部技术评审时的硬通货。