写点什么

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

张开翔

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

    阅读完需:约 13 分钟

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

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

“我篡改了区块链数据”

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:262361

评论

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

软件测试 | 测试开发 | 测试人生 | 疫情之下涨薪70%从手工转到测试开发,是种什么样的体验?

测吧(北京)科技有限公司

测试

软件测试 | 测试开发 | 使用 Zabbix + Grafana 搭建服务器监控系统

测吧(北京)科技有限公司

测试

【云舟说直播间】数字可视化专场来袭

云计算

UIE Slim满足工业应用场景,解决推理部署耗时问题,提升效能

汀丶人工智能

“程”风破浪的开发者|Lombok的使用

楠羽

学习方法 lombok “程”风破浪的开发者

“程”风破浪的开发者|OpenHarmony设备开发-开发板介绍

坚果

OpenHarmony 10月月更 “程”风破浪的开发者

JS词法环境和执行上下文

hellocoder2029

JavaScript

如何让研发成员在会议上知无不言?

LigaAI

项目管理 敏捷开发 会议管理 迭代管理 企业号十月PK榜

java线下培训机构哪里比较好

小谷哥

前端培训学习后的就业方向哪个比较好

小谷哥

股票价格跨度

掘金安东尼

算法 10月月更

ES6 Promise、Generator与async简单介绍与应用

木偶

前端 ES6 异步 10月月更

MySQL十种锁,一篇文章带你全解析

一灯架构

Java 10月月更

低代码开发平台盘点,让你的开发告别低效

飞算JavaAI开发助手

鸿蒙开发入门 | 开发第一个鸿蒙应用+页面跳转

TiAmo

华为 鸿蒙开发 10月月更

诺亚财富 X Hologres : 统一OLAP分析引擎,全面打造金融数字化分析平台

阿里云大数据AI技术

大数据 数据分析 企业号十月 PK 榜

新来个技术总监,仅花2小时,撸出一个多线程永动任务,看完直接跪了,真牛逼!

程序知音

Java 架构 多线程 多线程与高并发 后端技术

Plan Stitch:一种使用缝合物理计划解决查询计划性能退化问题的方法

KaiwuDB

阿里巴巴 Noslate 正式开源 - 面向云原生的 JavaScript 容器方案

阿里巴巴终端技术

JavaScript 开源 云原生 前端 企业号十月PK榜

Spring Boot 应用使用 application.yml 和 application.properties 的区别

汪子熙

Java mvc spring 后端开发 10月月更

突破单点瓶颈、挑战海量离线任务,Apache Dolphinscheduler在生鲜电商领域的落地实践

白鲸开源

海豚调度 Apache DolphinScheduler 大数据调度 数据调度 企业号十月 PK 榜

细说JavaScript闭包

hellocoder2029

JavaScript

企业级开发平台的演进

世开 Coding

软件开发 低代码 快速开发平台 少代码

Paddlenlp之UIE模型实战实体抽取任务【打车数据、快递单】

汀丶人工智能

nlp

基于网络安全的Docker逃逸

网络安全学海

黑客 网络安全 信息安全 渗透测试 WEB安全

JS知识点梳理之作用域、作用域链、柯里化、闭包

hellocoder2029

JavaScript

一文详解MySQL事务底层原理,全是干货,推荐收藏

一灯架构

Java 10月月更

2022年上海前端培训开发技术就业前景如何

小谷哥

解决 error: failed to push some refs to 'https://github.com/

timerring

git bug 10月月更

大数据开发学习周期是多久

小谷哥

北京培训java开发的机构比较好

小谷哥

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