技术角度解读CAT20:分形比特币上的新代币协议
54minutesago(09,292024(UTC))LikeDislikeComment本文仅作为技术分享,不构成任何投资建议。
BTC上也要有自己的智能合约了?
最近比特币生态上,FractalBTC在经历了多次测试网之后,终于在9月份上线主网。Fractal的一大特点就是具备“智能合约”的能力,并且几乎在推出主网的同时,上线了一个新的代币协议CAT20。CAT20有什么技术上的巧妙设计呢?我们又可以学到什么?
FractalBitcoin在了解CAT20之前我们需要简单了解一下FractalBitcoin,他们的关系就像ERC20和ETH一样,CAT20协议是部署在FractalBitcoin上的。
FractalBitcoin又称作分形比特币,是一个完全兼容BTC的“二层”网络。相比于BTC,它的区块确认时间更快,仅需要1分钟。它的基本原理简单来说就如它的名字所言,就是将BTC网络复制了几份,每条链都会处理交易,可以处理交易的节点多了,速度也就自然快了。不过具体的细节比如不同链之间是如何通信的目前还不是很清楚,官方也没有对应的技术文档可以参考。
如果只是一个二层链交易更快,似乎没有让人兴奋的点。但是,在Fractal中启用了BTC很久之前就因为安全原因弃用的操作码OP_CAT,让FractalBitcoin的能力上升了一个台阶,有人说OP_CAT能让BTC具有智能合约的能力,这样的话可以遐想的空间就更多了。
现在,就有人在FractalBitcoin上实现了一个类似ERC20的协议。
关于OP_CAT为什么弃用以及为什么又可以在FractalBitcoin上使用,后续可以展开讲讲,这里我们关注CAT20。CATProtocol以下内容参考白皮书:Introduction|CATProtocol(https://catprotocol.org/)以及github仓库:GitHub-CATProtocol/cat-token-box:AmonorepoforpackagesimplementingCATprotocol(https://github.com/CATProtocol/cat-token-box)有了底层的OP_CAT支持,很快就有了对应的协议,CATProtocol。目前一个已经在实际跑的协议是CAT20协议,在Unisat上也新增了对应的面板:https://explorer.unisat.io/fractal-mainnet/cat20。
看到CAT20的名字大家应该也能反应过来,它应该和ERC20比较像。相比于成熟的ERC20协议,大家部署一个Token已经非常的方便,CAT20是如何实现ERC20类似的生命周期呢。
Deploy在部署之前,用户需要指定自己的钱包地址以及代币的基本信息,代币的基本信息和ERC20的类似:
会有一些不同点CAT20可以设置预挖和每次Mint的数量限制。当然ERC20可以通过合约的能力也可以实现这些能力。
在部署阶段,会发起两笔交易,可以认为是两个阶段:“ commit ”和“ reveal ”。引用官方上的图,部署的阶段如下:
在“ commit ”阶段,交易的输出脚本中会将代币的基本信息写入,比如代币的名称、符号等。在“ commit ”阶段发起的交易hashId会作为该代币的标志,用于区分其他代币。
可以看到这笔交易“ bc1pucq...ashx ”这个utxo就是对应了commit。然后剩下的两笔指向“ bc1pszp...rehc4 ”的交易,第一笔是用于支付下面“ reveal ”阶段的gas费,另一笔则是找零。
在“ reveal ”阶段,可以看到有两笔utxo输入,对应了之前commit阶段的前两个输出。这笔交易首先会输出一个OP_RETURN,在OP_RETURN中会保存CAT20的初始状态的Hash。之后会再输出一个Minter,它会在后续的Mint过程中发挥重要作用,用来维护Mint过程的状态变化。
回过头看整个Deploy的过程,“commit ”和“ reveal ”遵循了区块链上常用的提交和揭示两个步骤,是一种比较常见的部署项目的方式,项目的一些数据只在“ reveal ”阶段才会揭露出来。
Mint我们先看一下MintToken的时候,交易是这么样的。
在上图中可以看到,Mint的过程有以下几个特征。
mint的输入是一个minter,最开始是由deploy的时候生成的。每一次mint都有且只有一个minter作为输入,有任意个minter作为输出(有点点问题)每一次mint都有且只有一个token(有点点问题)输出的顺序是有要求的,minter后面必须是token知道了Mint的过程,其实我们可以发现一些特殊情况,会让整个Mint的过程变得有趣。
比如,minter作为mint交易的输出,他可以是1个、多个甚至是0个。如果每次Mint的时候都设置为1个,那么整个网络中可以使用到的minter数量就会保持不变(1个),这会让Mint变得拥挤,大家都需要抢这个minter,为了避免这种情况,是需要将每次输出的minter数量设置为大于1,这样mint之后,大家可以使用的minter就会越来越多。
不过,每多输出一个minter意味这你需要多支付一笔utxo,出于经济考虑,更多的人会乐意将minter设置为0,就会不可避免的让minter变得通缩,这就需要一些人来进行奉献了,自愿支付多出来的minter。
在V2版本,默认是生成两个Minter,并且两个Minter的状态会尽可能相近。
交易的构建可能有小伙伴发现了一个问题,那就是为什么可以使用minter的utxo进行交易的构建?想要了解这个问题就需要对“合约”的源码进行分析。
1、revealutxo
首先我们对reveal过程中的交易进行分析,我们发现他使用了前一个交易的输出commit作为输入。为什么可以拿一个不是我们地址的utxo构建交易的输入呢?
按照常理,一个私钥对应一个公钥,公钥派生出地址。当验证一个输入的utxo是否有效的时候,一般是通过比较签名用公钥解密之后是否和原本的交易一致来确定。这部分的逻辑是写在比特币脚本中的。所以我们可以巧妙的改写脚本的逻辑,在脚本中写的公私钥对是我们自己地址的,这样我们就可以控制两个不同地址的utxo了。
看源码我们就能知道发生了什么:
这里还会有一个问题,就是一个私钥对应一个公钥,那么为什么生成的commit地址会和我们地址不一样呢?这里从源码中可以看到
也就是说,我们的私钥会根据一个ISSUE_PUBKEY来调整公钥,这也是P2TR地址的一个特性。
2、minterutxo
reveal过程中,我们使用不同的utxo的作为输入,但其实加密的密钥是同一把,也就是部署者的私钥。但是在minter阶段,所有的人都可以使用这些utxo作为输入,这又是怎么做到的呢?
这部分我猜测是之前说的OP_CAT的能力,也就是智能合约的能力,每一个minter就是一个智能合约。不过目前这部分的源码没有公开,暂时不知道具体的实现是怎么样的。
交易的状态(V2)在minter中,还保留了状态。这个状态存在两个地方:一个是交易输出的OP_RETURN中,另外就是存储在智能合约中,也就是上述提到的Minter以及Token。
在OP_RETURN中存储的是当前交易输出状态的Hash,在合约中会存储Token剩余的Mint次数。每次Mint之后,新生成的Minter的mint数量会等于剩余可以mint的数量除以二。用图表示:
最后打完的时候,所有Minter的剩余数量为0。
回到最开始的那张图上,除了Minter是一个智能合约之外,生成的Token也是智能合约,也就是CAT20。CAT20有两个基本的状态:数量以及Token的归属者地址。可以看到不像之前的BRC20或者铭文,你的CAT20并不是在你地址的UTXO上。
TransferTransfer的时候,构建交易的输入和输出的token其里面的数量需要保持一致。当然同一笔交易里面可以有多个不同的token,只需要不同token的其输入输出的数量保持一致就行。
Burn想要燃烧掉Token的话,只需要将Token转到一个普通地址上即可。
总结可以看到,所有的操作都是由用户自己去构建,灵活性非常大,所以在合约部分需要做很多的校验逻辑。目前爆出的一些漏洞也是因为校验逻辑出现了疏忽。
这样的设计可以有一些好处:
如果想要查找所有的Token的持有情况,只需要查一下token的utxo就行,不需要继续往上查。如果想要查看mint的当前情况,可以搜索OP_RETURN中数据带有cat的交易就好。ZAN无门槛领水来啦!
Tip:每24小时可领取一次0.01ETHfreetestnettoken,以支持您在以太坊生态内体验和测试Web3项目,点击马上领取: https://zan.top/faucet?chInfo=ch_WZ
更多公链即将支持~
本文由ZANTeam(X账号 @zan_team)的Yeezo(X账号 @GaoYeezo75065)撰写