是一个基于密码学、经济学和网络科学的新技术。对于一般的大众来说,其中的密码学并不是一门容易亲近的学科,甚至是上面提到的三个学科中,大家觉得最有距离感的学科。但身处区块链圈的朋友们一定会常常听到「区块链是一部 Trust Machine」这样的说法,或者有人会说在区块链的世界里是「In Math we Trust」,可见密码学对于区块链技术来说是根基一样的重要存在。
好了,那么问题来了:
· 区块链究竟在哪些地方用到密码学呢?
· 密码学为什么对区块链技术至关重要?
区块链的哪些地方用到了密码学?
首先,如果你是一个区块链用户,可能在你房间里的某个角落,会有一张纸条,上面抄着十二个不知道怎么来的单词,有的人还有很多张,甚至有些大 holder 会把这十二个英文单词刻在钢板上,然后锁进保险箱里。
是的,为什么这十二个助记词,或者像一长串乱码般的私钥能够代表你对资产的所有权呢?
这背后的原理其实就是密码学。
区块链上的密钥、地址和钱包都是通过密码学去实现,利用非对称加密技术——椭圆曲线算法(ECC)可以验证某人持有的私钥是否是吻合某个公钥,通过这个方式我们可以证明这个人是否是这笔加密资产的持有人,因为除了拥有私钥的人之外,其他没有该私钥的人是没有办法解锁这笔资产的。
我们在此用举例私钥、公钥和地址生成的原理,一个比特币钱包中包含一系列的密钥对,每个密钥对包括一个私钥和一个公钥。私钥通常是一个随机选出的 256 位的数字。基于私钥,我们就可以使用 secp256k1 标准的椭圆曲线这个单向密码函数产生一个公钥。基于公钥,我们又可以使用一个单向哈希函数 SHA256 和 RIPEMD160 生成比特币地址,再通过 Base58 check 编码将比特币地址变成现在这较为简洁的形式。而像我们比较常用的助记词,则是通过基于 BIP 39 标准而生成的随机英文单词。如果没有私钥或助记词的人,是无法使用这笔加密资产的。
当我们有了可以配对的密钥对后,可以在各种类型的钱包或者客户端上做验证,确认资产的所有权,并且通过这个客户端来进行各种资产的使用。例如最简单 BTC 转账,或者再进阶一点的用某个钱包去签署智能合约的交易:比如用 Metamask、imToken 或者 Alphawallet 等钱包里的 ETH 去购买加密猫,或者在 DeFi 的平台上面进行借贷,以及用 Uniswap 交换某些 ERC20 Token 等。
除了转账等基本的验证外,现在甚至某些平台的身份验证都可以用公私钥来做登录验证,或者通过验证你是某笔资产的所有人来进行各种权益的证明。简单来说,公私钥验证系统背后的密码学就是用户想畅游区块链世界的通行证。
在区块链中,还有另外一个不可忽视的密码学使用场景,就是区块中的交易排序,以及 Merkle Tree 等决定区块排序的过程。比特币就是将每笔交易用 SHA256 算法进行加密,在这里加密算法确保了区块链的安全性,以及几乎不可能被篡改的特性。光是在这两个比特币的基础使用场景中就都用到了密码学,于是乎甚至还有许多人在猜测,中本聪可能是个密码学大佬,才能够把密码学在这个点对点的现金系统中使用的淋漓尽致。
当然,除了在区块的生成和公私钥验证这两大区块链的核心功能上可以发挥用途之外,密码学在隐私保护甚至扩容等方面都可以派上用场。
现在的公链如何使用密码学?
· Wow,这是一条新的公链吗?
· 那它有没有钱包啊 ?
· 又要多一组新地址和抄一组新的助记词了。。。
如果一个用户真的愿意自己好好地保管自己的资产,也勤于投资不同的公链,我相信他们一定也会有类似的经验和好几组不同的助记词或私钥。但到最后,他们能够保存好的,可能只剩下那些最主要的持仓资产,有些人甚至忘记备份某些资产的助记词。
长期下来,区块链资产管理的问题也导致区块链的门槛越来越高。所以一些钱包为了解决这个问题,已经提出了很多的优化方案。有些钱包甚至可以做到一个身份钱包的单一助记词,可以管理多种资产等功能,但仍然有许多组不同的地址必须要由用户来做管理。这样的问题对于很多新公链而言可能更为严重,因为如果用户要去通过他们的网页或手机钱包,去尝试链上的应用,用户就会增加许多管理公私钥的成本,更何况他们不像邮箱的密码一样可以任由用户自己定义,既不滑顺也不香。
但为什么区块链会有这样的限制?
这样的限制是因为目前许多的公链,都将很多密码学原语的使用场景写入了共识层,因此在这些公链中,像公私钥签名、客户端验证,以及区块生成的哈希和常用的加密算法,基本上都是镶嵌在共识层中的。例如地址所使用的验证、交易使用的签名等,其实都写在底层协议中,因此会变得非常难以改动。另外,许多公链的虚拟机性能都不足以支持灵活的密码学原语部署,因此对于这样的公链而言,如果底层的虚拟机不预先支持某个密码学原语,那么基于该密码学原语的场景可能很难直接被开发者使用。
如果要更动,唯一的办法就是硬分叉!
拿为例,以太坊的共识层写入了哪些密码学的场景呢?
除了区块的加密签名和 Merkle Tree 的哈希外,还有交易签名和客户端的验证。如果有任何人想要在这些点上做改动,例如将以太坊公私钥的哈希算法 keccak-256 换成其他签名算法,那么唯一的办法就是提一个 EIP (Ethereum Improvement Proposal),然后等待、祈祷这个提案被排入硬分叉之中。因为写在协议层的内容,就是全网的所有用户都必须遵从的规则。
然而硬分叉往往需要非常长的时间,以 EIP 152 为例,这是一个 2016 年就提出的提案,希望将签名算法 BLAKE2 加入以太坊中,但直到 2019 年底的伊斯坦布尔提案中才被加入到升级的内容当中,整整历时 3 年之久。
从刚才 EIP 152 的例子中我们还会发现另一个限制,那就是在以太坊上如果要使用虚拟机不支持的密码学原语,几乎是不可能的。因为对于以太坊虚拟机而言性能是一大限制,光是简单的运算,就能够消耗大量的 gas。
因此我们如果回顾以太坊上历次的分叉,就可以发现从家园(HomeStead)的硬分叉升级开始,以太坊就不断地把所有可能常用到的密码学原语,例如 sha256 hash、ripenmd160hash 等持续的通过预编译(precompiled)的方式,加入到底层的虚拟机中。这点在拜占庭(Byzantium)或者伊斯坦布尔(Istanbul)的升级中也可以看到。以太坊通过硬分叉的形式,来预编译密码学原语以及这些密码学原语运算的 gas 定价。
如果不通过预编译合约在节点先进行实现,那么许多签名算法的智能合约部署将花费非常非常高的 gas 费,导致其根本无法部署。例如 EIP 196、 EIP 197 之所以被采纳,就是预见了 zkSNARK 需要大量的 gas 进行链上的运算。因此预先将这些加密算法,如椭圆曲线加法、乘法和配对验证等编译进了底层的 EVM 中,好让这些计算成本可以节省下来。所以,我们可以说在以太坊上除了已经做了预编译的签名算法外,其余的加密算法基本上是没办法使用的。
上述这些固化的密码学使用方式,对于开发者而言是一个很大的限制。
由于交易和客户端的签名验证都被写入共识层,因此验证工具和流程都必须按照规定的加密算法进行。例如在比特币或以太坊中,如果我们要创建一个账户,那么我们依旧需要管理一组新的密钥对。
对于想要带来良好用户体验的开发者而言,这样会产生很多的限制,并且需要通过其他方式,去弥补固化的底层设施带来的不友善的用户体验。比如在创建助记词之后,我们可以在某些钱包中使用 FaceID(如 imToken),比如在 ABC Wallet 中,用户起初只需要靠像手机里的六字验证码就能够登入,,等你真的觉得你需要把私钥或助记词导出了,再进行导出和备份。
这些都是开发者试图提升用户体验所想出来的好办法,但对于每一条新的公链,密钥对管理的本质都是需要有一组新地址和密钥,这个问题是一直存在的。
上述的公私钥验证方式不够灵活的问题,在比特币、以太坊等较为先发的公链上或许还不明显,因为他们已经有既有的用户,这些用户也被折磨习惯了。但对于近期兴起的公链而言,如果还存在和先前公链同样的进入摩擦成本,那么就是给用户设置了障碍,也会影响开发者是否想要在这个公链上开发的意愿。
一个对用户有学习成本的公链,在获取用户上就存在着先天的壁垒,即使这些公链有其他的亮点,可能对于开发者而言,也不会那么有吸引力,因为他们知道很多的用户可能都被这些不友善的用户体验给吓走了。
另外,密码学原语不能够灵活使用的问题,影响的层面还不止于公私钥的保存。对于开发者而言,如果以后他们想用更先进的密码学原语来保证隐私及安全,一样会面临到底层的虚拟机能不能部署,以及支持签名验证的挑战。当然还会影响目前大家讨论的很热的话题:跨链,因为不同的链使用的密码学原语也会有所不同,在虚拟机验证交易时就会遇到这个难题,这也是为什么目前许多同构跨链的解决方案(Cosmos / Polkadot )可行,但对于异构跨链的方案却停滞不前的原因。
Nervos 的设计有何不同?
在 Nervos CKB 中,除了交易排序外,没有其他硬编码的密码学原语,资产所有权的验证是通过 cell 中的 lock script 来做验证,其中的验证规则和使用的密码学原语都是可以自定义的,因此几乎所有的密码学原语都可以被开发者灵活的使用。
套用一句 Nervos 研究员 Cipher 老师的话来说,就是:「在 CKB 上除了最基础的交易排序以外,其余都是应用层的内容。」这让开发者拥有了非常大的开发弹性,去进行各式各样的开发,例如更自由的账户验证方法等。
因为在基于 RISC-V 的 CKB-VM 中,要求的就是一套能够符合 RISC-V 编码的验证规则而已,开发者有很多能够自由挥洒的空间。下图可以看出 Nervos 和其他可以支持智能合约的公链在灵活度上的差异,应用层的内容表示的是可以去做自定义的,协议层代表的是需要经过「分叉」才能改动的内容。
郑重声明:本文版权归原作者所有,转载文章仅为传播更多信息之目的,如作者信息标记有误,请第一时间联系我们修改或删除,多谢。