比特币MAST方案分享
本次分享以下几个内容:
1、 MAST方案的实现背景
2、 MAST的具体实现方案
3、 方案的收益
4、 可行性分析
四个方面的内容
实现背景:
主要是比特币安全性方面的原因,我们知道所有的比特币交易都是公开,可追溯的,并且永久性地存储在比特币网络中。在美剧《网络犯罪调查》第二季中,有一段比特币大盗抓捕过程,完整地展示了比特币交易可追溯性的意义(视频),原理就是通过比特币交易的时间和金额来锁定了地址,只要比特币大盗挪动比特币,或者在交易平台卖出,他的IP甚至实名信息就可能被追查出来。
针对这个可追溯问题,人们提出了几种方案,但是无法彻底解决
1、 使用新地址收款
每次接收新的付款你都应该使用一个新的比特币地址。此外,你可以使用多个钱包满足不同的需求。这样做可以将你的每笔交易都隔离开以使它们无法被关联起来。付款给你的人不会看到你其它的比特币地址,也不会知道你如何使用它们。
2、 尽可能不要公开比特币地址
如果你从这个地址向你其他的地址发送了任何资金,这些地址的隐私性也会由于你的公共地址的历史记录而被破坏
3、 Coinjoin 混合交易
混合交易就是把许多人的交易放一起签名,这样就不容易判断具体谁和谁发生了交易,举个例子:
有两个交易,用户Blob转账给Ted 15BTC,找零5BTC;用户Alice转账给Carol 8BTC,找零2BTC,我们把两个交易合并为一个,输入和输出不变,用户Bob只需要对他的输入签名,然后交给用户Alice,用户Alice只对她的输入签名。签名完成后就可以发布广播。
从本质上讲,CoinJoin允许多个用户将来自多个事务的所有输入和输出合并为一个大事务。 这样一个交易将会由不同地址的比特币输入和不同地址的输出构成,他们之间没有任何联系,我们无法通过一个发送地址找到对应的接收地址。
(这可以和一群把现金放在一起购物的人比较,只要每个人确保自己花自己的钱买自己的东西,其他人却无法知道每个人花了多少钱买了多少东西)
目前我们在游戏上用了这种模式,使用场景是用户a给用户b转了一个猫,转账的手续费由平台c来出,这实际是两个交易,我们合并为一个交易,既能够保证交易相互关联,也不需要让平台给用户发币,导致交易过程复杂化。
这几个方案能够带来一定的隐私性,但是交易一旦上链,还是有办法锁定交易双方。而MAST方案可以做到即使交易上链,交易双方的信息,你可能只知道一方。
实现方案
MAST方案由三部分构成,分别是支付给脚本hash(P2SH),抽象语法树(AST)和merkle树
支付给脚本hash(P2SH)
比特币有两种常见脚本的格式
P2PKH(支付到公钥地址模式):
输出脚本:OP_DUP OP_HASH160 (0×14) [一个20字节的哈希值] OP_EQUALVERIFY OP_CHECKSIG
输入脚本:[签名的字节数][签名]0×01 [公钥的字节数] [公钥]
P2SH(支付到脚本模式,使用多重签名就需要用到这种模式):
输出脚本:OP_HASH160 (0×14) [一个20字节的哈希值] OP_EQUAL “签名脚本”:(输入脚本)
输入脚本:0×00 [字节数] [签名1] 0×01 …[字节数] [签名m] 0×01 [支付合同脚本的字节数] [m] [字节数][公钥1]… [字节数][公钥n][n] OP_CHECKSIGVERIFY
这两个最大的区别是在输出脚本里面放公钥hash还是放脚本hash,如果放公钥hash,其实就是地址,那么交易地址就是暴露的,如果放脚本hash,就无法知道转账给哪个地址了。这一步已经做到了隐藏地址,但是还需要隐藏脚本。
抽象语法树(AST)
我们来看一个例子:
Alice希望能够随时使用比特币,但如果她的比特币在三个月内没有用完(可能是因为她已经死了或 无能为力),她希望她的兄弟姐妹鲍勃和查理能够使用她的比特币。
这个脚本不仅包括Alice的公钥(需要从她的私钥中验证签名),还包括超时逻辑以及Bob和Charlie的公钥。
在当前的比特币协议中,当爱丽丝的比特币被花费时,上述所有数据都必须被添加到块链中。 但是没有使用的花费条件,例如Bob's和Charlie的公钥,会增加交易规模,也会因为公开披露更多信息而暴露了更多隐私,MAST试图通过消除在块链中直接包含未使用的脚本部分的需求来改善这种情况。
抽象语法树(AST)是一种通过将程序分解成各个部分来描述程序的方式,这可以使分析和优化变得更加容易。 要生成一个AST,可以将每个函数连接到它的依赖关系,直到所有的依赖关系都被映射出来为止。
通过抽象语法树我们把一个复杂规则分解成一个个独立的简单条件,如果是alice花费了这笔钱,就把alice这部分条件上链;如果是她的兄弟花了这笔钱,就上链他的兄弟这个条件,这样即减少了上链的手续费,也隐藏了没有使用的信息。但是脚本变化了,脚本hash就不同了,为了确保脚本hash可以验证这种可以分拆的脚本,就需要用到Merkle树的概念。
抽象语法树有现成的工具来帮我们分解脚本,具体见http://n.bitcoin.ninja/mast
抽象语法树可以把脚本分解成部分,但是如何确保校验通过呢?毕竟花费条件是已经上链,不可更改的。这就需要用到merkle
merkle树
大家知道merkle树是一种特殊的二叉树,其特征是页子节点都是数据,而其他非页子节点都是hash值,Merkle Tree 的明显的一个好处是可以单独拿出一个分支来(也就是验证路径)对部分数据进行校验。
因此我们通过抽象语法树,把一个程序分解成不同的部分,然后通过Merkle树使我们能够在不存在整个程序的情况下验证属于一个完整程序的各个部分。
我们继续看上面的例子,我们转换为merkle树就是这个样子
下面这个就是merkle的两个分支树,如果是alice花费了这笔钱就用左边的树,如果是她的兄弟花了这笔钱就用右边的树,而验证的时候只需要证明merkle root hash相等就可以了。
收益
1、 更多的隐私保护
在这个例子中,只有alice知道谁可以使用这笔资金,并且使用资金有啥限制条件,即使这边资金被花费了,你也只能知道其中一个花费条件,无法知道全貌,当然alice也可以假装她有很多花费条件,实际就只能她花费。
在上面的比特币大盗的视频里面,如果黑客把钱转给了一个merkle root hash,那么只要他还没有花费这笔钱,警察不可能查到这笔钱被谁偷走了。
缺点是如果是两个商家的交易就可能存在信任危机,因为只有转账的商家完全知道花费条件,而收款的商家可能只知道一部分条件。
2、 较小的交易
使用mast后,代码被分割为几个脚本,当脚本超过2个部分后,代码量明显的减少,从而交易费用也会减少。
3、 更大的智能合约
比特币脚本的字节大小是有限制的,一般脚本是1w字节,而P2SH限制为520字节。但是我们用mast把脚本分解成小的脚本,每个脚本虽然受到了1w字节的限制,但是总体可以做的很复杂
可行性分析
1、 何时可以上线
这个无法回答,因为比特币没有上线,虽然mast只需要软分叉就可以上线,但是隔离见证就搞了两年,最近才上线,比特币的开发都忙着抄币去了,核心技术发展比较慢。
2、 应用场景有待发掘
当然你可以把目前的P2PKH都改成mast方式,但是比特币脚本用来开发一个复杂场景的合约还是比较难,比如如何发布个以太猫?大家习惯可视化开发了,现在用类似汇编的语言开发确实很难。
3、 完整的脚本保存到哪里
我们在转账的时候用的上个merkle root hash,这个是由完整的脚本生成的,只有花费的时候才用到脚本的一部分,这中间有个时间差,完整的脚本放哪里比较安全就是个问题了,万一搞丢了谁也用不了。