<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>以太坊 on 牛哥聊技术</title><link>https://www.lingcoder.com/tags/%E4%BB%A5%E5%A4%AA%E5%9D%8A/</link><description>Recent content in 以太坊 on 牛哥聊技术</description><generator>Hugo -- gohugo.io</generator><language>zh</language><lastBuildDate>Sat, 14 Feb 2026 15:30:00 +0800</lastBuildDate><atom:link href="https://www.lingcoder.com/tags/%E4%BB%A5%E5%A4%AA%E5%9D%8A/index.xml" rel="self" type="application/rss+xml"/><item><title>常见 EVM 提案速查：ERC 与 EIP 的核心标准</title><link>https://www.lingcoder.com/p/common-evm-eip-erc-cheatsheet/</link><pubDate>Sat, 14 Feb 2026 15:30:00 +0800</pubDate><guid>https://www.lingcoder.com/p/common-evm-eip-erc-cheatsheet/</guid><description>&lt;img src="https://www.lingcoder.com/p/common-evm-eip-erc-cheatsheet/cover.svg" alt="Featured image of post 常见 EVM 提案速查：ERC 与 EIP 的核心标准" /&gt;&lt;h2 id="写在前面"&gt;&lt;a href="#%e5%86%99%e5%9c%a8%e5%89%8d%e9%9d%a2" class="header-anchor"&gt;&lt;/a&gt;写在前面
&lt;/h2&gt;&lt;p&gt;Web3 生态里 ERC 和 EIP 提案多到眼花缭乱——&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ERC-20 / 721 / 1155 是耳熟能详的代币标准&lt;/li&gt;
&lt;li&gt;EIP-1559 改变了以太坊的费用模型&lt;/li&gt;
&lt;li&gt;EIP-712 让钱包能展示可读签名&lt;/li&gt;
&lt;li&gt;ERC-2981 解决了版税问题&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;新人看到这些数字号就头疼——&lt;strong&gt;每个具体在做什么？哪些重要哪些次要？&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;本文给一份&lt;strong&gt;能查的清单&lt;/strong&gt;——按用途分类，每个标准用一段讲清楚是什么、为什么重要、典型用法。&lt;strong&gt;适合放到 Notion / Obsidian 里&lt;/strong&gt;作为日常查询。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="一erc-vs-eip"&gt;&lt;a href="#%e4%b8%80erc-vs-eip" class="header-anchor"&gt;&lt;/a&gt;一、ERC vs EIP
&lt;/h2&gt;&lt;p&gt;先把概念分清：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;EIP（Ethereum Improvement Proposal）&lt;/strong&gt;：以太坊改进提案——任何关于以太坊的改进都是 EIP&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ERC（Ethereum Request for Comments）&lt;/strong&gt;：EIP 的一类子集，&lt;strong&gt;专门用于应用层标准&lt;/strong&gt;（代币、签名、接口等）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;简单理解：&lt;strong&gt;所有 ERC 都是 EIP，但不是所有 EIP 都是 ERC&lt;/strong&gt;。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="二代币标准"&gt;&lt;a href="#%e4%ba%8c%e4%bb%a3%e5%b8%81%e6%a0%87%e5%87%86" class="header-anchor"&gt;&lt;/a&gt;二、代币标准
&lt;/h2&gt;&lt;h3 id="erc-20可替代代币"&gt;&lt;a href="#erc-20%e5%8f%af%e6%9b%bf%e4%bb%a3%e4%bb%a3%e5%b8%81" class="header-anchor"&gt;&lt;/a&gt;ERC-20：可替代代币
&lt;/h3&gt;
 &lt;blockquote&gt;
 &lt;p&gt;最经典的代币标准。USDC、USDT、UNI、所有 DeFi 代币都是 ERC-20。&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;p&gt;核心接口：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;span class="lnt"&gt;8
&lt;/span&gt;&lt;span class="lnt"&gt;9
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-solidity" data-lang="solidity"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;totalSupply&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;external&lt;/span&gt; &lt;span class="k"&gt;view&lt;/span&gt; &lt;span class="k"&gt;returns&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;uint256&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;balanceOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;address&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;external&lt;/span&gt; &lt;span class="k"&gt;view&lt;/span&gt; &lt;span class="k"&gt;returns&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;uint256&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;transfer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;address&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;uint256&lt;/span&gt; &lt;span class="nb"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;external&lt;/span&gt; &lt;span class="k"&gt;returns&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;approve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;address&lt;/span&gt; &lt;span class="n"&gt;spender&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;uint256&lt;/span&gt; &lt;span class="nb"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;external&lt;/span&gt; &lt;span class="k"&gt;returns&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;allowance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;address&lt;/span&gt; &lt;span class="n"&gt;owner&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;address&lt;/span&gt; &lt;span class="n"&gt;spender&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;external&lt;/span&gt; &lt;span class="k"&gt;view&lt;/span&gt; &lt;span class="k"&gt;returns&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;uint256&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;transferFrom&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;address&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;address&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;uint256&lt;/span&gt; &lt;span class="nb"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;external&lt;/span&gt; &lt;span class="k"&gt;returns&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;event&lt;/span&gt; &lt;span class="nc"&gt;Transfer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;address&lt;/span&gt; &lt;span class="k"&gt;indexed&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;address&lt;/span&gt; &lt;span class="k"&gt;indexed&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;uint256&lt;/span&gt; &lt;span class="nb"&gt;value&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;event&lt;/span&gt; &lt;span class="nc"&gt;Approval&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;address&lt;/span&gt; &lt;span class="k"&gt;indexed&lt;/span&gt; &lt;span class="n"&gt;owner&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;address&lt;/span&gt; &lt;span class="k"&gt;indexed&lt;/span&gt; &lt;span class="n"&gt;spender&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;uint256&lt;/span&gt; &lt;span class="nb"&gt;value&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;strong&gt;最重要的标准——不可替代&lt;/strong&gt;。&lt;/p&gt;
&lt;h3 id="erc-721非同质化代币nft"&gt;&lt;a href="#erc-721%e9%9d%9e%e5%90%8c%e8%b4%a8%e5%8c%96%e4%bb%a3%e5%b8%81nft" class="header-anchor"&gt;&lt;/a&gt;ERC-721：非同质化代币（NFT）
&lt;/h3&gt;
 &lt;blockquote&gt;
 &lt;p&gt;每个 token 唯一。CryptoPunks、BAYC、CryptoKitties 都是 ERC-721。&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-solidity" data-lang="solidity"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;ownerOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;uint256&lt;/span&gt; &lt;span class="n"&gt;tokenId&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;external&lt;/span&gt; &lt;span class="k"&gt;view&lt;/span&gt; &lt;span class="k"&gt;returns&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;address&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;safeTransferFrom&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;address&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;address&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;uint256&lt;/span&gt; &lt;span class="n"&gt;tokenId&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;external&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;approve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;address&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;uint256&lt;/span&gt; &lt;span class="n"&gt;tokenId&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;external&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;setApprovalForAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;address&lt;/span&gt; &lt;span class="n"&gt;operator&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="n"&gt;approved&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;external&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;tokenURI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;uint256&lt;/span&gt; &lt;span class="n"&gt;tokenId&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;external&lt;/span&gt; &lt;span class="k"&gt;view&lt;/span&gt; &lt;span class="k"&gt;returns&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;每个 tokenId 一段独立元数据。&lt;/p&gt;
&lt;h3 id="erc-1155多代币标准"&gt;&lt;a href="#erc-1155%e5%a4%9a%e4%bb%a3%e5%b8%81%e6%a0%87%e5%87%86" class="header-anchor"&gt;&lt;/a&gt;ERC-1155：多代币标准
&lt;/h3&gt;
 &lt;blockquote&gt;
 &lt;p&gt;&lt;strong&gt;一个合约管理多种 token，每种可以有多份&lt;/strong&gt;。游戏道具、批量场景的事实标准。&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-solidity" data-lang="solidity"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;balanceOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;address&lt;/span&gt; &lt;span class="n"&gt;account&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;uint256&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;external&lt;/span&gt; &lt;span class="k"&gt;view&lt;/span&gt; &lt;span class="k"&gt;returns&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;uint256&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;safeTransferFrom&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;address&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;address&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;uint256&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;uint256&lt;/span&gt; &lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;bytes&lt;/span&gt; &lt;span class="nb"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;external&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;safeBatchTransferFrom&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;address&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;address&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;uint256&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;ids&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;uint256&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;amounts&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;bytes&lt;/span&gt; &lt;span class="nb"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;external&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;支持&lt;strong&gt;批量操作&lt;/strong&gt;——比 ERC-721 在多 token 场景下省 40 倍 Gas。&lt;/p&gt;
&lt;h3 id="erc-777增强版-erc-20争议"&gt;&lt;a href="#erc-777%e5%a2%9e%e5%bc%ba%e7%89%88-erc-20%e4%ba%89%e8%ae%ae" class="header-anchor"&gt;&lt;/a&gt;ERC-777：增强版 ERC-20（争议）
&lt;/h3&gt;
 &lt;blockquote&gt;
 &lt;p&gt;试图改进 ERC-20——支持 hooks（接收方能拦截转账）、operator 等。&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;p&gt;但&lt;strong&gt;重入攻击风险高&lt;/strong&gt;——一些项目（imBTC）因为它被攻击。&lt;strong&gt;社区主流是不用 ERC-777&lt;/strong&gt;——直接 ERC-20 + ERC-2612 更安全。&lt;/p&gt;
&lt;h3 id="erc-4626代币化金库tokenized-vault"&gt;&lt;a href="#erc-4626%e4%bb%a3%e5%b8%81%e5%8c%96%e9%87%91%e5%ba%93tokenized-vault" class="header-anchor"&gt;&lt;/a&gt;ERC-4626：代币化金库（Tokenized Vault）
&lt;/h3&gt;
 &lt;blockquote&gt;
 &lt;p&gt;标准化&amp;quot;存款进 vault 拿 share token&amp;quot;的接口。Yearn、Aave V3 等收益策略合约用它。&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-solidity" data-lang="solidity"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;asset&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;external&lt;/span&gt; &lt;span class="k"&gt;view&lt;/span&gt; &lt;span class="k"&gt;returns&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;address&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;totalAssets&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;external&lt;/span&gt; &lt;span class="k"&gt;view&lt;/span&gt; &lt;span class="k"&gt;returns&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;uint256&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;deposit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;uint256&lt;/span&gt; &lt;span class="n"&gt;assets&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;address&lt;/span&gt; &lt;span class="n"&gt;receiver&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;external&lt;/span&gt; &lt;span class="k"&gt;returns&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;uint256&lt;/span&gt; &lt;span class="n"&gt;shares&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;withdraw&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;uint256&lt;/span&gt; &lt;span class="n"&gt;assets&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;address&lt;/span&gt; &lt;span class="n"&gt;receiver&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;address&lt;/span&gt; &lt;span class="n"&gt;owner&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;external&lt;/span&gt; &lt;span class="k"&gt;returns&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;uint256&lt;/span&gt; &lt;span class="n"&gt;shares&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;strong&gt;所有 yield aggregator / lending protocol 都应该实现 ERC-4626&lt;/strong&gt;——可组合性大增。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="三接口与发现"&gt;&lt;a href="#%e4%b8%89%e6%8e%a5%e5%8f%a3%e4%b8%8e%e5%8f%91%e7%8e%b0" class="header-anchor"&gt;&lt;/a&gt;三、接口与发现
&lt;/h2&gt;&lt;h3 id="erc-165标准接口检测"&gt;&lt;a href="#erc-165%e6%a0%87%e5%87%86%e6%8e%a5%e5%8f%a3%e6%a3%80%e6%b5%8b" class="header-anchor"&gt;&lt;/a&gt;ERC-165：标准接口检测
&lt;/h3&gt;
 &lt;blockquote&gt;
 &lt;p&gt;让合约能查询&amp;quot;另一个合约是否实现某个接口&amp;quot;。&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-solidity" data-lang="solidity"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;IERC165&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;supportsInterface&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;bytes4&lt;/span&gt; &lt;span class="nb"&gt;interfaceId&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;external&lt;/span&gt; &lt;span class="k"&gt;view&lt;/span&gt; &lt;span class="k"&gt;returns&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// 用法
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;IERC165&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;addr&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;supportsInterface&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mh"&gt;0x80ac58cd&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 是否是 ERC-721
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;code&gt;interfaceId&lt;/code&gt; 是接口所有函数 selector 的 XOR——&lt;strong&gt;编译时计算&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;ERC-721、ERC-1155 都强制实现 ERC-165。&lt;/p&gt;
&lt;h3 id="erc-1820通用注册表"&gt;&lt;a href="#erc-1820%e9%80%9a%e7%94%a8%e6%b3%a8%e5%86%8c%e8%a1%a8" class="header-anchor"&gt;&lt;/a&gt;ERC-1820：通用注册表
&lt;/h3&gt;
 &lt;blockquote&gt;
 &lt;p&gt;像 ERC-165 但更通用——支持&amp;quot;为某地址绑定接口实现&amp;quot;。&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-solidity" data-lang="solidity"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;ERC1820Registry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;setInterfaceImplementer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;addr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;interfaceHash&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;implementer&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;ERC-777 用它做 hook 注册——但因为 777 不流行，&lt;strong&gt;1820 也只在少数场景用&lt;/strong&gt;。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="四签名标准"&gt;&lt;a href="#%e5%9b%9b%e7%ad%be%e5%90%8d%e6%a0%87%e5%87%86" class="header-anchor"&gt;&lt;/a&gt;四、签名标准
&lt;/h2&gt;&lt;h3 id="eip-712结构化数据签名"&gt;&lt;a href="#eip-712%e7%bb%93%e6%9e%84%e5%8c%96%e6%95%b0%e6%8d%ae%e7%ad%be%e5%90%8d" class="header-anchor"&gt;&lt;/a&gt;EIP-712：结构化数据签名
&lt;/h3&gt;
 &lt;blockquote&gt;
 &lt;p&gt;让钱包能&lt;strong&gt;显示可读的签名内容&lt;/strong&gt;，而不是一串十六进制 hash。&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;p&gt;老的 &lt;code&gt;eth_sign&lt;/code&gt;：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;请签名：0xa1b2c3d4e5f6...
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;EIP-712：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;请签名：
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; Permit:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; owner: 0xAlice...
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; spender: 0xUniswap...
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; value: 100 USDC
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; deadline: 2026-12-31
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;strong&gt;所有现代 dapp 的签名都用 EIP-712&lt;/strong&gt;——不仅可读，还防钓鱼。&lt;/p&gt;
&lt;h3 id="eip-2612permit无-gas-approve"&gt;&lt;a href="#eip-2612permit%e6%97%a0-gas-approve" class="header-anchor"&gt;&lt;/a&gt;EIP-2612：Permit（无 Gas approve）
&lt;/h3&gt;
 &lt;blockquote&gt;
 &lt;p&gt;用 EIP-712 签名替代 ERC-20 的 &lt;code&gt;approve&lt;/code&gt; 调用——&lt;strong&gt;用户不付 approve 的 Gas&lt;/strong&gt;。&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-solidity" data-lang="solidity"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;permit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kt"&gt;address&lt;/span&gt; &lt;span class="n"&gt;owner&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;address&lt;/span&gt; &lt;span class="n"&gt;spender&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;uint256&lt;/span&gt; &lt;span class="nb"&gt;value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kt"&gt;uint256&lt;/span&gt; &lt;span class="n"&gt;deadline&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;uint8&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;bytes32&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;bytes32&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;external&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;用户线下签 permit，dapp 把签名 + 操作打包成一笔 tx——&lt;strong&gt;省一笔 approve Gas + 改善体验&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;新代币几乎都实现 EIP-2612。&lt;/p&gt;
&lt;h3 id="eip-1271合约签名验证"&gt;&lt;a href="#eip-1271%e5%90%88%e7%ba%a6%e7%ad%be%e5%90%8d%e9%aa%8c%e8%af%81" class="header-anchor"&gt;&lt;/a&gt;EIP-1271：合约签名验证
&lt;/h3&gt;
 &lt;blockquote&gt;
 &lt;p&gt;让&amp;quot;智能账户合约&amp;quot;也能&amp;quot;签名&amp;quot;——&lt;code&gt;isValidSignature&lt;/code&gt; 让合约模拟 EOA 签名。&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-solidity" data-lang="solidity"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;isValidSignature&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;bytes32&lt;/span&gt; &lt;span class="n"&gt;hash&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;bytes&lt;/span&gt; &lt;span class="k"&gt;memory&lt;/span&gt; &lt;span class="n"&gt;signature&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;external&lt;/span&gt; &lt;span class="k"&gt;view&lt;/span&gt; &lt;span class="k"&gt;returns&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;bytes4&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;ERC-4337 智能账户、Safe 多签都用它。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="五版税与市场"&gt;&lt;a href="#%e4%ba%94%e7%89%88%e7%a8%8e%e4%b8%8e%e5%b8%82%e5%9c%ba" class="header-anchor"&gt;&lt;/a&gt;五、版税与市场
&lt;/h2&gt;&lt;h3 id="eip-2981nft-版税标准"&gt;&lt;a href="#eip-2981nft-%e7%89%88%e7%a8%8e%e6%a0%87%e5%87%86" class="header-anchor"&gt;&lt;/a&gt;EIP-2981：NFT 版税标准
&lt;/h3&gt;
 &lt;blockquote&gt;
 &lt;p&gt;标准化 NFT 二级市场的版税分配。&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-solidity" data-lang="solidity"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;royaltyInfo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;uint256&lt;/span&gt; &lt;span class="n"&gt;tokenId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;uint256&lt;/span&gt; &lt;span class="n"&gt;salePrice&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;external&lt;/span&gt; &lt;span class="k"&gt;view&lt;/span&gt; &lt;span class="k"&gt;returns&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;address&lt;/span&gt; &lt;span class="n"&gt;receiver&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;uint256&lt;/span&gt; &lt;span class="n"&gt;royaltyAmount&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;OpenSea、Blur、LooksRare 等市场调用这个接口确定版税收款方和金额。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;新 NFT 项目必实现 EIP-2981&lt;/strong&gt;——否则只能依赖每个市场各自的版税设置。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="六gas-与费用"&gt;&lt;a href="#%e5%85%adgas-%e4%b8%8e%e8%b4%b9%e7%94%a8" class="header-anchor"&gt;&lt;/a&gt;六、Gas 与费用
&lt;/h2&gt;&lt;h3 id="eip-1559基础费--优先费"&gt;&lt;a href="#eip-1559%e5%9f%ba%e7%a1%80%e8%b4%b9--%e4%bc%98%e5%85%88%e8%b4%b9" class="header-anchor"&gt;&lt;/a&gt;EIP-1559：基础费 + 优先费
&lt;/h3&gt;
 &lt;blockquote&gt;
 &lt;p&gt;2021 年伦敦升级——&lt;strong&gt;改变了以太坊的费用模型&lt;/strong&gt;。&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;p&gt;老模型：完全拍卖，gasPrice 用户出多少都行——&lt;strong&gt;网络拥堵时 gas 飙升不可预测&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;EIP-1559 模型：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;baseFee&lt;/strong&gt;：每个 block 由协议算出，&lt;strong&gt;会被 burn 销毁&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;priorityFee（tip）&lt;/strong&gt;：用户给矿工的小费&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// 现代以太坊 tx
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;maxFeePerGas&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;...,&lt;/span&gt; &lt;span class="c1"&gt;// 用户愿意付的最高总 fee
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;maxPriorityFeePerGas&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt; &lt;span class="c1"&gt;// 给矿工的小费
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;strong&gt;好处&lt;/strong&gt;：费用更可预测、ETH 经济学进入通缩。&lt;/p&gt;
&lt;h3 id="eip-1283--2200--2929gas-调整"&gt;&lt;a href="#eip-1283--2200--2929gas-%e8%b0%83%e6%95%b4" class="header-anchor"&gt;&lt;/a&gt;EIP-1283 / 2200 / 2929：Gas 调整
&lt;/h3&gt;&lt;p&gt;历史上多次调整 SSTORE / SLOAD 的 Gas 成本，主要影响合约 gas 估算与底层操作成本。&lt;strong&gt;经典副作用&lt;/strong&gt;是 EIP-2929（Berlin，2021-04）抬高 SLOAD/CALL 成本后，依赖固定 2300 gas 的 &lt;code&gt;transfer&lt;/code&gt; / &lt;code&gt;send&lt;/code&gt; 在接收方为合约时不再可靠——这是真实改变了应用层的可用性，并不只是&amp;quot;算 gas 时数字变了&amp;quot;。&lt;/p&gt;
&lt;h3 id="eip-3074--eip-7702让-eoa-也能批量执行"&gt;&lt;a href="#eip-3074--eip-7702%e8%ae%a9-eoa-%e4%b9%9f%e8%83%bd%e6%89%b9%e9%87%8f%e6%89%a7%e8%a1%8c" class="header-anchor"&gt;&lt;/a&gt;EIP-3074 / EIP-7702：让 EOA 也能&amp;quot;批量执行&amp;quot;
&lt;/h3&gt;&lt;p&gt;让 EOA 也能像智能账户一样&amp;quot;批量执行&amp;quot;。&lt;strong&gt;EIP-3074&lt;/strong&gt;（AUTH / AUTHCALL）方向几次评审后被放弃，由更轻量的 &lt;strong&gt;EIP-7702&lt;/strong&gt; 取代——后者已随 &lt;strong&gt;Pectra 升级（2025-05）上线主网&lt;/strong&gt;。EIP-7702 让 EOA 在一笔交易内&amp;quot;临时&amp;quot;挂上一段合约代码，从而原子地批量调用、付费代付（gas sponsor）、与 ERC-4337 形成互补。&lt;/p&gt;
&lt;h3 id="eip-4844proto-danksharding2024-年上线"&gt;&lt;a href="#eip-4844proto-danksharding2024-%e5%b9%b4%e4%b8%8a%e7%ba%bf" class="header-anchor"&gt;&lt;/a&gt;EIP-4844：Proto-Danksharding（2024 年上线）
&lt;/h3&gt;
 &lt;blockquote&gt;
 &lt;p&gt;引入 &lt;strong&gt;blob transaction&lt;/strong&gt;——L2 发数据成本大降。&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;p&gt;L2（Optimism、Arbitrum、zkSync 等）用 blob 替代 calldata 提交批数据——&lt;strong&gt;Gas 成本降到原来 10%&lt;/strong&gt;。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="七账户抽象"&gt;&lt;a href="#%e4%b8%83%e8%b4%a6%e6%88%b7%e6%8a%bd%e8%b1%a1" class="header-anchor"&gt;&lt;/a&gt;七、账户抽象
&lt;/h2&gt;&lt;h3 id="erc-4337账户抽象"&gt;&lt;a href="#erc-4337%e8%b4%a6%e6%88%b7%e6%8a%bd%e8%b1%a1" class="header-anchor"&gt;&lt;/a&gt;ERC-4337：账户抽象
&lt;/h3&gt;
 &lt;blockquote&gt;
 &lt;p&gt;智能合约账户标准——&lt;strong&gt;不需要修改 Layer1 协议&lt;/strong&gt;。&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;p&gt;让用户的&amp;quot;账户&amp;quot;是一个智能合约——可以：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;多签&lt;/strong&gt;（不只是私钥控制）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;社交恢复&lt;/strong&gt;（朋友帮你恢复账户）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;付 Gas 不需要 ETH&lt;/strong&gt;（用 USDC 付 Gas）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;批量交易&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;ERC-4337 的核心是 &lt;code&gt;EntryPoint&lt;/code&gt; 合约 + &lt;code&gt;UserOperation&lt;/code&gt; 数据结构 + &lt;code&gt;Bundler&lt;/code&gt; 角色。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;这是 Web3 走向主流的关键基础设施之一&lt;/strong&gt;——降低普通用户的使用门槛。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="八合约升级与可拥有"&gt;&lt;a href="#%e5%85%ab%e5%90%88%e7%ba%a6%e5%8d%87%e7%ba%a7%e4%b8%8e%e5%8f%af%e6%8b%a5%e6%9c%89" class="header-anchor"&gt;&lt;/a&gt;八、合约升级与可拥有
&lt;/h2&gt;&lt;h3 id="eip-1967标准-proxy-storage-slots"&gt;&lt;a href="#eip-1967%e6%a0%87%e5%87%86-proxy-storage-slots" class="header-anchor"&gt;&lt;/a&gt;EIP-1967：标准 Proxy Storage Slots
&lt;/h3&gt;
 &lt;blockquote&gt;
 &lt;p&gt;标准化 Proxy 合约的存储槽位置，避免槽位冲突。&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;implementation: keccak256(&amp;#34;eip1967.proxy.implementation&amp;#34;) - 1
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;admin: keccak256(&amp;#34;eip1967.proxy.admin&amp;#34;) - 1
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;OpenZeppelin Upgrades 用的就是这个。&lt;/p&gt;
&lt;h3 id="eip-1822uups-代理"&gt;&lt;a href="#eip-1822uups-%e4%bb%a3%e7%90%86" class="header-anchor"&gt;&lt;/a&gt;EIP-1822：UUPS 代理
&lt;/h3&gt;
 &lt;blockquote&gt;
 &lt;p&gt;把&amp;quot;升级逻辑&amp;quot;放进 implementation 合约——proxy 更精简、Gas 更省。&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;p&gt;OpenZeppelin 现在推荐 UUPS 而不是 Transparent Proxy。&lt;/p&gt;
&lt;h3 id="eip-2535diamond-标准"&gt;&lt;a href="#eip-2535diamond-%e6%a0%87%e5%87%86" class="header-anchor"&gt;&lt;/a&gt;EIP-2535：Diamond 标准
&lt;/h3&gt;
 &lt;blockquote&gt;
 &lt;p&gt;一个 proxy + 多个 facet——&lt;strong&gt;绕开合约 24KB 字节码上限&lt;/strong&gt;。&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;p&gt;适合超大型协议（Aavegotchi 是典型案例）。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="九其他常用提案"&gt;&lt;a href="#%e4%b9%9d%e5%85%b6%e4%bb%96%e5%b8%b8%e7%94%a8%e6%8f%90%e6%a1%88" class="header-anchor"&gt;&lt;/a&gt;九、其他常用提案
&lt;/h2&gt;&lt;h3 id="erc-2470singleton-factory"&gt;&lt;a href="#erc-2470singleton-factory" class="header-anchor"&gt;&lt;/a&gt;ERC-2470：Singleton Factory
&lt;/h3&gt;&lt;p&gt;部署在所有链上的&amp;quot;单例工厂&amp;quot;——通过 CREATE2 让你的合约在所有链上有&lt;strong&gt;相同地址&lt;/strong&gt;。&lt;/p&gt;
&lt;h3 id="erc-3156flash-loan-标准"&gt;&lt;a href="#erc-3156flash-loan-%e6%a0%87%e5%87%86" class="header-anchor"&gt;&lt;/a&gt;ERC-3156：Flash Loan 标准
&lt;/h3&gt;
 &lt;blockquote&gt;
 &lt;p&gt;闪电贷标准。Aave、dYdX、Maker 都实现。&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-solidity" data-lang="solidity"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;flashLoan&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IERC3156FlashBorrower&lt;/span&gt; &lt;span class="n"&gt;receiver&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;address&lt;/span&gt; &lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;uint256&lt;/span&gt; &lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;bytes&lt;/span&gt; &lt;span class="nb"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;external&lt;/span&gt; &lt;span class="k"&gt;returns&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="eip-1167minimal-proxy克隆合约"&gt;&lt;a href="#eip-1167minimal-proxy%e5%85%8b%e9%9a%86%e5%90%88%e7%ba%a6" class="header-anchor"&gt;&lt;/a&gt;EIP-1167：Minimal Proxy（克隆合约）
&lt;/h3&gt;
 &lt;blockquote&gt;
 &lt;p&gt;用 EVM bytecode 技巧把 proxy 合约压缩到 ~60 字节——&lt;strong&gt;部署成本极低&lt;/strong&gt;。&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;p&gt;适合&amp;quot;工厂部署大量同类合约&amp;quot;场景（如 Uniswap pair、Compound cToken）。&lt;/p&gt;
&lt;h3 id="eip-3675the-merge"&gt;&lt;a href="#eip-3675the-merge" class="header-anchor"&gt;&lt;/a&gt;EIP-3675：The Merge
&lt;/h3&gt;
 &lt;blockquote&gt;
 &lt;p&gt;2022 年的合并——POW 转 POS。&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;p&gt;不影响应用层 API，但&lt;strong&gt;让以太坊能耗降低 99%&lt;/strong&gt;。&lt;/p&gt;
&lt;h3 id="eip-4626再提一下"&gt;&lt;a href="#eip-4626%e5%86%8d%e6%8f%90%e4%b8%80%e4%b8%8b" class="header-anchor"&gt;&lt;/a&gt;EIP-4626（再提一下）
&lt;/h3&gt;&lt;p&gt;代币化 vault 标准——已经成事实标准。&lt;/p&gt;
&lt;h3 id="eip-3855push0-操作码"&gt;&lt;a href="#eip-3855push0-%e6%93%8d%e4%bd%9c%e7%a0%81" class="header-anchor"&gt;&lt;/a&gt;EIP-3855：PUSH0 操作码
&lt;/h3&gt;
 &lt;blockquote&gt;
 &lt;p&gt;添加 PUSH0 操作码（替代 PUSH1 0）——&lt;strong&gt;Solidity 0.8.20+ 利用，编译产物更小&lt;/strong&gt;。&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="十根据用途的速查"&gt;&lt;a href="#%e5%8d%81%e6%a0%b9%e6%8d%ae%e7%94%a8%e9%80%94%e7%9a%84%e9%80%9f%e6%9f%a5" class="header-anchor"&gt;&lt;/a&gt;十、根据用途的速查
&lt;/h2&gt;&lt;h3 id="做代币"&gt;&lt;a href="#%e5%81%9a%e4%bb%a3%e5%b8%81" class="header-anchor"&gt;&lt;/a&gt;做代币
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;同质化 → &lt;strong&gt;ERC-20&lt;/strong&gt; + &lt;strong&gt;EIP-2612&lt;/strong&gt;（permit）&lt;/li&gt;
&lt;li&gt;NFT → &lt;strong&gt;ERC-721&lt;/strong&gt; + &lt;strong&gt;EIP-2981&lt;/strong&gt;（版税）&lt;/li&gt;
&lt;li&gt;游戏 / 多种 → &lt;strong&gt;ERC-1155&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="做-defi"&gt;&lt;a href="#%e5%81%9a-defi" class="header-anchor"&gt;&lt;/a&gt;做 DeFi
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;借贷 / Vault → &lt;strong&gt;ERC-4626&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;闪电贷 → &lt;strong&gt;ERC-3156&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;自动批准 → &lt;strong&gt;EIP-2612&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="做-nft-市场"&gt;&lt;a href="#%e5%81%9a-nft-%e5%b8%82%e5%9c%ba" class="header-anchor"&gt;&lt;/a&gt;做 NFT 市场
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;标准支持 → ERC-721 + ERC-1155 + ERC-2981&lt;/li&gt;
&lt;li&gt;接口检测 → ERC-165&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="做钱包"&gt;&lt;a href="#%e5%81%9a%e9%92%b1%e5%8c%85" class="header-anchor"&gt;&lt;/a&gt;做钱包
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;签名 → &lt;strong&gt;EIP-712&lt;/strong&gt;（必须）&lt;/li&gt;
&lt;li&gt;智能合约签名 → &lt;strong&gt;EIP-1271&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;账户抽象 → &lt;strong&gt;ERC-4337&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="做-l2--rollup"&gt;&lt;a href="#%e5%81%9a-l2--rollup" class="header-anchor"&gt;&lt;/a&gt;做 L2 / Rollup
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;数据可用性 → &lt;strong&gt;EIP-4844&lt;/strong&gt; (blobs)&lt;/li&gt;
&lt;li&gt;跨链一致地址 → &lt;strong&gt;ERC-2470&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="做可升级合约"&gt;&lt;a href="#%e5%81%9a%e5%8f%af%e5%8d%87%e7%ba%a7%e5%90%88%e7%ba%a6" class="header-anchor"&gt;&lt;/a&gt;做可升级合约
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;标准槽位 → &lt;strong&gt;EIP-1967&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;UUPS 代理 → &lt;strong&gt;EIP-1822&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;大合约模块化 → &lt;strong&gt;EIP-2535&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="十一追踪新提案"&gt;&lt;a href="#%e5%8d%81%e4%b8%80%e8%bf%bd%e8%b8%aa%e6%96%b0%e6%8f%90%e6%a1%88" class="header-anchor"&gt;&lt;/a&gt;十一、追踪新提案
&lt;/h2&gt;&lt;p&gt;主要资源：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;EIP 主仓库&lt;/strong&gt;：&lt;a class="link" href="https://github.com/ethereum/EIPs" target="_blank" rel="noopener"
 &gt;github.com/ethereum/EIPs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;EIP 状态&lt;/strong&gt;：每个提案有 &lt;code&gt;Draft / Review / Last Call / Final / Withdrawn&lt;/code&gt; 状态&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Magicians 论坛&lt;/strong&gt;：&lt;a class="link" href="https://ethereum-magicians.org" target="_blank" rel="noopener"
 &gt;ethereum-magicians.org&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;All Core Devs 会议纪要&lt;/strong&gt;：核心开发者的双周会议&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;新提案出来时&lt;strong&gt;关注 status 是否 Final&lt;/strong&gt;——只有 Final 才算&amp;quot;标准&amp;quot;。Draft / Review 阶段的提案随时可能改。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="小结"&gt;&lt;a href="#%e5%b0%8f%e7%bb%93" class="header-anchor"&gt;&lt;/a&gt;小结
&lt;/h2&gt;&lt;p&gt;把全文压一句：&lt;/p&gt;

 &lt;blockquote&gt;
 &lt;p&gt;&lt;strong&gt;ERC / EIP 不是&amp;quot;考点&amp;quot;——是 Web3 协议设计的实战手册。掌握核心标准让你能站在巨人的肩膀上做事，而不是重新发明轮子。&lt;/strong&gt;&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;p&gt;工程纪律：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;代币必看 ERC-20/721/1155&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;签名必看 EIP-712 / EIP-2612&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;可升级必看 EIP-1967&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;追新关注 ERC-4337 / EIP-4844&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;不要造已有标准的轮子&lt;/strong&gt;——用 OpenZeppelin&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;收藏本文作为速查——下次遇到陌生编号时不用再 Google 半天。&lt;/p&gt;</description></item><item><title>不可变的合约如何「升级」？聊聊 Solidity 合约升级模式</title><link>https://www.lingcoder.com/p/solidity-contract-upgrade-patterns/</link><pubDate>Mon, 02 Sep 2024 20:00:00 +0800</pubDate><guid>https://www.lingcoder.com/p/solidity-contract-upgrade-patterns/</guid><description>&lt;img src="https://www.lingcoder.com/p/solidity-contract-upgrade-patterns/cover.svg" alt="Featured image of post 不可变的合约如何「升级」？聊聊 Solidity 合约升级模式" /&gt;&lt;h2 id="一个让所有以太坊新手都困惑的悖论"&gt;&lt;a href="#%e4%b8%80%e4%b8%aa%e8%ae%a9%e6%89%80%e6%9c%89%e4%bb%a5%e5%a4%aa%e5%9d%8a%e6%96%b0%e6%89%8b%e9%83%bd%e5%9b%b0%e6%83%91%e7%9a%84%e6%82%96%e8%ae%ba" class="header-anchor"&gt;&lt;/a&gt;一个让所有以太坊新手都困惑的悖论
&lt;/h2&gt;&lt;p&gt;智能合约最被反复强调的特性，是 &lt;strong&gt;不可变（immutable）&lt;/strong&gt;——代码部署上链之后，一行都不能改。&lt;/p&gt;
&lt;p&gt;但你只要在生产里跑过几个月就会发现一个现实：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;代码会有 bug&lt;/li&gt;
&lt;li&gt;业务会有新需求&lt;/li&gt;
&lt;li&gt;协议会被攻击，要打补丁&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这两件事看起来根本是矛盾的——&lt;strong&gt;承诺不可变，又必须能改&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;整个&amp;quot;合约升级&amp;quot;这个话题，本质上就是在回答：&lt;strong&gt;怎么在不破坏不可变承诺的前提下，让合约的行为可以演进？&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;下面我们从最朴素的方案开始，一路讲到现在主流的代理模式、UUPS、Beacon、Diamond，把这些方案的来龙去脉、踩坑点和适用边界一次性讲清楚。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="一最朴素的方案合约迁移contract-migration"&gt;&lt;a href="#%e4%b8%80%e6%9c%80%e6%9c%b4%e7%b4%a0%e7%9a%84%e6%96%b9%e6%a1%88%e5%90%88%e7%ba%a6%e8%bf%81%e7%a7%bbcontract-migration" class="header-anchor"&gt;&lt;/a&gt;一、最朴素的方案：合约迁移（Contract Migration）
&lt;/h2&gt;&lt;p&gt;最直观的思路：既然合约不能改，那就&lt;strong&gt;部署一份新的&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;流程大致是：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;部署 &lt;code&gt;TokenV2&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;写一个迁移脚本，把 &lt;code&gt;TokenV1&lt;/code&gt; 上每个用户的余额读出来，写进 &lt;code&gt;TokenV2&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;通知所有依赖方（前端、其他合约、CEX、用户）：地址换了，请用新的&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;这条路在小协议里偶尔还会用到，但作为通用方案，它的痛点很硬：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;地址变了&lt;/strong&gt;——所有依赖你的合约和应用都要改地址。DeFi 里这意味着流动性池要重建、用户授权要重做，几乎等于一次&amp;quot;硬分叉&amp;quot;。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;状态迁移成本高&lt;/strong&gt;——用户多的时候，光迁移就要几十万美元 Gas，且过程中可能有人在动账。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;信任成本极高&lt;/strong&gt;——用户怎么相信新合约里的余额没被篡改？&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;所以业界很快意识到：迁移不是&amp;quot;升级&amp;quot;，是&amp;quot;换房&amp;quot;。真正的升级，应该让&lt;strong&gt;地址不变、状态延续，只换&amp;quot;大脑&amp;quot;&lt;/strong&gt;。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="二核心技巧delegatecall-与代理模式"&gt;&lt;a href="#%e4%ba%8c%e6%a0%b8%e5%bf%83%e6%8a%80%e5%b7%a7delegatecall-%e4%b8%8e%e4%bb%a3%e7%90%86%e6%a8%a1%e5%bc%8f" class="header-anchor"&gt;&lt;/a&gt;二、核心技巧：&lt;code&gt;delegatecall&lt;/code&gt; 与代理模式
&lt;/h2&gt;&lt;p&gt;要做到&amp;quot;地址不变换大脑&amp;quot;，离不开 EVM 提供的一个特殊指令——&lt;strong&gt;&lt;code&gt;delegatecall&lt;/code&gt;&lt;/strong&gt;。&lt;/p&gt;
&lt;h3 id="一句话理解-delegatecall"&gt;&lt;a href="#%e4%b8%80%e5%8f%a5%e8%af%9d%e7%90%86%e8%a7%a3-delegatecall" class="header-anchor"&gt;&lt;/a&gt;一句话理解 &lt;code&gt;delegatecall&lt;/code&gt;
&lt;/h3&gt;&lt;p&gt;普通调用 &lt;code&gt;call&lt;/code&gt;：&lt;strong&gt;用别人的代码、操作别人的存储&lt;/strong&gt;。
&lt;code&gt;delegatecall&lt;/code&gt;：&lt;strong&gt;用别人的代码、操作自己的存储&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;也就是说，合约 A 通过 &lt;code&gt;delegatecall&lt;/code&gt; 调合约 B 的某个函数时，执行的是 B 的字节码，但 &lt;code&gt;msg.sender&lt;/code&gt;、&lt;code&gt;msg.value&lt;/code&gt;、&lt;strong&gt;所有存储读写都发生在 A 上&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;这就给了我们一个大胆的想法——&lt;/p&gt;

 &lt;blockquote&gt;
 &lt;p&gt;让一个&lt;strong&gt;只负责存数据&lt;/strong&gt;的合约（Proxy），通过 &lt;code&gt;delegatecall&lt;/code&gt; 把所有调用都转发给另一个&lt;strong&gt;只负责跑逻辑&lt;/strong&gt;的合约（Logic）。&lt;/p&gt;
&lt;p&gt;升级时只需要把 Proxy 指向的 Logic 地址换掉，&lt;strong&gt;Proxy 的地址和存储完全不变&lt;/strong&gt;。&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;h3 id="关系图"&gt;&lt;a href="#%e5%85%b3%e7%b3%bb%e5%9b%be" class="header-anchor"&gt;&lt;/a&gt;关系图
&lt;/h3&gt;&lt;pre class="mermaid" style="visibility:hidden"&gt;flowchart LR
 User([用户 / DApp])
 Proxy["Proxy 合约&lt;br/&gt;(地址不变 + 存储)"]
 LogicV1["Logic V1&lt;br/&gt;(纯代码)"]
 LogicV2["Logic V2&lt;br/&gt;(升级后)"]

 User -- 调用 --&gt; Proxy
 Proxy -- delegatecall --&gt; LogicV1
 Proxy -. 升级后改指向 .-&gt; LogicV2&lt;/pre&gt;&lt;h3 id="一个最小可运行的代理"&gt;&lt;a href="#%e4%b8%80%e4%b8%aa%e6%9c%80%e5%b0%8f%e5%8f%af%e8%bf%90%e8%a1%8c%e7%9a%84%e4%bb%a3%e7%90%86" class="header-anchor"&gt;&lt;/a&gt;一个最小可运行的代理
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;span class="lnt"&gt;19
&lt;/span&gt;&lt;span class="lnt"&gt;20
&lt;/span&gt;&lt;span class="lnt"&gt;21
&lt;/span&gt;&lt;span class="lnt"&gt;22
&lt;/span&gt;&lt;span class="lnt"&gt;23
&lt;/span&gt;&lt;span class="lnt"&gt;24
&lt;/span&gt;&lt;span class="lnt"&gt;25
&lt;/span&gt;&lt;span class="lnt"&gt;26
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-solidity" data-lang="solidity"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;contract&lt;/span&gt; &lt;span class="nc"&gt;MinimalProxy&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kt"&gt;address&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;implementation&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// 当前指向的逻辑合约
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kt"&gt;address&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;admin&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;address&lt;/span&gt; &lt;span class="n"&gt;_impl&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;implementation&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;_impl&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;admin&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;sender&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;upgrade&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;address&lt;/span&gt; &lt;span class="n"&gt;_newImpl&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;external&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;sender&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;admin&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;not admin&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;implementation&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;_newImpl&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;fallback&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;external&lt;/span&gt; &lt;span class="k"&gt;payable&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kt"&gt;address&lt;/span&gt; &lt;span class="n"&gt;impl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;implementation&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;assembly&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nf"&gt;calldatacopy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;calldatasize&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="ow"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;result&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="nf"&gt;delegatecall&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;gas&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;impl&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;calldatasize&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nf"&gt;returndatacopy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;returndatasize&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nf"&gt;switch&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;case&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nf"&gt;revert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;returndatasize&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;default&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nf"&gt;return&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;returndatasize&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;code&gt;fallback&lt;/code&gt; 把任何调用都 &lt;code&gt;delegatecall&lt;/code&gt; 到 &lt;code&gt;implementation&lt;/code&gt;。换 &lt;code&gt;implementation&lt;/code&gt; 就等于升级。&lt;/p&gt;
&lt;p&gt;看起来挺优雅，但魔鬼藏在细节里——&lt;strong&gt;存储布局&lt;/strong&gt;。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="三升级最大的坑存储布局冲突"&gt;&lt;a href="#%e4%b8%89%e5%8d%87%e7%ba%a7%e6%9c%80%e5%a4%a7%e7%9a%84%e5%9d%91%e5%ad%98%e5%82%a8%e5%b8%83%e5%b1%80%e5%86%b2%e7%aa%81" class="header-anchor"&gt;&lt;/a&gt;三、升级最大的坑：存储布局冲突
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;delegatecall&lt;/code&gt; 操作的是 &lt;strong&gt;Proxy 的存储&lt;/strong&gt;，但&lt;strong&gt;用的是 Logic 的代码&lt;/strong&gt;。这就要求两件事：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Logic 合约里读写哪个存储槽，必须和 Proxy 里实际的存储槽对得上&lt;/li&gt;
&lt;li&gt;升级前后两版 Logic 之间，存储槽不能错位&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;举个例子。假设 Logic V1 是这样：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-solidity" data-lang="solidity"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;contract&lt;/span&gt; &lt;span class="nc"&gt;LogicV1&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kt"&gt;address&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;owner&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// slot 0
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kt"&gt;uint256&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;totalSupply&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// slot 1
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;某天我们想升级，写了个看起来合情合理的 V2：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-solidity" data-lang="solidity"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;contract&lt;/span&gt; &lt;span class="nc"&gt;LogicV2&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kt"&gt;uint256&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;totalSupply&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// slot 0 ← 和 V1 的 owner 撞了！
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kt"&gt;address&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;owner&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// slot 1
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kt"&gt;uint256&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;newField&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// slot 2
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;升级完，原来 &lt;code&gt;owner&lt;/code&gt; 的位置被当成了 &lt;code&gt;totalSupply&lt;/code&gt;，瞬间把一个地址解读成天文数字的代币总量——&lt;strong&gt;协议直接报废&lt;/strong&gt;。&lt;/p&gt;
&lt;h3 id="三条铁律"&gt;&lt;a href="#%e4%b8%89%e6%9d%a1%e9%93%81%e5%be%8b" class="header-anchor"&gt;&lt;/a&gt;三条铁律
&lt;/h3&gt;&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;不能删除已有变量&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;不能调整变量顺序&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;不能改变量类型&lt;/strong&gt;（包括 &lt;code&gt;uint256&lt;/code&gt; ↔ &lt;code&gt;int256&lt;/code&gt;、定长数组长度等）&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;新版本想加字段？&lt;strong&gt;只能在末尾追加&lt;/strong&gt;。&lt;/p&gt;
&lt;h3 id="storage-gap-习惯openzeppelin-4x-时代的做法"&gt;&lt;a href="#storage-gap-%e4%b9%a0%e6%83%afopenzeppelin-4x-%e6%97%b6%e4%bb%a3%e7%9a%84%e5%81%9a%e6%b3%95" class="header-anchor"&gt;&lt;/a&gt;Storage Gap 习惯（OpenZeppelin 4.x 时代的做法）
&lt;/h3&gt;
 &lt;blockquote&gt;
 &lt;p&gt;&lt;strong&gt;时效性更新&lt;/strong&gt;：本节描述的 &lt;code&gt;__gap&lt;/code&gt; 模式是 OpenZeppelin 4.x 的标准做法。&lt;strong&gt;OpenZeppelin 5.0（2023-10）起的 &lt;code&gt;contracts-upgradeable&lt;/code&gt; 包已经改用 &lt;a class="link" href="https://eips.ethereum.org/EIPS/eip-7201" target="_blank" rel="noopener"
 &gt;ERC-7201 命名空间存储&lt;/a&gt;（Namespaced Storage Layout）&lt;/strong&gt;——每个合约的 storage 字段被收进一个独立 struct，slot 从 &lt;code&gt;keccak256(namespace) - 1&lt;/code&gt; 派生，&lt;strong&gt;升级加字段不再受顺序约束，也不再需要预留 &lt;code&gt;__gap&lt;/code&gt;&lt;/strong&gt;。新项目应该直接用 ERC-7201；老项目从 &lt;code&gt;__gap&lt;/code&gt; 模式迁移到 ERC-7201 时要小心 storage layout 兼容。下面这段 &lt;code&gt;__gap&lt;/code&gt; 写法仍然适用于 4.x 的基类继承场景（与 4.x 升级链路向后兼容）。&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;p&gt;为了给未来&amp;quot;末尾追加&amp;quot;留余地，可继承的基类里通常会预留一段空槽：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-solidity" data-lang="solidity"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;contract&lt;/span&gt; &lt;span class="nc"&gt;MyUpgradeable&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kt"&gt;address&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;owner&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kt"&gt;uint256&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;totalSupply&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;// ... 业务字段
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kt"&gt;uint256&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="n"&gt;__gap&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// 给未来升级留 50 个槽
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;这是 OpenZeppelin 4.x 的标准做法。一旦未来要在基类加字段，就从 &lt;code&gt;__gap&lt;/code&gt; 里&amp;quot;借&amp;quot;——既不破坏子类的存储布局，又不需要 fork 一份父类。&lt;/p&gt;
&lt;p&gt;ERC-7201 的等价写法长这样（5.0+）：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-solidity" data-lang="solidity"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;contract&lt;/span&gt; &lt;span class="nc"&gt;MyUpgradeable&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;/// @custom:storage-location erc7201:myproject.storage.MyUpgradeable
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;struct&lt;/span&gt; &lt;span class="nc"&gt;MyStorage&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kt"&gt;address&lt;/span&gt; &lt;span class="n"&gt;owner&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kt"&gt;uint256&lt;/span&gt; &lt;span class="n"&gt;totalSupply&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;// ... 业务字段
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;// keccak256(abi.encode(uint256(keccak256(&amp;#34;myproject.storage.MyUpgradeable&amp;#34;)) - 1)) &amp;amp; ~bytes32(uint256(0xff))
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kt"&gt;bytes32&lt;/span&gt; &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;constant&lt;/span&gt; &lt;span class="n"&gt;STORAGE_SLOT&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;...;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;_s&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;pure&lt;/span&gt; &lt;span class="k"&gt;returns&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;MyStorage&lt;/span&gt; &lt;span class="k"&gt;storage&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kt"&gt;bytes32&lt;/span&gt; &lt;span class="n"&gt;slot&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;STORAGE_SLOT&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;assembly&lt;/span&gt; { &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;slot&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;slot&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;每个合约把自己的 storage 锁进独立命名空间——升级时加字段、调顺序、改基类继承都不会再撞槽。这是 5.x 在升级模型上最关键的一步。&lt;/p&gt;
&lt;h3 id="升级前一定要做-storage-layout-校验"&gt;&lt;a href="#%e5%8d%87%e7%ba%a7%e5%89%8d%e4%b8%80%e5%ae%9a%e8%a6%81%e5%81%9a-storage-layout-%e6%a0%a1%e9%aa%8c" class="header-anchor"&gt;&lt;/a&gt;升级前一定要做 storage layout 校验
&lt;/h3&gt;&lt;p&gt;存储布局错位的检查靠人肉是不现实的——升级链路必须有自动化校验把这个关。具体工具按你用的栈选：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Hardhat 栈&lt;/strong&gt;：&lt;a class="link" href="https://github.com/OpenZeppelin/openzeppelin-upgrades" target="_blank" rel="noopener"
 &gt;OpenZeppelin Upgrades Plugin&lt;/a&gt;（&lt;code&gt;@openzeppelin/hardhat-upgrades&lt;/code&gt;）——升级前自动比对两版合约的存储布局，不兼容直接报错挡住。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Foundry 栈&lt;/strong&gt;：&lt;a class="link" href="https://github.com/OpenZeppelin/openzeppelin-foundry-upgrades" target="_blank" rel="noopener"
 &gt;openzeppelin-foundry-upgrades&lt;/a&gt;，或者直接 &lt;code&gt;forge inspect &amp;lt;Contract&amp;gt; storageLayout&lt;/code&gt; 把新旧两版的 storage layout 输出成 JSON，在 CI 里做 diff。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;更通用&lt;/strong&gt;：&lt;a class="link" href="https://github.com/crytic/slither" target="_blank" rel="noopener"
 &gt;Slither&lt;/a&gt; 的 &lt;code&gt;slither-check-upgradeability&lt;/code&gt; 也能做静态布局比对。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;形式不重要——&lt;strong&gt;一定要有一道自动检查&lt;/strong&gt;。生产合约靠肉眼 review storage layout 早晚出事。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="四三种主流代理标准"&gt;&lt;a href="#%e5%9b%9b%e4%b8%89%e7%a7%8d%e4%b8%bb%e6%b5%81%e4%bb%a3%e7%90%86%e6%a0%87%e5%87%86" class="header-anchor"&gt;&lt;/a&gt;四、三种主流代理标准
&lt;/h2&gt;&lt;p&gt;代理模式发展到今天，演化出了三种主流形态。&lt;/p&gt;
&lt;h3 id="1-transparent-proxy透明代理"&gt;&lt;a href="#1-transparent-proxy%e9%80%8f%e6%98%8e%e4%bb%a3%e7%90%86" class="header-anchor"&gt;&lt;/a&gt;1. Transparent Proxy（透明代理）
&lt;/h3&gt;&lt;p&gt;OpenZeppelin 早期推荐。它的核心问题是解决一个微妙的冲突——&lt;/p&gt;
&lt;p&gt;如果 Proxy 自己有个函数叫 &lt;code&gt;upgrade()&lt;/code&gt;，Logic 里也有个函数叫 &lt;code&gt;upgrade()&lt;/code&gt;，用户调进来时到底是哪个执行？&lt;/p&gt;
&lt;p&gt;Transparent Proxy 的解法是&lt;strong&gt;按调用者区分&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;管理员&lt;/strong&gt;调用 → 永远走 Proxy 自己的管理函数&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;普通用户&lt;/strong&gt;调用 → 永远走 &lt;code&gt;delegatecall&lt;/code&gt; 到 Logic&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="mermaid" style="visibility:hidden"&gt;flowchart LR
 Admin([管理员]) --&gt;|管理调用| ProxyAdmin["Proxy&lt;br/&gt;(管理逻辑)"]
 User([普通用户]) --&gt;|业务调用| ProxyDelegate["Proxy&lt;br/&gt;(delegatecall)"]
 ProxyDelegate --&gt; Logic["Logic 合约"]&lt;/pre&gt;&lt;p&gt;简单可靠，但代价是 &lt;strong&gt;Proxy 里要存管理员判断逻辑，每次调用都多一次条件判断和 SLOAD，Gas 偏贵&lt;/strong&gt;。&lt;/p&gt;
&lt;h3 id="2-uupserc-1822oz-现在的默认推荐"&gt;&lt;a href="#2-uupserc-1822oz-%e7%8e%b0%e5%9c%a8%e7%9a%84%e9%bb%98%e8%ae%a4%e6%8e%a8%e8%8d%90" class="header-anchor"&gt;&lt;/a&gt;2. UUPS（ERC-1822，OZ 现在的默认推荐）
&lt;/h3&gt;&lt;p&gt;UUPS 的核心反转是——&lt;strong&gt;把升级逻辑搬进 Logic 合约&lt;/strong&gt;。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-solidity" data-lang="solidity"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;contract&lt;/span&gt; &lt;span class="nc"&gt;LogicUUPS&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kt"&gt;address&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;owner&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;upgradeTo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;address&lt;/span&gt; &lt;span class="n"&gt;newImpl&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;external&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;sender&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;owner&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;not owner&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;// 通过 delegatecall 改的是 Proxy 自己的 implementation 槽
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;assembly&lt;/span&gt; { &lt;span class="nf"&gt;sstore&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_IMPL_SLOT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;newImpl&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;// ... 其他业务函数
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;这样一来：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Proxy 极度精简&lt;/strong&gt;，只有一个 fallback，Gas 最省&lt;/li&gt;
&lt;li&gt;升级权限由 Logic 控制——这意味着 &lt;strong&gt;如果你升级到一个忘了写 &lt;code&gt;upgradeTo&lt;/code&gt; 的新 Logic，合约就永远没法再升级了&lt;/strong&gt;（一种&amp;quot;自爆开关&amp;quot;）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;OpenZeppelin 现在更推荐 UUPS，但前提是开发者必须严格遵守&amp;quot;新版本永远要继承 &lt;code&gt;UUPSUpgradeable&lt;/code&gt;&amp;ldquo;的规范，否则可能误锁死。&lt;/p&gt;
&lt;h3 id="3-beacon-proxy信标代理"&gt;&lt;a href="#3-beacon-proxy%e4%bf%a1%e6%a0%87%e4%bb%a3%e7%90%86" class="header-anchor"&gt;&lt;/a&gt;3. Beacon Proxy（信标代理）
&lt;/h3&gt;&lt;p&gt;前两种都是&amp;quot;一个 Proxy 对应一个 Logic&amp;rdquo;。如果你有 &lt;strong&gt;几百上千个同种合约&lt;/strong&gt;（比如 Uniswap V3 工厂创建的众多池子），每次升级要逐一调用，成本难以承受。&lt;/p&gt;
&lt;p&gt;Beacon Proxy 抽象出一个&lt;strong&gt;信标合约&lt;/strong&gt;：&lt;/p&gt;
&lt;pre class="mermaid" style="visibility:hidden"&gt;flowchart LR
 Beacon["Beacon&lt;br/&gt;(只存当前 Logic 地址)"]
 Logic["Logic 合约"]

 P1["Pool Proxy 1"] -.读地址.-&gt; Beacon
 P2["Pool Proxy 2"] -.读地址.-&gt; Beacon
 P3["Pool Proxy ..."] -.读地址.-&gt; Beacon

 P1 -.delegatecall.-&gt; Logic
 P2 -.delegatecall.-&gt; Logic
 P3 -.delegatecall.-&gt; Logic

 Beacon -. 指向 .-&gt; Logic&lt;/pre&gt;&lt;p&gt;所有 Proxy 都从 Beacon 读&amp;quot;当前 Logic 地址&amp;quot;。&lt;strong&gt;升级时只改 Beacon 一处，所有 Proxy 同时生效&lt;/strong&gt;。代价是每次调用多一次跨合约读地址的 Gas。&lt;/p&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th style="text-align: left"&gt;方案&lt;/th&gt;
 &lt;th style="text-align: left"&gt;Gas 开销&lt;/th&gt;
 &lt;th style="text-align: left"&gt;升级权限位置&lt;/th&gt;
 &lt;th style="text-align: left"&gt;适用场景&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td style="text-align: left"&gt;Transparent Proxy&lt;/td&gt;
 &lt;td style="text-align: left"&gt;较高&lt;/td&gt;
 &lt;td style="text-align: left"&gt;Proxy&lt;/td&gt;
 &lt;td style="text-align: left"&gt;单实例、追求稳定保守&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td style="text-align: left"&gt;UUPS&lt;/td&gt;
 &lt;td style="text-align: left"&gt;最低&lt;/td&gt;
 &lt;td style="text-align: left"&gt;Logic&lt;/td&gt;
 &lt;td style="text-align: left"&gt;单实例、追求性能（OZ 默认推荐）&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td style="text-align: left"&gt;Beacon Proxy&lt;/td&gt;
 &lt;td style="text-align: left"&gt;中等&lt;/td&gt;
 &lt;td style="text-align: left"&gt;Beacon&lt;/td&gt;
 &lt;td style="text-align: left"&gt;多实例、需要批量同步升级&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h2 id="五更激进的方案diamondeip-2535"&gt;&lt;a href="#%e4%ba%94%e6%9b%b4%e6%bf%80%e8%bf%9b%e7%9a%84%e6%96%b9%e6%a1%88diamondeip-2535" class="header-anchor"&gt;&lt;/a&gt;五、更激进的方案：Diamond（EIP-2535）
&lt;/h2&gt;&lt;p&gt;EVM 对单个合约的字节码大小有 &lt;strong&gt;24KB 的硬上限&lt;/strong&gt;（EIP-170）。当协议复杂到一个 Logic 合约塞不下时，前面那些&amp;quot;单 Logic&amp;quot;的代理模式就不够用了。&lt;/p&gt;
&lt;p&gt;Diamond 模式的思路是——&lt;strong&gt;一个 Proxy（Diamond），多个 Logic（Facet）&lt;/strong&gt;，按函数选择器路由。&lt;/p&gt;
&lt;pre class="mermaid" style="visibility:hidden"&gt;flowchart TB
 User([用户调用])
 Diamond["Diamond Proxy&lt;br/&gt;(查路由表 + delegatecall)"]
 F1["Facet A&lt;br/&gt;转账逻辑"]
 F2["Facet B&lt;br/&gt;治理逻辑"]
 F3["Facet C&lt;br/&gt;奖励逻辑"]
 F4["Facet ...&lt;br/&gt;(可动态增删)"]

 User --&gt; Diamond
 Diamond -- delegatecall --&gt; F1
 Diamond -- delegatecall --&gt; F2
 Diamond -- delegatecall --&gt; F3
 Diamond -- delegatecall --&gt; F4&lt;/pre&gt;&lt;p&gt;每个 Facet 只实现一部分函数，Diamond 内部维护一张 &lt;code&gt;selector → facet address&lt;/code&gt; 的路由表，调用进来时查表然后 &lt;code&gt;delegatecall&lt;/code&gt;。升级时可以&lt;strong&gt;按 facet 增、删、换&lt;/strong&gt;，粒度比单 Logic 细得多。&lt;/p&gt;
&lt;p&gt;代价是复杂度陡升——存储布局要按&amp;quot;Diamond Storage&amp;quot;的命名空间约定写、调试链路更长、对应工具链不如 OZ 主流模式成熟。&lt;strong&gt;不是协议规模真的超过单合约能力，不要轻易上 Diamond&lt;/strong&gt;（Aavegotchi 是公认上得最成功的案例之一）。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="六不能忽略的工程细节"&gt;&lt;a href="#%e5%85%ad%e4%b8%8d%e8%83%bd%e5%bf%bd%e7%95%a5%e7%9a%84%e5%b7%a5%e7%a8%8b%e7%bb%86%e8%8a%82" class="header-anchor"&gt;&lt;/a&gt;六、不能忽略的工程细节
&lt;/h2&gt;&lt;h3 id="1-没有-constructor只有-initializer"&gt;&lt;a href="#1-%e6%b2%a1%e6%9c%89-constructor%e5%8f%aa%e6%9c%89-initializer" class="header-anchor"&gt;&lt;/a&gt;1. 没有 constructor，只有 initializer
&lt;/h3&gt;&lt;p&gt;&lt;code&gt;constructor&lt;/code&gt; 在合约部署时执行，&lt;strong&gt;只对 Logic 自己的存储生效，不会写到 Proxy 的存储&lt;/strong&gt;。所以可升级合约的初始化必须放在一个普通函数里，靠&lt;strong&gt;只能调用一次&lt;/strong&gt;的修饰符保护：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-solidity" data-lang="solidity"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;contract&lt;/span&gt; &lt;span class="nc"&gt;MyLogic&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="n"&gt;initialized&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kt"&gt;address&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;owner&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;initialize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;address&lt;/span&gt; &lt;span class="n"&gt;_owner&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;external&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;initialized&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;already initialized&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;initialized&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;owner&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;_owner&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;OpenZeppelin 提供了 &lt;code&gt;Initializable&lt;/code&gt; 基类，标准做法是用 &lt;code&gt;initializer&lt;/code&gt; 修饰符。&lt;/p&gt;
&lt;h3 id="2-部署后立刻调用-initializer"&gt;&lt;a href="#2-%e9%83%a8%e7%bd%b2%e5%90%8e%e7%ab%8b%e5%88%bb%e8%b0%83%e7%94%a8-initializer" class="header-anchor"&gt;&lt;/a&gt;2. 部署后立刻调用 initializer
&lt;/h3&gt;&lt;p&gt;如果部署完 Logic 不立刻初始化，&lt;strong&gt;任何人都可以抢先调一次 &lt;code&gt;initialize&lt;/code&gt; 把自己设成 owner&lt;/strong&gt;。这种漏洞历史上发生过多次。脚本部署 Proxy 时要用 &lt;code&gt;atomicallyDeployAndInitialize&lt;/code&gt; 之类的封装，把&amp;quot;部署 + 初始化&amp;quot;放进同一个交易。&lt;/p&gt;
&lt;h3 id="3-升级权限--协议生死开关"&gt;&lt;a href="#3-%e5%8d%87%e7%ba%a7%e6%9d%83%e9%99%90--%e5%8d%8f%e8%ae%ae%e7%94%9f%e6%ad%bb%e5%bc%80%e5%85%b3" class="header-anchor"&gt;&lt;/a&gt;3. 升级权限 = 协议生死开关
&lt;/h3&gt;&lt;p&gt;控制 &lt;code&gt;upgrade&lt;/code&gt; 的私钥，等于&lt;strong&gt;握有协议的全部资金权&lt;/strong&gt;。任何成熟协议都会用：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;多签&lt;/strong&gt;：避免单点泄密&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Timelock&lt;/strong&gt;：提案到生效之间留出延迟（通常 24~72 小时），让用户有撤资时间&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;DAO 治理投票&lt;/strong&gt;：进一步去中心化，把升级决策交给代币持有者&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果你看到一个号称&amp;quot;去中心化&amp;quot;的协议，升级权在一把单签钥匙上——&lt;strong&gt;它在技术上和中心化产品没有任何区别&lt;/strong&gt;。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="七可升级的代价安全与去中心化的张力"&gt;&lt;a href="#%e4%b8%83%e5%8f%af%e5%8d%87%e7%ba%a7%e7%9a%84%e4%bb%a3%e4%bb%b7%e5%ae%89%e5%85%a8%e4%b8%8e%e5%8e%bb%e4%b8%ad%e5%bf%83%e5%8c%96%e7%9a%84%e5%bc%a0%e5%8a%9b" class="header-anchor"&gt;&lt;/a&gt;七、可升级的代价：安全与去中心化的张力
&lt;/h2&gt;&lt;p&gt;可升级合约的存在，本身就违反了&amp;quot;不可变&amp;quot;的初心。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;管理员可以悄悄换掉 Logic，把所有用户的资金转走&lt;/strong&gt;——这是真实发生过的攻击。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;审计的难度被放大&lt;/strong&gt;：用户审计了今天的代码，明天升级后等于审了个寂寞。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;形式化验证、不可变指标都失效&lt;/strong&gt;：协议的安全保证从&amp;quot;代码&amp;quot;层退化为&amp;quot;运营方信誉 + 治理流程&amp;quot;层。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;所以业界有一种相反的声音：&lt;strong&gt;真正成熟的协议应当逐步放弃可升级性&lt;/strong&gt;。Uniswap V2/V3 的核心合约就是不可升级的——它的迭代靠&amp;quot;部署新协议、用户自愿迁移&amp;quot;完成，代价高，但换来了最强的信任。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;作为协议设计者，你需要问自己：&lt;/strong&gt;&lt;/p&gt;

 &lt;blockquote&gt;
 &lt;p&gt;&amp;ldquo;这个合约的升级权，是不是协议安全的天花板？&amp;rdquo;&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;p&gt;如果答案是&amp;quot;是&amp;quot;，那就要尽一切努力收紧它——多签、Timelock、治理、最终弃管。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;作为协议用户，你也要学会问：&lt;/strong&gt;&lt;/p&gt;

 &lt;blockquote&gt;
 &lt;p&gt;&amp;ldquo;这个合约能升级吗？升级权在谁手里？有 Timelock 吗？&amp;rdquo;&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;p&gt;回答不出来的协议，本质上就是一个许可型应用，无论它前端多花哨。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="小结"&gt;&lt;a href="#%e5%b0%8f%e7%bb%93" class="header-anchor"&gt;&lt;/a&gt;小结
&lt;/h2&gt;&lt;p&gt;把这一整圈讲下来，回到最初那个悖论——&lt;/p&gt;

 &lt;blockquote&gt;
 &lt;p&gt;智能合约的不可变是承诺，但现实的演进是必需。&lt;strong&gt;升级模式&lt;/strong&gt;就是在两者之间做工程妥协的产物。&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;p&gt;四种主流方案的本质：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;合约迁移&lt;/strong&gt;：放弃地址不变，老老实实换房&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Transparent Proxy / UUPS&lt;/strong&gt;：地址不变，靠 &lt;code&gt;delegatecall&lt;/code&gt; 把存储和代码解耦&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Beacon Proxy&lt;/strong&gt;：多个 Proxy 共享一个 Logic 指针，批量升级&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Diamond&lt;/strong&gt;：突破合约大小上限，按 facet 灵活增删&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;而无论用哪种方案，&lt;strong&gt;真正的难点从来不是合约怎么写，而是升级权怎么管&lt;/strong&gt;。技术层面可升级是简单的，治理层面让用户敢用一个可升级的合约，才是更难、也更重要的命题。&lt;/p&gt;
&lt;p&gt;一句话收尾：&lt;/p&gt;

 &lt;blockquote&gt;
 &lt;p&gt;&lt;strong&gt;可升级是工程能力，不可升级是产品承诺，怎么在两者之间找平衡，是每一个协议设计者要回答的问题。&lt;/strong&gt;&lt;/p&gt;

 &lt;/blockquote&gt;</description></item><item><title>NFT 标准选型与场景实践</title><link>https://www.lingcoder.com/p/nft-standards-comparison/</link><pubDate>Thu, 23 Jun 2022 16:00:00 +0800</pubDate><guid>https://www.lingcoder.com/p/nft-standards-comparison/</guid><description>&lt;img src="https://www.lingcoder.com/p/nft-standards-comparison/cover.svg" alt="Featured image of post NFT 标准选型与场景实践" /&gt;&lt;h2 id="两个标准都叫nft但它们解决的问题不同"&gt;&lt;a href="#%e4%b8%a4%e4%b8%aa%e6%a0%87%e5%87%86%e9%83%bd%e5%8f%abnft%e4%bd%86%e5%ae%83%e4%bb%ac%e8%a7%a3%e5%86%b3%e7%9a%84%e9%97%ae%e9%a2%98%e4%b8%8d%e5%90%8c" class="header-anchor"&gt;&lt;/a&gt;两个标准都叫&amp;quot;NFT&amp;quot;，但它们解决的问题不同
&lt;/h2&gt;&lt;p&gt;新人接触 NFT 时常被这两个标准的并存搞晕：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;ERC-721&lt;/strong&gt;：CryptoPunks、Bored Ape、CryptoKitties 都是这个标准&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ERC-1155&lt;/strong&gt;：Decentraland 道具、Enjin 卡牌、OpenSea 创作工具&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;它们都是 NFT，但&lt;strong&gt;底层模型完全不同&lt;/strong&gt;：&lt;/p&gt;

 &lt;blockquote&gt;
 &lt;p&gt;ERC-721 一个合约&lt;strong&gt;管理一系列独一无二的 token&lt;/strong&gt;，每个 tokenId 唯一。&lt;/p&gt;
&lt;p&gt;ERC-1155 一个合约&lt;strong&gt;管理多种 token&lt;/strong&gt;，&lt;strong&gt;每种 token 可以有多个&lt;/strong&gt;——既可以是 NFT，也可以是 SemiFungible，甚至 Fungible。&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;p&gt;理解这两个标准的边界，决定了你写 NFT 项目时该选哪个、为什么选。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="一erc-721经典的单一-nft"&gt;&lt;a href="#%e4%b8%80erc-721%e7%bb%8f%e5%85%b8%e7%9a%84%e5%8d%95%e4%b8%80-nft" class="header-anchor"&gt;&lt;/a&gt;一、ERC-721：经典的&amp;quot;单一 NFT&amp;quot;
&lt;/h2&gt;&lt;p&gt;ERC-721 由 Dieter Shirley、William Entriken 等人于 2018 年提出（EIP-721）。核心理念——&lt;strong&gt;每个 token 唯一&lt;/strong&gt;：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-solidity" data-lang="solidity"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;IERC721&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;ownerOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;uint256&lt;/span&gt; &lt;span class="n"&gt;tokenId&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;external&lt;/span&gt; &lt;span class="k"&gt;view&lt;/span&gt; &lt;span class="k"&gt;returns&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;address&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;balanceOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;address&lt;/span&gt; &lt;span class="n"&gt;owner&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;external&lt;/span&gt; &lt;span class="k"&gt;view&lt;/span&gt; &lt;span class="k"&gt;returns&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;uint256&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;transferFrom&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;address&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;address&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;uint256&lt;/span&gt; &lt;span class="n"&gt;tokenId&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;external&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;approve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;address&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;uint256&lt;/span&gt; &lt;span class="n"&gt;tokenId&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;external&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;// ... 其他
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;每个 tokenId 对应&lt;strong&gt;一个独一无二的资产&lt;/strong&gt;。一只 BAYC 猴子、一张 CryptoKitty——对应一个 tokenId。&lt;/p&gt;
&lt;h3 id="数据结构"&gt;&lt;a href="#%e6%95%b0%e6%8d%ae%e7%bb%93%e6%9e%84" class="header-anchor"&gt;&lt;/a&gt;数据结构
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-solidity" data-lang="solidity"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;mapping&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;uint256&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;address&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="n"&gt;_owners&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// tokenId → owner
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;mapping&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;address&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;uint256&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="n"&gt;_balances&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// owner → 持有数量
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="典型操作"&gt;&lt;a href="#%e5%85%b8%e5%9e%8b%e6%93%8d%e4%bd%9c" class="header-anchor"&gt;&lt;/a&gt;典型操作
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;span class="lnt"&gt;8
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-solidity" data-lang="solidity"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// 铸造一个 token
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;_owners&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;tokenId&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;_balances&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;to&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// 转账
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;_owners&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;tokenId&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;newOwner&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;_balances&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;-=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;_balances&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;to&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="erc-721-的特性"&gt;&lt;a href="#erc-721-%e7%9a%84%e7%89%b9%e6%80%a7" class="header-anchor"&gt;&lt;/a&gt;ERC-721 的特性
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;每个 tokenId 唯一&lt;/strong&gt;——一个 owner，不存在&amp;quot;持有多少&amp;quot;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;每个 token 一段元数据&lt;/strong&gt;——通过 &lt;code&gt;tokenURI(tokenId)&lt;/code&gt; 取&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;批量操作要循环 N 次&lt;/strong&gt;——转 100 个 NFT 要 100 次 &lt;code&gt;transferFrom&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="二erc-1155多代币--半同质"&gt;&lt;a href="#%e4%ba%8cerc-1155%e5%a4%9a%e4%bb%a3%e5%b8%81--%e5%8d%8a%e5%90%8c%e8%b4%a8" class="header-anchor"&gt;&lt;/a&gt;二、ERC-1155：多代币 + 半同质
&lt;/h2&gt;&lt;p&gt;ERC-1155 由 Enjin 团队 2018 年提出（EIP-1155），针对 ERC-721 的几个痛点：&lt;/p&gt;
&lt;h3 id="痛点-1游戏里有大量同种道具"&gt;&lt;a href="#%e7%97%9b%e7%82%b9-1%e6%b8%b8%e6%88%8f%e9%87%8c%e6%9c%89%e5%a4%a7%e9%87%8f%e5%90%8c%e7%a7%8d%e9%81%93%e5%85%b7" class="header-anchor"&gt;&lt;/a&gt;痛点 1：游戏里有大量同种道具
&lt;/h3&gt;&lt;p&gt;ERC-721 模型下，&amp;ldquo;100 把同样的剑&amp;quot;要 100 个不同 tokenId、100 次铸造、100 次转账——&lt;strong&gt;Gas 成本爆炸&lt;/strong&gt;。&lt;/p&gt;
&lt;h3 id="痛点-2合约碎片化"&gt;&lt;a href="#%e7%97%9b%e7%82%b9-2%e5%90%88%e7%ba%a6%e7%a2%8e%e7%89%87%e5%8c%96" class="header-anchor"&gt;&lt;/a&gt;痛点 2：合约碎片化
&lt;/h3&gt;&lt;p&gt;每个游戏出一种 NFT 都要部署一个新合约——以太坊上充斥着 1 万个仅区分一个游戏内物品的合约。&lt;/p&gt;
&lt;h3 id="痛点-3不能批量"&gt;&lt;a href="#%e7%97%9b%e7%82%b9-3%e4%b8%8d%e8%83%bd%e6%89%b9%e9%87%8f" class="header-anchor"&gt;&lt;/a&gt;痛点 3：不能批量
&lt;/h3&gt;&lt;p&gt;ERC-721 没有 &lt;code&gt;safeBatchTransferFrom&lt;/code&gt;——电商场景里&amp;quot;一键购买 5 件商品&amp;quot;做不到。&lt;/p&gt;
&lt;h3 id="erc-1155-的解法"&gt;&lt;a href="#erc-1155-%e7%9a%84%e8%a7%a3%e6%b3%95" class="header-anchor"&gt;&lt;/a&gt;ERC-1155 的解法
&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;一个合约管理多种 id，每种 id 可以有多份&lt;/strong&gt;。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-solidity" data-lang="solidity"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;IERC1155&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;balanceOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;address&lt;/span&gt; &lt;span class="n"&gt;account&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;uint256&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;external&lt;/span&gt; &lt;span class="k"&gt;view&lt;/span&gt; &lt;span class="k"&gt;returns&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;uint256&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;balanceOfBatch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;address&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;accounts&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;uint256&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;ids&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;external&lt;/span&gt; &lt;span class="k"&gt;view&lt;/span&gt; &lt;span class="k"&gt;returns&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;uint256&lt;/span&gt;&lt;span class="p"&gt;[]);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;safeTransferFrom&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;address&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;address&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;uint256&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;uint256&lt;/span&gt; &lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;bytes&lt;/span&gt; &lt;span class="nb"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;external&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;safeBatchTransferFrom&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;address&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;address&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;uint256&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;ids&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;uint256&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;amounts&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;bytes&lt;/span&gt; &lt;span class="nb"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;external&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;注意 &lt;code&gt;balanceOf&lt;/code&gt; 多了 &lt;code&gt;(account, id)&lt;/code&gt;——&lt;strong&gt;同一个 id 可以有多份&lt;/strong&gt;。&lt;/p&gt;
&lt;h3 id="数据结构-1"&gt;&lt;a href="#%e6%95%b0%e6%8d%ae%e7%bb%93%e6%9e%84-1" class="header-anchor"&gt;&lt;/a&gt;数据结构
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-solidity" data-lang="solidity"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;mapping&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;uint256&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kd"&gt;mapping&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;address&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;uint256&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="n"&gt;_balances&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// _balances[tokenId][owner] = 持有数量
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="三能力对比表"&gt;&lt;a href="#%e4%b8%89%e8%83%bd%e5%8a%9b%e5%af%b9%e6%af%94%e8%a1%a8" class="header-anchor"&gt;&lt;/a&gt;三、能力对比表
&lt;/h2&gt;&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th style="text-align: left"&gt;&lt;/th&gt;
 &lt;th style="text-align: left"&gt;ERC-721&lt;/th&gt;
 &lt;th style="text-align: left"&gt;ERC-1155&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td style="text-align: left"&gt;token 模型&lt;/td&gt;
 &lt;td style="text-align: left"&gt;每 id 唯一&lt;/td&gt;
 &lt;td style="text-align: left"&gt;每 id 可有多份&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td style="text-align: left"&gt;适合 NFT&lt;/td&gt;
 &lt;td style="text-align: left"&gt;✓&lt;/td&gt;
 &lt;td style="text-align: left"&gt;✓ （amount = 1 等于 NFT）&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td style="text-align: left"&gt;适合 Fungible&lt;/td&gt;
 &lt;td style="text-align: left"&gt;✗&lt;/td&gt;
 &lt;td style="text-align: left"&gt;✓&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td style="text-align: left"&gt;批量转账&lt;/td&gt;
 &lt;td style="text-align: left"&gt;✗（要循环）&lt;/td&gt;
 &lt;td style="text-align: left"&gt;✓ &lt;code&gt;safeBatchTransferFrom&lt;/code&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td style="text-align: left"&gt;批量查询余额&lt;/td&gt;
 &lt;td style="text-align: left"&gt;✗&lt;/td&gt;
 &lt;td style="text-align: left"&gt;✓ &lt;code&gt;balanceOfBatch&lt;/code&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td style="text-align: left"&gt;Gas（批量场景）&lt;/td&gt;
 &lt;td style="text-align: left"&gt;高&lt;/td&gt;
 &lt;td style="text-align: left"&gt;&lt;strong&gt;显著更低&lt;/strong&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td style="text-align: left"&gt;metadata&lt;/td&gt;
 &lt;td style="text-align: left"&gt;tokenURI(id)&lt;/td&gt;
 &lt;td style="text-align: left"&gt;uri(id)（可用 {id} 占位符）&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td style="text-align: left"&gt;approve 粒度&lt;/td&gt;
 &lt;td style="text-align: left"&gt;单 token&lt;/td&gt;
 &lt;td style="text-align: left"&gt;全合约（setApprovalForAll）&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td style="text-align: left"&gt;钱包/工具支持&lt;/td&gt;
 &lt;td style="text-align: left"&gt;几乎全部&lt;/td&gt;
 &lt;td style="text-align: left"&gt;主流支持，部分老钱包不支持&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td style="text-align: left"&gt;适用场景&lt;/td&gt;
 &lt;td style="text-align: left"&gt;头像、艺术、收藏品&lt;/td&gt;
 &lt;td style="text-align: left"&gt;游戏道具、批量、组合资产&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h2 id="四gas-成本erc-1155-的杀手级优势"&gt;&lt;a href="#%e5%9b%9bgas-%e6%88%90%e6%9c%acerc-1155-%e7%9a%84%e6%9d%80%e6%89%8b%e7%ba%a7%e4%bc%98%e5%8a%bf" class="header-anchor"&gt;&lt;/a&gt;四、Gas 成本：ERC-1155 的杀手级优势
&lt;/h2&gt;&lt;p&gt;铸造 100 个相同道具：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-solidity" data-lang="solidity"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// ERC-721
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;uint&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;_mint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;player&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;nextTokenId&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 100 次 SSTORE
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// ERC-1155
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;_mint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;player&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ITEM_SWORD&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 1 次 SSTORE（balance = 100）
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;实测对比（铸造 100 件相同道具）：&lt;/p&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th style="text-align: left"&gt;方案&lt;/th&gt;
 &lt;th style="text-align: left"&gt;Gas 消耗&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td style="text-align: left"&gt;ERC-721&lt;/td&gt;
 &lt;td style="text-align: left"&gt;~3,500,000&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td style="text-align: left"&gt;ERC-1155&lt;/td&gt;
 &lt;td style="text-align: left"&gt;~80,000&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;差距 40 倍。批量转账的差距类似。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;这是为什么链游、批量市场几乎都选 ERC-1155&lt;/strong&gt;——同等业务，Gas 成本压到几十分之一。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="五适用场景"&gt;&lt;a href="#%e4%ba%94%e9%80%82%e7%94%a8%e5%9c%ba%e6%99%af" class="header-anchor"&gt;&lt;/a&gt;五、适用场景
&lt;/h2&gt;&lt;h3 id="选-erc-721-的场景"&gt;&lt;a href="#%e9%80%89-erc-721-%e7%9a%84%e5%9c%ba%e6%99%af" class="header-anchor"&gt;&lt;/a&gt;选 ERC-721 的场景
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;每个 token 独一无二&lt;/strong&gt;：头像、PFP、艺术品、稀有收藏&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;每个 token 元数据完全不同&lt;/strong&gt;：CryptoPunks 每个都不一样&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;品牌效应&lt;/strong&gt;：BAYC、Doodles 这种&amp;quot;个体认知度&amp;quot;项目——单合约、单 tokenId&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="选-erc-1155-的场景"&gt;&lt;a href="#%e9%80%89-erc-1155-%e7%9a%84%e5%9c%ba%e6%99%af" class="header-anchor"&gt;&lt;/a&gt;选 ERC-1155 的场景
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;游戏道具&lt;/strong&gt;：剑、药水、卡牌——同种物品多份&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;门票 / 凭证&lt;/strong&gt;：演唱会门票每张相同但要发几千份&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;批量操作&lt;/strong&gt;：电商商品、物流凭证&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;混合资产&lt;/strong&gt;：一个合约里既有可堆叠物品，又有独一无二的稀有 NFT&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;组合金融产品&lt;/strong&gt;：一个合约里管理 N 种衍生品&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="一些灰色地带"&gt;&lt;a href="#%e4%b8%80%e4%ba%9b%e7%81%b0%e8%89%b2%e5%9c%b0%e5%b8%a6" class="header-anchor"&gt;&lt;/a&gt;一些灰色地带
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;限量版艺术品&lt;/strong&gt;（一种艺术 100 个相同复制品）：ERC-1155 更合适&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;演唱会门票（每张序列号不同）&lt;/strong&gt;：ERC-721 更合适&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Loot 这种链上随机生成&lt;/strong&gt;：ERC-721 元数据 on-chain 更合适&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;判断关键&lt;/strong&gt;：&amp;ldquo;这种 token 会有多份吗？&amp;quot;——会就 ERC-1155，不会就 ERC-721。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="六metadata-的差异"&gt;&lt;a href="#%e5%85%admetadata-%e7%9a%84%e5%b7%ae%e5%bc%82" class="header-anchor"&gt;&lt;/a&gt;六、metadata 的差异
&lt;/h2&gt;&lt;h3 id="erc-721-的-tokenuri"&gt;&lt;a href="#erc-721-%e7%9a%84-tokenuri" class="header-anchor"&gt;&lt;/a&gt;ERC-721 的 tokenURI
&lt;/h3&gt;&lt;p&gt;每个 tokenId 一个 URI：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-solidity" data-lang="solidity"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;tokenURI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;uint256&lt;/span&gt; &lt;span class="n"&gt;tokenId&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;view&lt;/span&gt; &lt;span class="k"&gt;returns&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="k"&gt;memory&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;abi&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;encodePacked&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;baseURI&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tokenId&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;()));&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;返回的 JSON：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-json" data-lang="json"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;name&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;BAYC #4521&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;description&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;...&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;image&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;ipfs://Qm.../4521.png&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;attributes&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;&lt;span class="nt"&gt;&amp;#34;trait_type&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Background&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;&amp;#34;value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Gold&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;}]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="erc-1155-的-uri"&gt;&lt;a href="#erc-1155-%e7%9a%84-uri" class="header-anchor"&gt;&lt;/a&gt;ERC-1155 的 uri
&lt;/h3&gt;&lt;p&gt;支持 &lt;code&gt;{id}&lt;/code&gt; 占位符：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-solidity" data-lang="solidity"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;uri&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;uint256&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;view&lt;/span&gt; &lt;span class="k"&gt;returns&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="k"&gt;memory&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;https://example.com/api/{id}.json&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;客户端拿到后用 64 位 hex（补全 &lt;code&gt;0x&lt;/code&gt; 前缀）替换 &lt;code&gt;{id}&lt;/code&gt;——这样&lt;strong&gt;一个 URI 模板能服务所有 id&lt;/strong&gt;，省心。&lt;/p&gt;
&lt;p&gt;但实际上很多 ERC-1155 项目仍然给每个 id 单独配 URI——尤其是游戏道具，每种道具一段元数据。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="七approve-模型差异"&gt;&lt;a href="#%e4%b8%83approve-%e6%a8%a1%e5%9e%8b%e5%b7%ae%e5%bc%82" class="header-anchor"&gt;&lt;/a&gt;七、approve 模型差异
&lt;/h2&gt;&lt;h3 id="erc-721"&gt;&lt;a href="#erc-721" class="header-anchor"&gt;&lt;/a&gt;ERC-721
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;approve(to, tokenId)&lt;/code&gt;：授权某地址转某个 token&lt;/li&gt;
&lt;li&gt;&lt;code&gt;setApprovalForAll(operator, true)&lt;/code&gt;：授权某地址操作所有 token&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="erc-1155"&gt;&lt;a href="#erc-1155" class="header-anchor"&gt;&lt;/a&gt;ERC-1155
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;没有单 token approve&lt;/strong&gt;——只能 &lt;code&gt;setApprovalForAll&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;这意味着用户必须信任整个 operator（如交易市场）能动他全部 1155 资产&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这是 ERC-1155 在用户安全侧的劣势——授权范围更大、撤销更重要。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="八写一个-erc-1155-合约"&gt;&lt;a href="#%e5%85%ab%e5%86%99%e4%b8%80%e4%b8%aa-erc-1155-%e5%90%88%e7%ba%a6" class="header-anchor"&gt;&lt;/a&gt;八、写一个 ERC-1155 合约
&lt;/h2&gt;&lt;p&gt;OpenZeppelin 提供了一行能用的实现：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;span class="lnt"&gt;19
&lt;/span&gt;&lt;span class="lnt"&gt;20
&lt;/span&gt;&lt;span class="lnt"&gt;21
&lt;/span&gt;&lt;span class="lnt"&gt;22
&lt;/span&gt;&lt;span class="lnt"&gt;23
&lt;/span&gt;&lt;span class="lnt"&gt;24
&lt;/span&gt;&lt;span class="lnt"&gt;25
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-solidity" data-lang="solidity"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;@openzeppelin/contracts/token/ERC1155/ERC1155.sol&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;@openzeppelin/contracts/access/Ownable.sol&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;contract&lt;/span&gt; &lt;span class="nc"&gt;GameItems&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="n"&gt;ERC1155&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Ownable&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kt"&gt;uint256&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;constant&lt;/span&gt; &lt;span class="n"&gt;SWORD&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kt"&gt;uint256&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;constant&lt;/span&gt; &lt;span class="n"&gt;SHIELD&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kt"&gt;uint256&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;constant&lt;/span&gt; &lt;span class="n"&gt;POTION&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kt"&gt;uint256&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;constant&lt;/span&gt; &lt;span class="n"&gt;LEGENDARY&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="n"&gt;ERC1155&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;https://example.com/api/{id}.json&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;_mint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;sender&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;SWORD&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;_mint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;sender&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;SHIELD&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;_mint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;sender&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;POTION&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;_mint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;sender&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;LEGENDARY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 唯一稀有 NFT
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;mint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;address&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;uint256&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;uint256&lt;/span&gt; &lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;external&lt;/span&gt; &lt;span class="n"&gt;onlyOwner&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;_mint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;to&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;mintBatch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;address&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;uint256&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="k"&gt;memory&lt;/span&gt; &lt;span class="n"&gt;ids&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;uint256&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="k"&gt;memory&lt;/span&gt; &lt;span class="n"&gt;amounts&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;external&lt;/span&gt; &lt;span class="n"&gt;onlyOwner&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;_mintBatch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;to&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ids&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;amounts&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;注意 &lt;code&gt;LEGENDARY&lt;/code&gt; 的 amount = 1——&lt;strong&gt;这相当于在同一个合约里用 ERC-1155 表达 NFT&lt;/strong&gt;。这是 ERC-1155 的灵活性。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="九踩坑提醒"&gt;&lt;a href="#%e4%b9%9d%e8%b8%a9%e5%9d%91%e6%8f%90%e9%86%92" class="header-anchor"&gt;&lt;/a&gt;九、踩坑提醒
&lt;/h2&gt;&lt;h3 id="1-safetransferfrom-接收方要实现钩子"&gt;&lt;a href="#1-safetransferfrom-%e6%8e%a5%e6%94%b6%e6%96%b9%e8%a6%81%e5%ae%9e%e7%8e%b0%e9%92%a9%e5%ad%90" class="header-anchor"&gt;&lt;/a&gt;1. &lt;code&gt;safeTransferFrom&lt;/code&gt; 接收方要实现钩子
&lt;/h3&gt;&lt;p&gt;如果接收方是合约，必须实现 &lt;code&gt;onERC721Received&lt;/code&gt; / &lt;code&gt;onERC1155Received&lt;/code&gt;，否则转账 revert。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-solidity" data-lang="solidity"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;onERC1155Received&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;address&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;address&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;uint256&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;uint256&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;bytes&lt;/span&gt; &lt;span class="n"&gt;calldata&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;external&lt;/span&gt; &lt;span class="k"&gt;pure&lt;/span&gt; &lt;span class="k"&gt;returns&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;bytes4&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;onERC1155Received&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;selector&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="2-erc-1155-的-transfer-必须带-amount"&gt;&lt;a href="#2-erc-1155-%e7%9a%84-transfer-%e5%bf%85%e9%a1%bb%e5%b8%a6-amount" class="header-anchor"&gt;&lt;/a&gt;2. ERC-1155 的 transfer 必须带 amount
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-solidity" data-lang="solidity"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// ERC-721 的语法
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;contract&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;transferFrom&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tokenId&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// ERC-1155 的语法
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;contract&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;safeTransferFrom&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;NFT 性质的 token 永远 amount = 1。&lt;/p&gt;
&lt;h3 id="3-metadata-占位符兼容"&gt;&lt;a href="#3-metadata-%e5%8d%a0%e4%bd%8d%e7%ac%a6%e5%85%bc%e5%ae%b9" class="header-anchor"&gt;&lt;/a&gt;3. metadata 占位符兼容
&lt;/h3&gt;&lt;p&gt;&lt;code&gt;{id}&lt;/code&gt; 占位符是 ERC-1155 标准里规定的——&lt;strong&gt;实际平台支持参差不齐&lt;/strong&gt;。OpenSea / 区块链浏览器多数支持，但小钱包可能不识别——保险起见每个 id 单独配 URI。&lt;/p&gt;
&lt;h3 id="4-不要混用模型"&gt;&lt;a href="#4-%e4%b8%8d%e8%a6%81%e6%b7%b7%e7%94%a8%e6%a8%a1%e5%9e%8b" class="header-anchor"&gt;&lt;/a&gt;4. 不要混用模型
&lt;/h3&gt;&lt;p&gt;同一个项目里&lt;strong&gt;要么用 ERC-721 要么用 ERC-1155&lt;/strong&gt;，不要在一个集合里两种都发。买家会困惑：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&amp;ldquo;为什么这个 NFT 在我的钱包里看不到？&amp;rdquo;&lt;/li&gt;
&lt;li&gt;&amp;ldquo;为什么我数量是 5 但只能转 1？&amp;rdquo;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="5-老钱包可能不支持-erc-1155"&gt;&lt;a href="#5-%e8%80%81%e9%92%b1%e5%8c%85%e5%8f%af%e8%83%bd%e4%b8%8d%e6%94%af%e6%8c%81-erc-1155" class="header-anchor"&gt;&lt;/a&gt;5. 老钱包可能不支持 ERC-1155
&lt;/h3&gt;&lt;p&gt;Trust Wallet、imToken 较新版本支持，但 5 年前的老钱包可能识别不出 1155——目标用户群里要有市场调研。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="十其他相关标准"&gt;&lt;a href="#%e5%8d%81%e5%85%b6%e4%bb%96%e7%9b%b8%e5%85%b3%e6%a0%87%e5%87%86" class="header-anchor"&gt;&lt;/a&gt;十、其他相关标准
&lt;/h2&gt;&lt;p&gt;NFT 生态的相关标准还有：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;ERC-2981&lt;/strong&gt;：版税标准——让 NFT 在二级市场卖出时自动扣版税给原作者&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;EIP-2535&lt;/strong&gt;：Diamond 合约标准——超大合约的模块化升级&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ERC-4907&lt;/strong&gt;：可租赁 NFT&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ERC-721A&lt;/strong&gt;：Azuki 优化的批量铸造 ERC-721（Gas 比标准 721 低很多）&lt;/li&gt;
&lt;/ul&gt;

 &lt;blockquote&gt;
 &lt;p&gt;🔥 ERC-721A 在某种程度上是对 ERC-1155 的&amp;quot;反击&amp;rdquo;——保留 ERC-721 的语义但优化批量铸造 Gas，是大量 PFP 项目的选择。&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="小结"&gt;&lt;a href="#%e5%b0%8f%e7%bb%93" class="header-anchor"&gt;&lt;/a&gt;小结
&lt;/h2&gt;&lt;p&gt;把全文压一句：&lt;/p&gt;

 &lt;blockquote&gt;
 &lt;p&gt;&lt;strong&gt;ERC-721 表达『每个唯一』，ERC-1155 表达『多种 + 多份』。一个合约一个项目就用 721；多类型批量场景必上 1155。&lt;/strong&gt;&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;p&gt;工程选型：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;PFP / 艺术 / 收藏&lt;/strong&gt; → ERC-721（或 ERC-721A）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;游戏 / 批量 / 多种&lt;/strong&gt; → ERC-1155&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;混合需求&lt;/strong&gt; → ERC-1155（amount=1 表 NFT，amount&amp;gt;1 表数量）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;二级市场版税&lt;/strong&gt; → 配 ERC-2981&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;NFT 生态还在演进，理解这些标准的边界比追新更重要——&lt;strong&gt;搞清&amp;quot;业务场景该用哪个&amp;rdquo;&lt;/strong&gt;，远比&amp;quot;哪个最先进&amp;quot;实用。&lt;/p&gt;</description></item></channel></rss>