Alert Source Discuss
⚠️ Draft Standards Track: ERC

ERC-7847: 社交媒体 NFT

以 NFT 的形式创建社交媒体帖子或出版物。

Authors Nick Juntilla (@nickjuntilla) <nick@ownerfy.com>
Created 2024-12-18
Discussion Link https://ethereum-magicians.org/t/erc-7847-social-media-nfts/22280
Requires EIP-721, EIP-1155

摘要

本提案定义了一种将去中心化社交媒体帖子表示为 NFT 的标准化格式。Nostr 协议在创建开放的去中心化社交媒体网络方面做了大量工作。此 ERC 旨在将这些标准适配到最常见的区块链非同质化代币标准。通过这种方式,我们可以利用区块链的覆盖范围和持久性。这里对其进行了通用化,以便可以轻松地将其映射到其他基于事件的去中心化社交媒体,如 AT 协议。事件可以用作社交媒体帖子、博客文章、论坛帖子、加密消息、RSS 源或任意电子出版物。此模型非常灵活,其中事件的含义和类型(原创、回复、转发、图像、视频、文本等)来自其元数据。用户是拥有私钥的任何人。不需要任何权限,任何人都可以使用任何 NFT 合约创建内容。任何人都可以将这些内容整理成 feed 或时间线。

帖子可能由其创建者“拥有”,但 NFT 本身的所有者在此标准中没有意义。这可能是一种有用的财务机制,但帖子的独立签名允许第三方代表另一用户发布消息。

动机

随着社交媒体平台的持续审查和操纵,真正去中心化和无需许可的社交媒体的存在变得越来越重要。与其他区块链去中心化社交媒体的尝试不同,此方法不依赖于一组集中的智能合约。作者签名的基于事件的社交媒体的区块链集成仅仅为标准化去中心化社交媒体的存在增加了一个强大的底层。区块链的优势包括但不限于持久性、抗审查性、货币性和中立性。NFT 标准是表示区块链上唯一数字数据的最常见和广泛使用的标准。使用 NFT 标准和标准 NFT 属性意味着每个使 NFT 可查看的市场、钱包和应用程序也是发布渠道。由于数据是公开可用的,因此还可以构建自定义 feed 算法,以将控制权交还给用户。

规范

获取 id

要获取 id,我们按此顺序对序列化的属性进行 sha256 哈希。序列化通过以下结构的 UTF-8 JSON 序列化字符串完成:

[
  0,
  <pubkey,作为小写十六进制字符串>,
  <created_at,以秒为单位的 Unix 时间戳>,
  <kind,作为数字>,
  <tags,作为非空字符串数组的数组>,
  <content,作为字符串>
]

为了防止实现差异为同一事件创建不同的事件 ID,必须遵循以下规则进行序列化:

  • UTF-8 应用于编码。
  • 必须从序列化的 JSON 和字段值中删除前导和尾部空白。
  • 如果在标签中使用空格,则它们必须是数组值中的单个空格。
  • content 字段中的以下字符必须按所示方式转义,并且所有其他字符必须逐字包含:
    • 换行符 (0x0A),使用 \n
    • 双引号 (0x22),使用 "
    • 反斜杠 (0x5C),使用 \
    • 回车符 (0x0D),使用 \r
    • 制表符 (0x09),使用 \t
    • 退格符 (0x08),使用 \b
    • 换页符 (0x0C),使用 \f

Kinds

0:用户元数据:content 设置为字符串化的 JSON 对象 {name: <username>, about: <string>, picture: <url, string>},描述了创建该事件的用户。可以设置额外的元数据字段。一旦中继获得相同 pubkey 的新事件,它可能会删除较旧的事件。 1:原创内容:原创生成的用户内容通常伴随有简短的文本,但可能包括对其他媒体或事件的链下或链上引用。

Tags

标签是一种灵活的机制,可以将额外的结构化数据附加到帖子。每个标签都是一个或多个字符串的数组,围绕它们有一些约定。

  • 对于使用此方法发布的事件,建议使用区块链标签。 ["blockchain", "<区块链名称或 ID>", "<合约>", "<token_id">]

其中:

  • <区块链名称或 ID> 是链的名称。例如,“Ethereum”、“Polygon”、“Base”或链 ID。例如,“1”、“137”、“8453”
  • <合约> 是合约地址。例如,“0x0000000000000000000000000000000000000000”
  • <token_id> 是 token id。例如,“12345”。如果 token_id 在发布之前未知,则可以省略 token_id,因为它是有符号数据的一部分。

可选标签:

  • 可以通过使用多个 imeta 标签 ["imeta", ...] 来附加多个媒体标签

    ["imeta",
      "dim 1920x1080",
      "url <URL>/1080/12345.mp4",
      "m video/mp4",
    ]
    
  • 引用其他帖子: ["e", "<被引用帖子的 id>"]

  • 此帖子中涉及的公共地址: ["p", "<pubkey>", ...]

  • 外部 URL: ["r", "<URL>"]

元数据 JSON

事件字段存储在 NFT 的元数据的 attributes 下。NFT 的 description 字段与 content 相同。name 可以是用户定义的,也可以包含作者和创建时间。除了 idpubkeycreated_atkindsigcontent 之外的所有属性都被假定为事件标签。

{
  "name": "<帖子标题>",
  "description": "<字符串应与属性 content 标签匹配>",
  "image": "<可选,通常是第一个 m image 标签>",
  "animation_url": "<可选,用于多媒体,如 MP4、MP3、WAV、WEBM 等,也应包含在 imeta 标签中>",
  "external_url": "<可选,应包含在属性 r 标签中>",
  "attributes": [
    {
      "trait_type": "id",
      "value": "<序列化属性数据的 32 字节小写十六进制编码的 sha256 哈希>"
    },
    {
      "trait_type": "pubkey",
      "value": "<公共创建者的 32 字节小写十六进制编码的公钥>"
    },
    {
      "trait_type": "created_at",
      "value": <以秒为单位的 Unix 时间戳>
    },
    {
      "trait_type": "kind",
      "value": <0  65535 之间的整数>
    },
    {
      "trait_type": "sig",
      "value": "<序列化属性数据的 sha256 哈希的 64 字节的小写十六进制签名,与 id 字段相同>"
    },
        {
      "trait_type": "content",
      "value": "<此键应与 description 匹配,即使是空字符串>"
    },
    {
      "trait_type": "imeta",
      "value": "<可选的 imeta 标签>"
    },
    {
      "trait_type": "e",
      "value": "<引用的事件的可选 ID>"
    },
    {
      "trait_type": "r",
      "value": "<到外部 URL 的可选引用>"
    },
    ...<其他_可选_属性>,
  ]
}

生成密钥

私钥: 可以使用任何 Ethereum 私钥或助记词,只要结果是 32 字节的十六进制字符串。也可以使用 openssl rand -hex 32 等命令在本地生成密钥。此密钥用于签署帖子并存储在 pubkey 字段中。

公钥: 公钥基于 Taproot + Schnorr,比特币 BIP 341。建议使用像 nostr-tools 这样的工具从私钥生成公钥。

签名帖子

签名基于 secp256k1 曲线的标准 Schnorr 签名。要在 secp256k1 上使用 Schnorr 签名进行签名,你需要一个私钥、一条消息和一个随机 nonce (k)。然后,你需要计算一个公共 nonce (R)、一个 challenge (e),最后,通过组合这些值来计算签名 (s)。最好使用像 nostr-tools 或 nostril 或比特币核心库中的 schnorr.c 这样的工具。

PubEvent

当创建新帖子时

event PubEvent(
    bytes32 id,
    bytes32 indexed pubkey,
    uint256 created_at,
    uint32 indexed kind,
    string content,
    string tags,
    string sig,
);
  • id:帖子的唯一标识符。
  • pubkey:帖子创建者的公钥。
  • created_at:创建的时间戳。
  • kind:事件类型;1,对于原创帖子。
  • content:帖子的文本内容。
  • tags:结构化元数据。
  • sig:帖子数据的签名。应为 64 字节。

回复帖子

event PubEvent(
    bytes32 id,
    bytes32 indexed pubkey,
    uint256 created_at,
    uint32 indexed kind,
    string content,
    string tags,
    string sig
);
  • id:帖子的唯一标识符。
  • pubkey:帖子创建者的公钥。
  • created_at:创建的时间戳。
  • kind:回复也为 1。
  • content:帖子的文本内容。
  • tags:包括下面概述的结构化元数据。
  • sig:帖子数据的签名。应为 64 字节。

回复 “e” 标签

["e", <事件 ID>, <中继 URL>, <标记>, <pubkey>]

其中:

<事件 ID> 是被引用事件的 ID。 <中继 URL>(可选)是推荐的链下中继器的 URL。如果没有或仅在区块链上,则使用空字符串“”。 <标记> 是可选的,如果存在,则为“reply”、“root”或“mention”之一。 <pubkey> 是可选的,应该是被引用事件的作者的 pubkey

标记为“reply”的表示正在响应的回复事件的 ID。标记为“root”的可以表示正在响应的回复线程的根 ID。标记为“mention”的表示引用的或转发的事件 ID。

<pubkey> 应该是 e 标记事件的作者的 pubkey,这在发件箱模型中用于从作者的写入中继中搜索该事件,其中中继提示未解析该事件。

“p”标签

["p", <pubkey>, ...] 用于文本事件中,包含用于记录谁参与回复线程的 pubkey 列表。

当回复文本事件 E 时,回复事件的“p”标签可以包含 E 的所有“p”标签以及被回复事件的“pubkey”。

示例:给定一个由 a1 创作的文本事件,其“p”标签为 [p1, p2, p3],则回复的“p”标签可以是 [a1, p1, p2, p3],顺序不限。

转发

转发是一种类型 6 事件,用于向关注者表明类型 1 文本帖子值得阅读。

转发事件的内容是被转发帖子的字符串化 JSON。它也可能为空,但不建议这样做。

转发事件必须包含一个 e 标签,其中包含要转发的帖子的 ID。该标签应包括区块链标签或索引中继,可以在其中获取帖子。

转发应该包含一个 p 标签,其中包含要转发的事件的 pubkey。

引用转发

引用转发是类型 1 事件,其中包含被引用转发的帖子的嵌入式 q 标签。q 标签确保引用转发不会被提取并包含在线程中作为回复。它还允许你轻松提取和计算帖子的所有引用。

q 标签应遵循与 e 标签相同的约定,但标记参数除外。

["q", <事件 ID>, <中继 URL>, <pubkey>, <区块链名称或 ID>]

原理

元数据中的这些属性与 Nostr 式事件是 1:1 映射。Nostr 是一种区块链兼容的社交媒体协议,因为它使用不依赖于中央智能合约集的公钥/私钥验证系统。它依赖于 EVM 链已经使用的相同格式的私钥。它具有基于 json 的事件系统,可以轻松映射到 NFT。内容可以在基于 web3 和 web2 的平台之间自由移动。每个帖子都由作者签名,从而实现防篡改的第三方传输和发布。标准化的标签系统允许引用其他区块链、其他合约或外部 URL 上的帖子。

参考实现

仅需要元数据格式和 PubEvent。

function createPost(
  uint256 tokenId,
  string uri,
  bytes32 id,
  bytes32 pubkey,
  uint256 created_at,
  uint32 kind,
  string content,
  string tags,
  string sig
) public {

  mint(tokenId, uri);
  emit PubEvent(id, pubkey, created_at, kind, content, tags, sig);
}

在此示例中,需要 PubEvent 来宣布已发生发布事件。此事件非常灵活,可用于所有事件类型和种类。

代币标准兼容性

  • ERC-721: 每个帖子都应该是唯一的 (tokenId)。
  • ERC-1155: 即使多次铸造,tokenId 也应仅代表一个帖子事件。

向后兼容性

这是在 ERC-721ERC-1155 之上的附加标准。现有的 NFT 保持兼容;理解此标准的客户端或平台可以将这些代币解释为社交帖子以及传统 NFT。

安全注意事项

数据完整性: 确保 id 始终如上所述推导,以防止伪造。如果帖子已正确签名,则 NFT 的所有者与帖子的真实性无关。

垃圾邮件和审核

事件驱动的社交媒体和 NFT 都允许无需许可地创建内容。基于此标准构建的平台应实施自己的审核层、阻止列表或声誉系统。

版权

版权和相关权利通过 CC0 放弃。

Citation

Please cite this document as:

Nick Juntilla (@nickjuntilla) <nick@ownerfy.com>, "ERC-7847: 社交媒体 NFT [DRAFT]," Ethereum Improvement Proposals, no. 7847, December 2024. [Online serial]. Available: https://eips.ethereum.org/EIPS/eip-7847.