diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/current/blockchain/mvc-improvements/back-to-genesis.md b/i18n/zh-CN/docusaurus-plugin-content-docs/current/blockchain/mvc-improvements/back-to-genesis.md index 412e136..90314a3 100644 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/current/blockchain/mvc-improvements/back-to-genesis.md +++ b/i18n/zh-CN/docusaurus-plugin-content-docs/current/blockchain/mvc-improvements/back-to-genesis.md @@ -2,3 +2,24 @@ sidebar_position: 3 --- # Token溯源问题 + +介绍什么是Token溯源问题以及为什么需要溯源。 + +在UTXO类型的合约中需要维护合约状态,合约状态需要通过溯源来实现,溯源状态需要从当前状态一路校验到创世状态,这个过程可能会导致状态无限膨胀。 + +我们举一个实际的例子: + +FT,也就是Fungible Token同质化代币合约,是一种标准的代币合约。与以太坊的全局合约账本状态不同的是,在MVC中,它的合约状态是一个个UTXO,这些FT UTXO的状态包括代币的代号,创始信息,代币数量,所有权等多个信息。合约需要让有FT所有权的人可以解锁,而没有控制权(私钥)的人无法解锁并转账FT。控制权的问题很好解决,只要在合约中要求状态转移函数携带所有者的签名,并且签名正确才可以转移所有权。 + +但是有另一个问题仅仅通过所有权校验无法被解决,那就是token真实性的问题。由于UTXO自身是无状态的,它无法感知到自身之外的信息,除非将外部信息作为参数传递给函数。另外由于UTXO函数的代码和状态数据都是链上公开的,任何人都可以伪造一个一模一样的UTXO,这个UTXO的状态和代码都是正确的,但是它并不是真正的FT UTXO,如果允许这样的行为,那么意味着FT将会被任意超发,发行者和持有者将会受到重大损失。 + +在UTXO合约中理论上当然可以解决这样的问题,编写FT合约的时候,我们强制要求参数中携带当前FT的所有祖先交易信息(无论通过递归方式还是通过循环方式),然后逐一校验祖先交易的合法性,一直追溯到创始交易,能够完整形成溯源证据链条的才被当作合法交易。而刚才伪造的交易一定无法构建溯源证据链条。 + +我们可以看到,随着FT合约的换手或者交易次数的累加,校验祖先信息所携带的证据链数据越来越多,会导致解锁状态所需要的数据量越来越大,这个过程可能会导致状态无限膨胀,这个问题在UTXO合约中是一个非常严重的问题,严重影响token的可用性。 + +![状态膨胀](/img/russian-nesting-dolls.png) + +在一些竞争链解决方案中,token正确性一般通过两种方式来解决,一种是indexer共识,在一层utxo状态外再建立一套indexer机制,由indexer负责校验utxo是否合法,这是一种二层方案。二层方案最大的弊端就是无法保证和主链的一致性,比如说,brc20依赖indexer,你可以意外把brc20token当作普通satoshi花费掉,还有一些场景,layer1可以解锁的合约在indexer上并不合法,也就是说,共识不仅仅是layer1来保证,而是通过layer1和indexer共同保证,出bug和问题的可能性大大增加。另一种解决方法是使用oracle,这是一种利用外部可信数据源来保证token正确性的方案,但是oracle的问题是,它依赖于外部数据源,一旦外部数据源出现问题,那么token的正确性也会受到影响(oracle作恶问题)。 + +MVC使用了一种称为[MetaTxid](meta-txid.md)的技术,可以在不引起交易膨胀的前提下,实现纯一层合约的溯源功能,不再依赖外部indexer和oracle来维护状态正确性,而是仅仅通过utxo本身以及部分前序交易就可以鉴别token合法性,也就是说token是否合法的信息,已经全部包含在合约内部了,不需要区块链外部状态辅助判断(这是layer1的一个重要特征)。 + diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/current/blockchain/mvc-improvements/safe-zero-confirmation.md b/i18n/zh-CN/docusaurus-plugin-content-docs/current/blockchain/mvc-improvements/safe-zero-confirmation.md index a72aae8..9995dfa 100644 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/current/blockchain/mvc-improvements/safe-zero-confirmation.md +++ b/i18n/zh-CN/docusaurus-plugin-content-docs/current/blockchain/mvc-improvements/safe-zero-confirmation.md @@ -2,3 +2,43 @@ sidebar_position: 7 --- # 零确认安全性 + +介绍什么是零确认,以及零确认为什么可以保证安全。 + +零确认指的是交易还没有被打包进区块,但是已经被广播到网络中,被主要的交易处理商(或者矿工)所接受。在比特币网络中,零确认交易是不安全的,因为比特币网络的区块产生时间是10分钟,而且区块大小有限,导致交易需要等待一段时间才能被确认,这样就给了攻击者足够的时间进行双花攻击。因此比特币网络中的零确认交易是不安全的,商家一般不接受零确认交易。 + +## 网络结构改善 + +MVC在此基础上进行了改进,首先移除了可能导致未确认交易被替换的RBF机制,让内存池交易具备不可篡改性,其次由于MVC的区块大小没有限制,可以容纳更多的交易,因此对于**费率正常**的交易,可以预期在下一个区块内被打包,这样极大降低了双花的可能性。另外MVC还内置了交易安全机制,如果有交易被双花,可以立刻被网络发现并且标记,这样可以让商家在接受交易的时候更加放心。 + +通过网络节点之间更强更紧密的链接,让交易以指数级扩散并触达全网,让双花的代价无限放大,这也是所谓的“[小世界网络](../../mining/concepts/small-world-model.md)”希望实现的目标: + +![/img/zero-confirmation.png](/img/zero-confirmation.png) + + +## 中本聪的设计思路 + +其实这种设计正是比特币的发明者中本聪所设想的,中本聪在bitcoinTalk中曾经提到过为何10秒中已经足够让交易保证安全: + +[点击查看中本聪本人的评论](https://bitcointalk.org/index.php?topic=423.msg3819#msg3819) + +```text +I believe it'll be possible for a payment processing company to provide as a service the rapid distribution of transactions with good-enough checking in something like 10 seconds or less. + +The network nodes only accept the first version of a transaction they receive to incorporate into the block they're trying to generate. When you broadcast a transaction, if someone else broadcasts a double-spend at the same time, it's a race to propagate to the most nodes first. If one has a slight head start, it'll geometrically spread through the network faster and get most of the nodes. + +A rough back-of-the-envelope example: +1 0 +4 1 +16 4 +64 16 +80% 20% + +So if a double-spend has to wait even a second, it has a huge disadvantage. + +The payment processor has connections with many nodes. When it gets a transaction, it blasts it out, and at the same time monitors the network for double-spends. If it receives a double-spend on any of its many listening nodes, then it alerts that the transaction is bad. A double-spent transaction wouldn't get very far without one of the listeners hearing it. The double-spender would have to wait until the listening phase is over, but by then, the payment processor's broadcast has reached most nodes, or is so far ahead in propagating that the double-spender has no hope of grabbing a significant percentage of the remaining nodes. +``` + +MVC的零确认设计思路就是践行了中本聪所设想的,通过各种安全机制,让双花的代价无限放大,让商家可以放心接受零确认交易,提高用户体验。 + +实际操作中,MVC可以根据交易转账的金额,综合双花所需的成本,对交易给出一个风险评级,风险评级越高的交易,需要等待的区块数越多,这样可以让商家根据自己的风险承受能力来决定是否接受零确认交易。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/current/blockchain/mvc-improvements/utxo-smart-contract.md b/i18n/zh-CN/docusaurus-plugin-content-docs/current/blockchain/mvc-improvements/utxo-smart-contract.md index 25fbfb8..c846bc2 100644 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/current/blockchain/mvc-improvements/utxo-smart-contract.md +++ b/i18n/zh-CN/docusaurus-plugin-content-docs/current/blockchain/mvc-improvements/utxo-smart-contract.md @@ -2,3 +2,80 @@ sidebar_position: 2 --- # 基于UTXO的智能合约 + +介绍什么是UTXO智能合约以及为什么UTXO合约可以极大提高性能。 + +## UTXO模型简介 + +UTXO模型(UnspentTransactionOutput 未花费交易输出)是比特币的核心设计之一,相比于以太坊等链账户模型,它的优势在于可以实现大规模的并行处理。 + +账户模型是维护了一个个全局的状态(账户余额,合约数据信息等),在进行每一步交易之前,都需要对这个全局状态进行读写操作,类似于银行账户余额。在高并发的情况下,对全局状态的读写会导致资源竞争,为了确保安全,账户必须进行串行有序的操作,这也就是为什么账户模型存在一个nonce字段来标记交易的顺序,交易的有效性严格依赖这些顺序,交易之间也必须按顺序进行校验。 + +UTXO模型则更加类似于现金或者硬币,并没有一个全局的状态来记录每一个地址的余额,而是通过一个个未花费的交易输出(单独的带面值硬币)来表示它的归属关系。地址的余额是通过统计所有未花费的输出(UTXO)总面额来计算出来的。在进行交易的时候,只需要对这些未花费的交易输出进行操作,而不需要对全局状态进行读写,这样就可以实现大规模的并行处理,提高了整个系统的性能。用日常生活的例子来对比,utxo模型维护的状态实际上就是一大堆硬币,每个硬币上面标记了面值和归属(或者花费它的条件),每个硬币之间都是独立互不影响的,可以同时对任意数量的硬币进行操作,这也就带来了更高的并行处理能力。 + +下图表示了UTXO模型的基本结构: + +![img/utxo-presentation.png](/img/utxo-presentation.png) + +每一笔交易都包括输入和输出,输入一定来自于前一个交易的输出。类比而言,每一个输入相当于将对应的UTXO销毁,每一个输出则是创造新的UTXO。在比特币中,每一笔交易都会消耗之前的UTXO,生成新的UTXO,UTXO能且只能被花费一次,一旦花费就不再是UTXO,也就不再参与计算余额,这样就保证了每一笔交易都是有效的,不会出现双花的情况。 + +>注意:coinbase交易,也就是矿工挖矿获得收益的交易不会消耗UTXO,只会产生新的utxo,这也可以看作是铸币的过程。 + +从上面的图示可以看出,UTXO模型控制的最小单位不是交易,而是一个个的UTXO,理论上可以对任意数量的UTXO同时进行操作,这就是UTXO模型的并行处理能力的来源。为了突出UTXO的并行性,我们可以用几个简单的例子来说明: + +1. UTXO转账并行:我可以构造一个1输入,10000输出的交易,将一笔钱平均分给10000个人,使用1笔交易就可以完成,而账户模型完成同样的目标则需要10000笔有序的交易交易,前序转账未完成前不能进行下一笔。(UTXO并行转账) +2. UTXO收款并行:我的地址可以同时接受10000笔转账,注意这里是同时,它们之间的顺序并不重要,谁先到谁后到都不影响最终结果,而账户模型则需要交易出现在区块中的顺序进行串行处理。(UTXO并行接收) +3. UTXO处理并行:节点软件或者矿工可以将交易池中的交易按照不同的规则(比如UTXO相关性)进行分组,然后由多个处理模块并行处理,这样可以通过横向拓展提高整个网络的处理能力,要知道能够进行横向拓展是无限扩容的必要条件,而账户模型则需要对每一笔交易进行有序处理,无法并行。(UTXO并行处理) + +因此,MVC采用UTXO模型作为交易并行处理的根基,同时解决了UTXO模型的一些缺点,比如难以实现智能合约,难以维护全局状态等问题,使得MVC具备了高性能的基础。 + +使用UTXO模型进行标准的转账交易是非常简单的,但是要实现智能合约却受到很多限制,也存在很多技术难度: + +* UTXO模型因为不存在全局状态,进行类似以太坊智能合约的全局状态管理非常困难。 +* UTXO模型是纯函数式编程,需要一定的理论基础才可以掌握正确的编程模式。 +* BTC等公链限制了可以执行的脚本数量和类型,只允许几大标准类型的交易输出,导致智能合约的功能受到限制。 +* UTXO生态中缺乏完善的智能合约开发工具,开发者需要自己编写脚本并且手动构造交易,非常不友好。 +* UTXO合约由于其技术特点,存在很多编译期常量,在处理循环,递归等复杂逻辑时会遇到很多困难。 + +MVC充分考虑了UTXO模型的优势和缺点,在吸取以太坊和其他UTXO公链的经验的基础上,引入了BVM(Blockchain Virtual Machine)的概念和MetaTxid等技术来实现真正的纯一层UTXO智能合约。并且同[sCrypt](https://scrypt.io/)团队深度合作,提供了更加友好的智能合约开发工具,大大降低了编写和部署BVM智能合约的门槛。 + +## BVM(Bitcoin Virtual Machine) + +BVM是基于比特币的[脚本系统](https://en.bitcoin.it/wiki/Script)进行了操作码恢复和功能扩展的虚拟机,它是MVC智能合约的执行引擎。比特币的脚本系统是一个双栈结构的执行器,包括输入栈和输出栈,使用类forth语言对栈进行任意操作,实现更高层次的逻辑。实际上,很多现代编程语言的执行结构很大程度上都要依赖执行栈,从原理上来说,你甚至可以通过栈式结构来实现任意复杂的程序逻辑(只要内存资源足够多)。可以说,栈式结构是构成现代编程语言的基础,拥有无限的潜力。 + +但由于BTC的限制,脚本系统只能进行简单的逻辑判断,可以使用的操作码也非常有限,无法实现复杂的智能合约逻辑。BVM在脚本系统的基础上进行了功能扩展,[引入了更多的操作码](bvm-opcode-unlocking),支持更多的数据类型,提供了更多的功能,使得MVC智能合约可以实现更多的复杂逻辑。 + +我们可以对BVM及其合约进行如下的定义和特点归纳: + +1. BVM是基于比特币脚本系统的操作码进行了功能扩展的虚拟机。 +2. BVM由输入栈和输出栈组成。输出栈可以看作智能合约的函数定义以及数据,输入栈可以看作智能合约的函数调用以及参数。 +3. BVM合约是[纯函数式运算](https://www.turing.com/kb/introduction-to-functional-programming),具备函数式编程的原子性,无状态,无副作用,可并行执行等特点。 +4. BVM的合约计算的结果只包含TRUE或者FALSE,通过UTXO是否能够被解锁来判断合约是否执行成功。 +5. BVM的合约具备原子性,要么全部成功,要么全部失败,不会出现部分执行的情况。校验失败的合约不会消耗GAS费,因为会被看作非法交易,不会记录上链。 + +![BVM](/img/bitcoin-virtual-machine.png) + + +更多关于BVM的操作码和合约编程的详细容请参考[后续章节](bvm-opcode-unlocking.md)。 + +## UTXO智能合约简介 + +UTXO智能合约就是将合约的逻辑和数据存储在UTXO中,将合约的调用和参数作为input来尝试解锁合约,通过BVM执行合约的逻辑,最终通过能否解锁(函数返回true或false)来达到控制合约状态的目的。这样的模式可能对于以太坊智能合约开发者来说有些陌生,但实际上结合函数式编程思想,配合一些概念的转换,UTXO智能合约也可以实现非常复杂的逻辑。 + +UTXO模型由于不存在全局状态,因此需要将合约的状态和逻辑存储在UTXO中,通过UTXO交易调用链的传递来进行状态的传递和转换,如下图所示: + +![UTXO state chain](/img/utxo-state-chain.png) +(UTXO合约状态链,图片取自[sCrypt](https://docs.scrypt.io/how-to-write-a-contract/stateful-contract)) + +每一次的UTXO交易都会消耗之前的UTXO,生成新的UTXO,通过这种方式可以实现合约的链式状态转移。而能否解锁UTXO也就对应着合约的执行结果是否允许状态进行转移,如果合约判断不允许修改状态(比如不允许转账,不允许修改数据等),则会返回false,UTXO不会被解锁,合约执行失败。 + +我们把合约看作对数据状态进行转移操作的状态机,那么这里可以看出UTXO合约和Account合约的区别: + +* account合约维护全局状态,一个交易可能导致EVM进行多次的状态转移,频繁地修改状态数据直到合约执行完成或者Gas消耗完。而UTXO合约的交易一个input合约调用只会触发一次状态转移,并且无论合约内部的逻辑多复杂,状态转移多少次,BVM只会将最终的状态转移结果记录在链上。 +* UTXO合约没有全局状态,只有一个个等待被执行的“函数”(UTXO)。需要转移状态,就要先找到这个状态所在的函数,通过函数调用来修改状态并且生成新的函数。这样的模式使得UTXO合约的状态转移更加清晰,更加容易理解。 +* 由于UTXO合约不依赖外部状态,因此一次合约调用,无论调用多少次,它的结果必然是确定的,这也就给合约的分析和调试以及单元测试带来了巨大的便利。反观EVM合约,由于依赖全局状态,合约的执行结果很可能会受到外部环境的影响,导致合约的执行结果不确定(余额够是一个结果,不够又是另一个结果),这也是EVM合约的安全性和可预测性的一个重要问题。 + +当然,每次将状态传递下去也不是没有代价,在一些需要溯源的场景中,状态可能会随着传递链条的增大而增大,因为溯源需要校验的数据可能越来越多,[状态本身会无限膨胀](back-to-genesis.md)。这个问题MVC也通过称为[MetaTxid](meta-txid.md)的技术,通过哈希和数据抽取等密码学的手段将状态膨胀的一大类问题彻底解决,这也是MVC智能合约区别于其他UTXO链的一个重要特点。 + + +![UTXO smart contract](/img/bitcoin-smart-contract.png)