当前位置: 首页 > 科技观察

区块链世界有什么不能信任的?

时间:2023-03-21 17:55:35 科技观察

大家好,我是张凯翔。上一篇分享了《当你信任区块链时,你在信任什么?这一次,我们将从不同的角度,走在月球的暗面,谈谈我们在设计区块链系统和服务时不信任的地方。先说结论:几乎没有什么是可以信任的!树立Don'tTrust,JustVerify的理念是对待区块链世界的正确态度。——我随便说的1不要相信其他节点区块链节点和其他节点会建立P2P通信,共同组成一个网络,传递区块、交易、共识信令等各种信息。其他节点可能由不同的组织和不同的人持有,他们可能是善意的,也可能是恶意的。即使在善意的假设中,节点运行和生存的健康状况也会受到运维水平和资源的影响。比如在不稳定的网络中,偶尔会挂掉,乱发消息,或者硬盘满了等原因导致数据存储。故障,以及其他可能的故障。在进行恶意假设时,需要预先假设其他节点可能欺骗或伤害自己,例如传递错误的协议包,或使用奇怪的指令寻找漏洞进行攻击,或发起高频垃圾请求,频繁连接然后断开,等等。或者大量的连接占用资源等等。因此,节点应该把自己看作是一个人在黑暗丛林中的猎手,必须要有一种“独立”和“自给自足”的态度,以“自我保护”的姿态保护自己。不信任任何其他节点”。当节点被接纳时,需要使用证书技术来验证节点的身份;在连接控制方面,拒绝异常连接;使用频率控制来限制连接数、请求量等;核实。自己发送的信息不应暴露自己的隐私信息,也不期望其他节点立即做出正确的回应。必须采用异步处理和容错设计。2节点和客户端互不信任。客户端是指在区块链网络之外向区块链发起请求的模块,如业务使用的javasdk、钱包客户端等,客户端与节点通过网络端口进行通信。如果客户端落在不受控制的人手里,就有可能向节点发起大量请求,或者发送一堆垃圾信息,让节点疲于应付,甚至巧妙地构造漏洞攻击信息,试图获得未经授权的访问、窃取信息或使节点故障。同时,从客户端的角度来看,节点可能没有响应或响应慢,或者返回错误的数据,包括格式错误、状态错误、表示收到但未处理等,甚至有别有用心的人动机会设置一个“假”节点与客户端通信,欺骗客户端。以不符合预期的方式响应的节点可能会导致客户端操作错误并损害功能。为了提高节点与客户端之间的相互信任,可以为双方分配数字证书。必须通过证书执行双向握手。客户端只有在私钥签名后才能向节点发起交易请求。节点应控制客户端权限,拒绝高风险接口调用。请勿轻易打开节点管理界面、系统配置界面等,双方严格检查每次通信的数据格式和数据有效性。双方在交互时也应进行频率控制和异步处理,并对每次交互的结果进行验证。不能假定对方会正确处理,必须取得交易回执和处理结果进行确认。当认为只与一个节点通信不能保证安全时,客户端可以使用“f+1查询”的思想,与尽可能多的节点通信。如果当前链的共识安全模型是“3f+1”,那么如果从f+1个节点读取的信息是一致的,就可以确认结果。3不要相信区块高度区块高度是一个非常关键的信息,代表了整个链的当前状态。向区块链发送交易、节点之间的共识、验证区块和状态等操作都取决于区块高度。当节点断网或处理速度慢时,其区块高度可能落后于整条链,或者当节点恶意伪造数据时,其区块高度可能超过整条链。当链中存在分叉时,如果某个分叉上的块高度被另一个分叉超过,则后分叉将变得毫无意义。即使在正常情况下,节点仍然有可能间歇性地落后整个链一个或几个区块,然后在一定时间内赶上最新的高度。例如,在PBFT共识模型中,当超过2/3的节点总数处于同一高度时,整条链就有机会达成共识,继续出块。其余1/3的节点可能与参与共识的节点高度不同,这意味着从该节点读取的数据不是全网最新数据,而仅代表该高度的链的快照.业务逻辑可以以区块高度为参考值,根据高度做一些判断逻辑。在确定性共识(如PBFT)的链上,使用f+1查询等方式确认链的最新高度。在链上,需要参考“6个区块确认”的逻辑,慎重选择一个可信的区块高度。4非可信交易数据交易(Transaction)代表一方向另一方发起交易请求。交易可能导致资产转移、账户状态或系统配置发生变化,区块链系统将在通过共识后确认交易,使相关交易生效。交易必须带有发送方的数字签名。交易中的所有数据字段都必须包含在签名中。未签名的字段可能是伪造的,不会被接受。当交易数据在网络上广播时,可以被其他人读取。如果交易数据包含隐私数据,发送方必须对数据进行脱敏或加密。交易可能因为网络原因被重发,也可能被他人故意保存并重发,导致交易“重播”。因此,区块链系统必须防止重复交易,避免“双花”。5不要相信状态数据区块链的状态(State)数据是智能合约运行后产生的。理想情况下,每个节点的合约引擎是一致的,输入是一致的,规则是一致的,所以输出状态应该是一致的。但是,不同的节点可能安装了不同的软件版本,或者合约引擎的沙盒机制不够严格,引入了不确定因素,甚至被入侵、篡改,或者存在其他莫名的BUG,都可能导致合约输出结果不一致。合同。那么就无法保证一致性和事务性。状态验证是一件非常昂贵的事情。典型的验证方法是使用MPT(MerklePatriciaTree)树来管理树中的所有状态。MPT树可以将所有状态归于一个MerklerootHash,在共识过程中节点间交易操作确认后生成的状态树Merkleroot保证了状态的一致性。这棵树结构复杂,数据量大,消耗大量的计算和存储资源,很容易成为性能瓶颈。因此,需要有一种更快、更简单、更安全的状态验证方案,比如结合版本验证、增量哈希验证等算法,辅以数据缓存,减少重复计算,优化IO次数,并且可以确保一致性在保证准确性和正确性的同时,可以有效提高验证效率。6不信任私钥持有者使用私钥签署交易等关键操作,然后使用公钥验证签名,这是区块链上最基本的验证逻辑。只要正确使用私钥,此逻辑就是安全的。但是私钥只是一段数据,只有依靠私钥才能使用户匿名。在联盟链面临的场景中,需要使用基于权限的身份。首先,通过KYC、尽职调查、权威认证等现实世界的验证方式确认身份,然后将身份和公钥绑定公钥,或者结合PKI系统。数字证书颁发公钥和私钥,使私钥对应的身份是已知的、可信的、可控的。私钥可能因遗失、泄露或因遗忘而丢失资产而被他人窃取。因此,在私钥的存储上,需要考虑完善的保护方案,比如加密存储、TEE环境、密码卡、USBkey、软硬加密机等方案。在私钥管理方面,需要考虑丢失后如何安全地重置和找回密钥。增强版私钥有多种使用方式,如多重签名、门限签名等,每笔交易必须使用多个私钥进行签名,私钥可以存放在不同的地方,安全性高,但是技术解决方案和复杂的经验。另一种是交易私钥和管理私钥分离。交易私钥用于管理资产,管理私钥用于管理个人数据。交易私钥可以通过管理私钥进行重置,管理私钥本身通过阈值、分片等算法单独存储保管,用于重置或取回。7不要相信其他链在跨链场景下,每条链都有自己的资产和共识,链与链之间的安全模型变得非常复杂。比如一条链上的记账人串通作弊,或者链条分叉,区块高度回滚。此时如果链外其他模块与链上交互不严谨,就会造成数据不一致或资产丢失。如果不同的链采用不同的平台架构,工程化会更加复杂。跨链和侧链仍然是业界正在研究和逐步实现的课题。主要目的是解决链与链之间的通信,进行资产锁定和资产交换,保证全流程的全局一致性,事务性交易,反腐败。欺诈罪。将资产从A链转移到B链,需要保证A链上的资产被锁定或销毁,并且必须向B链添加相应的资产。在双方可能分叉或回滚的时间窗口内,必须有一种机制来确保双向资产安全。在现有的跨链方案中,有中继、跨链HUB等方式。这些系统的设计也必须满足高度可信和可靠的标准,安全级别不应低于甚至高于所连接的链。应采用多中心、群体共识的系统设计,整体复杂度可视为链的N次方。8不要信任网络层区块链节点需要与其他节点进行通信,因此必须在网络上暴露自己的通信端口。如果他们通过公网通信,就相当于把自己暴露在公网上,很容易被类似的渗透,DDOS这样的网络攻击。节点必须在网络层进行自我保护,包括在网关上设置IP黑白名单、设置端口策略、DDOS流量防护、监控网络流量和网络状态等。如果网络流量或连接数突然增加,也许,是有人把它当成肉鸡,或者正在出库的过程中。不应向公共网络开放不必要的端口。例如,用于管理和监控的RPC端口只能在组织内部开放。在设置网络策略之前要小心。9不要相信代码“Codeislaw”确实是一句响亮的口号,但是在程序员的头发还没掉之前,他写的代码可能有bug,就看写bug快还是修复快。无论是底层代码还是智能合约代码,都可能存在技术或逻辑上的隐患,但代码产生的任何数据和指令行为都需要另一段代码来严格验证,代码本身也需要静态和动态的。扫描,包括使用形式证明等技术进行全面审查和验证,以检测可能的逻辑错误、安全漏洞或信息泄漏。前段时间在github上公布了一个酒店系统代码,里面居然包含了mysql连接用户名和密码,数据库端口居然是对外开放的。这种陷阱简直难以想象。发布的开源代码当然可以被审查反馈,提高安全性,但也有可能被人查漏洞,被随意修改,甚至被恶意埋地雷。但总的来说,开源利大于弊。在开源社区中,开发者会向项目提交PR(PullRequest)。审查PR是一项关键而繁重的工作,值得安排专家并分配大量时间进行审查。某开源项目老司机透露,该项目核心模块PR的review时间长达数年之久,否则“加一个功能引入两个bug”实在得不偿失,更别提了如果它被植入漏洞并埋下地雷。10不信任记账人共识的过程可以大致抽象为,选择记账人,记账人发布区块,其他节点检查确认。公链中的记账可以通过“挖矿”(如比特币)的方式进行。矿工用大量的算力为自己的诚信背书,或者用大量的资产权益获得记账权(Pos和Consensus如DPos)。在联盟链常用的PBFT/Raft等算法中,记账人列表可以是随机的,也可以是轮换的。簿记员给出提案,其他选民分多个步骤提交以收集选票。根据少数服从多数的原则,一般有2/3以上的共识节点同意达成共识。从系统可用性的角度来看,簿记员可能会出错、崩溃或运行缓慢,影响整个链条的出块。或者记账员只能收录手续费高的交易,舍弃部分交易,导致部分交易始终无法完成。一些记账人还可以依靠算力或黑箱操作,进行“预挖”或“扣块攻击”,破坏游戏关系……如果记账人发生故障或作恶,超过共识安全阈值,会直接损害整个链条的价值基础。根据不同的记账模型,记账人需要设计不同的容错、验证、反欺诈算法,实施激励和惩罚机制,并在运行过程中定期检查记账人的健康状况。记账节点,全网不接受他们的记账结果,对他们进行惩罚,甚至踢出网络。...还有很多要列举的,包括合约、证书、同步等等,每个模块都有自己的功能和风险点,简直多到写不完。总之,区块链作为一个分布式的多方协作系统,接入了各个参与者。整个系统绝不是单个开发人员或运营商的单一控制点。“善意炒作”在这个领域已经不适用,步步惊心,冷箭无处不在,共识和安全只能通过严谨的算法和复杂的流程来维护。简而言之,没有经过验证的信息,单个字节是不可信的。与单一环境下的软件设计相比,区块链领域的设计思路确实具有颠覆性。开发者要跳出“做功能,只做容错,不做防欺诈”的思维模式,以“怀疑一切”的态度去设计。开发者在面对区块链领域时,不仅仅要思考如何实现一个功能,更要思考整个过程会不会出现错误,会不会有人篡改数据,发现漏洞,攻击系统,诈骗他人参与者。需要同理心自己实现的功能,别人会如何使用,在不同的环境下会有怎样的表现,可能会造成什么后果。任何接收到的信息,任何过程的输入输出,都必须经过严格验证才能被接受。开发者如果能做到这一点,也算是打开了区块链新世界的大门,至少能活到系列第一阶段。两集。分布式算法、对称和非对称加密、HASH、证书、安全和隐私等技术在区块链领域大行其道,这些技术都是在保护信息的同时为信息增加证明层和可验证因素。这让整个系统变得复杂和繁琐,但这是值得的,因为可以一起验证,建立“安全”和“信任”。以上是为准备跳坑,或者已经入坑的程序员写的。共勉。