<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/">
    <channel>
        <title>Omen</title>
        <link>https://paragraph.com/@omen</link>
        <description>Blockchain Dev 
Rest life to Learning &amp; Buidling in Web3.</description>
        <lastBuildDate>Tue, 07 Jul 2026 23:45:49 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <language>en</language>
        <image>
            <title>Omen</title>
            <url>https://storage.googleapis.com/papyrus_images/aa2a7e735ece6364b3d26c141165823133ef19b99416bfc86a3f8963ac6340be.jpg</url>
            <link>https://paragraph.com/@omen</link>
        </image>
        <copyright>All rights reserved</copyright>
        <item>
            <title><![CDATA[初探ERC3525]]></title>
            <link>https://paragraph.com/@omen/erc3525</link>
            <guid>hMk0O5oRi7Q9e0roxlJE</guid>
            <pubDate>Wed, 15 Feb 2023 08:16:10 GMT</pubDate>
            <description><![CDATA[ERC3525半同质化(semi-fungible)标准, ERC3525定义一个<Id，Slot，Value>三重参数模型，用于表示Token的半同质化结构。 基于Id参数,保证了兼容ERC721同质化的特性,可以通过transfer在地址间转移,也可以实现aprrove方法; Value参数,类似ERC20标准的Token数量balance; Slot参数, 当两个不同ID的Token具有相同的Slot时,可视这两个Token是同质化的. 即通过SLOT可以判断不同ID间的Token是否为同质化的.TL;DRERC3525标准在非同质化ERC721通证的基础之上,通过引入Slot参数, 实现了TokenId级别的半同质化特性: 不同TokenId的Slot参数相同,则同质; 若不同,则非同质.引入同质化特性后, 即可加入Value参数, 标识单个TokenId内有多少数量(value)的Token( or 任何有含义的资产).ERC3525标准则在Slot和Value维度上, 扩展了类似ERC721的授权,转移和查询方法,具体见文.此外, ERC3525标准建议将metada...]]></description>
            <content:encoded><![CDATA[<h1 id="h-erc3525" class="text-4xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">ERC3525</h1><p>半同质化(semi-fungible)标准, ERC3525定义一个<code>&lt;Id，Slot，Value&gt;</code>三重参数模型，用于表示Token的半同质化结构。</p><p>基于<code>Id</code>参数,保证了兼容ERC721同质化的特性,可以通过<code>transfer</code>在地址间转移,也可以实现<code>aprrove</code>方法;</p><p><code>Value</code>参数,类似ERC20标准的Token数量<code>balance</code>;</p><p><code>Slot</code>参数, 当两个不同ID的Token具有相同的<code>Slot</code>时,可视这两个Token是同质化的. 即通过SLOT可以判断不同ID间的Token是否为同质化的.</p><h2 id="h-tldr" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">TL;DR</h2><p>ERC3525标准在非同质化ERC721通证的基础之上,</p><ol><li><p>通过引入<code>Slot</code>参数, 实现了TokenId级别的半同质化特性: 不同TokenId的Slot参数相同,则同质; 若不同,则非同质.</p></li><li><p>引入同质化特性后, 即可加入<code>Value</code>参数, 标识单个TokenId内有多少数量(value)的Token( or 任何有含义的资产).</p></li><li><p>ERC3525标准则在<code>Slot</code>和<code>Value</code>维度上, 扩展了类似ERC721的授权,转移和查询方法,具体见文.</p></li><li><p>此外, ERC3525标准建议将metadata数据存于链上, 可以通过<code>Slot</code>来在链上索引Slot维度的metadata数据, 也可以实现TokenId维度的metadata获取.</p></li></ol><h2 id="h-1-erc3525" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">1 基本ERC3525标准</h2><p>继承自IERC165和IERC721标准<code>interface IERC3525 /* is IERC165, IERC721 */ {...}</code>.对比ERC721,以下从授权,转移和查询(approve, transfer and view)三个维度对ERC3525方法进行分类:</p><h3 id="h-11-approve" class="text-2xl font-header !mt-6 !mb-4 first:!mt-0 first:!mb-0">1.1 关于授权(approve)</h3><pre data-type="codeBlock" text="// 721方法, msg.sender授权_tokenId的操作权限给_approved地址
function approve(address _approved, uint256 _tokenId) external payable;
// 721方法, msg.sender授权(或取消授权)其所有权限给_operator地址
function setApprovalForAll(address _operator, bool _approved) external;
// 721方法, 查询单个_tokenId的授权情况, 针对approve(address,uint256)方法
function getApproved(uint256 _tokenId) external view returns (address);
// 721方法, 查询拥有者_owner地址的授权情况,针对setApprovalForAll方法
function isApprovedForAll(address _owner, address _operator) external view returns (bool);

// 3525方法, msg.sender授权_tokenId的_value数量的操作权限给_operator地址
function approve(uint256 _tokenId, address _operator, uint256 _value) external payable;
// 3525方法, 查询_operator操作地址对单个_tokenId的授权情况, 针对approve(uint256,address,uint256)方法
function allowance(uint256 _tokenId, address _operator) external view returns (uint256);
"><code><span class="hljs-comment">// 721方法, msg.sender授权_tokenId的操作权限给_approved地址</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">approve</span>(<span class="hljs-params"><span class="hljs-keyword">address</span> _approved, <span class="hljs-keyword">uint256</span> _tokenId</span>) <span class="hljs-title"><span class="hljs-keyword">external</span></span> <span class="hljs-title"><span class="hljs-keyword">payable</span></span></span>;
<span class="hljs-comment">// 721方法, msg.sender授权(或取消授权)其所有权限给_operator地址</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">setApprovalForAll</span>(<span class="hljs-params"><span class="hljs-keyword">address</span> _operator, <span class="hljs-keyword">bool</span> _approved</span>) <span class="hljs-title"><span class="hljs-keyword">external</span></span></span>;
<span class="hljs-comment">// 721方法, 查询单个_tokenId的授权情况, 针对approve(address,uint256)方法</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getApproved</span>(<span class="hljs-params"><span class="hljs-keyword">uint256</span> _tokenId</span>) <span class="hljs-title"><span class="hljs-keyword">external</span></span> <span class="hljs-title"><span class="hljs-keyword">view</span></span> <span class="hljs-title"><span class="hljs-keyword">returns</span></span> (<span class="hljs-params"><span class="hljs-keyword">address</span></span>)</span>;
<span class="hljs-comment">// 721方法, 查询拥有者_owner地址的授权情况,针对setApprovalForAll方法</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">isApprovedForAll</span>(<span class="hljs-params"><span class="hljs-keyword">address</span> _owner, <span class="hljs-keyword">address</span> _operator</span>) <span class="hljs-title"><span class="hljs-keyword">external</span></span> <span class="hljs-title"><span class="hljs-keyword">view</span></span> <span class="hljs-title"><span class="hljs-keyword">returns</span></span> (<span class="hljs-params"><span class="hljs-keyword">bool</span></span>)</span>;

<span class="hljs-comment">// 3525方法, msg.sender授权_tokenId的_value数量的操作权限给_operator地址</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">approve</span>(<span class="hljs-params"><span class="hljs-keyword">uint256</span> _tokenId, <span class="hljs-keyword">address</span> _operator, <span class="hljs-keyword">uint256</span> _value</span>) <span class="hljs-title"><span class="hljs-keyword">external</span></span> <span class="hljs-title"><span class="hljs-keyword">payable</span></span></span>;
<span class="hljs-comment">// 3525方法, 查询_operator操作地址对单个_tokenId的授权情况, 针对approve(uint256,address,uint256)方法</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">allowance</span>(<span class="hljs-params"><span class="hljs-keyword">uint256</span> _tokenId, <span class="hljs-keyword">address</span> _operator</span>) <span class="hljs-title"><span class="hljs-keyword">external</span></span> <span class="hljs-title"><span class="hljs-keyword">view</span></span> <span class="hljs-title"><span class="hljs-keyword">returns</span></span> (<span class="hljs-params"><span class="hljs-keyword">uint256</span></span>)</span>;
</code></pre><p>三个授权层级:</p><ul><li><p>(ERC721)针对单个地址的所有操作权限: setApprovalForAll</p></li><li><p>(ERC721)针对单个TokenId的所有操作权限: approve(address, uint256)</p></li><li><p>(ERC3525)针对单个TokenId内指定Value数量的操作权限: approve(uint256, address, uint256)</p></li></ul><p>根据以上三类授权层级, 分别有相应的查询方法. 在本文2.2部分可见, 扩展的IERC3525SlotApprovable标准还增加了Slot级别的授权层级;</p><h3 id="h-12-transfer" class="text-2xl font-header !mt-6 !mb-4 first:!mt-0 first:!mb-0">1.2 关于转移(transfer)</h3><pre data-type="codeBlock" text="// 721方法, 将_tokenId从_from地址转移至_to地址;附加校验_to地址是否为合约地址; 附加额外数据data;
function safeTransferFrom(address _from, address _to, uint256 _tokenId, bytes data) external payable;
// 721方法, 将_tokenId从_from地址转移至_to地址;附加额外校验, 一般为onERC721Received;
function safeTransferFrom(address _from, address _to, uint256 _tokenId) external payable;
// 721方法, 将_tokenId从_from地址转移至_to地址;
function transferFrom(address _from, address _to, uint256 _tokenId) external payable;

// 3525方法, 将单个_fromTokenId中_value数量转移至单个_toTokenId中; 要求_fromTokenId和_toTokenId是同质的, 即slot参数要相同;
function transferFrom(uint256 _fromTokenId, uint256 _toTokenId, uint256 _value) external payable;
// 3525方法, 将单个_fromTokenId中_value数量转移给_to地址; 若_to存在slot与_fromTokenId的tokenId, 则累加, 否则需要新创建一个tokenId;
function transferFrom(uint256 _fromTokenId, address _to, uint256 _value) external payable returns (uint256);
"><code><span class="hljs-comment">// 721方法, 将_tokenId从_from地址转移至_to地址;附加校验_to地址是否为合约地址; 附加额外数据data;</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">safeTransferFrom</span>(<span class="hljs-params"><span class="hljs-keyword">address</span> _from, <span class="hljs-keyword">address</span> _to, <span class="hljs-keyword">uint256</span> _tokenId, <span class="hljs-keyword">bytes</span> data</span>) <span class="hljs-title"><span class="hljs-keyword">external</span></span> <span class="hljs-title"><span class="hljs-keyword">payable</span></span></span>;
<span class="hljs-comment">// 721方法, 将_tokenId从_from地址转移至_to地址;附加额外校验, 一般为onERC721Received;</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">safeTransferFrom</span>(<span class="hljs-params"><span class="hljs-keyword">address</span> _from, <span class="hljs-keyword">address</span> _to, <span class="hljs-keyword">uint256</span> _tokenId</span>) <span class="hljs-title"><span class="hljs-keyword">external</span></span> <span class="hljs-title"><span class="hljs-keyword">payable</span></span></span>;
<span class="hljs-comment">// 721方法, 将_tokenId从_from地址转移至_to地址;</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">transferFrom</span>(<span class="hljs-params"><span class="hljs-keyword">address</span> _from, <span class="hljs-keyword">address</span> _to, <span class="hljs-keyword">uint256</span> _tokenId</span>) <span class="hljs-title"><span class="hljs-keyword">external</span></span> <span class="hljs-title"><span class="hljs-keyword">payable</span></span></span>;

<span class="hljs-comment">// 3525方法, 将单个_fromTokenId中_value数量转移至单个_toTokenId中; 要求_fromTokenId和_toTokenId是同质的, 即slot参数要相同;</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">transferFrom</span>(<span class="hljs-params"><span class="hljs-keyword">uint256</span> _fromTokenId, <span class="hljs-keyword">uint256</span> _toTokenId, <span class="hljs-keyword">uint256</span> _value</span>) <span class="hljs-title"><span class="hljs-keyword">external</span></span> <span class="hljs-title"><span class="hljs-keyword">payable</span></span></span>;
<span class="hljs-comment">// 3525方法, 将单个_fromTokenId中_value数量转移给_to地址; 若_to存在slot与_fromTokenId的tokenId, 则累加, 否则需要新创建一个tokenId;</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">transferFrom</span>(<span class="hljs-params"><span class="hljs-keyword">uint256</span> _fromTokenId, <span class="hljs-keyword">address</span> _to, <span class="hljs-keyword">uint256</span> _value</span>) <span class="hljs-title"><span class="hljs-keyword">external</span></span> <span class="hljs-title"><span class="hljs-keyword">payable</span></span> <span class="hljs-title"><span class="hljs-keyword">returns</span></span> (<span class="hljs-params"><span class="hljs-keyword">uint256</span></span>)</span>;
</code></pre><p>两个转移层级:</p><ul><li><p>(ERC721)针对单个TokenId的转移</p></li><li><p>(ERC3525)针对单个TokenId下Value的转移</p><ul><li><p>同质化转移: 相同<code>Slot</code>的token之间的<code>Value</code>值转移</p></li><li><p>非同质化转移: 从Token到地址的<code>Value</code>值转移</p></li></ul></li></ul><h3 id="h-13-view" class="text-2xl font-header !mt-6 !mb-4 first:!mt-0 first:!mb-0">1.3 关于查询(view)</h3><p>如图, 相比ERC721包含的查询方法1和2,ERC3525增加了针对TokenId下的Value以及Slot的查询方法.</p><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><figcaption HTMLAttributes="[object Object]" class="">ERC3525查询</figcaption></figure><pre data-type="codeBlock" text="// 721方法, 查询_owner拥有TokenId的数量, 对应箭头1
function balanceOf(address _owner) external view returns (uint256);    
// 721方法, 查询_tokenId的拥有者, 对应箭头2
function ownerOf(uint256 _tokenId) external view returns (address);

// 3525方法, 查询单个_tokenId目前拥有的Value数量, 对应箭头3
function balanceOf(uint256 _tokenId) external view returns (uint256);
// 3525方法, 查询单个_tokenId对应的slot参数, 用于区分不同TokenId之间是否为同质的, 对应箭头4
function slotOf(uint256 _tokenId) external view returns (uint256);
// 3525方法, 查询Value值的精度数(小数位数), 对应箭头5
function valueDecimals() external view returns (uint8);
"><code><span class="hljs-comment">// 721方法, 查询_owner拥有TokenId的数量, 对应箭头1</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">balanceOf</span>(<span class="hljs-params"><span class="hljs-keyword">address</span> _owner</span>) <span class="hljs-title"><span class="hljs-keyword">external</span></span> <span class="hljs-title"><span class="hljs-keyword">view</span></span> <span class="hljs-title"><span class="hljs-keyword">returns</span></span> (<span class="hljs-params"><span class="hljs-keyword">uint256</span></span>)</span>;    
<span class="hljs-comment">// 721方法, 查询_tokenId的拥有者, 对应箭头2</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">ownerOf</span>(<span class="hljs-params"><span class="hljs-keyword">uint256</span> _tokenId</span>) <span class="hljs-title"><span class="hljs-keyword">external</span></span> <span class="hljs-title"><span class="hljs-keyword">view</span></span> <span class="hljs-title"><span class="hljs-keyword">returns</span></span> (<span class="hljs-params"><span class="hljs-keyword">address</span></span>)</span>;

<span class="hljs-comment">// 3525方法, 查询单个_tokenId目前拥有的Value数量, 对应箭头3</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">balanceOf</span>(<span class="hljs-params"><span class="hljs-keyword">uint256</span> _tokenId</span>) <span class="hljs-title"><span class="hljs-keyword">external</span></span> <span class="hljs-title"><span class="hljs-keyword">view</span></span> <span class="hljs-title"><span class="hljs-keyword">returns</span></span> (<span class="hljs-params"><span class="hljs-keyword">uint256</span></span>)</span>;
<span class="hljs-comment">// 3525方法, 查询单个_tokenId对应的slot参数, 用于区分不同TokenId之间是否为同质的, 对应箭头4</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">slotOf</span>(<span class="hljs-params"><span class="hljs-keyword">uint256</span> _tokenId</span>) <span class="hljs-title"><span class="hljs-keyword">external</span></span> <span class="hljs-title"><span class="hljs-keyword">view</span></span> <span class="hljs-title"><span class="hljs-keyword">returns</span></span> (<span class="hljs-params"><span class="hljs-keyword">uint256</span></span>)</span>;
<span class="hljs-comment">// 3525方法, 查询Value值的精度数(小数位数), 对应箭头5</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">valueDecimals</span>(<span class="hljs-params"></span>) <span class="hljs-title"><span class="hljs-keyword">external</span></span> <span class="hljs-title"><span class="hljs-keyword">view</span></span> <span class="hljs-title"><span class="hljs-keyword">returns</span></span> (<span class="hljs-params"><span class="hljs-keyword">uint8</span></span>)</span>;
</code></pre><h2 id="h-2" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">2 扩展标准</h2><h3 id="h-21-slotierc3525slotenumerable" class="text-2xl font-header !mt-6 !mb-4 first:!mt-0 first:!mb-0">2.1 扩展slot枚举标准(IERC3525SlotEnumerable)</h3><p>继承自IERC3525和IERC721Enumerable: <code>interface IERC3525SlotEnumerable is IERC3525 /* , IERC721Enumerable */ {...}</code>. 在枚举TokenId的基础之上,实现了针对Slot的枚举方法.</p><p>该标准的ERC165标识符为:<code>0x3b741b9e</code></p><pre data-type="codeBlock" text="// 721Enumerable方法, 获取TokenId的总供应量
function totalSupply() external view returns (uint256);
// 721Enumerable方法, 枚举获取TokenId
function tokenByIndex(uint256 _index) external view returns (uint256);
// 721Enumerable方法, 枚举获取Owner地址拥有的TokenId
function tokenOfOwnerByIndex(address _owner, uint256 _index) external view returns (uint256);

// 3525SlotEnumerable方法, 获取Slot的总数, 类比totalSupply()
function slotCount() external view returns (uint256);
// 3525SlotEnumerable方法, 枚举获取Slot, 类比tokenByIndex(uint256)
function slotByIndex(uint256 _index) external view returns (uint256);
// 3525SlotEnumerable方法, 获取指定Slot的总数, (~~类比totalSupplyInOwner(address _owner) returns(uint256 amount), hhhhh~~)
function tokenSupplyInSlot(uint256 _slot) external view returns (uint256);
// 3525SlotEnumerable方法, 枚举指定Slot, 获取TokenId, 类比tokenOfOwnerByIndex(address, uint256)
function tokenInSlotByIndex(uint256 _slot, uint256 _index) external view returns (uint256);
"><code><span class="hljs-comment">// 721Enumerable方法, 获取TokenId的总供应量</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">totalSupply</span>(<span class="hljs-params"></span>) <span class="hljs-title"><span class="hljs-keyword">external</span></span> <span class="hljs-title"><span class="hljs-keyword">view</span></span> <span class="hljs-title"><span class="hljs-keyword">returns</span></span> (<span class="hljs-params"><span class="hljs-keyword">uint256</span></span>)</span>;
<span class="hljs-comment">// 721Enumerable方法, 枚举获取TokenId</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">tokenByIndex</span>(<span class="hljs-params"><span class="hljs-keyword">uint256</span> _index</span>) <span class="hljs-title"><span class="hljs-keyword">external</span></span> <span class="hljs-title"><span class="hljs-keyword">view</span></span> <span class="hljs-title"><span class="hljs-keyword">returns</span></span> (<span class="hljs-params"><span class="hljs-keyword">uint256</span></span>)</span>;
<span class="hljs-comment">// 721Enumerable方法, 枚举获取Owner地址拥有的TokenId</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">tokenOfOwnerByIndex</span>(<span class="hljs-params"><span class="hljs-keyword">address</span> _owner, <span class="hljs-keyword">uint256</span> _index</span>) <span class="hljs-title"><span class="hljs-keyword">external</span></span> <span class="hljs-title"><span class="hljs-keyword">view</span></span> <span class="hljs-title"><span class="hljs-keyword">returns</span></span> (<span class="hljs-params"><span class="hljs-keyword">uint256</span></span>)</span>;

<span class="hljs-comment">// 3525SlotEnumerable方法, 获取Slot的总数, 类比totalSupply()</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">slotCount</span>(<span class="hljs-params"></span>) <span class="hljs-title"><span class="hljs-keyword">external</span></span> <span class="hljs-title"><span class="hljs-keyword">view</span></span> <span class="hljs-title"><span class="hljs-keyword">returns</span></span> (<span class="hljs-params"><span class="hljs-keyword">uint256</span></span>)</span>;
<span class="hljs-comment">// 3525SlotEnumerable方法, 枚举获取Slot, 类比tokenByIndex(uint256)</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">slotByIndex</span>(<span class="hljs-params"><span class="hljs-keyword">uint256</span> _index</span>) <span class="hljs-title"><span class="hljs-keyword">external</span></span> <span class="hljs-title"><span class="hljs-keyword">view</span></span> <span class="hljs-title"><span class="hljs-keyword">returns</span></span> (<span class="hljs-params"><span class="hljs-keyword">uint256</span></span>)</span>;
<span class="hljs-comment">// 3525SlotEnumerable方法, 获取指定Slot的总数, (~~类比totalSupplyInOwner(address _owner) returns(uint256 amount), hhhhh~~)</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">tokenSupplyInSlot</span>(<span class="hljs-params"><span class="hljs-keyword">uint256</span> _slot</span>) <span class="hljs-title"><span class="hljs-keyword">external</span></span> <span class="hljs-title"><span class="hljs-keyword">view</span></span> <span class="hljs-title"><span class="hljs-keyword">returns</span></span> (<span class="hljs-params"><span class="hljs-keyword">uint256</span></span>)</span>;
<span class="hljs-comment">// 3525SlotEnumerable方法, 枚举指定Slot, 获取TokenId, 类比tokenOfOwnerByIndex(address, uint256)</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">tokenInSlotByIndex</span>(<span class="hljs-params"><span class="hljs-keyword">uint256</span> _slot, <span class="hljs-keyword">uint256</span> _index</span>) <span class="hljs-title"><span class="hljs-keyword">external</span></span> <span class="hljs-title"><span class="hljs-keyword">view</span></span> <span class="hljs-title"><span class="hljs-keyword">returns</span></span> (<span class="hljs-params"><span class="hljs-keyword">uint256</span></span>)</span>;
</code></pre><h3 id="h-22-slotierc3525slotapprovable" class="text-2xl font-header !mt-6 !mb-4 first:!mt-0 first:!mb-0">2.2 扩展slot授权标准(IERC3525SlotApprovable)</h3><p>继承自IERC3525,实现对slot维度的授权</p><p>该标准的ERC165标识符为:<code>0xb688be58</code></p><pre data-type="codeBlock" text="// 3525SlotApprovable方法, _owner授权(或取消授权)_slot的的操作权限给_operator地址
function setApprovalForSlot(address _owner, uint256 _slot, address _operator, bool _approved) external payable;
// 3525SlotApprovable, 查询_operator对_owner拥有的_slot是否拥有操作权限
function isApprovedForSlot(address _owner, uint256 _slot, address _operator) external view returns (bool);
"><code><span class="hljs-comment">// 3525SlotApprovable方法, _owner授权(或取消授权)_slot的的操作权限给_operator地址</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">setApprovalForSlot</span>(<span class="hljs-params"><span class="hljs-keyword">address</span> _owner, <span class="hljs-keyword">uint256</span> _slot, <span class="hljs-keyword">address</span> _operator, <span class="hljs-keyword">bool</span> _approved</span>) <span class="hljs-title"><span class="hljs-keyword">external</span></span> <span class="hljs-title"><span class="hljs-keyword">payable</span></span></span>;
<span class="hljs-comment">// 3525SlotApprovable, 查询_operator对_owner拥有的_slot是否拥有操作权限</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">isApprovedForSlot</span>(<span class="hljs-params"><span class="hljs-keyword">address</span> _owner, <span class="hljs-keyword">uint256</span> _slot, <span class="hljs-keyword">address</span> _operator</span>) <span class="hljs-title"><span class="hljs-keyword">external</span></span> <span class="hljs-title"><span class="hljs-keyword">view</span></span> <span class="hljs-title"><span class="hljs-keyword">returns</span></span> (<span class="hljs-params"><span class="hljs-keyword">bool</span></span>)</span>;
</code></pre><h3 id="h-23-yuanierc3525metadata" class="text-2xl font-header !mt-6 !mb-4 first:!mt-0 first:!mb-0">2.3 扩展元数据标准(IERC3525Metadata)</h3><p>继承自IERC3525和IERC721Metadata: <code>interface IERC3525Metadata is IERC3525 /* , IERC721Metadata */ {...}</code>.</p><p>该标准的ERC165标识符为:<code>0xe1600902</code></p><pre data-type="codeBlock" text="// 721Metadata方法, 该系列Token的名字
function name() external view returns (string _name);
// 721Metadata方法, 该系列Token的符号
function symbol() external view returns (string _symbol);
// 721Metadata方法, 指定TokenId的元数据: 可以是外部url, 也可以是直接由链上数据生成; 
//                  标准建议返回以’data:application/json;‘起始的json格式数据;
function tokenURI(uint256 _tokenId) external view returns (string);

// 3525Metadata方法, 该系列Token整体的信息: 标准建议返回以’data:application/json;‘起始的json格式数据;
function contractURI() external view returns (string memory);
// 3525Metadata方法, 指定slot的元数据: 标准建议返回以’data:application/json;‘起始的json格式数据;
function slotURI(uint256 _slot) external view returns (string memory);
"><code><span class="hljs-comment">// 721Metadata方法, 该系列Token的名字</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">name</span>(<span class="hljs-params"></span>) <span class="hljs-title"><span class="hljs-keyword">external</span></span> <span class="hljs-title"><span class="hljs-keyword">view</span></span> <span class="hljs-title"><span class="hljs-keyword">returns</span></span> (<span class="hljs-params"><span class="hljs-keyword">string</span> _name</span>)</span>;
<span class="hljs-comment">// 721Metadata方法, 该系列Token的符号</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">symbol</span>(<span class="hljs-params"></span>) <span class="hljs-title"><span class="hljs-keyword">external</span></span> <span class="hljs-title"><span class="hljs-keyword">view</span></span> <span class="hljs-title"><span class="hljs-keyword">returns</span></span> (<span class="hljs-params"><span class="hljs-keyword">string</span> _symbol</span>)</span>;
<span class="hljs-comment">// 721Metadata方法, 指定TokenId的元数据: 可以是外部url, 也可以是直接由链上数据生成; </span>
<span class="hljs-comment">//                  标准建议返回以’data:application/json;‘起始的json格式数据;</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">tokenURI</span>(<span class="hljs-params"><span class="hljs-keyword">uint256</span> _tokenId</span>) <span class="hljs-title"><span class="hljs-keyword">external</span></span> <span class="hljs-title"><span class="hljs-keyword">view</span></span> <span class="hljs-title"><span class="hljs-keyword">returns</span></span> (<span class="hljs-params"><span class="hljs-keyword">string</span></span>)</span>;

<span class="hljs-comment">// 3525Metadata方法, 该系列Token整体的信息: 标准建议返回以’data:application/json;‘起始的json格式数据;</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">contractURI</span>(<span class="hljs-params"></span>) <span class="hljs-title"><span class="hljs-keyword">external</span></span> <span class="hljs-title"><span class="hljs-keyword">view</span></span> <span class="hljs-title"><span class="hljs-keyword">returns</span></span> (<span class="hljs-params"><span class="hljs-keyword">string</span> <span class="hljs-keyword">memory</span></span>)</span>;
<span class="hljs-comment">// 3525Metadata方法, 指定slot的元数据: 标准建议返回以’data:application/json;‘起始的json格式数据;</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">slotURI</span>(<span class="hljs-params"><span class="hljs-keyword">uint256</span> _slot</span>) <span class="hljs-title"><span class="hljs-keyword">external</span></span> <span class="hljs-title"><span class="hljs-keyword">view</span></span> <span class="hljs-title"><span class="hljs-keyword">returns</span></span> (<span class="hljs-params"><span class="hljs-keyword">string</span> <span class="hljs-keyword">memory</span></span>)</span>;
</code></pre><p>关于contract, token和slot维度的metadata数据, 标准建议返回以`data:application/json;‘起始的json格式数据, 示例如下:</p><pre data-type="codeBlock" text="function slotURI(uint256 slot_)
    public
    view
    virtual
    override
    returns (string memory)
{
    return
        string(
            abi.encodePacked(
                // solhint-disable 
                &quot;data:application/json;base64,&quot;,
                Base64.encode(
                    abi.encodePacked(
                        &apos;{&quot;name&quot;:&quot;&apos;,
                        _slotDetails[slot_].name,
                        &apos;&quot;,&quot;description&quot;:&quot;&apos;,
                        _slotDetails[slot_].description,
                        &apos;&quot;,&quot;image&quot;:&quot;&apos;,
                        _slotDetails[slot_].image,
                        &apos;&quot;,&quot;properties&quot;:&apos;,
                        _slotProperties(slot_),
                        &quot;}&quot;
                    )
                )
                // solhint-enable
            )
        );
}
"><code><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">slotURI</span>(<span class="hljs-params"><span class="hljs-keyword">uint256</span> slot_</span>)
    <span class="hljs-title"><span class="hljs-keyword">public</span></span>
    <span class="hljs-title"><span class="hljs-keyword">view</span></span>
    <span class="hljs-title"><span class="hljs-keyword">virtual</span></span>
    <span class="hljs-title"><span class="hljs-keyword">override</span></span>
    <span class="hljs-title"><span class="hljs-keyword">returns</span></span> (<span class="hljs-params"><span class="hljs-keyword">string</span> <span class="hljs-keyword">memory</span></span>)
</span>{
    <span class="hljs-keyword">return</span>
        <span class="hljs-keyword">string</span>(
            <span class="hljs-built_in">abi</span>.<span class="hljs-built_in">encodePacked</span>(
                <span class="hljs-comment">// solhint-disable </span>
                <span class="hljs-string">"data:application/json;base64,"</span>,
                Base64.encode(
                    <span class="hljs-built_in">abi</span>.<span class="hljs-built_in">encodePacked</span>(
                        <span class="hljs-string">'{"name":"'</span>,
                        _slotDetails[slot_].<span class="hljs-built_in">name</span>,
                        <span class="hljs-string">'","description":"'</span>,
                        _slotDetails[slot_].description,
                        <span class="hljs-string">'","image":"'</span>,
                        _slotDetails[slot_].image,
                        <span class="hljs-string">'","properties":'</span>,
                        _slotProperties(slot_),
                        <span class="hljs-string">"}"</span>
                    )
                )
                <span class="hljs-comment">// solhint-enable</span>
            )
        );
}
</code></pre><h2 id="h-3-token-receiver" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">3 合约接收标准(Token Receiver)</h2><p>该标准的ERC165标识符为:<code>0x009ce20b</code></p><pre data-type="codeBlock" text="interface IERC3525Receiver {
    // @return bytes4(keccak256(&apos;onERC3525Received(address,uint256,uint256,uint256,bytes)&apos;)) == 0x009ce20b
    function onERC3525Received(address _operator, uint256 _fromTokenId, uint256 _toTokenId, uint256 _value, bytes calldata _data) external returns (bytes4);
}
"><code><span class="hljs-class"><span class="hljs-keyword">interface</span> <span class="hljs-title">IERC3525Receiver</span> </span>{
    <span class="hljs-comment">// @return bytes4(keccak256('onERC3525Received(address,uint256,uint256,uint256,bytes)')) == 0x009ce20b</span>
    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">onERC3525Received</span>(<span class="hljs-params"><span class="hljs-keyword">address</span> _operator, <span class="hljs-keyword">uint256</span> _fromTokenId, <span class="hljs-keyword">uint256</span> _toTokenId, <span class="hljs-keyword">uint256</span> _value, <span class="hljs-keyword">bytes</span> <span class="hljs-keyword">calldata</span> _data</span>) <span class="hljs-title"><span class="hljs-keyword">external</span></span> <span class="hljs-title"><span class="hljs-keyword">returns</span></span> (<span class="hljs-params"><span class="hljs-keyword">bytes4</span></span>)</span>;
}
</code></pre>]]></content:encoded>
            <author>omen@newsletter.paragraph.com (Omen)</author>
        </item>
    </channel>
</rss>