这里比较难理解的部分在于,由于UTXO实际上包含很多个聪,那么这个UTXO中的每一个聪看起来都一样,怎么给他们排序呢?这个实际上是第二条规则决定的,举一个简单的例子吧:
我先假设BTC的最小分割单位是1,总共出了10个区块,每个区块的出块奖励是10个BTC,即总量是100个。我们直接可以给这100个BTC赋予一个(0-99)的序号。如果没有任何转账情况,那我们只知道第一个区块的10个BTC编号是(0-9),第二个区块的10个BTC编号是(10-19),一直到第十个区块的10个BTC编号是(90-99)。这其中因为没有任何花费,也就没有任何output,我们就只能给每10个BTC赋予一个编号范围。
假设在第二个区块中加入两个支出(output),一个是3BTC,一个是找零的7BTC,对应于给别人转账了3个BTC,再给自己找零7个BTC。此时在区块的交易列表中,假设给自己找零的7个BTC排名第一(对应的编号是10-16),给别人的3BTC排第二(对应的编号是17-19)。这就通过对output的的转移确认了某个UTXO所包含sats的顺序集合。
注意是每一个sat不是UTXO!由于UTXO是不可再分的最小交易单元,因此sat只能存在于UTXO中,且UTXO包含了一定范围的sats,且只能在花费某一UTXO后产生新的输出中对sats编号进行拆分。
至于用什么方式来表达这个编号,Ordinal支持多种形式,比如上面提到的整数法,其他还有十进制小数法,度数法,百分比法,纯字母命名法。
sats有了统一的序号之后,就可以考虑铭刻了(inscription)了。我们在上文中提到,可以在见证数据区域4M大小的空间上传任意数据类型的文件,不管是文本,还是图片和视频,上传之后,文件会自动转为16进制存放在的taproot脚本区。所以是,1个UTXO,对应1个Taproot脚本区,而这1个UTXO会同时包含很多sats(整体是一个sats序列集合,为了防止粉尘攻击,限制单个UTXO中的比特币数量不可少于546聪。)。Ordinal协议为了方便记录,人为地规定使用这个序列集合的第一个sat编号来代表绑定关系(白皮书原话是第一个output的第一个聪的编号),比如包含(17-19)号sats的UTXO就直接用17号来代替这个集合和铭刻内容绑定。
OrdinalNFT很显然就是把各种文件上传到隔离见证区的脚本中并与之绑定一个sats序列集合,从而实现了在BTC链上发行NFT资产。但是这里还有一个问题,隔离见证区的脚本即包含input的解锁脚本,又包含output的锁定脚本,那么内容是放在哪个脚本中呢?正确的答案是两者都有。这里不得不提到区块链技术中的commit-reveal机制。
区块链中的Commit-Reveal机制是一种用于确保信息公平和透明处理的协议。这个机制通常用在需要提交隐藏信息(如投票或竞标),然后在以后的某个时间点揭示这些信息的场景中。Commit-Reveal机制分为两个阶段:提交(Commit)阶段和揭示(Reveal)阶段。
1.提交(Commit)阶段:在这个阶段,用户提交他们的信息(如投票选择或竞标价格),但这个信息是加密的。通常,用户会生成这个信息的哈希值(即信息的加密摘要),然后将这个哈希值发送到区块链上。由于哈希函数的特性,它们可以生成一个独特的输出(哈希值),这个输出对于原始信息来说是不可逆的。这意味着无法从哈希值推断出原始信息。这个过程确保了信息在提交时的保密性。
2.揭示(Reveal)阶段:在一个预定的以后时间,用户必须揭示他们的原始信息,并证明它与之前提交的哈希值相匹配。这通常是通过提交原始信息以及用于生成哈希值的任何附加数据(如随机数或盐)来完成的。网络然后验证这个原始信息的哈希值是否与之前提交的哈希值相同。如果匹配,则原始信息被接受为有效。
我们前面讲过,铭刻的内容是需要和UTXO包含的sats序列集合绑定一起,UTXO在区块中是一个output,所以必须附着在output的锁定脚本中。但是BTC的全节点需要在本地维护和传输全网络所有的UTXO集合。想象一下,要是有1万个4M的视频文件直接上传到1万个UTXO的锁定脚本,那所有的全节点需要有超高的存储空间和超快的网速,可以说整个链直接就崩了。因此,唯一的解决方法是把内容放到input中的解锁脚本,然后再让这个内容指向到另一个output。
所以说Ordinal资产的铸造是需要分为两步(钱包是把这两步进行合并处理了,在构造交易时,同时构造commit-reveal这个父子交易,用户体验上会感觉只有一个步骤并且节省了gas费)。
在铸造阶段,用户首先需要上传某个文件的哈希值到commit交易中(自己A地址给自己B地址转账)的UTXO中的锁定脚本,因为是哈希值,所以不占用过多全节点的UTXO数据库空间。其次,用户再构造一个新的交易(自己B地址给自己A地址转账),称之为reveal交易,此时的input需要使用上一步commit交易中含有文件哈希值的那个UTXO,并且该input的解锁脚本必须包含原始铭刻文件。用白皮书中的原话描述,就是首先,在commit中,创建一个提交到包含铭文内容的脚本的taproot输出。其次,在reveal交易中,使用commit交易产生的输出,来显示链上的铭文内容。
在转移阶段,OrdinalNFT和BRC20稍有不同,OrdinalNFT因为是整体转移,只需要把绑定某个UTXO的NFT直接转给接收者即可,类似于普通的BTC转账。但BRC20因为牵扯到自定义数额转账,同样分为两步,第一步叫铭刻交易(InscribeTRANSFER),第二步叫转账交易(TransferTRANSFER),第一步的铭刻交易实际类似于一个OrdinalNFT的铸造过程,暗含了commit-reveral父子交易对,第二步转账交易类似于一个普通的OrdinalNFT的转账,把绑定某个UTXO的BRC20资产直接转给接收者。有的钱包会把这三个交易(父子孙三代交易)同时构建,从而节省时间和gas。
总结来说,commit交易用来把铭刻内容(原始内容的哈希值)和带序号的sats(UTXO)绑定,reveal交易用来把内容显示出来(原始内容)。这个父子交易对共同完成了对于NFT的铸造。
上面关于铸造的技术讨论还没完结,因为有人会好奇,reveal交易到底是如何验证commit交易中的铭文信息呢?为啥构造交易的时候需要自己的AB两个地址互相转账呢?打铭文的时候也没看到需要准备两个钱包啊。这里就需要讲到Taproot的重大升级之一P2TR了。
P2TR(Pay-to-Taproot)是由Taproot升级引入的一种新类型的比特币交易。P2TR交易通过允许用户使用单一公钥或更复杂的脚本(如多重签名钱包或智能合约)来花费比特币,实现了更高的隐私和灵活性。这是通过使用MerkleizedAbstractSyntaxTrees(MAST)和Schnorr签名来实现的,这些技术使得可以在单个交易中有效地编码多种花费条件。
创建花费条件
要创建一个P2TR交易,用户首先定义一个花费条件,例如单一公钥或更复杂的脚本,指定了花费比特币的要求(例如,多重签名钱包或智能合约)。
生成Taproot输出
然后,用户生成一个Taproot输出,其中包括一个单一公钥(公钥代表花费条件)。这个公钥是从用户的公钥和脚本的哈希的组合中派生出来的,使用一种称为tweaking的过程。这确保了输出看起来像一个标准的公钥,使其在区块链上与其他交易难以区分。
花费比特币
当用户想要花费比特币时,他们可以使用他们的单一公钥(如果花费条件被满足),或者透露原始脚本并提供必要的签名或数据以满足花费条件。这是通过使用Tapscript来完成的,它允许更高效和灵活地执行花费条件。
验证交易
矿工和节点随后通过检查所提供的Schnorr签名和数据与花费条件进行验证交易。如果条件被满足,交易被视为有效,比特币可以被花费。
增强的隐私和灵活性
因为P2TR交易只在花费比特币时透露必要的花费条件,所以它们保持了高水平的隐私。此外,使用MAST和Schnorr签名使得能够高效地编码多个花费条件,允许更复杂和灵活的交易,而不会增加交易的总体大小。
以上就是Ordinal铭文协议的原理与技术细节讨论的全部内容,望能这篇Ordinal铭文协议的原理与技术细节讨论可以帮助您解决问题,能够解决大家的实际问题是非常好学习网一直努力的方向和目标。