规范

原子协议的详细文档

Atomicals 的核心是铸造、转移、更新、删除和提取操作时需要遵循的一些简单规则。熟悉该理论后,只需要几分钟就可以开始铸造您的第一个数字原子对象。

注意:该规范是在代码中定义的,查看 atomicals-js 中的命令以了解它们如何精准运行。

信封

所有方法都遵循利用 Taproot (P2TR) 支出路径脚本的“提交和显示”方案。在输入的见证脚本中,我们放置 Atomicals 信封,其中包含可以在 Atomical 上合法执行的各种操作。

约定是使用 OP_FALSE OP_IF ... OP_ENDIF 将任意不可执行的内容放置在见证支出脚本中。我们使用“atom”(十六进制的 61746F6D )来指示该信封属于原子协议。

OP_FALSE
OP_IF
 0x0461746F6D // Push "atom" 4 bytes
 <Operation>  // Followed by a single push to denote the operation type
 <Payload>    // Payload (CBOR encoded) for the operation
OP_ENDIF

信封可以出现在支出脚本中的任何位置,但建议将其放在 Pay-to-PubKey-Hash (P2PKH) 之后,这实际上是:

<pubkey-hash>
OP_CHECKSIG     // Perform a check signature against the pubkey-hash
OP_FALSE
OP_IF
 0x0461746F6D // Push "atom" 4 bytes
 <Operation>  // Followed by a single push to denote the operation type
 <Payload>    // Payload (CBOR encoded) for the operation
OP_ENDIF

<Operation> 字段的格式是表示后续操作类型的单个推送数据。 <Payload> 数据在操作类型的上下文中进行解释。 <Payload> 是CBOR编码的数据结构,可以用多种编程语言进行解码。 CBOR 提供了一种简洁而富有表现力的数据编码方式,并极大地简化了解析 Atomicals 协议操作,因为只有推送数据包含所有文件及其元数据的必要信息。

负载格式说明

有效负载格式直观且简单:每个顶级字段都是一个文件(或字段)名称,其下方可以是任何有效的类似 JSON 的结构。如果有效负载中有 "ct" (内容类型)字段,则它被解释为该类型的文件,字节位于 "d"

有效负载采用 CBOR 编码,并且可以是单个推送数据中的任意大小,最多 520 字节。如果有效负载较大,则包括大小为 520 的后续推送数据。可以理解为解析器会将所有块连接在一起,然后执行 CBOR 解码以获得数据结构。

如果有效负载不符合 CBOR 编码,则假定没有与 NFT 相关的数据。缺少有效负载字段是有效的,但也仅仅表示没有数据。某些数字对象可能没有明确的有效负载数据作为其铸造事件的一部分。

最后要注意的是,当且仅当还提供了 "d" 字节时,任何具有子键 "ct" (内容类型)的字段都被假定为文件。如果未提供,则该字段将被视为非文件元数据字段。

负载格式示例

{
  "someimage.png": "binary data",
  "meta": {
    "some": "value",
    "another: {
      "fieldabc": 123
    }
  },
  "args": {
    "r": "abc"
  }
}

原子协议如何工作?

原子是使用带有 “atom” 信封和铸造 “m” 操作的两步提交揭示过程铸造的。一旦通过铸造过程创建了 Atomical,它就可以使用任何地址类型的 Bitcoin 正常规则进行转移。这些规则非常容易理解,可以用以下语句来概括:

某个输出上的 Atomical 在输入与输出的顺序中被花费和分配。第一个输入被分配给第一个输出,第二个输入被分配给第二个输出,依此类推...... 唯一的例外是当相应的输出不足时,且在交易中的第 n 个输入没有至少 n 个输出时,在这种情况下,该 Atomical 将自动分配给第一个输出。

读者可能会意识到,这使得将许多 Atomicals 数字对象分配给同一个 UTXO 成为可能。为了能够拆分或“提取” Atomical,在多个 Atomicals 与同一个 UTXO 关联的情况下,我们使用操作 “x” 表示的 “splat” 操作,将 Atomical 从当前输入 UTXO 移动到第一个输出。

通过这种方式,Atomicals 的所有者可以有选择地将 Atomicals 放入单独的 UTXO 中。这种技术可以轻松避免错误,并确保数字对象永远不会意外地被用作矿工的费用。还有一个“split” “y”操作,可以对 ARC20 可替代代币执行类似的操作。

Example 1:从一个地址转移 Atomical 到另一个地址

Inputs => Outputs

[A] [funding] => [A] [change]

第 0 个输入具有原子 A 标记并分配给第 0 个输出

Example 2:同时转移两个 Atomical,并且传输到不同的地址

Inputs => Outputs

[A] [B] [funding] => [A] [B] [change]

第 0 个输入具有原子 A 标记并分配给第 0 个输出

第 1 个输入具有原子 B 标记并分配给第 1 个输出

Example 3a:同时传输 3 个 Atomical,但是只有 2 个输出

Inputs => Outputs

[A] [B] [C] [funding] => [A,C] [B]

第 0 个输入具有原子 A 标记并分配给第 0 个输出

第 1 个输入具有原子 B 标记并分配给第 1 个输出

第 2 个输入具有 Atomical C 的标记,并被分配给第 0 个输出,这是因为它没有相应的输出,所以被分配给第 0 个输出

Example 3b:如何对包含原子 [A, C] 的 UTxO 进行 splat 或提取

答案:使用 “x” 表示的“提取”操作来指定将 Atomical 移动到另外一个输出

Inputs => Outputs

[ non Atomicals Input ] [A,B 'x'] [funding] => [B] [A]

第 0 个输入是常规的普通非 Atomical 输入

第 1 个输入印有 Atomical A 和 B,通常两者会一起传输到第 1 个输入,但是提供了 "x" 提取操作,并且用户提供了要提取的 Atomical B 的标识符。所以,Atomical B 移动到第 0 个输出,Atomical A 保留在第 1 个输出。从而允许 Atomical 的所有者有选择地分割出之前组合到同一个 UTxO 中的任意数量的 Atomicals。

请注意,只有当用户犯了错误并意外组合了 Atomical 时才需要这样做,实际上这种情况不应该发生,因为正常用法是一次传输一个 Atomical,从而完全避免了这一问题。尽管如此,如果出于任何原因有必要的话,用提取技术提取意外组合的原子是很容易的。

Last updated