title: 81.区块链铭文 CreateTime: 2024-01-17 14:45:36 UpdateTime: 2024-06-25 12:51:48 CategoryName: BlockChain --- # 海外铭文 近期,币圈中铭文赛道的暴富神话引人瞩目.其中,BRC-20 ORDI在一个月内实现了数千倍的涨幅,而以太坊铭文也在两周内实现了300倍的涨幅.但是不断涌出的新概念,如递归铭文和ESC20等,层出不穷,给投资者带来了诸多困惑.目前铭文赛道仍处于起步阶段,总市值约为10亿美金,仍具有广阔的发展空间.那么,铭文是什么、有哪些协议和玩法呢? ## 铭文是什么 铭文这一概念最初是在2022年12月14日由Ordinals协议提出的.简单来说,Ordinals协议是一个为比特币最小单位(聪)进行编号的系统.由于BTC的总量为2100万枚,因此总共有2100万亿聪. 此外,Ordinals协议还能够将数据植入到聪里面,这个过程称为铭刻(inscribe),被植入的数据被称为铭文(inscription),因此携带铭文的聪产生了独特性和稀缺性.其实,这个协议是将比特币的最小单位变成了新的炒作目标.某种程度上,这也对比特币的价值进行了扩容,并且是铭刻. ![1.png](/public/upload/20240117144455729291922856284030.png) 铭刻在哪里?在比特币网络中,每笔交易上链时,除了基本的交易元数据之外,还允许用户提交一串自定义字符的交易备注,这与在银行转账时添加备注的原理相同.在早期的比特币网络中,这个交易备注字段主要是「op_return」字段,其容量相对较小.然而,在Taproot升级之后,该字段也可以是交易witness字段.witness字段的容量得到了显著提升,最多支持铭刻4M的内容,而不再是几十kb的限制.这为铭刻提供了发挥空间. ![2.png](/public/upload/20240117144503380627259449911921.png) 那么具体怎么铭刻呢?铭刻是通过将待铭刻的聪(聪为比特币的最小单位)发送到交易中来实现的.在每次比特币交易后,都会生成一个未使用的交易输出(UTXO),它类似于证明你余额的证书,并存储在比特币网络上. Ordinals 协议允许你将你的 NFT 信息附加到 UTXO 上,即将 NFT 雕刻在你的余额证书上.当然,为了实现雕刻,数据必须被编码成字符串形式. ![3.png](/public/upload/20240117144510844594776927599691.png) 我们做一个通俗易懂的类比.假设你有5元钱在口袋里,现在你想给我4元.按照UTXO的原则,你需要将这5元都放在桌面上,然后给我4元.这样,剩下的1元就成为你的余额.Ordinals协议则是利用这个过程,在你想给我4元的同时,将一个备注像刻章一样刻在那1元上.这样,那1元就有了特殊的"铭文". 从本质上讲,Ordinals协议实际上是借用了比特币链上的内存来记录自己的账本,从而形成了新的共识.这个新的共识既基于比特币的共识,保持了去中心化和加密原生的特点,又完成了自身的进化.这就是Ordinals协议的寄生虫生存法则,它巧妙地将比特币作为工具,让比特币成为数据存储的"硬盘"宿主,即数据可用层.而Ordinals协议本身则是真正的共识层,完成了自身NFT的破茧而出. ## 铭文是不是NFT 这时候有人就会疑惑了,铭文到底是NFT(非同质化代币),还是FT(同质化代币)?首先铭文就是NFT! 这两张均为比特币铭文,左侧的聪上刻有一张 punk 图像,而右侧的聪上刻有 "Well" 这四个字符.原本,它们都是相同的比特币聪,只是挖出时间先后不同.一聪等于一聪,这是同质化代币的特性.然而,经过铭刻后,这两枚聪变得独特,具有非同质化特性. ![4.png](/public/upload/20240117144517344490345510184541.png) 那么,如果在其他聪上也刻上 punk 图像,它的价值是否会翻倍.这并不行,除非您是第一个部署和刻上punk的发行者.这与传统的NFT类似,铭文的共识也是 ```First is first```.如果有多个人想要在多个聪上刻同一张图片,他们当然可以这样做.但是,只有第一个铭文是有价值的.这时,时间戳就起到了关键作用,可以判断谁的铭文是第一个. 综上所述,铭文就是NFT,```First is first```.与以太坊上的NFT相比,更加去中心化并遵循原始原则,更具吸引力. ## 铭文如何操作 铭文的铸造和部署通常需要在链上进行操作,以一个铭文为例:BRC-20 第二大市值的meme token——pepe,一个悲伤的小青蛙,这些操作可以通过 ordinals 协议来实现. ![7.png](/public/upload/20240117144526083567904519241598.png) 「p」:定义协议类型.BRC-20 代表使用 BRC-20 协议处理,帮助其他系统识别与处理 BRC-20 事件.除了 BRC-20 之外,还有诸如 .sats 域名协议、ORC-20 协议等其他协议. 「op」:定义事件类型.例如部署(Deploy)、铸造(Mint)或转账(Transfer). 「tick」:定义 BRC-20 Token 的名称,由 4 个字母组成. 「max」:定义token 的最大供应量. 「lim」:定义用户铸造一个铭文最多可以获取的 BRC-20 Token 数量.在 pepe 的设置中,这个数量是 1000,因此铸造单个铭文最多可获取 1000 个 pepe. 在 ordinals 上,您可以使用这个格式进行操作.这是最原始的操作方式,而现在各种应用协议和 AI 技术的发展,使得部署、铸造、转账等操作变得非常简单,无需亲自进行刻写. 更为重要的是,Ordinals 成为了铭文赛道的源起,将铭文的星星之火点燃至每一条公链.根据 Galaxy 的研究报告,到 2025 年,Ordinals NFT 的市场规模将达到 45 亿美元.因此,铭文赛道的未来充满期待. # 国内符文 海外铭文发展如火如荼,国内应该如何实现铭文呢?盛见科技根据国内法律法规要求,基于XuperOS(百度开放网络),开发了适合国内的铭文协议--符文. 符文有以下特点: - ```First is first```,铭文以第一个上链为准 - 无许可,任何用户都可以进行铭文,项目方也无控制权限 - 不是转账交易,符合国情和监管需求 - 不依赖合约,更加去中心化 - 用户掌握私钥,无中心化风险 ## 设计思路 XuperOS调用合约交易时,可以附加```desc```描述字段,将符文内容通过交易的```desc```字段写入区块链,监听区块链的所有交易信息,读取符合符文协议的```desc```内容,根据```First is first```原则,对交易进行排序,标记第一个有效符文,并提供查询核验服务. ## 符文协议 ```json { "p": "RUNE", //协议头 "tick": "XUPER", //名称,由4--20个字母组成,不可重复,以第一个发布的有效. 内置TXT(文本,max=-1,lim=1),域名是特殊文本 "nonce": "20240116175905000000326660616000", //nonce 随机值 "op": "mint", //定义事件类型.例如部署(deploy)、铸造(mint)或转移(transfer) "max": 21000000, //部署时的发行总量, -1为不限制 "lim": 1,//每次mint的限制数量, -1为不限制 "amt": 10,//转移(transfer)的数量 "from": "", //调用合约,支付gas的address "to": "", //接收地址,可以是自己,也可以是代打的用户地址 "data":"" //mint文本类型的数据,或当lim=1的资产(例如文本或ERC-721)交易时,是其mint hash. } ``` 符文协议支持以下常见场景: ## 文本 部署(deploy)TXT类型,协议已内置部署 ```json { "p": "RUNE", "tick": "TXT", "nonce": "TXT", "op": "deploy", "max": -1, "lim": 1 } ``` 铸造文本内容,例如 "hello world": ```json { "p": "RUNE", "tick": "TXT", "nonce": "20240116175905000000326660616001", "op": "mint", "amt": 1, "from": "QpAaedypd4ds4bfDyYeYie8sMen8886hW", "to": "TAM2XDL6NKWdRRK4tpX4j3cuhf5Szs2iV", "data":"hello world" } ``` 转移文本: ```json { "p": "RUNE", "tick": "TXT", "nonce": "20240116175905000000326660616002", "op": "transfer", "amt": 1, "from": "TAM2XDL6NKWdRRK4tpX4j3cuhf5Szs2iV", "to": "QpAaedypd4ds4bfDyYeYie8sMen8886hW", "data":"b98dad0f86541b6c2535cce59101c9440385694c80d6c747634d97a8ba7ebea3" } ``` 域名属于特殊的文本,内容符合一级域名格式,例如 ```abc.agi``` ## ERC-721 部署(deploy)自己的721藏品,例如 ```SJCP```,总量20000个,每次只能铸造1个 ```json { "p": "RUNE", "tick": "SJCP", "nonce": "20240116175905000000326660616003", "op": "deploy", "max": 20000, "lim": 1 } ``` 铸造藏品: ```json { "p": "RUNE", "tick": "SJCP", "nonce": "20240116175905000000326660616004", "op": "mint", "amt": 1, "from": "QpAaedypd4ds4bfDyYeYie8sMen8886hW", "to": "TAM2XDL6NKWdRRK4tpX4j3cuhf5Szs2iV" } ``` 转移藏品: ```json { "p": "RUNE", "tick": "SJCP", "nonce": "20240116175905000000326660616005", "op": "transfer", "amt": 1, "from": "TAM2XDL6NKWdRRK4tpX4j3cuhf5Szs2iV", "to": "QpAaedypd4ds4bfDyYeYie8sMen8886hW", "data": "b98dad0f86541b6c2535cce59101c9440385694c80d6c747634d97a8ba7ebea3" } ``` ## ERC-1155 部署(deploy)自己的1155藏品,例如 ```SJCP```,总量20000个,每次只能铸造100个 ```json { "p": "RUNE", "tick": "SJCP", "nonce": "20240116175905000000326660616006", "op": "deploy", "max": 20000, "lim": 100 } ``` 铸造藏品: ```json { "p": "RUNE", "tick": "SJCP", "nonce": "20240116175905000000326660616007", "op": "mint", "amt": 100, "from": "QpAaedypd4ds4bfDyYeYie8sMen8886hW", "to": "TAM2XDL6NKWdRRK4tpX4j3cuhf5Szs2iV" } ``` 转移藏品: ```json { "p": "RUNE", "tick": "SJCP", "nonce": "20240116175905000000326660616008", "op": "transfer", "amt": 10, "from": "TAM2XDL6NKWdRRK4tpX4j3cuhf5Szs2iV", "to": "QpAaedypd4ds4bfDyYeYie8sMen8886hW" } ``` ## 符文合约 符文协议是和合约无关性的,只要交易的```desc```内容,所以任何合约都可以使用,即便链平台封杀了某个合约,也可以发布新的合约. 以下是合约的例子,也可以根据自己的需求编写合约. ```C++ #include "xchain/xchain.h" struct Rune : public xchain::Contract {}; DEFINE_METHOD(Rune, initialize) { xchain::Context* ctx = self.context(); ctx->ok("initialize succeed"); } DEFINE_METHOD(Rune, savekey) { xchain::Context* ctx = self.context(); const std::string& key = ctx->arg("key"); char buf[32]; snprintf(buf, 32, "%d", 1); ctx->put_object(key, buf); ctx->ok(buf); } DEFINE_METHOD(Rune, get) { xchain::Context* ctx = self.context(); const std::string& key = ctx->arg("key"); std::string value; if (ctx->get_object(key, &value)) { // 检查value是否为空 if (value.empty()) { ctx->error("key not found or the value is empty"); } else { ctx->ok(value); } } else { ctx->error("key not found or failed to get the object"); } } ```