共计 4913 个字符,预计需要花费 13 分钟才能阅读完成。
id:BSN_2021
公众号:BSN 研习社
先讲论断:简直什么都不能信!
1 不信赖其余节点
区块链节点和其余节点会建设 P2P 通信,独特组成网络,传递区块、交易、共识信令等各种信息。其余节点可能是由不同的机构、不同的人持有,持有节点的人可能是善意,也可能是歹意。
即便在善意假如时,节点运行存活的衰弱度也会受运维程度和资源影响,比方处于一个不稳固的网络里,会偶然挂掉,会抽风乱发音讯,或者硬盘满等起因导致数据存储失败,以及呈现其余可能的故障。
在歹意假如时,要预设其余节点可能会骗本人或挫伤本人,比方传递过去谬误的协定包,或者用诡异的指令寻找破绽进行攻打,或者发动高频垃圾申请,频繁连贯而后断开,又或者海量连贯占用资源等。
所以节点应该是把本人看成在光明丛林里孤身求生存的猎人,必须有“独立自主”、“自力更生”的态度,摆出“不置信其余任何节点”的姿态爱护本人。在节点准入时,须要采纳证书技术来认证节点身份;在连贯管制上,回绝有异样的连贯;采纳频率管制对连贯次数、申请量等做限度;在协定包格局和指令正确性等方面做验证。本人收回去的信息,不应裸露本人的公有信息,也不冀望其余节点肯定会给出立即和正确的响应,必须采纳异步解决和校验容错的设计。
2 节点和客户端相互不信赖
客户端,指在区块链网络外,向区块链发动申请的模块,如业务应用的 java sdk、钱包客户端等。客户端和节点通过网络端口通信。
如果客户端把握在不受控的人手里,有可能会向节点发动大量的申请,或发送一堆垃圾信息,使节点疲于应答,甚至奇妙地构建破绽攻打信息,试图越权拜访,窃取信息或使节点出错。
同时,从客户端的角度看,节点有可能不响应或响应迟缓,或者返回谬误的数据,包含格局谬误、状态谬误、示意收妥但其实不解决等,甚至居心叵测的人会设置一个“假”节点和客户端通信,坑骗客户端。节点做出这些与冀望不符的反馈,可能使客户端运行出错,性能受损。
为晋升节点和客户端的互信,能够为单方调配数字证书,必须通过证书进行双向握手,客户端通过私钥签名能力对节点发动交易类申请,节点应答客户端进行权限管制,回绝高危的接口调用,不要轻易凋谢节点治理接口、系统配置接口等。单方对每次通信的数据格式、数据有效性都进行紧密校验。
单方在交互时也应该进行频率管制,异步解决,对每一个交互进行后果校验,不能预设对方正确处理,必须获取交易回执和处理结果进行确认。
当认为只和一个节点通信并不能保障平安时,客户端能够采纳“f+ 1 查问”的思路,尽可能多地和几个节点通信。如果以后链的共识平安模型是“3f+1”,那么,如果从 f + 1 个节点读到的信息是统一的,后果是能够确认的。
3 不信赖区块高度
区块高度是一个十分要害的信息,代表整个链以后的状态。向区块链发送交易、节点间进行共识、对区块和状态的校验等操作都会依赖区块高度。
某个节点在断网或处理速度迟缓时,其区块高度有可能落后于整个链,又或者某个节点歹意伪造数据时,其高度又可能超过整个链。在链呈现分叉时,如某一个分叉上的区块高度被另一个分叉超过,落后的分叉就会变得毫无意义。即便在失常的状况下,节点仍旧有可能间歇性地落后于整个链一到几个区块,而后在肯定工夫内才可能追上最新高度。
如在 PBFT 共识模型里,总数 2 / 3 以上节点在同一个高度时,全链就有机会达成共识持续出块。余下的 1 / 3 的节点有可能和参加共识的节点高度不同,这时意味着从这个节点读取到的数据,并不是全网最新的数据,只能代表链在该高度时的一个快照。
业务逻辑能够把区块高度做为一个参考值,基于高度做一些断定逻辑,在确定性共识(如 PBFT)的链上,采纳 f + 1 查问等办法确认链的最新高度,在可能分叉的链上,须要参考“6 个区块确认”的逻辑,审慎选取可信的区块高度。
4 不信赖交易数据
交易(Transaction)代表一方向另一方发动了一个事务申请,交易可能导致资产的转移、扭转帐户状态或系统配置,区块链零碎通过共识后确认交易,使相干的事务失效。
交易必须带上发送者的数字签名,交易里所有数据字段都必须蕴含在签名里,未经签名的字段存在被伪造的可能,不予采信。
交易数据在网络上播送时,能够被其他人读取,如交易数据里蕴含隐衷数据,发送者则必须对数据进行脱敏或加密爱护。
交易可能因为网络起因被重发,或者被其他人保留下来刻意再次发送,造成交易的“重放”,所以区块链零碎必须对交易进行防重,避免出现“双花”。
5 不信赖状态数据
区块链的状态(State)数据是由智能合约运行后生成的,现实状况下,每个节点的合约引擎统一、输出统一、规定统一,那么输入的状态就应该统一。但不同的节点可能装置了不同的软件版本,或者合约引擎的沙盒机制不够紧密引入了不确定性因素,甚至被侵入、篡改,或者存在其余莫名其妙的 bug,都可能导致合约运行输入后果不统一,那么一致性和事务性就无奈失去保障。
状态的校验是老本很高的事件,典型的校验办法是应用 MPT(Merkle Patricia Tree)树,把所有状态都塞到树里治理起来。MPT 树能够把所有的状态归结为一个 Merkleroot Hash,节点之间在共识过程中确认交易运行后生成的状态树 Merkleroot,确保状态统一。
这棵树结构简单,数据量大,耗费不少的计算和存储资源,很容易就成为了性能瓶颈。所以对状态的校验须要有更快、更简略,且又稳当的计划,如联合版本验证、增量 Hash 验证等算法,辅以数据缓存,可缩小反复计算和优化 IO 次数,能在保障一致性、正确性的同时,无效地晋升验证效率。
6 不信赖私钥持有者
采纳私钥对交易以及其余要害操作进行签名,再应用公钥验签,是区块链上最根底的验证逻辑。只有私钥被正确应用,这个逻辑是平安的。
但私钥仅仅是一段数据,只依赖私钥则用户是匿名的。在联盟链面对的场景里,须要应用许可型的身份,首先通过 KYC、尽调、权威认证等事实世界的验证形式确认身份,而后将身份和公钥绑定并公示,或者联合 PKI 体系的数字证书发放公私钥,这样私钥对应的身份是可知、可信、可控的。
私钥可能会因失落、透露而被别人盗用,或者因被忘记导致资产损失。所以在私钥的保留上,须要思考采纳周全的爱护计划,如加密存储、TEE 环境、明码卡、USBkey、软硬加密机等计划。在私钥的治理上,则须要思考密钥失落后如何平安的重置、找回。
加强版的私钥应用思路有几个,比方应用多签、门限签名等形式,每次交易时必须用多个私钥进行签名,私钥能够保存在不同的中央,安全性高,但技术计划和应用体验简单。
还有一种是交易私钥和治理私钥拆散。交易私钥用于治理资产,治理私钥用于治理个人资料,交易私钥能够被治理私钥重置,治理私钥自身则通过门限、分片等算法,离开存储保存,以备重置或找回。
7 不信赖其余链
在跨链的场景里,每条链有本人的资产、共识,链之间的平安模型变得非常复杂,比方一条链上的记账者串通造假,或者链呈现了分叉、区块高度回滚,这时如果链外的其余模块和链有不够谨严的交互,都会造成数据不统一或资产损失。
如果不同的链采纳的还是不一样的平台架构,那么在工程上会更加简单。
跨链、侧链目前仍旧是业界在钻研和逐渐实现的课题,次要目标是解决链和链之间的通信,进行资产锁定和资产替换,保障整个过程的全局一致性、交易事务性,以及抗欺诈。从 A 链往 B 链转移一个资产,必须要确保 A 链上的资产被锁定或销毁,且 B 链上肯定能减少对应的一笔资产,在单方可能别离呈现分叉、回滚的工夫窗里,要有机制确保双向的资产平安。
在现有跨链的计划里,存在中继、链间 HUB 等形式,这些零碎的设计自身也要达到高度可信牢靠的规范,安全等级应不低于甚至高于所对接的链,同样也应采纳多核心、群体共识的体系设计,整体复杂度可算是链的 N 次方了。
8 不信赖网络层
区块链节点须要和其余节点产生通信,所以必须在网络上裸露本人的通信端口,如果通过公网通信,那么相当于在公网上裸露了本人,很容易受到相似浸透、DDOS 这样的网络攻击。节点必须在网络层爱护本人,包含在网关上设置 IP 黑白名单、设置端口策略、进行 DDOS 流量防护,且对网络流量、网络状态进行监测,如果突发网络流量或连接数暴增,说不定,就是被人当肉鸡或者正在脱库进行时了。
非必要端口,切忌对公网凋谢,如用于做治理监控的 RPC 端口,只能对机构外部凋谢,在进行网络策略设定之前,肯定要慎之又慎。
9 不信赖代码
“Code is law”的确是一句嘹亮的口号,然而在程序员头发掉光之前,他写的代码都可能有 bug,只是看写 bug 快还是修 bug 快而已。
无论是底层的代码还是智能合约代码,都可能存在技术性或逻辑性的坑,凡是代码产生的数据和指令行为,都须要另一段代码对其进行严格地校验,代码自身也须要进行动态和动静扫描,包含采纳形式化证实等技术进行全面地审核验证,以检测可能的逻辑谬误、安全漏洞或是否有信息泄露。前段时间有一份颁布到 github 上的某酒店零碎的代码,竟然包含了 mysql 的连贯用户名明码,且数据库端口竟然是向公网凋谢的,这种坑几乎不可设想。
凋谢进来的开源代码,诚然能够被人审查、反馈以晋升安全性,也可能被人翻找破绽、随便批改,甚至歹意埋雷。但总的来说,开源还是利大于弊。在开源社区中,开发者会向我的项目提交 PR(Pull Request)。审核 PR 是很要害也很沉重的工作,值得安顿专家并调配大量工夫去做审核。有开源我的项目的老司机走漏,其我的项目外围模块的 PR 的审核工夫长达经年,否则“加了个性能引入两个 bug”那真是得失相当,更别说如果被植入破绽埋雷了。
10 不信赖记账者
共识的流程大抵能够形象为,选出记账者,记账者公布区块,其余节点校验和确认。公链里记账能够用“挖矿”的形式进行(如比特币),矿工用大量的算力代价为它本人的诚信背书,又或者是用大量的资产权利抵押取得记账权(Pos 和 DPos 等共识)。在联盟链罕用的 PBFT/Raft 等算法里,记账者列表能够是随机或轮换产生,记账者给出提案,其余投票人多步提交,收集投票。按多数遵从少数的准则,个别是 2 / 3 以上共识节点批准,共识能力达成。
从零碎可用性角度看,记账者有可能出错、解体,或者运行迟缓,影响整个链的出块。又或者记账者能够只收录手续费高的交易,摈弃一些交易,导致有些交易总是不能达成。有的记账者还能够凭借算力或暗箱运作,进行“预挖”或者“扣块攻打”,毁坏博弈关系……
记账者故障或作恶,超过了共识的平安阈值的话,将间接挫伤整条链的价值根底。依据不同的记账模式,记账者须要设计不同的容错、校验、抗欺诈算法,执行激励和惩办机制,在运行过程中定期检查记账者的衰弱度,对于有力记账或者作恶的记账节点,全网不承受他们的记账后果,并对其进行惩戒,甚至是踢出网络。
……
列举起来还有很多,包含合约、证书、同步等等,每一个模块都有本人的功能和危险点,几乎罄竹难书。总之,区块链做为分布式的多方合作的体系,接入了不拘一格参与者,整个体系绝不是单个开发者或运营者所能单点把控,“善意揣测”在这个畛域曾经不尽实用,整个世界步步惊心,处处冷箭,只能通过周密的算法和繁冗的流程维系共识和平安,简而言之,没有通过验证的信息,一个字节都不能置信。
比起繁多环境里的软件设计,区块链畛域的设计思路的确存在颠覆性,开发者要从“做性能,只容错,不防骗”的思维模式里跳进去,带着“狐疑所有”的态度进行设计。
开发者在面向区块链畛域时,不能只是思考怎么实现一个性能,而更要去思考整个流程会不会有出错,会不会被人篡改数据、挖掘破绽、攻打零碎、欺诈其余参与者。要换位思考本人所实现的性能,会被他人用什么形式应用,在不同的环境会有什么体现,可能造成什么结果。任何收到的信息,任何流程输出、输入,都必须通过严格地校验能力采信,开发者能做到这一点,才算是关上了区块链新世界的大门,能力在连续剧里至多活到第二集。
分布式算法、对称非对称加密、HASH、证书、平安和隐衷等技术在区块链畛域大行其道,都是为了在爱护信息的同时,给信息加上一层又一层的证实和可验证因子,这使得整个零碎变得复杂、繁琐,但这是值得的,因为这样能力独特验证,构建“平安”和“信赖”。
以上,写给筹备跳坑,或曾经在坑里的程序员。共勉。