写点什么

如何解释“我篡改了区块链”这个问题

张开翔

  • 2020-07-06
  • 本文字数:3815 字

    阅读完需:约 13 分钟

如何解释“我篡改了区块链”这个问题

AI 大模型超全落地场景&金融应用实践,8 月 16 - 19 日 FCon x AICon 大会联诀来袭、干货翻倍!

区块链数据“全局一致”、“难以篡改”这两个特性已经广为人知,是区块链营造“信任”的基石。为了达到这两个效果,区块链的共识、同步、校验等技术细节足可大书特书,而本文要从“我篡改了区块链数据”讲起。

“我篡改了区块链数据”

FISCO BCOS 开源联盟链社区现在相当活跃,每天都会产生大量的讨论,大家也会饶有兴趣地研究和挑战区块链如何做到“难以篡改”。我们注意到,尤其在 FISCO BCOS 支持 MySQL 数据库作为数据存储引擎后,隔一阵子就有同学在群里问:“我手动修改了我节点连接的数据库里某个状态数据,这是不是就是篡改了区块链数据呢?


直观地举个例,如链上有个智能合约,管理特定资产余额,在数据库合约表里,经过共识的 Alice 的余额本来是 100,这时有人打开 MySQL 客户端,找到那个合约对应的 Table,把 Alice 的余额 update 成 10000


这时他表示:“你看,我调用合约的查询接口,查出来 Alice 的余额确实是 10000,这就不对了嘛,而且,链还在出块,根本不防篡改嘛!”。

初步分析和解答

为何这类问题最近多起来了?我们分析了下,猜想主要是由于 MySQL 数据库用户基础良好,体系比较成熟,给用户提供友好的命令行或图形化交互工具,FISCO BCOS 提供了一种 Table 风格的合约开发模式,表结构设计得清晰直观,对于用户来说,一方面理解和管理起来更容易了,另一方面顺手 update 甚至 delete 一下都是小意思。


下图仅为示例数据,采用 KVTable 合约方式,创建了名为 t_kv_node 的合约表,系统自动加了“u_”前缀,可见,这个表结构和数据一目了然。



而之前只采用 LevelDB 或 RocksDB 作为存储引擎,这两个文件型数据库交互工具比较少,在用户面前的存在感不强,操作相对晦涩,主要通过 API 编程访问,数据用肉眼难以辨别的 Hash key 寻址,动手修改数据库的 case 就少了一些(但也不是不可能)。


所以,热点问题浮出水面,前提是用户可以更方便地修改底层数据了,而不是这个问题之前不存在。


这时我们会建议用户试一下,针对 Alice 的余额,发起一个交易,比如给 Alice 充值,或者让 Alice 转账操作,这时,修改过数据的节点将无法参与共识。因为该节点上算出来的 Alice 的余额和其他节点结果不同,其他节点依旧按 100 的余额进行计算,而不是 10000,显然结果是对不齐的。



复习下 PBFT 的容错模型:定义“f”为可容错节点数,网络中共识节点总数应等于或多于 3f+1。即链上有 4 个共识节点时,可容错的 f=1,共识节点总数为 7 个时,f=2,以此类推。


如果未修改过数据的节点数满足 PBFT 要求的 2f+1 的数量,链依旧可以出块。但被修改过的节点,一旦有交易涉及脏数据,就像踩到了雷一样,从此再无法与链共识、同步,相当于被抛弃了。这种节点可以称为“拜占庭节点”,即作恶或出错的节点,具备节点准入控制能力的联盟链甚至会将拜占庭节点隔离出去。


还有一种可能性是,手动修改了数据库里的数据,但节点内存里还刚好缓存了一份副本,并没有被修改,所以通过节点对这个数据的查询、交易还是正常的,甚至会用正确的结果把数据库里被篡改过的数据覆盖掉,不过这是概率性事件,取决于缓存的大小和当时包含的数据项。


注:对于采用 PoW 或其他共识机制的链来说,容错模型有所不同,但在容错范围内的少数节点被篡改,也不会影响链的共识。

“能否篡改整个联盟链”

有的同学可能会继续刨根问底:“那我多修改几个节点的数据是不是就篡改了?”,一般提出这个问题的同学是面向他自己部署的开发测试环境,所有节点都在他手上,所以可以随便改。


在真实的联盟链环境上,节点分别掌握在不同机构手里,要修改,首先得侵入他人的网络、获得服务器和数据库权限、发起修改再全身而退。事实上,在注重安全防护的商业化环境里,这是非常艰难、几乎不可能做到的事情。



从机构粒度来看,单个机构掌握的节点数,应该低于共识算法可容错的数量。比如,链上总共有 7 个共识节点,那么单个机构掌握的共识节点不应多于 2 个,这样可以避免机构内部强行修改自己掌握的节点数据,或一个机构的所有节点都意外出错、掉线(比如机房光纤都被挖断了),导致链无法出块。


真的没有办法防“本地篡改”吗?

考虑区块链数据本地验证的机制,比如区块之间的 Hash 关系、状态的 Merkle 树结构、共识节点的签名等,按数据的互验关系顺藤摸瓜进行检测,似乎有一定概率可以本地检测出数据异常。


但进一步想,对某个数据的查询,区块链的本地校验范围是有限的,一般不会超出单个区块或者一棵 merkle 树,所以如果篡改者比较熟悉区块链数据的结构和本地校验逻辑,也可以顺着数据校验关系,从状态值开始,把 merkle 树、区块 Hash 等关键数据全部改掉。


甚至更彻底地,从创世块开始,把所有的区块、系统配置(对于 PoW,可以修改挖矿难度以加速出块)、PBFT 的共识者列表等等,都按他的逻辑改一遍,这样这条本地数据链依旧是校验自洽的,只是无法和其他节点共识了。


这种改法,听起来需要不少力气活,但对于一个有决心、有能力的篡改者来说,改改本地数据这个事情其实并不难,难的只是去改别的机构数据而已。



到了这个份上,就相当于一个人铁了心要“骗自己”,那神仙都没有办法了。一旦把本地数据修改的权限交给了不适当的人,最坏情况下,整条链没有一个字节是对的。


但是,本地数据再错,也只会影响自己,影响不了别人,一旦和其他节点进行共识,就会被发现,甚至被惩戒,整个效果会有一点掩耳盗铃的意思。

“为什么区块链不拦住我篡改数据?”

再进一步,那位同学又会问:“为什么区块链不能立刻发现、并且阻止我篡改数据?也许我只是无意手误呢”。坦率说,这有点对区块链期望过高了。


区块链系统并非无所不能,也不会包办一切,区块链并不会阻止用户对自己的服务器、软件、数据库等施加操作,就像法律不能也不应去阻止你打碎家里的杯子一样。


本质上,区块链的一致性、难以篡改性是面向“全局”的,是由多方博弈和协作达成的,当链上交易牵涉错误数据时,共识机制可以检测并拒绝已被篡改的数据,保证链上剩余的大多数健康节点继续共识出块。而节点本地不参与共识的数据,共识机制鞭长莫及。


那么,区块链为什么不能主动检测和纠正错误,保证每个节点上的数据一致性?首先,链上的数据非常庞杂,用户直接登入数据库手动修改少量数据,区块链节点并不知道哪一条数据被修改了,无法触发检查。


如果区块链系统定期巡检所有数据,并将所有数据和其他节点进行比对,可想而知,这样做的话,网络、磁盘和计算开销会非常大。


关键是,这并不解决问题,因为从数据被篡改后到检测出来的时间窗里,哪怕脏数据只存在了几十毫秒,但这时如果不幸有应用来查询数据,依旧会得到篡改后的结果。对要求苛刻的业务来说,事后检测未必是最佳选项,因为有可能已经造成了业务损失,届时能做的最多就是告警和冲正了。


当然,也可以结合数据库的操作监控、binlog 等辅助机制,加速响应速度和检测效率。方法还是有的,如上所述,只是性价比较低,也不彻底解决问题,只有对数据修改极其敏感,且业务上接受延时发现和修订的特定场景,才会考虑将其作为补救措施。我们把这部分归类到运营管理工具里,根据场景需求来实现。


还有一种方法,可以部分解决查询问题:f+1 查询。即查询数据时,无论是查区块数据,还是合约的状态数据,不妨多查几个节点,查询节点数多于 f 即可。


如链上有个 7 个节点时,f=2,用户查询自己节点之外,继续发出网络请求去查询其他机构的 2 个节点,共查询 3 个节点,如果得到的数据都是一致的,则表示数据一定是正确的,反之,一定是这 3 个节点里出了问题。



但是,要执行 f+1 查询,前提是其他机构开了查询接口权限,让你连接上去查询。在很多安全防护严密的联盟链上,一般只打开节点之间 P2P 互联的网络端口,不会轻易给其他机构提供数据查询权限。再则,在网络上发起多次查询,其异步性、时效性、成功率和性能表现都会带来更多变数。


综上所述,对节点本地的数据,就像打地鼠,冒头的(发出交易参与共识,或进行 f+1 查询),区块链全局共识和容错机制能发现,没有冒头仅蹲在用户硬盘里的,只能用户自己负责了。

结语

区块链通过网络博弈、多方校验实现了全网的容错防作恶,而区块链同步给到各节点的本地数据,需要用户自行妥善管理保存。


从信任传递来看,首先用户得“信自己”,如果连自己都无法相信,说明系统和数据管理有漏洞,莫说是修改数据了,在本地系统的整个链路上,包括区块链软件、SDK、业务服务都有可能出错和篡改作假,这样的环境有何信任可言?


节点持有者必须非常审慎,首先不要手痒或手误去改数据,然后关键是要建立周全的制度,包括管理策略和技术防护,比如,主机访问控制、数据库登录和操作权限控制、操作审计、日志审计等,以避免本机构内有人越权访问监守自盗,或者被外部渗透。


万一数据出错,区块链比中心化系统好一点的就是,还有可能通过与其他节点互相校验检测出来,这时则应该进行告警、查证、补正和追责,以及在有条件和有必要的前提下,善用 f+1 查询方法,给查询操作加一点点保险。


另外,建议定期备份节点数据到安全的离线设备上,这样无论是出现意外还是人为的数据问题,依旧可以从冷数据里快速恢复,保证一定的 RTO(复原时间目标)和 RPO(恢复点目标)。


而区块链的健壮性在于,无论单个角色怎么折腾自己的节点和数据,对全局是没有影响的,只有修改者自己受损。任凭窝里翻天覆地,链上依旧云淡风轻,其“全局一致”、“难以篡改”的定律依旧成立,链仍然是信任的锚点,这就是区块链的魅力。

关于作者

张开翔,FISCO BCOS 首席架构师。


2020-07-06 09:262053

评论

发布
暂无评论
发现更多内容

Harbor和Dragonfly双剑合璧 打造容器镜像运维新模式

亨利笔记

容器 k8s Harbor dragonfly 镜像

死磕Java并发编程(4):happens-before是什么?JMM最最核心的概念,看完你就懂了

Seven七哥

Java Java并发 happens-before JMM

如何读IPO招股说明书(2)到哪儿下载招股书?

赵新龙

IPO 上市 招股说明书

演讲的秘诀

伯薇

个人成长 演讲 追求极致 完美主义

“IPO上市扒层皮”,以阿里巴巴为例看看公开了什么 | 如何读IPO招股书(3-a)

赵新龙

阿里巴巴 IPO 招股说明书

JCJC错别字检测JS接口新增CORS跨域支持

田春峰-JCJC错别字检测

如何避免把中台变成外包团队

松花皮蛋me

数据中台

程序员陪娃漫画系列——吃饭

孙苏勇

程序员 生活 陪伴 漫画

“消灭你,与你无关”——阿里巴巴的风险 | 旧文重发

赵新龙

阿里巴巴 风险 蒋凡 IPO

曾国藩的人生“六戒”

霍太稳@极客邦科技

身心健康 个人成长 心理学

不知不觉,写了10000字了

小天同学

写作 个人感想 思辨

“IPO上市扒层皮”,以阿里巴巴为例看看公开了什么 | 如何读IPO招股书(3-b)

赵新龙

阿里巴巴 IPO 招股说明书

我不是怕表错态,而是怕我会不自觉地捍卫它

池建强

个人成长

vSphere 7融合Kubernetes,构建现代化应用的平台

亨利笔记

Kubernetes 容器 云原生 k8s vSphere

OpenCV 在 Android 上的应用

fengzhizi715

android OpenCV 计算机视觉

Nginx学习

陈雷雷

nginx

我们是时候降低对完全自动驾驶的期望了

赵钰莹

自动驾驶 AI

像产品设计一样思考、像程序运行一样执行

水色

哪儿有真实靠谱的数据,说谎话必须负责的那种?| IPO招股说明书(1)

赵新龙

阿里巴巴 IPO 旷视科技 数据

迷茫时,想想能为这个世界做些什么就好了

霍太稳@极客邦科技

身心健康 个人成长 团队协作

浅谈行业软件

孙苏勇

软件 思考 转型

二叉树的先序中序后序递归实现

Kenn

算法 递归

Golang 真的好用吗?

极客时间

编程语言 Go 语言

批注MYSQL开发规范,助你了解其背后的“道”

三石

数据库规范 规范背后的原理 白话规范

ZGC都出来了,你还不懂G1?

大白给小白讲故事

G1 JVM

祝这些不要脸的王八蛋同行家里着火

二爷

运维 Harbor 镜像仓库的法宝:Operator

亨利笔记

Kubernetes 容器 k8s Harbor operator

“WHY-HOW-WHAT”这个被誉为伟大的领袖如何激励行动的黄金圈法则,非常值得大家学一学!

数列科技杨德华

思维方式

二叉树先序中序后序的非递归实现

Kenn

算法

回"疫"录(4):见证历史

小天同学

疫情 回忆录 现实纪录 纪实

判断链表是否有环

Kenn

算法 链表 双指针 Brent

如何解释“我篡改了区块链”这个问题_语言 & 开发_InfoQ精选文章