# OP_CAT带给BTC的可能性-以CAT20为例 By: **@cyberorange** (https://x.com/xcshuan) [TOC] ## 1.背景 相比之前,近一年BTC生态得到了很大的发展,涌现了诸多基于索引器或者基于CSV(客户端验证)的资产协议,如BRC20, Runes,Atomicals,RGB,RGB++,Taproot Assets等等,这些协议提升了BTC的链上活跃度,但是都只是用BTC作为 DA 或者交易排序服务来抗双花,而并非真的由BTC验证其操作的有效性。 那么有没有可能使用 BTC 验证计算呢?诸多设计被提了出来,如BitVM和BitVM2,旨在使用BTC的脚本能力去验证任意计算,但我们不得不面对这些方案实现的复杂性,使用成本,以及诸多使用体验问题。 但另一方面,一些极客声称,只需简单地在BTC上重新启用一个被长久封印地操作码-`OP_CAT`,我们就可以在BTC上拥有非常多我们梦寐以求的特性,如`交易内省`,`带状态的UTXO`,`Covenants 乃至 Recursive Covenants`,甚至验证任意计算,这一简单的路径果真能向我们允诺如此之大的可能性吗? 本文将简述通达这一目标的一些方案,同时将这些方案与一个 Extended UTXO 模型-[Cell模型](https://medium.com/nervosnetwork/https-medium-com-nervosnetwork-cell-model-7323fca57571)进行对比,因为 Cell 模型是一个支持交易内省,任意的Covenants,并且可以存储任意状态的UTXO模型,通过理解 Cell 模型,将有助于理解在 BTC 上实现这一切功能的目标。 探索是否仅通过 `OP_CAT`,BTC的UTXO模型就能取得和扩展UTXO模型一样的能力,过程中,你将感受到一个非常简单的指令居然可以产生这么多可能性,颇有点一生二、二生三、三生万物的味道。 ## 2.UTXO 与 Extented UTXO(Cell) ### 2.1 UTXO与Cell UTXO,即未花费的交易输出,是BTC首先使用的一种链上状态表达模型,它具有很多有点,比如 + 并行执行 + 链下确定性 + 链上验证,链下计算 + 易于实现轻节点; 在 BTC 的 UTXO 中,本质只有两项,即: 1. Value,代表该 UTXO 中包含的 BTC 数量。 2. ScriptPubkey,代表该UTXO的解锁条件。 可以说,BTC 提供的最基础的功能只有保存BTC,以及转移BTC,BTC并没有提供更多的功能,虽然 Script 提供了一定程度的编程性。 而在扩展UTXO模型 Cell 中,存在以下项: ```rust pub struct CellOutput { pub capacity: u64, pub data: Vec<u8>, pub lock: Script, pub type_: Option<Script>, } ``` 其中 + `Capacity`:代表了 Cell 中主币的数量,同时也约束了该Cell占据的状态空间大小,即这个Cell占据的链上状态空间,不能超过 Capacity 所允许的值。 + `data`: data中可以存储任意状态,如代币数量,NFT数据,合约状态数据等等。 + `lock script`:与 BTC UTXO 中的 ScriptPubkey 类似,代表了该 Cell 的解锁条件,lock 仅在该 Cell 消费时执行。 + `type script`:可选项,如果不存在 type,说明这就是一个简单的Cell,而如果存在 type,这个 Cell 的意义就被 type 脚本所约束,比如代表某种代币,某个合约等,type脚本在 Cell 消费,以及 Cell 被创建时,都会执行。 Cell模型作为一种 Extended UTXO模型,最主要的扩展有以下几点: 1. 增加了 data,一个 Cell 可以携带任意的链上状态。 2. 增加了 type,从而可以实现 Recursive Covenants,因为 type 不仅验证Cell消费时交易是否合法,也在创建Cell时验证了Cell的生成是否合法,所以对 Cell 的约束可以永远传递下去。 3. 使用基于寄存器的RISC-V执行脚本,保证了图灵完备。 4. 实现了诸多用于交易内省的 syscall,如 `load_input(source, index)`, `load_output(source, index)`,`load_witness(source, index)`,`load_cell_dep(source, index)`。 5. 使用了两个脚本约束一个 Cell,从而将所有权控制与状态意义表达解耦。 由此,我们可以得出结论,Cell模型作为一种 Extended UTXO 模型,可以实现 `交易内省`,`Recursive Covenants`,`携带任意状态`,`图灵完备`。 下面对一些术语进行定义: ### 2.2 交易内省 对于 UTXO 模型来说,交易内省即为交易的验证过程中,可以读取交易本身的值。 在BTC支持的op_code中,也没有op能在脚本中获取到当前交易的输入,输出等信息,仅有 `OP_CHECKSEQUENCEVERIFY`,`OP_CHECKLOCKTIMEVERIFY `,`OP_CHECKSIG` 可以获取极少一部分交易的内省信息,所以 BTC 脚本层面,是不支持完全的交易内省的。 交易内省可以让脚本在执行过程中,读取当前交易的输入,输出的一些信息,从而可以根据这些信息决定是否要解锁交易。 Cell模型通过内置各种交易内省的 syscall,从而实现了脚本执行的交易内省。 ### 2.3 Covenants 与 Recursive Covenants Covenants 在 BTC 生态并不是一个很精确的术语,因为对于不同的 `Covenants` 方案,其所能实现的功能并不一样。但是可以进行一个简单的定义: + 一个 UTXO 模型支持 `Covenants` 意味着,一个UTXO的解锁脚本可以约束交易输出中,BTC输出地数量以及输出地址。 + 例如约束一个UTXO两个解锁路径,路径1,地址 A 最多获得30%,地址B最多获得70%,剩下的转给地址C;路径2,地址C获得全部。 当交易内省能力开启后,`Covenants` 可以简单地实现。 另一个更强地能力是,`Recursive Covenants`,我们也可以给它下一个定义: + 一个 UTXO 模型支持 `Recursive Covenants` 意味着,一个UTXO的解锁脚本可以约束交易输出中,BTC输出地数量以及输出地址,这个交易地输出地址应该可以继续保持这个约束。 + 例如约束一个UTXO由两个解锁路径,路径1,地址 A 最多获得30%,地址B最多获得70%,剩下的转给继续转给相同的 Covenants 地址;路径2,地址C获得全部。 当交易内省能力开启后,`Recursive Covenants` 也可以简单地实现。 同时,定义一种新的 Covenants,`Retrospective Covenants`,即回溯Covenants,`Retrospective Covenants` 是一种比`Recursive Covenants` 更强的约束: + 一个 UTXO 模型支持 `Retrospective Covenants` 意味着,一个UTXO的解锁脚本可以约束交易输出中,BTC输出地数量以及输出地址,这个交易地输出地址应该可以继续保持这个约束,同时可以保证其生成是由约束本身限制。 + BTC链上资产发行可以作为 `Retrospective Covenants` 的例子,根据铸造规则,如果给一个 UTXO 绑定了 1000 Coin,那么一个很显然的需求是,后续该UTXO消费,其所能转移的Coin永远不会大于1000,以此类推。例如约束一个UTXO绑定了一个染色币A,则任意染色币A的UTXO都可以追溯到染色币A的合法发行,且整个过程由BTC脚本验证。 Cell模型使用 type script,在创建和生成的时候都执行脚本验证,从而实现了 `Retrospective Covenants`。而在BTC上,则需要更复杂的机制来实现。 ### 2.4 Stateful UTXO 一个 UTXO 如果是有状态的,意味着该 UTXO 除了携带 BTC 余额之外,还可以携带任意的数据作为状态,并且该状态的可以借由Covenant的约束,在UTXO中跨交易传递。 当我们可以在UTXO里放置经过验证的状态后,可以做的事就很多了: + 比如说在状态里放置状态根,然后使用脚本去验证状态转换的正确性,由此可以得到一个 Validium。 + 比如在状态里放置另一个区块链区块头组成的 Merkle Mountain Range根,并使用脚本验证区块头状态转换的正确性,则我们可以得到一个双向SPV跨链桥。 Cell模型直接在Cell中的Data位置放置任意状态数据。 ## 3.OP_CAT 与UTXO的链上验证范式 前面论述了一些UTXO的扩展方向,那么 `OP_CAT` 是什么?为什么它可以帮助实现这些扩展方向? `OP_CAT` 是一个非常简单的操作码,其功能为从栈中取两个值,拼接起来再压入栈。仅凭这么一个简单的操作码,就能让原本受限的UTXO模型拥有前面那些好处吗?从某种意义上来说是的,即使我们还需要更多细致的工作,但是理论上已经完全可行了。 另外需要说明的一点,不同于账户模型,UTXO更倾向于链下计算,链上验证的范式,任何指令码可以正用,也可以反用,比如说 `OP_CAT`,可以将两个值拼接,也可以用来证明一个值拆分开是另两个值。 某种意义上,写UTXO脚本有点像写 zk 电路,重要的是,约束交易的输入到输出的转换是符合约束的,而脚本验证的是这个约束是否成立。 而以EVM为代表的账户模型,更侧重的是链上计算,即给定一个输入,经由某些合约函数处理,会得到一个输出。 ### 3.1 基于 OP_CAT 的交易内省 我们知道,在BTC支持的op_code中,没有op能在脚本中获取到当前交易的输入,输出等信息,只能通过 `OP_CHECKSEQUENCEVERIFY`,`OP_CHECKLOCKTIMEVERIFY `,`OP_CHECKSIG `获取极少一部分交易的内省信息,所以 BTC脚本层面,是不支持完全交易内省的。 其中 `OP_CHECKSIG` 的功能为:从栈中读取两个值,一个签名,一个公钥,然后使用签名里所指示 sigHashType 以及交易本身计算出哈希,然后使用哈希,公钥,签名来验证签名的正确性。对于`Taproot`,以 `SIG_HASH_ALL `为例,其 `SIG_HASH` 计算方式如下: ``` sig_msg = ( sighash_epoch + sighash_type + version + locktime + sha_prevouts + sha_amounts + sha_scriptpubkeys + sha_sequences + sha_outputs + spend_type + index_of_this_input # Now includes the index of the input being signed ) # Taproot uses tagged hashes for the sighash tag_hash = sha256("TapSighash".encode()) sighash = sha256(tag_hash + tag_hash + sig_msg) print("Taproot sighash digest: ", sighash.hex()) ``` 可以看到,`OP_CHECKSIG` 其实是以一种曲折的方式访问到了 SigHash,同时也就绑定了交易相关的属性,那么是否有可能利用这一点,读取到交易的完整内容呢? 为了说明这个问题,首先需要理解BTC脚本中所使用的签名算法,由于目前 `OP_CAT` 的提案是在 `Tapscript` 中添加,所以仅介绍 `Schnorr` 签名。 Schnorr签名算法的流程如下: > 假设用户私钥为 $x$, 则公钥为 $P=x\cdot G$。 > > 生成签名流程如下: > > 1. 假设待签名消息为 $m$ > 2. 用户随机选择一个 nonce $r$,并计算 $R = r\cdot G$ > 3. 计算 $e=H(R|P|m)$,$s=r+k\cdot e$ > 4. 则签名为 (R, s) > > 验证签名流程如下: > > 1. 计算 $e=H(R|P|m)$。 > 2. 计算 $A=R+e\cdot P$,$B=s\cdot G$ > 3. 验证 $A=B$ 是否成立 理论上,只要我们可以重新计算出签名,并通过`OP_CHECKSIG`验证,即可保证交易正确性,一种可行的流程如下: 1. 将 tx 放置在栈中。 2. 使用 `OP_SHA256`以及其他操作码 计算出 `sigHash`。 3. 在脚本中使用私钥构造出签名。 4. 在栈中放置公钥。 5. 使用 `OP_CHECKSIG` 检查生成的签名是否正确。 6. 如果签名验证成功,则证明根据 `tx` 生成的 `sigHash` 与当前交易生成的一样,则栈中的tx即为当前tx,由此实现了交易内省。 上面这个流程很大程度依赖 `OP_CAT`,为了使用交易中的某些项(比如输入金额或者输出),需要先将这些项拆开放置在栈中以便使用,然后使用 `OP_CAT `将所有的值拼接起来,再计算哈希,并计算签名。 另一个问题是,如何在脚本中实现 Schnorr 签名?要知道 Schnorr 签名涉及标量乘和椭圆曲线点乘,由于 BTC不能使用 `OP_MUL`,在BTC脚本计算乘法是很困难的。 但是考虑到我们只是需要验证两边哈希的一致性,而非真的在这里使用签名来保障资产安全,那么签名所用私钥和nonce都可以用最简单的值,如 `x=1, r=1`,那么可以得出公钥 $P=1\cdot G=G$。 那么签名计算如下: 1. 假设交易的 sigHash 为 m。 2. 取nonce $r=1$,得 $R=1\cdot G=G$。 3. 计算 $e=H(R|P|m)=+H(G|G|m)$,$s=1+1\cdot e=1+H(R|P|m)=1+H(G|G|m)$ 则最后签名为:$R=G, s=1+H(G|G|m)$,整个过程只用到了哈希,并且公钥和R都为$G$,可以直接写在脚本里。 通过这个方法,我们可以将 tx 的各项放置在脚本中,然后使用 `OP_CAT `拼接,再计算出 `SIG_HASH`,再用 `SIG_HASH` 计算出 `e`,再加一,最后使用 `OP_CHECKSIG` 验证签名正确性。 具体脚本实现还需要用一些技巧,由于 BTC 脚本不支持 256bit 的运算,可以使用技巧将其转换为拼接问题,然后使用 `OP_CAT` 解决。 + 首先,通过 `交易研磨` 保证 `s` 的最后一个字节一定为 `0x01`。 + 然后在栈中放置 `s` 去掉最后一字节的值。 + 那么对 `s` 使用 `OP_CAT` 拼接 `0x01`,就得到了 s 可以用来签名 + 对 `s` 使用 `OP_CAT` 拼接 `0x00` 就得到了 `s-1` 即 `e` ,可以用来比较 `e` 的值是否正确。 由于只限定了 256 种可能的一种,所以这个计算不算很困难,通过调整timelock等地方的值就可以不断尝试即可,类似`PoW`。 经过对栈中交易的验证,交易中的各种值如输入的数量,输入的脚本等待,在脚本执行过程中都可以使用,由此,就实现了交易内省。 + 通过 `sha_prevouts`,可以获得输入的 `Outpoint` + 通过 `sha_amounts` 可以获取输入的BTC数量 + 通过 `sha_scriptpubkeys` 可以获取输入的 `scriptPubkey` + 通过 `sha_outputs` 可以获取输出 通过交易内省,可以实现简单的 `Covenants`。 ### 3.2 基于 OP_CAT 的各种 Covenants 首先是 `Covenants`,这在支持交易内省以后是很容易实现的,脚本可以在栈中使用OP_IF以及OP_CAT等操作码,拼接出期待的 `outputs`,然后再将拼接出的 `outputs` 与上一节的交易内省获取的 `sha_outputs` 对比,从而达到约束输出的地址和数额的效果。 对于 `Recursive Covenants`,通过交易内省也可以简单构造,毕竟交易内省可以获取解锁的地址,自然可以约束解锁的地址与输出的地址保持一致,从而保证约束的延续性。 那么,如何实现 `Retrospective Covenants` 呢?单纯的交易内省并不能保证这一点,因为当前脚本解锁的时候,无法检查输出的下一笔如何解锁,当前也无法知道上一笔交易是如何解锁的。 ![image](https://hackmd.io/_uploads/r1WrtyiAR.png) 但其实,实现交易内省的技巧还可以再用一次,通过上一节说的技巧,可以在脚本中读取 `sha_prevouts`,并获取对应的 `Outpoint`,而 `Outpoint` 中拥有上一笔交易的 `TxID`,那么只要将上一个交易也放到栈中,并验证其 txId 与 Outpoint 中的一致,就可以验证 `preTx` 的正确性,然后验证上一笔交易是否被当前一样的 Script 所约束,由此,`Retrospective Covenants` 也是一件可以实现的功能,同理,还可以回溯到 `prePreTx`,其为 `preTx` 的 `preTx` 以验证UTXO来源的合法性,由此可以获取任意回溯交易的任意项。 ### 3.3 UTXO绑定状态 在解决了 `Recursive Covenants` 的问题后,接下来的问题是,如何将状态绑定到一个UTXO上呢? 对于 `Taproot` 之前的 `Script`,如果可以实现交易内省,这其实不是一个很困难的问题,因为非 `Taproot` 的 Script 在解锁时,会将所有的Script明文都放置在 Witness 中,那么其实可以直接使用 Script 存放状态数据,将Data放置在Script数据的末尾,如下图所示: ![image](https://hackmd.io/_uploads/r1J8FJo00.png) 每当执行完一笔交易,Script就需要检查输出中的Script,其Data位置的值是否已更新成了计算后的值。 但是对于 `Taproot` 形式的 `Script` 执行,上述方案就不能简单实施了,因为 `Taproot` 的脚本在使用时,并不会在 `Witness` 里 公布所有的值,而是通过 `ControlBlock` 定位到 `Taptree` 中的一个 `Script` ,如下图,可能的解锁路径有 A,B,C 三条,同时使用 `Internal Private Key` 直接提供签名也可以解锁。由于没有公布 `Script`,像前面所说的在 Script 内保留一部分位置存储状态数据就难以实施了。 ![image](https://hackmd.io/_uploads/Byj8YkiRA.png) 另外一种思路是使用交易的 `op_return `用来存储状态数据,`op_return` 是 BTC 中的一个特殊交易输出,可以用来放置 80 字节数据,但是不能再被解锁。 ![image](https://hackmd.io/_uploads/HJ5PYJs0C.png) 每一次脚本解锁,`Script` 在验证状态转换时,都可以通过前面说的交易内省和 `Retrospective Covenants` 等技巧,读取当前交易的`op_return`输出值,以及上一笔交易的 `op_return` 输出值,并用这两个值作为 UTXO 绑定的状态值,然后验证状态转换的正确性。 可以在 `op_return ` 的数据中放置代币余额,状态树的树根等各种数据。 ## 4.以CAT20为例 CAT20是一个利用了上述特性的基于OP_CAT的FT资产协议,相比BRC20和Runes,其不需要索引器,完全由BTC保障资产安全,也不会出现烧币等等情况。其代码可见于:[CATProtocol/cat-token-box: A monorepo for packages implementing CAT protocol ](https://github.com/CATProtocol/cat-token-box). 为了理解 CAT20 的设计,先定义以下术语: + curTx:当前正在执行脚本验证的交易。 + parentTx:当前交易的输入所在的历史交易。 + grandparentTx:parentTx的输入所在的历史交易 + CAT20State:对于代币UTXO,包含UTXO绑定的amount,以及UTXO所属的地址;对于 Minter UTXO,应该包含该 minter 能 mint 的数量,其存放位置为 op_return 输出。 + id:UTXO绑定代币的id,以创世交易绑定元信息的outpoint为TokenID,即 `genesisTxid + vout`。 + id 应该嵌入 Minter 的 script,以区分不同的 Minter,Minter 的Script应嵌入 Token 的Script,以区分不同的 Token。 ![image](https://hackmd.io/_uploads/SJNotJi00.png) ### 4.1 Deploy ![image](https://hackmd.io/_uploads/H10oYJoAA.png) 构造一个交易,其中一个输出的 witness 写入 token 的元数据,如 name, symbol, decimals等等,该交易被称为 genesis tx。 解锁 genesisTx 的绑定了 token 元数据的 UTXO,构造一笔交易: + 第一个输出为 op_return,使用前述的 UTXO 绑定状态的模式,绑定 minter 的状态。 + 所有非 op_return 输出都是 minter UTXO,代表了一定数量的代币铸造权限。 Depoly 流程只有两笔交易,故无法触发 `Retrospective Covenant` 的检查。 ### 4.2 Mint ![image](https://hackmd.io/_uploads/S18hF1sRA.png) Mint 代币有两种可能性: + 当前 mint 代币使用的 Minter 是直接从 genesis tx 生成的。 + 当前 mint 代币使用的 Minter 是消费另一个 Minter 生成的。 那么针对 Mint,应具有如下约束: + 为保证代币数额平衡,检查 `curTx.Minter.Amount + curTx.Token.Amount == parentTx.Minter.Amount` + 检查代币为同 id 代币,`curTx.Minter.id == parentTx.Minter.id`, `curTx.Token.MinterScript == curTx.Minter.Script` + 检查代币来源合法,以下两个检查必须有一个成立: + `parentTx.Minter.Script == grandParentTx.Minter.Script` + `parentTx.Minter.id == tdid(grandParentTx) | vout` ### 4.3 Transfer ![image](https://hackmd.io/_uploads/B1W6FyiR0.png) Transfer主要也是检查两点,即数额平衡,Owner授权,以及代币来源合法,对于 Transfer 应存在以下约束。 + 为保证代币数额平衡,检查 `curTx.Token.Amount == parentTx.Token.Amount` + 为保证Owner提供了授权,检查 `checkSig(curTx.Token.Owner, signature)` + 为保证代币来源合法,首先检查前后一致`curTx.Token.Script == parentTx.Token.Script`,然后需要保证以下两个检查必须有一个成立: + `grandParentTx.Script == parentTx.Token.MinterScript`,即来源为 Minter。 + `grandParentTx.Script == parentTx.Token.Script`,即来源为另一笔 Token 的 transfer ### 4.4 一些 Tips + 解锁权限与意义约束分离:将UTXO的解锁权限存储在 Token.State 中,以实现像 Cell Model 一样的 UTXO 意义与 UTXO 权限的分离。 + 合约持有代币:Token.State.Owner 不一定绑定的是一个用户的公钥,也可以绑定另一个解锁脚本,其在解锁时,,检查输入的解锁脚本是否与Owner匹配,由此,可以实现合约持有代币,从而可以实现 AMM,借贷等应用。 + 判质效率高:当需要验证一个UTXO是否代表了合法的代币时,只需要回溯检查两层交易即可,无需使用索引器扫描整个流程。 + 缓解状态争用:由于mint 时需要消费 minter UTXO,这会产生状态争用,为了缓解这个问题,同时保证总量限制。可以在消费一个Minter的时候,多产生几个新的Minter UTXO,从而使得 Minter UTXO的数量不断增长,同时每个Minter UTXO所能Mint的上限也是被约束的。 + 由于 CAT20 需要在 Witness 中放置回溯交易,这使得 CAT20 的转账交易体积都比较大,以 [交易:2537706ed1000d5dd3a28d79a95ade8f674fd3e25c020cbcf97fd1b1e86ec8ef - (fractalbitcoin.io)](https://mempool.fractalbitcoin.io/zh/tx/2537706ed1000d5dd3a28d79a95ade8f674fd3e25c020cbcf97fd1b1e86ec8ef) 为例,其具有两个 Token input,一个Token Output,最终交易的大小为 14.82 kB,虚拟大小为 3.93 kB。 + 由于目前 OP_CAT 的实现有一个约束,即拼接完的字符串,不可以大于 520 bytes,而 CAT20 需要在栈中拼接出交易,然后计算哈希,故交易大小也不可超过 520 Bytes,根据文档,CAT20交易的最大输入数量和最大输出数量都为6个。 + 为了实现对不同输入输出数量的CAT20的约束,CAT20使用了 TransferGuard 和 BurnGuard 来约束整个交易的操作,由于脚本只有在输入中才会被执行,所以每次发起 transfer 或者 burn 操作,都需要先用另一笔交易构造出对应的 guard UTXO,然后再将 guard UTXO 放置在输入中构造 Tansfer 交易或者 Burn 交易,即需要两笔交易,才能发起转账。 ## 5. 走向通用计算 前面描述了,如何使用OP_CAT加上BTC的UTXO模型,即可实现类似Extended UTXO的功能,并以 CAT20 作为例子。 那么有没有可能在 BTC Script 上实现更通用的计算呢?比如说验证 zkRollup 的状态转换,直接使用 Script 变成是一种很困难并且难以互操作的模式,一种可行的路径是使用 Script 验证 zkProof。 + 对于 zkProof 的验证,Scrypt 团队曾在 BSV 上部署过 Groth16 的验证脚本,其大小有 24MB,这对于当前BTC的容量,是无法使用的。 + 另一种可行的策略是基于小域的zkSTARK,其计算使用的域足够小,可以用Script自带的操作码执行计算,以使用最终的验证脚本大小维持在一个合理的范围。另外,STARK最核心的操作为哈希和Merkle证明,而借助OP_CAT,很多操作都可以直接使用原生的OP_CODE,从而减少脚本大小。 如果最终脚本大小还是略大于合理范围,可以将脚本拆分成多个子脚本,然后使用拼接,或者挑战响应的模式在BTC上执行。 该仓库[Bitcoin-Wildlife-Sanctuary/bitcoin-circle-stark: Building blocks of a Circle STARK verifier in Bitcoin script ](https://github.com/Bitcoin-Wildlife-Sanctuary/bitcoin-circle-stark) 正在实现基于 op_cat 的 circle-stark 验证脚本。 当我们在BTC上拥有了,交易内省,Recursive Covenant,Stateful UTXO,General Computing等等功能之后,通过组合这些功能,我们可以完成什么工作呢? + 双向SPV跨链桥,当前 [Bitcoin-Wildlife-Sanctuary/scrypt-poc-bridge](https://github.com/Bitcoin-Wildlife-Sanctuary/scrypt-poc-bridge) 正在实现 BTC <-> Starknet 的跨链桥 POC。 + 使用 State 维护另一条链的区块头的累加器状态根。 + 使用 zk 验证区块头的转换,如PoW的哈希计算。 + 使用 zk + 交易内省验证 deposit 和 withdraw 的合法性。 + 在另一条链使用合约维护 BTC 的 SPV,并验证跨入跨出事件。 + zkRollup,Validium + 使用 State 维护侧链的状态根 + 使用 zk 验证状态转换的有效性。 + 使用 zk + 交易内省验证 deposit 和 withdraw 的合法性。 在进行了上述的历程之后,你或许可以理解为什么很多BTC OG都对OP_CAT无比热情,因为 OP_CAT 非常简洁,而其蕴含的能力却无比强大,可以预见,OP_CAT 在 BTC 上被重新启用,可能是下一轮 BTC生态热潮的开始,使用 OP_CAT 带来的能力,诸如MEME币,稳定币,DEFI,zk侧链,无准入跨链桥,更好的闪电网络等待,将极大刺激BTC上的生态创新。 [一些参考链接] [Cell Model. A generalized UTXO as state storage | by Jan Xie | Nervos Network | Medium](https://medium.com/nervosnetwork/https-medium-com-nervosnetwork-cell-model-7323fca57571) [Bitcoin OP_CAT Use Cases Series #1: Covenants | by sCrypt | Medium](https://scryptplatform.medium.com/trustless-ordinal-sales-using-op-cat-enabled-covenants-on-bitcoin-0318052f02b2) [Bitcoin OP_CAT Use Cases Series #4: Recursive Covenants | by sCrypt | Medium](https://scryptplatform.medium.com/bitcoin-op-cat-use-cases-series-4-recursive-covenants-6a3127a24af4) [Introduction | CAT Protocol](https://catprotocol.org/) [OP_CAT: A Big Step towards Bitcoin Contracts, From Vault to General Computing | Bitlayer Blog](https://blog.bitlayer.org/opcat_a_big_step_towards_Bitcoin_contracts/) [The path to general computation on Bitcoin | StarkWare](https://starkware.co/blog/general-computation-on-bitcoin/) [How to verify ZK proofs on Bitcoin?@polyhedra](https://hackmd.io/@polyhedra/bitcoin)