本文主要来自Atomical官方文档的翻译和摘取,时间:2024.1
<!--StartFragment-->
本文主要来自Atomical官方文档的翻译和摘取,时间:2024.1
Atomicals协议文档:https://docs.atomicals.xyz/\ Indexer 解析器:https://github.com/atomicals/atomicals-electrumx\ 铸造工具:https://github.com/atomicals/atomicals-js\ 相关交易市场:\ https://atomicalmarket.com/\ [https://satsx.io/](https://satsx.io/marketplace/atomicals/ft/sort?page=1)\ https://bitatom.io/\ 社区的ElectrumX服务端点:https://docs.atomicals.xyz/reference-and-tools/electrumx-api-and-public-endpoints\ 简介:\ Atomical是基于UTXO的,比特币网络上的NFT,不需要indexer就可以工作。Atomicals 是可自证、易于验证的。\ Atomical的目标是描述数字对象(注意它是对象,不是特指NFT)。静态或动态对象都可以。\ Atomical的理念是把在传输时,验证UTXO的整个历史。即使一个atomical被转手了10000次,产生的数据大小也仅有2.5MB (250byte*10000)。所以它是自证明的,不依赖于第三方服务和indexer。\ "No transaction history, not your digital object"\ 常见用法:\
标识\ Atomical的标识有3种:\
动态对象\ 将一个或多个文件或变量添加Atomical的每次交易的 UTXO 的支出中,indexer会计算并展示最终的状态。\ 数据可以是key-value,也可以是文件,比如PDF,图片等。\ 针对每个Atomical,在转移,更新等操作时,都会验证它的全部历史,从而获得它的最新状态。\
铸造:\ Atomical通过Taproot支出脚本的两步提交和揭示方案创建,通过Atomical信封+"m"表示的铸造操作来铸造。交易的输出中承诺了被提交的数据或文件。然后数据被包含在一个支出脚本中,以揭示内容,这可以是一个或多个文件,包括任何类型的内容,如图像、文本或任何媒体。\ 更新:\ 除了不可变的内容和文件之外,Atomicals 数字对象支持在使用由字母 "u" 表示的更新操作后的任何时间附加任意数量的文件和状态。方法与铸造类似。\ 由于不可变存储的特性,每个文件的修订历史都被永久存储,以便能够准确回放状态变化。\ 转移:\ 一旦铸造完成,Atomical 可以像普通比特币一样通过任何类型的交易进行转移,包括 Taproot (P2TR)、SegWit、Multisig 和传统地址 (P2PKH)。\ 强烈建议使用支持 Atomicals 的钱包,在使用不支持 Atomicals 识别的钱包时,用户如果不小心可能会将其发送给错误的接收方。\ 转移的规则:\
注意,转账规则也适用于最初铸造的 Atomical。例如,如果在输入位置 i 处铸造了一个 Atomical,那么该 Atomical 的标识将被印在第 i 个输出上,除非输出较少,或者碰到了一个无法花费的OP_RETURN,在这种情况下,标识始终将被印在第一个输出上。请注意,可以在单个交易中铸造多个Atomical,如果输出数量少于相对于输入数量所需的数量,则在没有匹配的第 i 个输出的情况下,Atomical将分配给第一个输出。\
\ SWAP\ 下面是一个swap的例子,input1是买家输入的,input2是卖家输入的,把7771卖给买家。\
\ Splat\ 注意分离出来的顺序。\
\
ARC20用聪来代表token,它们可以像普通比特币那样组合和拆散。\ ARC20的名字先到先得,一旦被注册,后续重名的就无效。\ ARC20的mint有直接mint和去中心化mint两种。\ 2.1 mint\ 2.1.1 去中心化mint\ 初始化\ 去中心化mint的初始化包括如下内容:\
例如:名字:myticker123,每次允许mint :1,000, mint次数总量:10,000
,从块810,000
开始mint,使用 image.jpg 甚至metadata(例如描述、链接).\
npm run cli init-dft <tick> <per_mint_amt> <mint_count>
\
<start_height> metadata.json
\
\
\
Optional flags:
\
--mintbitworkc=<prefix>
\
--satsbyte=<number>
\
初始化时还可以加一个可选的mintbitworkc
参数。它要求minter提供一个工作量证明前缀,来表示自己付出了一定工作量。例如--mintbitworkc="777",表示minter要计算出开头为777的证明。\
--satsbyte=<number>
是为每byte愿意支付的gas fee(聪计价),不是Atomical协议的部分。\
mint\
npm run cli mint-dft <tick>
\
Optional flags:
\
--satsbyte=<number>
\
2.1.2 Direct Mint\
在一次交易里把全部的都mint出来。每一聪代表一个币。\
npm run cli mint-ft <tick> <total_supply> metadata.json
\
Optional flags:
\
--satsbyte=<number>
\
例如,要铸造供应量为 100,000,00000 的代币,只需创建一个恰好包含 1 个完整比特币的输出(因为 1 BTC = 100,000,00000 Satoshis)。使用直接铸造模式的一个优点是,必须提供所需数量的比特币来证实铸造的总供应量;这大大减少了不诚实的行为者凭空打印代币的情况。\
metadata可以直接写进铸币交易。可以用permanent-file-storage来保存图片,再把图片ref进去。\
{ "name": "", "desc": "", "image": "atom:btc:dat:\<location of store-file data>/image.png", "decimals": 0, "links": { "x": { "v": "https://x.com/..." }, "website": { "v": "https://..." }, "realm": { "v": "atom:btc:realm:myrealmname.subrealm" }, "discord": { "v": "https://discord.gg/..." } }, "legal": { "terms": "" } }\
metadata里没有任何字段是必须的,也可以采用任何形式,只要是json就行。\
2.2 转账\
\
\
\
\
\
\
2.3 swap\
步骤 1. 卖方签署包含 ARC20 Atomical 9810 的第二个输入和第二个输出,以接收 5000 Satoshis。签名SIGHASH_SINGLE | ANYONECANPAY
允许买方添加额外的资金输入以及接收 ARC20 代币的接收地址。\
步骤 2. 买方在第一个输入中添加资金输入,并添加第一个输出以接收 ARC20 Atomical 9810 值。签署即表示SIGHASH_ALL
买方承诺所有输入和输出。\
\ 2.4 指数\ 这个功能在文档里显示还未开发完。\ 由于粉尘限制,使用比特币在单个 UTXO 中传输少于 546 聪是不可能的,因此不可能以低于 546 面额的 ARC20 代币进行传输,这在实际种不太合适。\ 因此考虑通过ST操作符表示进行指数缩放(有放大也有缩小),表示10的几次方。\
\
\
\
\ 当没有SP操作符,但是有指数时,用最大的指数。\
\
这是一种特殊的Atomical对象,专门用来作为NFT的集合。容器名字可读,表示NFT和metadata的集合。容器名字以#开头。可以向容器里添加物品,也可以永久封住,不做任何改变。\ Collection的格式:大部分的field都是可选的。\ { "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/..." }, "website": { "v": "https://..." }, "discord": { "v": "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 ] } } }\ 如果你的集合没有attr等复杂结构,可以用下面的最简单形式:\ { "name": "Collection Name", "image": "atom:btc:dat:\<location of store-file data>/image.png", "items": { "0": { "id": "84718b469c40b1bcc7cb324b8e24e4e442f88cd913687ea2bc7b3e79d4fc4fdei0" }, "1": { "id": "1070d7c98304bf5ac9a5addceb13e0ce4e840641f82d71d84cebbdac427c1f4fi0" }, "9999": { "id": "14a0d7c98304bf5ac9a5addceb1de0ce4e840641f82d71d84cebbdac427c1fc3i0" } } }\ 可以通过以下命令在链上存储图片,并生成Collections.\ // 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\ 容器的一个常见用法是作为NFT集合的容器,进行DMINT(Decentralized Mint)。下面是DMINT的方法:\
DMINT包含四个步骤:\
项目方负责1-3, 要mint的用户最终把NFT mint出来。这样上传图片,验证NFT所需要消耗的gas fee,就都是由minter来承担。\ 整个过程挺常规的,不细说了。\
就是域名,did\ 一个人类可读的名字,关联到地址或者某个资源,可以转让。\ Realm Names必须以"+"开头。\ 命令:\ npm run cli mint-realm "myrealmname"\ 5.1 支付\ 可以在支持Atomical的钱包里,通过Realm names进行转账。\ +[inbox]@[realm_name] + 总是出现,表示这是个Atomical Realm inbox: 表示该realm_name下的收款账号。一个realm_name可以有多个收款账号 @ 分隔符,必须有 realm_name: 注册的realm_name 例如: +hello\@samplerealm +main\@samplerealm +support\@samplerealm\ 关于inbox的定义:\ { "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" } } } } }\ 5.2 子领域\ 应用思考:https://news.marsbit.co/20231118130551840807.html\ 拥有realm name, 就可以在它下面注册子名字,跟ENS的概念一样。\
\ 在Realm,或subRealm的结构里,在“subrealms"名字空间里定义规则。\ 定义规则:\ Step1:定义规则:\ 规则如何定义的描述:https://docs.atomicals.xyz/rules-subrealms-and-dmint\ 下面是一个例子:这个文件命名为rules.json\ { "subrealms": { "rules": [ { "p": "^[a-z0-9]{6,64}$", "bitworkc": "8888.8" }, { "p": ".*", "o": { "0014383fb23c5b1b40025b0e1dd3e310d6e1ee6d316e": { "v": 1000 } } } ] } }\ 上面规则文件表示两条规则:\
Step2:\ 提交rules上链,使其active。下面的 +mycoolrealm是之前申请的realm。\ yarn cli enable-subrealms +mycoolrealm file.json --satsbyte=100\ Mint subrealm\
就是不断换参数(nonce)生成新的交易hash,看交易hash的前几位是否达到了要求。\ 可以微调,例如要求前缀是 7777.10,这里7777就要求前面几位必须是7777,.后面的10表示第5位必须是第10个字符以上,即a,b,c,d,e,f\ 示例:\ https://mempool.space/testnet/tx/000005970d1d9ac218be8e6f78cfda667e4112a63f2fb0b7b000a8cb2d0dded0\ 他的难度就是00000为前缀,然后具体参数需要解码里面的P2TR 信息解码。比如61746f6d 用十六进制解码后则是 atom,646d74 解码后则是Operation 中的 dmt ,然后 payload 信息,需要使用 cbor方法解码,解出来是\ node cbor.js\ {\ "args": {\ "time": 1703318358,\ "nonce": 8083950,\ "bitworkc": "00000",\ "mint_ticker": "atom"\ }\
7.1 递归和引用\ { // 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 ... }\ Atomicals Universal Resource Name (URN) 定义是:\ atom:\<chain>:\<ref_type>:\<identifier>[$ or /[\<file>]]\ ref_type:"id", "container", "realm", and "dat"\ identifier,对不同ref_type来说,是不同的内容。如对dat来说,是reveal location of the immutable data,即不可变数据的地址。\ 其中:$表示mint时的data,/表示最新的data。注意对ref_type为dat的来说,无论用$还是/,返回内容都一样\ 例如:\
...\ 7.2 链上永久保存图片\ // 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" } }\ 可以用db8a761ed493627138c5733071558c4caa65912c5cba3e1061c02d6d7933461fi0来引用到这种图片,这就是它的atomical id
<!--EndFragment-->
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!