Skip to content

Commit 68764e0

Browse files
committed
Add study notes for 2025-08-20
1 parent 5edac73 commit 68764e0

1 file changed

Lines changed: 103 additions & 0 deletions

File tree

3956ray.md

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,109 @@ timezone: UTC+8
1515
## Notes
1616

1717
<!-- Content_START -->
18+
# 2025-08-20
19+
20+
下面以区块链与合约开发者的视角,系统阐述 ERC‑721 的定义、技术细节、实现要点与在合约/DeFi 中的典型用法,并配上若干可直接复用的代码示例,帮助你从标准到工程落地一把过。
21+
22+
一、定义与背景
23+
- 定义:ERC‑721 是以太坊最早、最广泛使用的“非同质化代币”(NFT)标准,核心特性是“唯一性 + 可确权归属”,每个 tokenId 代表一个不可互换的资产单元。
24+
- 标准目标:
25+
- 标准化拥有者查询、转移、授权与元数据访问的接口;
26+
- 为合约间 NFT 交互提供强约束(如 safeTransfer 的合约接收回调);
27+
- 与钱包、市场、浏览器等基础设施的互操作性。
28+
- 对比 ERC‑20/EIP‑1155:
29+
- ERC‑20 可替代;ERC‑721 完全非同质;
30+
- ERC‑1155 为多代币/半同质模型,适合大规模铸造与批量转移;ERC‑721 更强调 “每个 tokenId 是独立实体”。
31+
32+
二、核心接口与事件
33+
- IERC165:接口检测
34+
- 合约需实现 supportsInterface(bytes4 interfaceId)
35+
- IERC721:核心
36+
- balanceOf(owner)、ownerOf(tokenId)
37+
- approve(to, tokenId)、getApproved(tokenId)、setApprovalForAll(operator, approved)、isApprovedForAll(owner, operator)
38+
- transferFrom(from, to, tokenId)、safeTransferFrom(from, to, tokenId[, data])
39+
- 事件:Transfer、Approval、ApprovalForAll
40+
- IERC721Receiver:合约安全接收回调
41+
- onERC721Received(operator, from, tokenId, data) -> bytes4
42+
- safeTransferFrom 若目标是合约,必须返回正确的 selector,否则 revert
43+
- IERC721Metadata(可选但行业事实标准)
44+
- name()、symbol()、tokenURI(tokenId)
45+
- IERC721Enumerable(可选,不再推荐用于大规模集合)
46+
- tokenOfOwnerByIndex、totalSupply、tokenByIndex(链上枚举成本高)
47+
- 常见扩展
48+
- EIP‑2981: 版税标准(royaltyInfo)
49+
- EIP‑2309: 批量铸造事件(ConsecutiveTransfer)用于部署期大批量 mint 记账
50+
- EIP‑4494: NFT Permit(签名授权,无需先 on-chain approve)
51+
- EIP‑4907: 可租用角色(user/expiry)
52+
53+
三、实现要点与存储结构
54+
- 典型存储
55+
- mapping(uint256 => address) _ownerOf
56+
- mapping(address => uint256) _balanceOf
57+
- mapping(uint256 => address) _tokenApprovals
58+
- mapping(address => mapping(address => bool)) _operatorApprovals
59+
- 必备不变量
60+
- ownerOf(tokenId) 非零地址代表已存在
61+
- balanceOf 与 Transfer 事件保持一致性
62+
- 转移后应清空 token 级别的 single-approval
63+
- 转移安全
64+
- 对未知地址优先使用 safeTransferFrom,避免 NFT 被转进不支持的合约导致“黑洞”
65+
- checks-effects-interactions 原则:在对外调用前更新状态,必要时加 ReentrancyGuard
66+
- 元数据
67+
- tokenURI 返回 JSON 元数据 URL(可 HTTP/IPFS/Arweave/data URI)
68+
- 大集合建议 baseURI + tokenId 拼接,或 on-chain SVG/JSON(需注意 gas)
69+
- 构造 tokenId
70+
- 常用自增计数器(如 OpenZeppelin Counters)
71+
- 若需随机/稀有度分布,慎用链上随机(需 VRF/预承诺等抗操纵机制)
72+
- Gas/可扩展性
73+
- 尽量避免 IERC721Enumerable;链上枚举昂贵
74+
- 大规模集合:考虑 EIP‑2309、稀疏存储压缩、或使用优化实现(如批量 mint 的 gas 模式、稀疏 ownership 记录)
75+
- 升级性:使用代理(UUPS/Transparent),注意构造函数逻辑迁移到 initializer
76+
77+
四、可用 ERC‑721(基于 OpenZeppelin)
78+
包含:安全转移、BaseURI、仅拥有者铸造
79+
80+
```solidity:contracts/MyNFT.sol
81+
// SPDX-License-Identifier: MIT
82+
pragma solidity ^0.8.20;
83+
84+
import {ERC721} from "@openzeppelin/contracts/token/ERC721/ERC721.sol";
85+
import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";
86+
import {Strings} from "@openzeppelin/contracts/utils/Strings.sol";
87+
88+
contract MyNFT is ERC721, Ownable {
89+
using Strings for uint256;
90+
91+
string private _baseTokenURI;
92+
uint256 private _nextId;
93+
94+
constructor(string memory name_, string memory symbol_, string memory baseURI_) ERC721(name_, symbol_) Ownable(msg.sender) {
95+
_baseTokenURI = baseURI_;
96+
_nextId = 1;
97+
}
98+
99+
function setBaseURI(string calldata baseURI_) external onlyOwner {
100+
_baseTokenURI = baseURI_;
101+
}
102+
103+
function mint(address to) external onlyOwner returns (uint256 tokenId) {
104+
tokenId = _nextId++;
105+
_safeMint(to, tokenId); // 使用 safeMint,自动调用 onERC721Received
106+
}
107+
108+
function _baseURI() internal view override returns (string memory) {
109+
return _baseTokenURI;
110+
}
111+
112+
// 如果需要自定义 tokenURI,可覆盖如下
113+
function tokenURI(uint256 tokenId) public view override returns (string memory) {
114+
_requireOwned(tokenId);
115+
string memory base = _baseURI();
116+
return bytes(base).length > 0 ? string(abi.encodePacked(base, tokenId.toString(), ".json")) : "";
117+
}
118+
}
119+
```
120+
18121
# 2025-08-19
19122

20123
# 1. EIP-20

0 commit comments

Comments
 (0)