集训营课程表中的“概念小抄”,可以当作Web3技术随身小册,用于宏观理解Web3中的各类术语。
这是根据线下集训课程表(Web3学习路线)制作的概念“小抄”,新手可以通过这篇文章理解一下截止到目前的Web3知识框架;专家可以通读全文以复习巩固。其中各个部分的“一句话总结”只是作者的个人见解,如果有错误欢迎帮忙指出!
一句话总结区块链的基础:通过分布式数据和共识机制解决中心化数据带来的可被篡改问题,它与中心化数据的唯一区别在于“修改需要共识”。其他的性质如可追溯性,隐私性等等中心化数据也能够做好,并不是二者的核心差别。从这个角度来讲:区块链技术发展的方向应该是与中心化解决方案有本质差异的场景,而不是相同的场景。
课程模块 | 时间安排(W:Week, D:DAY) | 课程内容 |
---|---|---|
区块链基础 | W1D1 | 为什么需要区块链技术 如何实现基于代码的信任 比特币网络运行原理: 1. 去中心化网络 2. 区块链结构 3. 非对称密码学 4. POW 共识机制 |
区块链基础 | W1D2 | 以太坊核心概念介绍: 1. 以太坊 POS 共识 2. 以太坊是如何执行代码的 3. 用 Solidity 编写第一个合约及 Remix 4. 以太坊的 gas 机制(EIP1559)以及 EVM 5. 区块链浏览器 6. 账户与钱包 7. 各种不同的网络与链:测试络、EVM 兼容链 |
一句话总结Solidity:一种开发语言,用于运行在EVM虚拟机上,包含一系列接口屏蔽了区块链底层P2P网络之间的交互,可以简单地完成查询,交易,回调等操作;通过solidity编写的程序可以固定在区块链中,不可篡改并且能够自动执行,通过这项技术为用户提供了一种在数据共识之上的“规则的共识”。
课程模块 | 时间安排(W:Week, D:DAY) | 课程内容 |
---|---|---|
W1D3 | 实例介绍 Sol 语法: 变量数据类型:地址、合约类型、数组、 映射 理解链不同存储位置的差异,关注 gas 消耗 函数的定义:不同的可见性与可变性 (payable 等) 如何向合约转账:特殊的回调函数(receive 与 fallback) Solidity 内置变量与函数 | |
Solidity 语言特性系统讲解 | W1D4 | 函数修改器 错误处理:理解与传统开发语言错误的差异 合约接口:如何使用做合约之间的调用 继承与抽象合约 |
W1D5 | 理解合约调用的本质: ABI 理解底层调用:call 与 delegateCall 理解 EVM 调用的上下文环境的切换(msg.sender 及 tx.origin ) 合约事件的使用及什么时候该用事件 合约库(library) |
address user = 0x123...abc;
,可用来转账(user.transfer(1 ether)
)、判断合约调用者(msg.sender == user
)。MyToken token = MyToken(0x456...def);
,直接调用 token
合约的 transfer
函数。uint[3] arr;
)和动态长度(uint[] arr;
)。
mapping(address => uint) balances;
)。
storage
(合约存储):永久存区块链上,修改成本极高(Gas 费贵),类似数据库持久化存储。 memory
(内存):临时存函数执行过程中,调用结束销毁,Gas 费低,类似程序内存。 calldata
(调用数据):外部调用传入的参数,只读,常用于函数参数(节省 Gas)。storage
变量会触发区块链状态变更,需全网节点共识,所以 Gas 费远高于 memory
/calldata
操作。public
:外部、内部都能调用,自动生成 getter 函数(如 uint public count;
)。 private
:仅当前合约内部可调用,外部(包括继承合约)无法访问。 internal
:当前合约及继承合约可调用,外部用户/合约无法直接访问。 external
:仅外部可调用(如用户、其他合约),内部调用需加 this.
(this.myFunc()
)。payable
等):
payable
:函数可接收 ETH 转账,调用时需附带 value
(如 myContract.myPayableFunc{value: 1 ether}()
)。 view
:只读函数,不修改区块链状态(查询数据),Gas 费极低(甚至免费)。 pure
:更严格的只读,不访问任何 storage
变量,仅处理传入参数。receive
与 fallback
receive
函数:
receive() external payable {}
,用户直接给合约转 ETH 时触发。fallback
函数:
external payable
。 fallback() external payable { /* 自定义逻辑,如解析数据 */ }
,常用于兼容旧版调用、实现通用接收逻辑。msg.sender
:当前调用者的地址(用户/合约),核心身份标识,用于权限控制(如 if (msg.sender == owner) { ... }
)。 msg.value
:调用时附带的 ETH 数量(仅 payable
函数可用 )。 block.number
/ block.timestamp
:当前区块高度、时间戳,用于随机数生成(需注意安全性)、锁定期逻辑(如 if (block.timestamp > unlockTime) { ... }
)。 tx.origin
:最初发起调用的外部用户地址(区别于 msg.sender
,msg.sender
可能是中间合约 ),慎用!存在钓鱼攻击风险(恶意合约可冒充用户)。modifier onlyOwner() {
require(msg.sender == owner, "Not owner");
_; // 执行原函数逻辑的位置
}
function setPrice(uint _price) external onlyOwner {
price = _price;
}
调用 setPrice
时,先执行 onlyOwner
校验,通过后再执行函数内容。
require
/ revert
/ assert
:
require(条件, "错误信息")
:常用!校验输入、权限,失败则回滚交易,退还剩余 Gas。 revert("错误信息")
:主动回滚交易,常用于复杂逻辑判断(如 if (balance < amount) revert("Insufficient balance");
)。 assert(条件)
:调试用,失败则触发 PANIC(消耗所有 Gas),生产环境少用。interface IERC20 {
function transfer(address to, uint amount) external returns (bool);
}
contract MyDApp {
function transferToken(IERC20 token, address to, uint amount) external {
token.transfer(to, amount); // 调用其他合约的 transfer 函数
}
}
只要其他合约实现了 IERC20
接口,就能被本合约调用,实现“解耦开发”。
contract MyToken is ERC20, Ownable { ... }
,直接继承 OpenZeppelin 的 ERC20
代币标准、Ownable
权限管理。function myFunc() external virtual;
),需被继承合约实现。 abstract contract Payment { function pay() external virtual; }
)。web3.eth.call({ to: 合约地址, data: ABI编码数据 })
)。 transfer(address to, uint amount)
的 ABI 编码,会把函数名、参数类型哈希成固定格式,让 EVM 识别调用逻辑。call
与 delegateCall
call
:
otherContract.call(abi.encodeWithSignature("transfer(address,uint256)", to, amount))
。 msg.sender
是当前合约地址(相当于“代理调用”)。delegateCall
:
storage
,执行目标合约的代码(常用于“合约升级”“代理模式”)。 proxyContract.delegateCall(abi.encodeWithSignature("upgradeLogic()", ...))
,让代理合约执行新逻辑合约的代码,但状态存在代理合约。 delegateCall
会按目标合约的存储布局操作当前合约存储 )。msg.sender
与 tx.origin
msg.sender
:直接调用者的地址(可能是用户或合约)。
msg.sender
是合约 A。tx.origin
:最初发起交易的外部用户地址(始终是用户,不会是合约 )。
tx.origin
钓鱼(如冒充用户调用高权限函数),建议优先用 msg.sender
做权限控制。event Transfer(address indexed from, address indexed to, uint amount);
function transfer(address to, uint amount) external {
// 转账逻辑...
emit Transfer(msg.sender, to, amount); // 触发事件
}
- `indexed`:标记可索引字段,让事件能被快速查询(但最多传 3 个 `indexed` 参数 )。
- 优势:事件存储在“日志”中,不占合约存储(Gas 费低),是链上数据可视化的核心。
SafeMath
库(旧版),用于安全数学运算: library SafeMath {
function add(uint a, uint b) internal pure returns (uint) {
require(a + b >= a, "Overflow");
return a + b;
}
}
contract MyToken {
using SafeMath for uint; // 启用库,可直接调用 `uint.add()`
function mint(uint amount) external {
totalSupply = totalSupply.add(amount); // 安全加法
}
}
- 特点:`library` 函数需声明 `internal` 或 `pure`/`view`,且通过 `using Library for Type;` 关联类型,实现语法糖。
一句话总结:Web3行业中存在ERC标准,用来统一多种区块链技术与应用的实现方式。OpenZepplin是根据标准实现的一套开发库,通过它可以屏蔽标准实现的底层细节,快速编写应用逻辑并接入到遵循这套标准的实现中。(类似于前端开发中的ES6) NFT是区块链技术的一个重要的应用,用于虚拟物品的确权。
课程模块 | 时间安排(W:Week, D:DAY) | 课程内容 |
---|---|---|
OpenZepplin 库 Token 及 NFT标准 | W2D1 | OpenZeppelin 代码库介绍 EIP 与 ERC标准 如何使用 ERC20 实现代币(Token) 理解 ERC20 授权与合约回调 实际使用 ERC20 的一些坑 ERC20 的拓展:ERC-777、ERC-1363 Token 交易所(DEX)初探 |
W2D2 | 使用 ERC721 实现 NFT 如何处理 NFT 的元数据 IPFS 、Arweare 去中心化存储 NFT 上架到 OpenSea ERC1155 |
ERC20
合约(contract MyToken is ERC20 { ... }
),自动实现转账、授权等功能;用 Ownable
管理合约权限(仅 owner 可 mint 代币)。transfer
、approve
等函数 )。 transfer(address to, uint256 amount)
:直接转账(用户 → 用户)。 approve(address spender, uint256 amount)
:授权第三方(如 DEX 合约)代操作代币。 transferFrom(address from, address to, uint256 amount)
:第三方调用(需先授权 ),实现“代转账”(如 DEX 撮合交易)。import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
contract MyToken is ERC20 {
constructor() ERC20("MyToken", "MTK") {
_mint(msg.sender, 1000 * 10**18); // 发行 1000 枚代币(考虑小数位)
}
}
继承 ERC20
后,自动获得所有标准功能,无需重复编写。
approve
允许其他合约(如 Uniswap)操作自己的代币(如 approve(uniswapAddress, 100 * 10**18)
)。 approve
多次调用会覆盖额度,建议用 increaseAllowance
/decreaseAllowance
)。transferFrom
时,ERC20 标准无强制回调,但部分拓展标准(如 ERC777)会触发 tokensReceived
回调,用于实现“转账即触发逻辑”(如自动质押、分红 )。uint256
存总量,需手动处理小数位(如 1 ETH = 10^18 Wei
),否则易出现“发行 1 枚代币实际是 1 Wei”的错误。 transferFrom
调用外部合约时,对方再次调用 transferFrom
),虽 OpenZeppelin 已修复,但需了解历史风险。tokensReceived
)、发送者/接收者黑名单、批量操作。 onTransferReceived
)、授权后回调(onApproveReceived
)。 transferAndCall
一次性完成转账+回调 )。x*y=k
恒定乘积公式(如 ETH-USDT 池,ETH 增加则 USDT 减少,价格自动调整 )。transferFrom
调用用户授权的代币,实现兑换(如用户授权 Uniswap 后,合约转走 ETH 并 mint 对应数量的 LP 代币 )。mint(address to, uint256 tokenId)
:铸造 NFT(每个 tokenId
唯一 )。 transferFrom(address from, address to, uint256 tokenId)
:转移 NFT 所有权。 tokenURI(uint256 tokenId)
:返回 NFT 元数据链接(如 IPFS 地址 )。import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
contract MyNFT is ERC721 {
constructor() ERC721("MyNFT", "MNFT") {}
function mintNFT(address to, uint256 tokenId) external {
_mint(to, tokenId); // 铸造 NFT
}
}
继承 ERC721
后,自动支持 NFT 铸造、转移、查询所有权。
{
"name": "My NFT #1",
"description": "A cool NFT",
"image": "ipfs://Qm...abc", // 图片存储地址
"attributes": [ { "trait_type": "Color", "value": "Blue" } ] // 属性
}
CID
)访问。 ipfs://Qm...
。approve
授权平台转售。ERC721
标准,且元数据可访问(IPFS/Arweave 地址有效 )。tokenId
代表一类 ),且可批量操作(如一次转移 10 个不同 tokenId
)。 ERC1155
只需一个 tokenId
,铸造 100 份 )。import "@openzeppelin/contracts/token/ERC1155/ERC1155.sol";
contract MyMultiNFT is ERC1155 {
constructor() ERC1155("ipfs://Qm.../{id}.json") {} // 元数据模板
function mint(address to, uint256 tokenId, uint256 amount) external {
_mint(to, tokenId, amount, ""); // 铸造 amount 个 tokenId 的 NFT
}
}
一句话总结: Foundry 相当于区块链开发的脚手架工具cli,和代码编辑器Cursor/VScode等共同组成IDE(intergrated Development environment 集成开发环境)
课程模块 | 时间安排(W:Week, D:DAY) | 课程内容 |
---|---|---|
Foundry 开发工具 | W2D3 | IDE 与 AI 编辑器 Foundry 工程化: 项目初始化、编译、测试、部署 Foundry 实战技巧: 管理依赖库 私钥管理:不同形式下安全(私钥、助记词与 keystore) 节点 RPC 配置 合约开源验证 cast 常用指令:转账、合约调用、编码 |
W2D4 | 深入 Foundry 测试 console.log 使用 测试指令与 gas 报告 常用测试作弊码:更改区块高度、更改余额、模拟交易发送者、重置 ERC20 余额 错误断言 fork 主网状态、分叉测试 模糊(Fuzz)测试 不变量(invariant)测试 |
Solidity Extension Pack
),支持语法高亮、智能提示、调试(结合 Foundry 命令 )。 forge init my-project
,自动生成标准 Foundry 项目结构(含 src/
合约目录、test/
测试目录、script/
部署脚本 )。 forge build
,编译 src/
目录下的 Solidity 合约,输出字节码、ABI(存 out/
目录 )。 forge build --compiler-version 0.8.24
)。forge test
,自动运行 test/
目录下的测试用例(基于 Forge 测试框架 )。 forge create
直接部署合约(需填私钥、RPC 节点 )。 script/Deploy.s.sol
),用 forge script
执行(支持多签、验证 )。forge install
安装依赖(如 forge install openzeppelin/openzeppelin-contracts
),自动关联 GitHub 仓库,支持版本锁定(lib/
目录管理 )。 forge wallet import
可导入 )。 --private-key
或环境变量 PRIVATE_KEY
传入,生产环境建议用硬件钱包/安全托管。foundry.toml
配置: rpc_endpoints = { mainnet = "https://mainnet.infura.io/v3/...", sepolia = "https://sepolia.infura.io/v3/..." }
- 作用:测试、部署时指定链环境(如 `forge test --fork-url mainnet` )。
forge verify-contract
,将已部署合约的字节码、源码提交到区块链浏览器(如 Etherscan ),实现“开源验证”(用户可查合约逻辑 )。 --compiler-version
)。cast send --private-key $PK $TO_ADDRESS --value 0.1ether
cast call $CONTRACT "balanceOf(address)" $OWNER_ADDRESS
cast sig "transfer(address,uint256)" $TO 100
(生成函数签名哈希 )console.log
使用:
vm.console.log()
打印变量(类似 JavaScript ),需导入 forge-std/Test.sol
: import "forge-std/Test.sol";
contract MyTest is Test {
function testLog() public {
uint256 x = 100;
vm.console.log("x value:", x); // 测试时输出日志
}
}
- 作用:调试时快速查看变量值,比区块链浏览器查日志更高效。
forge test --match-test testFunction
:只运行指定测试函数。 forge test --gas-report
:输出每个测试函数的 Gas 消耗报告(优化合约成本关键 )。vm.
前缀 ),用于“模拟链上环境”(开发/测试专用,主网无效 )。 vm.blockNumber(1000000);
(测试区块高度相关逻辑 )。 vm.deal(address(this), 100 ether);
(给合约地址发 ETH )。 vm.prank(attackerAddress);
(让后续调用假装来自 attackerAddress
)。 vm.setBalance(tokenAddress, userAddress, 1000 * 10**18);
(测试代币操作 )。require
/ assert
/ expectRevert
:
expectRevert
验证合约应抛出的错误: function testTransferFail() public {
vm.expectRevert("Insufficient balance"); // 期望抛出该错误
token.transfer(recipient, 1000 ether); // 执行会失败的操作
}
- 作用:确保合约逻辑符合预期(如转账失败时回滚 )。
forge test --fork-url mainnet
,在本地模拟主网状态(复制区块、账户余额、合约数据 )。 vm.prank
模拟攻击、vm.setStorageAt
篡改存储 ),验证合约鲁棒性。uint256 amount
传 0~2^256-1 的值 ),测试合约边界情况。 function testTransferFuzz(uint256 amount) public {
vm.assume(amount > 0 && amount <= balanceOf(msg.sender)); // 过滤无效输入
token.transfer(recipient, amount); // 用随机 amount 测试
assert(balanceOf(recipient) == oldBalance + amount); // 断言结果
}
- 优势:发现手动测试遗漏的漏洞(如溢出、极端值处理 )。
function invariant_totalSupply() public {
assert(token.totalSupply() == 1000 ether); // 总供应量应始终为 1000 ETH
}
- 作用:检测合约状态是否被意外篡改(如 mint 函数是否超额发行 )。
一句话总结Dapp:核心数据通过区块链保存的应用程序(App),与传统App的不同在于需要链接“钱包”用于获取身份标识,底层核心数据通过区块链存储。(应用的逻辑性感觉需要好好思考一下)
课程模块 | 时间安排(W:Week, D:DAY) | 课程内容 |
---|---|---|
W2D5 | DAPP 初探: 交易是如何发送到链上 外接与链技术的通道 JSON-RPC 各种交互库(JSON-RPC 的封装):Viem.sh 、ethers.js 、go-ethereum、alloy-rs 重点介绍 viem.js 使用: 钱包链接、私钥签名、转账、获取链上数据、监听事件等 | |
W3D1 | 钱包开发: 如何创建钱包,理解钱包相关的标准BIP32、BIP44、BIP39 (各公链账户生成都遵循的标准) 私钥的加密 keystore 私钥的分片 MPC 如何构造一个交易、签名交易、发送交易 插件钱包和移动端钱包浏览器的实现原理 中心化钱包与去中心化钱包 硬件钱包与合约钱包、及多签钱包(Safe) AA 钱包:ERC4337 与 EIP7702 | |
钱包及前后端与链交互开发 | W3D2 | DAPP 应用前端开发 使用 Wagmi 方便管理数据状态(与链同步) 钱包链接的多种方式: 常规方式、Wallet Connect 、使用 AppKit 及 Rainbow kit 理解 SIWE 以太坊登录 如何使用合约签名登录(EIP1271、EIP4494) |
W3D3 | 以太坊签名与应用: 如何在合约中验证用户的签名 熟悉相关的签名标准: EIP191 、 EIP712 如何使用 ERC20-Permit 、 ERC721-Permit 优化体验 Permit2 的应用 | |
W3D4 | 后端的数据索引: 理解 ABI 描述与 ABI 编解码 使用事件订阅获取最新数据 构建一个扫块服务,获取想要的链上数据 |
to
、value
、data
等字段 ),通过 RPC 节点(如 Infura )广播到区块链网络,矿工打包进区块后完成上链。 {"method": "eth_sendTransaction", "params": [...]}
)调用节点 API,实现交易发送、数据查询。 connectWallet()
关联 MetaMask 等钱包。 signMessage()
用钱包私钥签名消息(非交易,用于身份验证 )。 sendTransaction()
发起 ETH 转账。 readContract()
调用合约 view
函数(如查余额 )。 watchContractEvent()
监听合约事件(如 Transfer
)。mnemonic.toSeed()
推导私钥 )。 m/44'/60'/0'/0/0
对应 ETH 主网第一个账户 ),实现“一套助记词管理多链、多账户”。 m/ purpose' / coin_type' / account' / change / address_index
),让不同链的账户路径统一(如 ETH 是 44'/60'
,BTC 是 44'/0'
)。keystore
),解密需密码(web3.eth.accounts.decrypt(keystore, password)
),平衡安全与存储。 t-of-n
机制 ),防止单点泄漏风险(企业级钱包常用 )。 { to, value, gas, data }
)→ 用私钥签名(signTransaction()
)→ 广播到链(sendRawTransaction()
)。window.ethereum
对象,实现 DApp 交互。 eth_requestAccounts
申请连接、eth_sendTransaction
发交易 )。Safe
合约实现复杂权限 )。 import { useAccount, useBalance } from 'wagmi';
function WalletInfo() {
const { address } = useAccount(); // 自动获取钱包地址
const { data: balance } = useBalance({ address }); // 自动查 ETH 余额
return <div>Address: {address}<br>Balance: {balance?.formatted}</div>;
}
- 优势:无需手动写 RPC 请求,状态自动更新(链上变化时前端实时响应 )。
window.ethereum.request({ method: 'eth_requestAccounts' })
连接 MetaMask。 import { createWalletConnectConnector } from 'wagmi/connectors/walletConnect';
const connector = createWalletConnectConnector({ chains, options: { projectId: '...' } });
await connector.connect(); // 弹出 Wallet Connect 二维码
RainbowKit
内置多种钱包适配 )。I sign in to DApp at 2024-10-01
),替代传统密码登录,实现“区块链身份认证”。
ecrecover
确认是地址所有者 )。isValidSignature
)。 signMessage
),合约用 ecrecover
函数恢复签名者地址,验证是否为目标地址: function verifySignature(bytes32 message, bytes memory sig) public view returns (bool) {
address signer = ecrecover(message, sig.v, sig.r, sig.s);
return signer == expectedAddress;
}
struct Transfer {
address to;
uint256 amount;
}
function transfer(Transfer calldata req, bytes memory sig) public {
// 验证 EIP712 签名
bytes32 digest = _hashTypedDataV4(keccak256(abi.encode(...)));
address signer = ecrecover(digest, sig.v, sig.r, sig.s);
require(signer == req.to, "Invalid signature");
// 执行转账...
}
approve
+ transferFrom
),易出错且耗 Gas。 approve
,实现“一步授权+转账”: function permit(address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) public {
// 验证签名,直接设置授权额度
_approve(owner, spender, value);
}
transfer(address,uint256)
)转成字节码(data
字段 )。 topics
+ data
)转回可读数据(如 Transfer(from, to, amount)
)。eth_subscribe
监听合约事件(如 Transfer
),实时获取链上操作(如 DEX 监听交易对流动性变化 )。 eth_getBlockByNumber
),解析每个区块的交易和事件,提取目标数据(如统计某地址历史转账 )。
一句话总结Contract:正了八经在以太坊链上运行的合约需要考虑gas优化,安全等,在开发过程中需要熟悉一些技巧用于定位错误,调试等。
课程模块 | 时间安排(W:Week, D:DAY) | 课程内容 |
---|---|---|
合约开发进阶: EVM 、GAS 优化 如何写出更优秀的代码 | W3D5 | 合约地址是如何生成的 创建合约的几个方式: CREATE、CREATE2、Create3(库) 最小代理的使用 理解如何预测合约地址、如何在不同链上生成相同的地址 |
W4D1 | EVM 是如何运行的 查看 EVM 执行指令的过程 理解 EVM 中不同的存储区域及特性、尤其是 GAS 的差异 深入理解合约中定义变量的存储布局、Gas 优化的前提 | |
W4D2 | 更多 GAS 优化技巧,如果做合理的数据设计和链上链下数据的平衡 介绍优秀的设计模式: 可迭代链表、默克尔树应用、MultiCall 交易打包 | |
W4D3 | 如果做合约迁移(如果被攻击) 理解合约升级的设计:代理与实现合约分开 理解合约升级解决的几个问题:存储布局冲突、函数冲突 合约升级实战中的方案:透明代理、UUPS 理解钻石代理 和 信标代理的使用场景 | |
W4D4 | 如何提升合约安全: 合约审计、最小化合约功能、完整测试、预案与演练 熟悉常见的安全漏洞: 重入攻击、Dos 拒绝服务、签名重用 溢出问题、精度损失、重入攻击、权限控制 CTF 资料推荐 | |
W4D5 | 合约审计: 如何做审计、准备什么、怎么做代码分析、静态分析、动态分析、AI 分析、人工分析 合约监控及自动化: 监控哪些内容、如何自动化处理(Chinalink automation 等服务) 事故分析:分析资金流、定位错误 |
nonce
)推导,公式:合约地址 = keccak256(rlp([部署者地址, nonce]))[12:]
。
nonce
递增 ),无法预测。合约地址 = keccak256(0xff + 工厂地址 + salt + keccak256(字节码))[12:]
。
Create3.sol
),简化盐值管理,让确定性部署更易用。// 最小代理字节码模板
bytes memory proxyCode = hex"3d602d80600a3d3981f3363d3d373d3d3d363d73bebebebebebebebebebebebebebebebebebebebebebe5af43d82803e903d91602b57fd5bf3";
address proxy = createProxy(proxyCode, implementationAddress);
- 作用:批量部署轻量级代理合约(如 NFT 铸币合约 ),节省成本。
PUSH
/POP
/MSTORE
等 )→ 修改存储或返回结果。 forge debug
单步跟踪 EVM 指令,或通过 Tenderly 查看交易执行轨迹( opcode 级分析 )。storage
(持久存储):存合约状态变量,修改成本极高(Gas 费贵,需共识 )。 memory
(临时内存):函数执行时临时存储,调用结束销毁,Gas 费低。 calldata
(调用数据):外部传入的只读数据,Gas 费最低(常用于函数参数 )。storage
写入(合并变量、用 memory
暂存计算结果 ),优先使用 calldata
传参。uint256 a; uint256 b;
占 1 个槽位 )。 uint8 a; uint8 b;
可存到一个槽位 )。 uint128 a; uint256 b;
会浪费空间 )。storage
操作。 Multicall
合约批量调用多个函数(如一次更新多个状态 ),减少交易次数和 Gas(forge multicall
支持 )。struct Node { uint256 data; address next; }
mapping(address => Node) nodes; // 链表存储
- 优势:插入/删除只需修改指针,无需遍历数组(节省 Gas )。
merkletreejs
生成根哈希,链上验证用户证明(verifyProof
),避免全量数据上链。storage
,转发调用到“实现合约”(Logic )。 __gap
占位符预留空间 )。 bytes4(keccak256("func()"))
)不与旧函数重复。owner
仅保留关键操作 )。 forge test
)+ Fuzz 测试(随机输入 )+ 主网 Fork 测试(模拟真实环境 )。 approve
+ transferFrom
),盗取资产。
ReentrancyGuard
(OpenZeppelin ),或“检查-生效-交互”模式。for (uint i; i < arr.length; i++) { ... }
被无限扩容 )。
permit
授权未过期 ),重复调用函数。
nonce
或时间戳校验。uint256 a = type(uint256).max; a++
溢出 )。
SafeMath
(旧版 )或 Solidity 0.8+ 自动溢出检查。slither
扫描代码漏洞 )。 forge test --fuzz
模拟运行 )。 debug_traceTransaction
),还原事故现场。一句话总结DeFi:去中心化比中心化的交易效率提高很多,这在金融场景上是天然的优势,DeFi也是区块链技技术的重要应用之一,稳定币法案的发布似乎意味着去中心化金融与中心化金融的融合即将到来。
课程模块 | 时间安排(W:Week, D:DAY) | 课程内容 |
---|---|---|
去中心化金融(DEFI)<br/>去中心化金融(DEFI) | W5D1 | 回顾行业发展关键事件 Token 的发行 IDO 与 LaunchPad 的实现 常见锁仓解锁机制及实现 探索代币经济模型 |
W5D2 | DEX 去中心化交易所: AMM 做市商模型:K = x*y Uniswap 添加、移除流动性 如何兑换、滑点、够代码讲解 理解滑点 什么是三明治攻击(夹子机器人),如何实施 | |
W5D3 | 继续深入 DEX: 1. ETH 与 WETH 2. 流动性提供的的无常损失 3. 什么是闪电兑换及应用 4. 如何获取 DEX价格(实时价格与时间加权价格)及 Chainlink价格预言机 5. Uniswap 的各版本迭代的优化(V3、V4,Uniswap X) 6. 其他的 DEX:SushiSwap、PancakeSwap 7. 交易聚合器 - 寻找最佳的交易路由(1Inch 等) SushiSwap 流动性挖矿: | |
W5D4 | 理解 1 池、2 池的不同 重点理解链上收益的单位累计的计算方式 核心挖矿的分析 | |
W5D5 | 借贷协议分析 - Compound 与 Aave 重点介绍 Compound 超额抵押借贷模型、预言机评估存贷价值 如何使用闪电贷、如何根据借贷资金使用率来动利率模型 利率模型相关代码分析 理解 APR 与 APY 资不抵债时,如何进行清算 Vault 拓展 - EIP4626 | |
W6D1 | 稳定币: 抵押型稳定币 - USDC(原 DAI)- 稳定币作为债务,以美元抵押的 USDC,USDT 算法稳定币:通过算法调节供需关系实现价格稳定 AmpL,理解 Rebase 机制 野生美联储 - Basis Cash FEI:理解 PCV:协议控制价值 Frax:渐进式稳定币 LUNAUST 的崩盘 | |
W6D2 | 杠杆交易: 杠杆在金融的工作原理:杠杆倍数、头寸、保证金、PNL 等 理解杠杆的正与负,不同情况的盈利和亏损表现 Perpetual 为例,分析杠杆交易的的实现 理解 vamm 虚拟流动性的作用 | |
W6D3 | 期货的由来、理解永续合约的工作原理 分析永续杠杆交易,不同方向的盈利和亏损表现 如何使用期货对冲,获取稳健收益 GMX 各模块及运行逻辑介绍 期权与期货的不同,如何使用期权对冲 债券与合成资产介绍 | |
W6D4 | 什么是 DAO 与 DAO 治理 协议 DAO 治理的流程 常见的投票机制、锁仓投票机制 重点理解 ERC20 Token 投票的实现 TimeLock 时间延迟的应用 | |
W6D5 | 什么是 MEV 常见的 MEV 策略:三明治(抢跑+尾随和)、不同市场套利、清算机会 MEV 案例分析、如何攻防 MEV Flashbots 介绍 如何发掘交易 |
ERC20
合约 _mint
函数 )生成原生代币,作为生态内的价值载体(如 Uniswap 的 UNI、Compound 的 COMP )。 vesting
合约 ),分阶段解锁(防止砸盘 ),示例: // 简化锁仓逻辑
function releaseToken(uint256 amount) public {
require(block.timestamp > unlockTime, "Not unlocked");
_transfer(owner, msg.sender, amount);
}
x*y=k
)替代传统订单簿,实现去中心化交易。
x
ETH 和 y
USDC,交易时 x
/y
变化,价格自动调整。function flashSwap() external {
// 借入代币
(uint256 amount0, uint256 amount1) = uniswapV3Pool.flash(fee, amount, data);
// 套利操作...
// 归还代币
uniswapV3Pool.repay(amount0, amount1);
}
ERC20Votes
合约(OpenZeppelin )记录代币投票权重,TimeLock
延迟执行投票结果(防止闪电攻击 )。一句话总结链上数据分析:区块链技术的底层原理决定了所有链上数据都是可以公开访问的,因此可以用数据分析的方法进行链上数据的分析,找历史规律等。
课程模块 | 时间安排(W:Week, D:DAY) | 课程内容 |
---|---|---|
W7D1 | 各种数据服务介绍 自索引服务与第三方服务 TheGraph 数据索引服务 工作原理 如和使用 TheGraph 索引数据(子图开发) GraphQL 查询 TrueBlocks 开源索引器 | |
协议数据分析 | W7D2 | DUNE 数据索引 Dune SQL 介绍 利用 DUNE 数据集 ( Transactions / Logs / dex.trades) 创建仪表板(Line, Bar, Pie, Table ) |
以下是对“协议数据分析”模块课程内容的概念拆解,帮你理解区块链数据索引与分析的核心工具和流程:
schema.graphql
(声明要查询的数据结构,如 type Trade { id: ID!, amount: BigInt! }
)。 mapping.ts
(映射链上事件到 schema,如监听 Uniswap Swap
事件,提取 amount
等字段 )。 graph deploy
命令 )。query {
trades(first: 10, orderBy: timestamp, orderDirection: desc) {
id
amount
timestamp
}
}
- 作用:查询最近 10 笔交易,按时间倒序排列,获取交易 ID、金额、时间戳。
geth
节点的 leveldb
),生成结构化数据(如地址交易历史、合约事件 )。 transactions
、logs
、dex.trades
)。transactions
:存储所有链上交易(from
、to
、value
、gas
等字段 )。 logs
:存储合约事件日志(topic0
是事件签名,data
是事件参数 )。 dex.trades
:Dune 整理的 DEX 交易数据(关联 transactions
和 logs
,提取 token_in
、token_out
、amount
等 )。SELECT
SUM(amount_in_usd) AS total_volume
FROM
dex.trades
WHERE
exchange_name = 'uniswap'
AND block_time >= NOW() - INTERVAL '24 HOURS';
total_volume
随时间变化 )。一句话总结Layer2:针对Layer1区块链打包缓慢的问题,Layer2 通过批量向Layer1提交数据以提高Layer1的吞吐量,加快交易的确认。
Layer2 开发 | W7D3 | 深入理解 POS 以太坊: 出块机制 epoch 与 slot 验证者质押与 LSD 、 EigenLayer 重新质押协议 为什么需要 Layer2 及 DA 层服务(4844、Celestia、 EigenDa) layer2: ZK Rollup、 OpRollup 运行原理及各自代表项目 |
---|---|---|
W7D4 | layer2 主流开发技术框架: Op-Stack、 Polygon CDK 、 Arbitrum Orbit、 ZkSync SuperChain 应用链: Cosmos-SDK 理解 Op-Stack 项目架构与各个组件(Sequencer、 Rollup Services、 Verifier、证明系统等) 如何基于 Op-Stack 开发 Layer2 | |
W7D5 | Op-Stack 跨链桥原理及实现 Op-Stack 的充值流程(一层到二层) Op-Stack 的取现流程(二层到一层) ETH 与 ERC20 的不同处理 | |
W8D1 | ZKEVM 项目演变,各 ZKEVM 项目不同技术路线 Polygon ZkEvm 的主要模块 Polygon CDK 技术框架 Polygon 桥实现 |
一句话总结Solona:基于POH技术的超快速高吞吐量公链,但验证节点仅有2000余个,牺牲部分去中心化带来了高性能,基于Rust开发。
课程模块 | 时间安排(W:Week, D:DAY) | 课程内容 |
---|---|---|
Solana 开发 | W8D2 | Solana 核心概念: 理解 POH(历史证明)、共识算法、Solana 出块流程、账户模型、PDA 等 重点理解 Solana 数据与程序分开的账户模型 |
W8D3 | 与 Solana 链交互: 理解 SPL Token 如何使用 Web3.js 发起交易、创建第一个 Token 及 NFT | |
W8D4 | Solana 合约开发基础: Rust 基础、 Solana Playground 、合约编译、部署 | |
W8D5 | Anchor 框架介绍 使用 Anchor 开发 Solana 程序 处理指令、管理状态、CPI Solana 程序测试 | |
W9D1 | Solana DApp 开发: 钱包接入、合约调用 DApp接入 Blinks 链上数据的索引 |
PDA = findProgramAddress([seed], programId)
。create Mint
)、转账(transfer
)、授权(approve
),兼容 Solana 生态钱包/交易所。import { Connection, Keypair, LAMPORTS_PER_SOL } from '@solana/web3.js';
import { createMint } from '@solana/spl-token';
const connection = new Connection('https://api.devnet.solana.com');
const wallet = Keypair.generate();
// 创替代币
const mint = await createMint(connection, wallet, wallet.publicKey, null, 9);
console.log('Token Mint Address:', mint.toBase58());
lib.rs
)。 solana-cli
编译:cargo build-bpf
。 solana program deploy target/deploy/program.so
。instruction
函数,处理链上操作(如转账、更新状态 )。 Account
结构体存程序状态,Anchor 自动序列化/反序列化。 window.solana
对象连接钱包、签名交易。@project-serum/anchor
库加载程序 ID、调用指令(如 mint NFT ),与链上程序交互。如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!