{"content":{"title":"Atomical协议学习","body":"<!--StartFragment-->\r\n\r\n本文主要来自Atomical官方文档的翻译和摘取，时间：2024.1\r\n\r\n\r\n\r\n\r\n# 1. 协议基础\r\n\r\nAtomicals协议文档：[https://docs.atomicals.xyz/](https://docs.atomicals.xyz/)\\\r\nIndexer 解析器：[https://github.com/atomicals/atomicals-electrumx](https://github.com/atomicals/atomicals-electrumx)\\\r\n铸造工具：[https://github.com/atomicals/atomicals-js](https://github.com/atomicals/atomicals-js)\\\r\n**相关交易市场：**\\\r\n[https://atomicalmarket.com/](https://atomicalmarket.com/)\\\r\n\\[[https://satsx.io/](https://satsx.io/)]\\([https://satsx.io/marketplace/atomicals/ft/sort?page=1](https://satsx.io/marketplace/atomicals/ft/sort%3Fpage%3D1))\\\r\n[https://bitatom.io/](https://bitatom.io/)\\\r\n社区的ElectrumX服务端点：[https://docs.atomicals.xyz/reference-and-tools/electrumx-api-and-public-endpoints](https://docs.atomicals.xyz/reference-and-tools/electrumx-api-and-public-endpoints)\\\r\n**简介**：\\\r\nAtomical是基于UTXO的，比特币网络上的NFT，不需要indexer就可以工作。Atomicals 是可自证、易于验证的。\\\r\nAtomical的目标是描述数字对象（注意它是对象，不是特指NFT)。静态或动态对象都可以。\\\r\nAtomical的理念是把在传输时，验证UTXO的整个历史。即使一个atomical被转手了10000次，产生的数据大小也仅有2.5MB (250byte\\*10000)。所以它是自证明的，不依赖于第三方服务和indexer。\\\r\n\"No transaction history, not your digital object\"\\\r\n常见用法：\\\r\n\r\n\r\n* NFT\r\n* ARC20\r\n* Collections Container\r\n* Realm Names\r\n\r\n**标识**\\\r\nAtomical的标识有3种：\\\r\n\r\n\r\n* Atomical Number：从0开始的顺序字符，表示atomical铸造的顺序，是个短的简单的表达法。\r\n* Atomical ID:是Atomical的唯一标识符。是铸造它的txid和输出的序号， ***\\<txid>*i*\\<index>*** 例如：a14e65573ff32b95b91a0ed8367feec64125e5f4ff44d9901002b262da959e6di0 i不是16进制里的数字，所以一定不会认错。上面表示a14e65573ff32b95b91a0ed8367feec64125e5f4ff44d9901002b262da959e6d是txid，i是分隔符，0表示第一个output。\r\n* REF，是把Atomical ID用Crockford-base32 编码显示的结果，可以有更丰富的字符集。\r\n\r\n**动态对象**\\\r\n将一个或多个文件或变量添加Atomical的每次交易的 UTXO 的支出中，indexer会计算并展示最终的状态。\\\r\n数据可以是key-value，也可以是文件，比如PDF,图片等。\\\r\n针对每个Atomical，在转移，更新等操作时，都会验证它的全部历史，从而获得它的最新状态。\\\r\n\r\n\r\n1. NFT\r\n\r\n**铸造**：\\\r\nAtomical通过Taproot支出脚本的两步提交和揭示方案创建，通过Atomical信封+\"m\"表示的铸造操作来铸造。交易的输出中承诺了被提交的数据或文件。然后数据被包含在一个支出脚本中，以揭示内容，这可以是一个或多个文件，包括任何类型的内容，如图像、文本或任何媒体。\\\r\n**更新**：\\\r\n除了不可变的内容和文件之外，Atomicals 数字对象支持在使用由字母 \"u\" 表示的更新操作后的任何时间附加任意数量的文件和状态。方法与铸造类似。\\\r\n由于不可变存储的特性，每个文件的修订历史都被永久存储，以便能够准确回放状态变化。\\\r\n**转移**：\\\r\n一旦铸造完成，Atomical 可以像普通比特币一样通过任何类型的交易进行转移，包括 Taproot (P2TR)、SegWit、Multisig 和传统地址 (P2PKH)。\\\r\n强烈建议使用支持 Atomicals 的钱包，在使用不支持 Atomicals 识别的钱包时，用户如果不小心可能会将其发送给错误的接收方。\\\r\n转移的规则：\\\r\n\r\n\r\n* Atomical 的身份从交易中的第 i 个输入流向第 i 个相应的输出。如果交易中的输出少于 i 个，则 Atomical 的身份总是流向该交易中的第一个输出。\r\n* 如果在同一笔交易中花费了多个 Atomicals，并且每个 Atomical 花费都没有足够的相应输出（例如，有2个输入，但只有1个输出），那么会发生这样的情况：这些多个 Atomicals 将流向第一个输出，从而在同一UTXO上印刻了多个 Atomicals！这并不是一个大问题，实际上，这是一个有用的特性，可以将多个 Atomicals 关联到单个 UTXO 上。\r\n* 我们必须提供一种方法来\"分裂\"或提取任何单个 Atomical，通过 Atomical Id 进行引用。以下是为此目的提供的 'Splat' 协议操作。提取操作接受一个数组：将当前输入中的 Atomical Id 强制放入第一个输出。这就是能够从单个 UTXO 中拆分出任意数量的 Atomicals 所需的全部操作。如果携带的输入与 Atomical Id 不相关（由于开发者错误），那么它被视为\"无操作\"。\r\n\r\n注意，转账规则也适用于最初铸造的 Atomical。例如，如果在输入位置 i 处铸造了一个 Atomical，那么该 Atomical 的标识将被印在第 i 个输出上，除非输出较少，或者碰到了一个无法花费的OP_RETURN，在这种情况下，标识始终将被印在第一个输出上。请注意，可以在单个交易中铸造多个Atomical，如果输出数量少于相对于输入数量所需的数量，则在没有匹配的第 i 个输出的情况下，Atomical将分配给第一个输出。\\\r\n\r\n\r\n![](https://pic4.zhimg.com/80/v2-937bd224fe41972ad0178693aaa1bc23\\_1440w.webp)\r\n\r\n\\\r\n**SWAP**\\\r\n下面是一个swap的例子，input1是买家输入的，input2是卖家输入的，把7771卖给买家。\\\r\n\r\n\r\n![](https://pic1.zhimg.com/80/v2-a96e6d43c735ce945f5ba58de2228964\\_1440w.webp)\r\n\r\n\\\r\n**Splat**\\\r\n注意分离出来的顺序。\\\r\n\r\n\r\n![](https://pic1.zhimg.com/80/v2-d748755a0dde630b9bfcab7d713d2090\\_1440w.webp)\r\n\r\n\\\r\n\r\n\r\n# 2 . ARC20\r\n\r\nARC20用聪来代表token，它们可以像普通比特币那样组合和拆散。\\\r\nARC20的名字先到先得，一旦被注册，后续重名的就无效。\\\r\nARC20的mint有直接mint和去中心化mint两种。\\\r\n2.1 mint\\\r\n2.1.1 **去中心化mint**\\\r\n初始化\\\r\n去中心化mint的初始化包括如下内容：\\\r\n\r\n\r\n* ticker(名字）\r\n* per mint award (每次mint获得多少）,\r\n* total mints allowed （总共可以执行多少次mint）,\r\n* start block height（开始mint的块高）,\r\n* metadata\r\n\r\n例如：名字：`myticker123，每次允许mint :1,000, mint次数总量：10,000`，从块`810,000`开始mint，使用 image.jpg 甚至metadata（例如描述、链接).\\\r\n`npm run cli init-dft <tick> <per_mint_amt> <mint_count>`\\\r\n`<start_height> metadata.json`\\\r\n\\\r\n\\\r\n`Optional flags:`\\\r\n`--mintbitworkc=<prefix>`\\\r\n`--satsbyte=<number>`\\\r\n初始化时还可以加一个可选的`mintbitworkc`参数。它要求minter提供一个工作量证明前缀，来表示自己付出了一定工作量。例如--mintbitworkc=\"777\"，表示minter要计算出开头为777的证明。\\\r\n`--satsbyte=<number>`是为每byte愿意支付的gas fee（聪计价），不是Atomical协议的部分。\\\r\nmint\\\r\n`npm run cli mint-dft <tick>`\\\r\n`Optional flags:`\\\r\n`--satsbyte=<number>`\\\r\n2.1.2 Direct Mint\\\r\n在一次交易里把全部的都mint出来。每一聪代表一个币。\\\r\n`npm run cli mint-ft <tick> <total_supply> metadata.json`\\\r\n`Optional flags:`\\\r\n`--satsbyte=<number>`\\\r\n例如，要铸造供应量为 100,000,00000 的代币，只需创建一个恰好包含 1 个完整比特币的输出（因为 1 BTC = 100,000,00000 Satoshis）。使用直接铸造模式的一个优点是，必须提供所需数量的比特币来证实铸造的总供应量；这大大减少了不诚实的行为者凭空打印代币的情况。\\\r\nmetadata可以直接写进铸币交易。可以用[permanent-file-storage](https://docs.atomicals.xyz/permanent-file-storage)来保存图片，再把图片ref进去。\\\r\n{ \"name\": \"\", \"desc\": \"\", \"image\": \"atom:btc:dat:\\<location of store-file data>/image.png\", \"decimals\": 0, \"links\": { \"x\": { \"v\": \"[https://x.com/..](https://x.com/..).\" }, \"website\": { \"v\": \"[https://..](https://..).\" }, \"realm\": { \"v\": \"atom:btc:realm:myrealmname.subrealm\" }, \"discord\": { \"v\": \"[https://discord.gg/..](https://discord.gg/..).\" } }, \"legal\": { \"terms\": \"\" } }\\\r\nmetadata里没有任何字段是必须的，也可以采用任何形式，只要是json就行。\\\r\n2.2 转账\\\r\n\r\n\r\n1. 所有的input应该完全，干净的进入到output。如果output不够，或者某个output过多会导致膨胀（比如多个输入，其中一个有atomical，其他的没有，就可能导致output膨胀），此时多余的余额会被烧掉。 例如下图，1932、7920、0542 Atomical，按FIFO顺序分配，同时跳过不可花费的输出 (OP_RETURN)。第一个输入 NFT 从输出 0 开始分配，然后每个后续 NFT 输入分配给下一个可用输出。 同一 UTXO 输入的多个 Atomical 按atomical_id 排序。由于“1932”在“7920”之前，因此它排在第一位。\r\n\r\n![](https://pic4.zhimg.com/80/v2-1f7fefe50cd41dfeda93dcb126030ba7\\_1440w.webp)\r\n\r\n\\\r\n\r\n\r\n1. 在无法完全（或“干净”）分配输出的情况下，算法会尝试从输出 0 开始分配所有 ARC20 令牌，无论是否已分配另一个 ARC20。做出这一决定是为了在开发人员或钱包意外未能跟踪多个输入 ARC20 的情况下给予宽大处理 - 换句话说，将“尽最大努力”尝试进行补偿和分配 (没看懂，为什么7920不被分配进第2，3个output? 为什么第3个output没有包含600个0542?)\\\r\n\r\n\r\n\\\r\n\r\n\r\n![](https://pic4.zhimg.com/80/v2-8ec205a6015f467a659d47b1dde3a32b\\_1440w.webp)\r\n\r\n\\\r\n\r\n\r\n\\\r\n\r\n\r\n1. 当输出中没有足够数量的聪来容纳输入值时，原子分配不足。结果是多余的输入值被烧毁——或永久销毁。上面的例子显示 Atomical 86a1 的输入值为 2600，但输出中只有 1600 Satoshi，这实际上导致 1000 个单位的 Atomical 86a1 被销毁。\r\n\r\n![](https://pic3.zhimg.com/80/v2-f4a5947ead371c630a6578097afa4942\\_1440w.webp)\r\n\r\n\\\r\n\r\n\r\n1. 当预期输出中的 Satoshis 过多并且原子的输入没有足够的剩余余额时，原子的分配会被错误地分配。上面的例子显示 Atomical 86a1 的输入值为 2600，第一个输出有 600 个 Satoshi，但第二个输出有 2100 Satoshi，这无法与 Atomical 86a1 抗衡，因为只剩下 2600 - 600 = 2000 个单位的 Atomical 剩余分配。尝试分配会导致供应膨胀，因此被视为无效。结果是 2000 单位 Atomical 86a1 被永久摧毁\r\n\r\n![](https://pic1.zhimg.com/80/v2-6b2756446c3a1f880dafef7e2f50ea18\\_1440w.webp)\r\n\r\n\\\r\n2.3 swap\\\r\n**步骤 1.** 卖方签署包含 ARC20 Atomical 9810 的第二个输入和第二个输出，以接收 5000 Satoshis。签名`SIGHASH_SINGLE | ANYONECANPAY`允许买方添加额外的资金输入以及接收 ARC20 代币的接收地址。\\\r\n**步骤 2.** 买方在第一个输入中添加资金输入，并添加第一个输出以接收 ARC20 Atomical 9810 值。签署即表示`SIGHASH_ALL`买方承诺所有输入和输出。\\\r\n\r\n\r\n![](https://pic1.zhimg.com/80/v2-13697373c192a852e239c48bbdd9f30c\\_1440w.webp)\r\n\r\n\\\r\n2.4 指数\\\r\n这个功能在文档里显示还未开发完。\\\r\n由于粉尘限制，使用比特币在单个 UTXO 中传输少于 546 聪是不可能的，因此不可能以低于 546 面额的 ARC20 代币进行传输，这在实际种不太合适。\\\r\n因此考虑通过ST操作符表示进行指数缩放（有放大也有缩小），表示10的几次方。\\\r\n\r\n\r\n![](https://pic4.zhimg.com/80/v2-462981c08b4ba6b9bf99eabbf023e41b\\_1440w.webp)\r\n\r\n\\\r\n\r\n\r\n![](https://pic1.zhimg.com/80/v2-c684f3485ee4d11efcaebe38e678ed58\\_1440w.webp)\r\n\r\n\\\r\n\r\n\r\n![](https://pic3.zhimg.com/80/v2-04015097b11f84a5761ecbd7fe6370b2\\_1440w.webp)\r\n\r\n\\\r\n\r\n\r\n![](https://pic4.zhimg.com/80/v2-1c34d499a635eab985a4f357d16b4737\\_1440w.webp)\r\n\r\n\\\r\n当没有SP操作符，但是有指数时，用最大的指数。\\\r\n\r\n\r\n![](https://pic3.zhimg.com/80/v2-9489d74c52381a5548d7e4067b2c683a\\_1440w.webp)\r\n\r\n\\\r\n\r\n\r\n# 3 . 容器（Collection containers)\r\n\r\n这是一种特殊的Atomical对象，专门用来作为NFT的集合。容器名字可读，表示NFT和metadata的集合。容器名字以#开头。可以向容器里添加物品，也可以永久封住，不做任何改变。\\\r\nCollection的格式：大部分的field都是可选的。\\\r\n{ \"name\": \"Collection Name\", \"desc\": \"Collection description\", \"image\": \"atom:btc:dat:\\<location of store-file data>/image.png\", \"legal\": { //建议要有 \"terms\": \"...\", \"license\": \"CC\" }, \"links\": { \"x\": { \"v\": \"[https://x.com/..](https://x.com/..).\" }, \"website\": { \"v\": \"[https://..](https://..).\" }, \"discord\": { \"v\": \"[https://discord.gg/..](https://discord.gg/..).\" } }, \"attrs\": \\[ { \"name\": \"bodyarmor\", \"desc\": \"Type of body armor\", \"type\": \"string\", \"values\": \\[ \"metal\", \"leather\", \"field\" ] }, { \"name\": \"headcovering\", \"desc\": \"The type of head covering\", \"type\": \"string\", \"values\": \\[ \"bandana\", \"helmet\", \"scarf\", \"baseball cap\" ] }, { \"name\": \"stamina\", \"desc\": \"The stamina of the hero\", \"type\": \"integer\", \"min\": 0, \"max\": 10 } ], \"items\": { \"0\": { \"id\": \"84718b469c40b1bcc7cb324b8e24e4e442f88cd913687ea2bc7b3e79d4fc4fdei0\", //必须 \"n\": \"Some Name\", \"a\": \\[ //必填，代表attributes.它是一个数组，里面每个值代表“attrs”里定义的每一项的值。 0, 3, 8 ] }, \"1\": { \"id\": \"1070d7c98304bf5ac9a5addceb13e0ce4e840641f82d71d84cebbdac427c1f4fi0\", \"n\": \"Another Name\", \"a\": \\[ 1, 2, 10 ] }, \"Signature Series 1\": { \"id\": \"14a0d7c98304bf5ac9a5addceb1de0ce4e840641f82d71d84cebbdac427c1fc3i0\", \"n\": \"Special\", \"a\": \\[ 2, 3, 7 ] } } }\\\r\n如果你的集合没有attr等复杂结构，可以用下面的最简单形式：\\\r\n{ \"name\": \"Collection Name\", \"image\": \"atom:btc:dat:\\<location of store-file data>/image.png\", \"items\": { \"0\": { \"id\": \"84718b469c40b1bcc7cb324b8e24e4e442f88cd913687ea2bc7b3e79d4fc4fdei0\" }, \"1\": { \"id\": \"1070d7c98304bf5ac9a5addceb13e0ce4e840641f82d71d84cebbdac427c1f4fi0\" }, \"9999\": { \"id\": \"14a0d7c98304bf5ac9a5addceb1de0ce4e840641f82d71d84cebbdac427c1fc3i0\" } } }\\\r\n可以通过以下命令在链上存储图片，并生成Collections.\\\r\n// first store the desired main image on chain (see section below) npm run cli store-file ./path/to/image.png image.png --satsbyte=10 Success sent tx: db8a761ed493627138c5733071558c4caa65912c5cba3e1061c02d6d7933461f { \"success\": true, \"data\": { \"commitTxid\": \"b57bad8c0b7f58a552574fafc16b6efbbb3bf966b9ccfb24f03580f9462b5997\", \"revealTxid\": \"db8a761ed493627138c5733071558c4caa65912c5cba3e1061c02d6d7933461f\", \"dataId\": \"db8a761ed493627138c5733071558c4caa65912c5cba3e1061c02d6d7933461fi0\" } } // We will use the dataId above to reference the data on chain // ie: atom:btc:dat:db8a761ed493627138c5733071558c4caa65912c5cba3e1061c02d6d7933461fi0/image.png // Store the collection metadata with the following command: npm run cli set-container-data #mycollection-name collection.json --satsbyte=10\\\r\n容器的一个常见用法是作为NFT集合的容器，进行DMINT（Decentralized Mint）。下面是DMINT的方法：\\\r\n\r\n\r\n![](https://pic1.zhimg.com/80/v2-66b37559571fdc5b25e9c8d1690135e8\\_1440w.webp)\r\n\r\n# 4. DMINT\r\nDMINT包含四个步骤：\\\r\n\r\n\r\n1. 准备Collection的所有数据（各个NFT的数据，如图片等，会公开给社区）。\r\n2. 配置容器（Collection链上铭刻）。\r\n3. 验证 NFT item（是Mint NFT里的一个动作）。\r\n4. Mint NFT（用户操作）\r\n\r\n项目方负责1-3， 要mint的用户最终把NFT mint出来。这样上传图片，验证NFT所需要消耗的gas fee，就都是由minter来承担。\\\r\n整个过程挺常规的，不细说了。\\\r\n\r\n\r\n# 5 . Realm Names\r\n\r\n就是域名，did\\\r\n一个人类可读的名字，关联到地址或者某个资源，可以转让。\\\r\nRealm Names必须以\"+\"开头。\\\r\n命令：\\\r\nnpm run cli mint-realm \"myrealmname\"\\\r\n5.1 支付\\\r\n可以在支持Atomical的钱包里，通过Realm names进行转账。\\\r\n\\+\\[inbox]@\\[realm_name] + 总是出现，表示这是个Atomical Realm inbox: 表示该realm_name下的收款账号。一个realm_name可以有多个收款账号 @ 分隔符，必须有 realm_name: 注册的realm_name 例如： +hello\\@samplerealm +main\\@samplerealm +support\\@samplerealm\\\r\n关于inbox的定义：\\\r\n{ \"paynames\": { \"delegate\": \"atom:btc:id:\\<atomical_id>/paynames\", \"hello\": { \"delegate\": \"atom:btc:id:\\<atomical_id>/paynames/hello\" }, \"main\": { \"types\": { \"btc\": { \"value\": \"bitcoin btc address\" }, \"ltc\": { \"value\": \"litecoin ltc address\", \"notes\": \"optional notes\", \"instructions\": \"optional instructions\" } } } } }\\\r\n5.2 子领域\\\r\n应用思考：[https://news.marsbit.co/20231118130551840807.html](https://news.marsbit.co/20231118130551840807.html)\\\r\n拥有realm name, 就可以在它下面注册子名字，跟ENS的概念一样。\\\r\n\r\n\r\n![](https://pic1.zhimg.com/80/v2-d4a7b59fc29a132052f113cdd2aafad0\\_1440w.webp)\r\n\r\n\\\r\n在Realm，或subRealm的结构里，在“subrealms\"名字空间里定义规则。\\\r\n定义规则：\\\r\n**Step1:定义规则**：\\\r\n规则如何定义的描述：[https://docs.atomicals.xyz/rules-subrealms-and-dmint](https://docs.atomicals.xyz/rules-subrealms-and-dmint)\\\r\n下面是一个例子：这个文件命名为rules.json\\\r\n{ \"subrealms\": { \"rules\": \\[ { \"p\": \"^\\[a-z0-9]{6,64}$\", \"bitworkc\": \"8888.8\" }, { \"p\": \".\\*\", \"o\": { \"0014383fb23c5b1b40025b0e1dd3e310d6e1ee6d316e\": { \"v\": 1000 } } } ] } }\\\r\n上面规则文件表示两条规则：\\\r\n\r\n\r\n1. 任何人都可以在完成bitworkc：8888.8(大概1-2分钟cpu计算）的情况下，都可以免费mint 6-64长度的，包含a-z,0-9字符的sub realm.\r\n2. 发送给0014383fb23c5b1b40025b0e1dd3e310d6e1ee6d316e 1000 聪以上，就可以mint任意长度的sub realm。\r\n\r\n**Step2**:\\\r\n提交rules上链，使其active。下面的 +mycoolrealm是之前申请的realm。\\\r\nyarn cli enable-subrealms +mycoolrealm file.json --satsbyte=100\\\r\nMint subrealm\\\r\n\r\n\r\n1. 用以下命令查询要申请的subrealm是否存在，以及要申请的名字是否合法 yarn cli realm-info mycoolrealm.nicesubrealm\r\n2. 用以下命令完成subrealm的申请 yarn cli mint-subrealm +mycoolrealm.nicesubrealm --satsbyte=100\r\n3. 如果需要支付，用下面命令完成支付 yarn cli pending-subrealms\r\n\r\n\r\n\r\n# . Bitwork挖矿\r\n\r\n就是不断换参数（nonce）生成新的交易hash，看交易hash的前几位是否达到了要求。\\\r\n可以微调，例如要求前缀是 7777.10，这里7777就要求前面几位必须是7777，.后面的10表示第5位必须是第10个字符以上，即a,b,c,d,e,f\\\r\n示例：\\\r\n[https://mempool.space/testnet/tx/000005970d1d9ac218be8e6f78cfda667e4112a63f2fb0b7b000a8cb2d0dded0](https://mempool.space/testnet/tx/000005970d1d9ac218be8e6f78cfda667e4112a63f2fb0b7b000a8cb2d0dded0)\\\r\n他的难度就是00000为前缀，然后具体参数需要解码里面的P2TR 信息解码。比如61746f6d 用十六进制解码后则是 atom，646d74 解码后则是Operation 中的 dmt ，然后 payload 信息，需要使用 cbor方法解码，解出来是\\\r\nnode cbor.js\\\r\n{\\\r\n\"args\": {\\\r\n\"time\": 1703318358,\\\r\n\"nonce\": 8083950,\\\r\n\"bitworkc\": \"00000\",\\\r\n\"mint_ticker\": \"atom\"\\\r\n}\\\r\n\r\n\r\n# 7. 其他\r\n\r\n7.1 递归和引用\\\r\n{ // Any Atomical data above... \"ctx\": { // Implied to always get the latest data for an atomical: \"resourcename\": \"atom:btc:id:\\<atomical_id>/mydata\", // Gets permanent data file image.png at the dat_id \"icon\": \"atom:btc:dat:\\<dat_id>/image.png\", // Gets the minted \"name\" property for a collection \"collection-name\": \"atom:btc:container:\\<dat_id>$name\", // Gets the latest version of import.js located at a realm name \"assetbuilder.js\": \"atom:btc:realm:\\<realm_name>/import.js\", }, // Another other Atomical data ... }\\\r\nAtomicals Universal Resource Name (URN) 定义是：\\\r\natom:\\<chain>:\\<ref_type>:\\<identifier>\\[$ or /\\[\\<file>]]\\\r\nref_type:\"**id\", \"container\", \"realm\", and \"dat\"**\\\r\nidentifier，对不同ref_type来说，是不同的内容。如对dat来说，是reveal location of the immutable data，即不可变数据的地址。\\\r\n其中：$表示mint时的data，/表示最新的data。注意对ref_type为dat的来说，无论用$还是/，返回内容都一样\\\r\n例如：\\\r\n\r\n\r\n* atom:btc:id:\\<atomical_id> atom:btc:id:14a0d7c98304bf5ac9a5addceb1de0ce4e840641f82d71d84cebbdac427c1fc3i0 表示一个atomical id\r\n* atom:btc:id:\\<atomical_id>$ 表示这个atomical_id最初mint时提供的json\r\n* atom:btc:id:\\<atomical_id>$info.pdf 这个atomical_id最初mint时的info.pdf文件\r\n* atom:btc:id:\\<atomical_id>/ 获取最新数据\r\n* atom:btc:id:\\<atomical_id>/image.png@\\[txid or version number or blockheight] 获取某个版本的数据\r\n* atom:btc:container:\\<containerName>$ 获取container在mint时的数据\r\n\r\n...\\\r\n7.2 链上永久保存图片\\\r\n// immutably store an image on-chain to reference in the container metadata npm run cli store-file ./path/to/image.png image.png --satsbyte=10 Success sent tx: db8a761ed493627138c5733071558c4caa65912c5cba3e1061c02d6d7933461f { \"success\": true, \"data\": { \"commitTxid\": \"b57bad8c0b7f58a552574fafc16b6efbbb3bf966b9ccfb24f03580f9462b5997\", \"revealTxid\": \"db8a761ed493627138c5733071558c4caa65912c5cba3e1061c02d6d7933461f\", \"dataId\": \"db8a761ed493627138c5733071558c4caa65912c5cba3e1061c02d6d7933461fi0\" } }\\\r\n可以用db8a761ed493627138c5733071558c4caa65912c5cba3e1061c02d6d7933461fi0来引用到这种图片，这就是它的atomical id\r\n\r\n<!--EndFragment-->"},"author":{"user":"https://learnblockchain.cn/people/13806","address":null},"history":null,"timestamp":1710210196,"version":1}