# listURI() 返回一个指向 JSON 对象

By [的内容](https://paragraph.com/@0x163cae8251eb79729f8b87fbee3972a097dc3e82) · 2023-04-07

---

实现 CLG 合约的关键创新是代币访问控制。代币访问控制背后的概念是，除非你用含有特定访问代币的钱包连接到主机，否则你不能访问主机上的特定数据。

例如，你可以对 IPFS 上的内容进行代币访问控制，这样只有用钱包中的特定 NFT 连接到端点的读者才能查看特定的文件。

CLG 使用令牌门为我们的社交合约增加了一些间接性，因此，社交 NFT 不是代表一种特定类型的关系--关注、静音或屏蔽--而是代表对你的社交图谱的一部分的读取权限。

很明显，为了使代币门槛发挥作用，平台必须尊重它。据推测，如果平台不尊重代币访问控制，你会把你的关系列表转移到其他平台，并改变你的合约，必要时重新发布任何 NFT。

另外，要清楚的是，有些人的名单在某些时候会泄露。我们生活在一个个人数据泄露的世界，所以如果数据被托管在某个地方，那么有些数据就会被泄露。我将在后面的章节中讨论一些可能的缓解措施。下面的合约将是一个标准的 ERC721 NTFT 合约，与上述 OCG 的合约非常接近：

// SPDX-License-Identifier: MIT pragma solidity ^0.8.4; import "@openzeppelin/contracts/token/ERC721/ERC721.sol"; import "@openzeppelin/contracts/security/Pausable.sol"; import "@openzeppelin/contracts/access/Ownable.sol"; import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Burnable.sol"; import "@openzeppelin/contracts/utils/Counters.sol"; contract CLGFollows is ERC721, Pausable, Ownable, ERC721Burnable { using Counters for Counters.Counter; Counters.Counter private \_tokenIdCounter; constructor() ERC721("CLGFollows", "CLGF") {} function \_baseURI() internal pure override returns (string memory) { return "[https://jonstokes.com/clgfollows/](https://jonstokes.com/clgfollows/)"; } function listURI() public { return "[https://jonstokes.com/clgfollows/list](https://jonstokes.com/clgfollows/list)"; } function relationship() public { return "clg follows"; } function pause() public onlyOwner { \_pause(); } function unpause() public onlyOwner { \_unpause(); } function safeMint(address to) public onlyOwner { uint256 tokenId = \_tokenIdCounter.current(); \_tokenIdCounter.increment(); \_safeMint(to, tokenId); } function \_beforeTokenTransfer(address from, address to, uint256) pure override internal { //Disable token transfers. require(from == address(0) || to == address(0), "Cannot be transferred."); } }

所有的扩展都与 OCG 相同，只是我没有包括 ERC721Enumerable，因为不清楚是否有人想让他们的 CLG Follows 代币被列举出来（另外它提高了铸币的 gas 成本）

至于函数方面，我对OpenZeppelin向导的输出做了以下修改：

*   relationship()： 与 OLG 一样，它返回社交合约的类型。同样，对于 Solidity 合约来说，这可能没有必要，我也没有见过这样做，但尽管如此，我觉得我想让合约自我报告它的类型。所以我不知道--如果这冒犯了你，请忽略。
    
*   listURI() 返回一个指向 JSON 对象的链接，该对象是你正在关注（或静音或屏蔽，取决于合约类型）的 ENS 名称列表。我们希望这个 URI 能被标记为隐私，但这并不是必须的。
    

大多数情况下，你会使用 CLG Follows NTFT，把它发布到社交平台拥有的地址。这样，该平台可以读取你的关注列表，并向你展示正确的帖子。

但你也可以把这些 NTFTs 发给追随者，以便你的追随者可以发现其他追随者。你可以通过空投给追随者，或者通过解禁造币，让任何人造币来实现。

所有其他合约的工作方式与上述完全相同，但有不同的名称和符号，并从 relationship() 和 listURI() 返回不同的值。如果你担心你的列表从不同的服务中泄漏，那么把 listURI() 变成更像 tokenURI(uint256 tokenId) 的东西是非常直接的，即签名是 listURI(uint256 tokenId)，它把 tokenID 连接到一个基本URI的末尾，这样每个 token 持有者就可以得到自己的列表URL。这个功能与列表主机上的一些逻辑相结合，可以让你把列表隔离开来，使不同的令牌持有者得到主图的不同子图。这样一来，如果一个平台被拥有，那么只有我的图的那一部分被泄露了。

和 OCG 一样，你可以把 safemint 变成一个可支付的函数，并向访问你的列表的人收费。请看 OCG 部分的代码，以了解这个例子的情况。

你可能希望能够更新 tokenURI() 和 / 或 listURI() 返回的 URLs，在这种情况下，你需要将这些 URLs 存储在变量中，在构造函数中初始化它们，并为更新它们提供 onlyOwner setter 函数。这将增加你的铸币成本，但如果你只打算把它们给服务而不是个人，这可能并不重要。

---

*Originally published on [的内容](https://paragraph.com/@0x163cae8251eb79729f8b87fbee3972a097dc3e82/listuri-json)*
