1、课程目标
在本课中,我们将从零开始实现一个 最小可用的 ERC20 代币合约,并逐步扩展功能,包括铸造(mint)、销毁(burn)、权限控制(owner / onlyOwner)。 通过本课,我们可以:
技术博客与学习记录
在本课中,我们将从零开始实现一个 最小可用的 ERC20 代币合约,并逐步扩展功能,包括铸造(mint)、销毁(burn)、权限控制(owner / onlyOwner)。 通过本课,我们可以:
在 EVM 中,Gas 主要分为三类:
selfdestruct 等低级指令的风险Solidity 使用 32 字节为一个存储槽(storage slot)。在继承或代理合约模式下,如果新旧合约的状态变量定义不一致,就可能发生槽冲突,导致关键数据被覆盖。
区块链合约的“代码即法律”带来了强大的确定性,但同时也意味着:
在区块链上,合约一旦部署便不可修改,这是去中心化的根本保障。但对于复杂应用来说,这却成了一把双刃剑:
在区块链合约中,权限管理是核心问题之一。 如果权限控制不当,可能导致:
从这一课开始,我们将会进入实战环节,通过编写测试来学习 Solidity 合约的各种高级用法。
在复杂的智能合约系统中,代码复用与模块化至关重要。Solidity 提供了 库(Library) 机制,用来组织可重用逻辑,避免重复开发与部署,提升合约的可维护性与安全性。
delegatecall,在代理合约中使用 delegatecall 调用逻辑合约的函数,使得代码在代理的存储上下文中执行。(bool success, bytes memory data) = implementation.delegatecall(msg.data);
delegatecall 会在当前合约的存储和上下文中执行目标合约的代码。upgradeTo 函数完成。| 风险点 | 说明 | 解决方案 |
| :-------------------- | :------------------------------------------------- | :-------------------------------------------------- |
| 存储布局冲突 | 升级后逻辑合约的变量顺序、类型不一致,导致数据错位 | 遵循固定的变量追加规则,避免删除或更改类型 |
| 初始化漏洞 | 新逻辑合约的构造函数不会被代理调用 | 使用 initializer 修饰的初始化函数,防止重复初始化 |
| delegatecall 风险 | 调用外部不可信合约可能破坏存储 | 严格控制升级权限,禁止不可信代码执行 delegatecall |
| 权限丢失 | 升级过程中可能被替换成恶意逻辑 | 使用多签或 Timelock 控制升级 |
| 调用方式 | 是否切换上下文(storage/msg.sender/msg.value) | 是否能改状态 | 特点与用途 |
|:-------------- |:------------------------------------- |:------ |:----------------------- |
| call | ✅ 切换到被调用合约 | ✅ | 最通用的外部调用,可带 ETH,可调用任意函数 |
| delegatecall | ❌ 保持当前合约上下文 | ✅ | 代理模式核心,让当前合约执行别人的代码 |
| staticcall | ✅ 切换到被调用合约 | ❌ | 安全读取外部数据,不改状态 |