星球日报
搜索
手机客户端
iPhone · Android
微信公众号
微信公众号

iPhone · Android

微信公众号

小明学习笔记 | 一文看懂区块链虚拟机

2018-08-17

沉迷学习,无法自拔。

小明学习笔记 | 一文看懂区块链虚拟机

编者按:区块链涉及到的技术很多,从互联网底层到不明觉厉的密码学,可是往往关注币价者多而研究技术的人少。牛市的时候,大家为了炒币也会努力学习,熊市的时候,反正也没啥事,我觉得可以更加努力学习。作为一个文科生,我当然会有很多理科生看起来觉得很白痴的问题。作为一个记者,我不难找到业内懂的人用人话给我解释,而且他们往往不会当面嫌弃我。

我写下我的学习笔记大家分享。这次学习的是虚拟机,还准备学习的有跨链、VRF、开源历史和文化、网络体系结构与区块链分层体系对比、“假如把币圈看成一个国家这个国家的货币在经历什么”。如果有其他有趣问题,欢迎投稿和提问。

小明学习笔记 | 一文看懂区块链虚拟机

这篇笔记真的长得超出我意料之外

智能合约是目前公链需要完善的一大方向。

以太坊的智能合约多次出现漏洞,业界普遍认为与智能合约太过灵活有关,即以太坊想把智能合约做成图灵完备。此前在我采访 ArcBlock CEO 冒志鸿的时候,他总结,以太坊智能合约漏洞,一是因为太过灵活了;二是由于虚拟机和语言是新做的,不太成熟。“前段时间发出溢出的问题(美图币的问题,都是整数溢出导致的),本来应该在语言层面就解决 。”

基于以太坊存在的这两个问题,致力于“做更好的以太坊”或者“垂直版的以太坊”的项目,会在原来的基础上改进,或发明自身的智能合约语言,我报道过的有以分片落地为特色的公链 Zilliqa,还有电商公链 CyberMiles。

CyberMiles 的虚拟机(CVM)及高级编程语言 Lity 是在最近发布的,我借此机会向他们首席科学家 Michael Yuan 请教了一些关于虚拟机的基础知识,并将我们的对话整理了出来。

记忆中,我最初接触到虚拟机是在学校网络中心做网管(此处省略一万字关于文科生在网络中心被碾压的悲惨故事),因为权限比较高,会在学校数据中心有个虚拟机上的账号;后来是我在财新实习时,一位同事为了在 Mac 系统上装万得而装了一个 Win 虚拟机;然后是在我报道阿里云和 Docker 合作时,由于虚拟机与 Docker  都是虚拟化技术,当时了解了一下两者的区别;最后,我又听到了 Java 虚拟机和以太坊的虚拟机(EVM)。

小明学习笔记 | 一文看懂区块链虚拟机

至此,我听过了操作系统之下和之上的虚拟机,究竟什么是虚拟机,先有系统还是先有虚拟机,为什么区块链需要虚拟机?

什么是虚拟机?

虚拟机顾名思义是相对于物理机而言,比如你们明明在用同一台电脑,我让你们觉得自己分别有一台电脑;你明明在用很多台电脑,让你觉得自己在用一台电脑。定义这种东西当然问度娘很容易找到,当往往似懂非懂——虚拟指通过软件模拟的具有完整硬件系统功能的、运行在一个完全环境中的完整计算机系统。但是操作系统之上的虚拟机似乎就不是那么回事了。

Michael 说人话的解释加深了我对虚拟机的理解。他告诉我,虚拟机的出现比 Windows这类操作系统和互联网还早,最早是为了解决计算机的分时租赁问题。

小明:虚拟机的作用究竟是什么?最早什么时候出现?

Michael:“最开始大型计算机是很多用户共用的,就是你用十秒,我用十秒,你觉得这台机器一直都是你的,我觉得它一直都是我的,但我其实不停地在等它十秒。在计算机从你切换到我的时候,必须重新把你刚刚计算的那些东西,全部给 restore 回来给你看,然后十秒钟之后,把你的去掉,把我的东西全部露出来给我看。”

“我们用的是同一台硬件,但上面有不同的虚拟机,每个人觉得这个硬件是自己的,但其实是用软件方法实现的,就是在大型机上实现虚拟机的做法。后来个人虚拟机的作用就小了,就没有必要去用。直到 1997 年 Java 出现的时候,虚拟机又变的特别重要。因为那个时候有Windows、Unix各种各样的操作系统。Java 是第一个说我用虚拟机把这些全部统一起来,你们就不用专门在 Windows写一个,在Unix写一个了,你们就用 Java 写,我上面有虚拟机。”

“虚拟机就是一个抽象化的作用,我虚拟机有自己的语言,然后你可以在虚拟机里面写东西,但是虚拟机下面可以有不同的硬件、不同的软件,甚至同一个硬件我怎么分成不同的时间片。虚拟机为什么叫做虚拟机?就是他把下面的东西给抽象掉了,你不需要管你的下面是什么。”

最早的虚拟机大概是 1965 年前后,IBM 的发明:一个单一的计算机系统可以通过 IBM 模型来模拟多个装有不同操作系统的计算机。这使得用户可以在一个计算机上创建和管理多个不同的虚拟机拷贝。IBM 模型的一个主要特征就是通过分割计算机资源和完全隔离程序来使程序共享同样的硬件。(copy 自《虚拟机总结》)

到上世纪 90 年代时,Java 程序语言开始流行,这打开了虚拟机应用的重头戏。因为当时网络跨越了不同的操作系统,不同的浏览器,不同的设备,要想运行同一个应用程序是何等困难,Java 正好满足这种需求(Java 虚拟机的最主要特征就是程序只要书写一次就可依托 JAVA 虚拟机在多个平台上执行),就顺应时代需要流行起来了,当时宣传的口号是 “一处编译,到处运行”。(copy 自《虚拟机历史》)

到 2005 年,Google 就收购 Dndroid 这个系统,2007 年发布第一个开源版本,在这个系统里存在一个叫 dalvik 的虚拟机,它跟 Java  虚拟机有点像,但它又是不一样的,因为它主要被设计运行在手机和平板电脑里,内存有限、 CPU 频率低的机器里,目前已经数不胜数的手机应用运行在这个虚拟机里了。随便 Android 系统的攻城拔寨,可以这样说:前 30 年的 IT 业可以用 Intel Inside 总结,后 30 年就可以用 Android Inside 来形容了。这个当初被 SUN 设计运行在嵌入式设备里的虚拟机,直到今天的 dalvik 虚拟机才真正地实现它的原本应有辉煌应用,才做到所有设备统一平台的机会。(copy 自《虚拟机的历史》)

为什么区块链需要虚拟机?

理解了虚拟机“统一”的作用之后,原来的认知告诉我,虚拟机的性能肯定比不过你直接调用物理机,当中会有些损耗,按理来说层级越多损耗越大。为什么区块链为什么需要给自己增加一层虚拟机,它需要统一什么?

简单来说就是:区块链有共识机制,所以要求所有人的计算结果是一样的,但是传统的虚拟机不支持这样,后者可能会因为底层硬件的不同输出不同的结果,所以 V 神要再写一个。之前采访老冒他也说过,“以太坊之所以选择写一套新语言Solidity,就是为了能实现智能合约代码的一致性。”

小明:区块链上的跟我们传统接触的虚拟机有什么不同?为什么需要虚拟机?

Michael :Mainframe 大型机的虚拟机是在操作系统下面的,Java 虚拟机在操作系统上面,所以就是不同的虚拟机。区块链的虚拟机到底统一了什么?区块链的虚拟机统一了不同的节点,每个节点都是不一样的。

底层语言用比如C++构起来,虚拟机要么就是 Vyper 或 Solidity ,要么就是虚拟机有自己的语言。第一代区块链是没有虚拟机的,比特币是没有虚拟机的。比特币就是交易,把钱从A打到B,但是以太坊的天才想法是,我为什么交易一定是要把钱从A打到B呢?为什么我不能让 A 到 B 这个过程是一段代码?但是要执行这段代码,需要在上面有一个执行代码的层面,这个层面就是虚拟机。

这时候,区块链的作用也从打钱不会出错变成执行代码不会出错,这需要所有的节点执行同一代码都是同样的结果。

所有的节点在这个执行的代码上有同样的结果,这个要求很高。因为在传统的虚拟机,比如Java虚拟机里面,是达不到这一点的。因为有些机器是64位的,有些机器是32位的,10 的负十次方,在 A 机上表示和B机上表示是不一样的,这样计算的话,各个节点不容易发生共识,所以他必须要写自己的虚拟机。因此,Vitalik就写了第一版以太的虚拟机。

这虚拟机还得防攻击,因为虚拟机里面不能说任意代码都可以执行,否则会有人来写无限循环执行的代码。因此,虚拟机里面要做 gas,要知道这个东西存储量有多大(智能合约的代码存在区块链上,代码越长 gas 费会越高),根据这个我帮你收钱,要通过交易费来保证虚拟机上的安全。所以区块链的虚拟机跟通用计算的虚拟机的需求是不一样的,但是作用其实是差不多的,就是要执行一段代码。

小明:那以太坊虚拟机改变什么?它做到了这个有什么坏处吗?

Michael:他牺牲了性能,Java 虚拟机性能后来大幅提高,是因为所谓 Just-in-time (JIT,即时编译),虚拟机会根据现在的这段代码来预测下一段代码是什么。Java虚拟机是非常非常聪明的,因为在里面花了大量的钱,搞了大量的优化。以太坊虚拟机首先从来没有干过这个事,因为在 2016 年以前没有人花任何钱去干这事,大家都认为这是个小孩做的事情,这是其一。

其二,优化过程也很复杂, Java 虚拟机里面可以容忍不同的虚拟机里面出来的结果有少量的差别,这个是可以的。但是在区块链里不行,区块链里所有的结果都必须一样。

今天在区块链虚拟机,其实也就三个流派。一个是从以太坊改的;然后 EOS 是从 WebAssembly 改的,是一个 JavaScript 虚拟机,在 EOS 之前就有了,他把里面跟区块链不符合的东西去掉;现在又看到一些去改 Lua 的虚拟机,Lua 是一种经常在 IoT 中使用的脚本语言。

我觉得也没有任何理由,需要去重新解决虚拟机。因为 Vitalik 写过一个虚拟机,19岁的时候就写了,这也不是什么特别难的事。

为什么有的链需要发明一套新语言?

正如我开篇所言,有的项目会开发新的虚拟机,往往也会伴随着新的虚拟机语言。这说的是什么意思?

离题一会,讲一下虚拟机、虚拟机语言(高级语言)和编译器的关系。

简单来说,虚拟机决定虚拟机语言,编译器是写这个语言的工具。

虚拟机是你所写代码的运行环境,就像“一个世界”。维特根斯坦说过:“语言的边界是就是世界的边界。”语言就像这个世界能做的事情的外化,语言中有哪些词汇,说明这个世界能做什么,一旦你写了超过这个世界能理解的词,虚拟机是不会执行的。这两个东东某种程度是一体的,一旦你的虚拟机支持了新功能,也需要有相应的词汇来将其外化。

至于编译器的常见作用,有点像把人能看懂的语言,翻译成计算机能懂的语言。

小明学习笔记 | 一文看懂区块链虚拟机计算机语言有三种,机器语言、汇编语言、高级语言(推荐阅读《深入理解计算机系统(3.1)------汇编语言和机器语言》)。只有第一种是计算机能直接识别和执行的,它用二进制代码表示,对人来说很难记。于是有了汇编语言,把一些指令抽象出来方便人记忆和理解。

小明学习笔记 | 一文看懂区块链虚拟机

不过,这两种都是直接面对硬件/处理器的,都跟处理器种类有绑定。高级语言则不然,比如Java、C、C++、C#、python等等,是高度封装的编程语言,更易学也意味着更不灵活。用其所编写的软件源代码也能被编译器翻译为不同处理器的语言。

可见,“低级语言”可能更“高级”,因为灵活(越低级的语言实现的效果越强大),更难掌握,懂的人也更少。

回到正题,要开发新语言,其实就是要做新的虚拟机,做以太坊虚拟机没做的事。

CyberMiles 主要是针对垂直场景做优化。CyberMiles 的虚拟机(CVM)是基于以太坊的虚拟机改的,所以兼容以太坊虚拟机语言 Solidity,同时支持一些以太坊虚拟机所不支持的功能。这意味着如果你本来就懂 Solidity,你可以用 Solidity 写,但是如果你想用到 CVM 的一些功能,这部分你就可以用 Lity 写,CVM 两者都能“看得懂”。

Michael :Lity 和 CVM,对于CyberMiles 最重要的一点就是,让我们做以太坊不能做的事。其实我们是以太坊社区里面的。我们不认为我们跟以太坊是一种竞争关系,我们跟他们是不同的哲学。他们在追求另外一个目标,他们在追求世界计算机的目标,我们不是。我们承认90%的事我们干不了,我们就把10%的事干了,所以我们 Lity 和 CVM,是把以太坊的一个图灵完备的系统,针对特定场景优化。

Vitalik 2015年的时候就知道了我们的做法,但是他不愿意做,因为他不愿意把以太做成一个为电商或者为跨链优化的一个虚拟机,他希望能够找到一个通用的解决方案。这就是一个世界观的问题,以太坊讲到的是世界计算机,我们不想当世界计算机,我们认为没有人能当世界计算机,一个做得好的区块链是垂直的。

这中间还需要去中心化交易。因为不可能我电商用一种币,吃饭用的是一种币,要能够实时地高水平交换才行,今天已经在解决,比如Cosmos这样的跨链项目。我们不想解决这个问题,我们还是想干电商。

CyberMiles 基于 EVM 做了哪些优化?

那么,CyberMiles 的虚拟机 CVM,跟 EVM 相比优化在哪?通过 CyberMiles 做的一些优化,也可以帮助我们理解以太坊的特性。

第一,可动态扩展,CyberMiles 所开发的语言可以针对不同的业务场景做优化,提高性能。

据 CyberMiles 官方介绍:“Lity的灵活性源自其添加新的语言OTA架构。这个版本中,LibENI函数是亮点。通过 CyberMiles 虚拟机中新的 OPCODE,使用者现在可以在 Lity 语言中添加更多功能。这种扩展可以在不停止或者升级区块链软件的情况下,通过超级节点共识,动态部署到 CyberMiles 区块链上。”

给看不懂的官方介绍加点注释(详细可看最后参考文章):

OTA 是 Over the air,就是在虚拟机不重启的情况下,动态地升级系统本身的软件。手机的无线升级系统也用到的类似的技术。

OPCODE 即operation code,操作码,是一堆机器语言的指令集,简单来说就是指令序列号,用来告诉CPU需要执行哪一条指令。CVM 在 EVM 里加了后者没有的 OPCODE 以实现自己的功能。

Michael :在一边运营的情况下,我可以一边往里加些新的功能和特性,这是很重要的一点。比如我有个新的加密算法,在以太坊的实现非常非常贵,我就用 C++ 能够把它加进去,在我机器不下档的情况下,我可以往里面加东西。

作为电商公链,我们开发出来的虚拟机,或者我们开发出来的语言是能扩展的。其他人要做一个外卖公链或金融公链,完全可以用,这也是我们做开源共享的原因。

第二,在 Lity 编译器和 CVM 上安装代码检查模式。简单来说,对已知的以太坊Solidity智能合约引起的安全问题,CyberMiles 团队进行了分类并提取了常见模式。通过编译器和虚拟机优化,Lity 可以主动防止 Solidity 中常见的安全问题,如整数溢出和通证被意外转到不受支持的合约地址。

Michael :我们有一个building feature,比如刚刚讲了 BEC 的安全漏洞,就是忘了加safemath,所以就会有整数溢出的问题,后来掉了几亿美金。BEC 的合约可以在 CyberMiles compile,可以在我们虚拟机上运行。但用同样的问题不会发生在我们虚拟机上,因为我们虚拟机在 runtime 的时候会查整数是不是被溢出,会报错。我觉得这个就显示了 EVM 的成熟。这种东西在 Java 里面都出现过,1997年 Java 开始,Java 里面也没有 check,后来就加进去。

第三,基于时钟的长期智能合约。Lity就可以执行一些发生在未来的事情。

Michael :以太里面还有一个大问题:以太的合约是不能自己启动的。你不能设计一个闹钟让合约在未来某天启动。但在电商里面经常有这事,比如汇款和发货。在以太干不了这件事,在以太坊专门有一个东西叫以太坊闹钟,这是一个线下的机构,专门收钱,帮你到了某个时间,来实施以太坊的合约。我们把它做进虚拟机了。

这个东西听起来是很小的事。你去看Java的发展历史,这些事情都发生过,就是因为你在企业应用中,要是没有这个功能,你做不到分期付款。

比如说今天Solidity是不能小数运算的,只能是整数,为什么?因为在不同的机器上,小数运算产生的结果不一样,所以没办法达成共识。那我们在这里就改变了这一点,数学运算的库就大多了。你要搞钱的事,小数运算还是需要的。我觉得当然还有其他的特征,比如白皮书里提到的规则引擎。

规则引擎是什么?规则引擎就是有很多嵌套的条件逻辑,在你的程序里面都不用去手写,用手写的话错误率就很高。这就是为什么在企业级用户里面,大家都用规则引擎,不会自己去手写那种很长的规则,这种很长的 rules,他们改不了。但我们就把 rules 放在虚拟机里面,所以你可以直接写一套规则出来,在虚拟机里面执行,而不是还需要低层次的东西。

这些“优化”有什么代价?

跟 Michael 聊完,其实会发现,很多 CVM 针对垂直行业的优化,以太坊真的是“非不能也,是不为也”。如果一条通用计算公链,要实现这些功能可能会牺牲一些东西,最直接的就是治理机制。CVM 之所以能实现高性能,需要一定程度上与底层操作系统做沟通,但是以太坊不可能要求加入网络的节点都用特定的系统,可是用 DPOS 的 CyberMiles 可以;虚拟机层面实现的模块化、可扩展,也需要基于 DPOS 超级节点全体同意

换言之,CyberMiles 的语言跟跟他采用 DPOS 的共识机制分不开,这是以太坊不愿意采用的。

关于虚拟机的性能优化

小明:我们这次的几个特性,LibENI函数,还有刚刚提到的代码检查,我感觉这个好像主要是在虚拟机本身上面,因为语言本身无法决定我是否被检查?

Michael :语言包括语言的语法和它的编译器,检查的东西放在编译器里面,这个是语言系统的一部分。但是 LibENI 必须要在语言领域实现。因为在以太坊领域有一个概念,是没有一个可以添加的函数,以太坊在白皮书都写清楚了。那我要在里面新加OPSCODE,这个是对语言本身的一个改变。还有就像闹钟这种东西,闹钟这东西也需要在语言上掌握关键词,才可以说我要三天后执行,十天后执行。

小明:那回到我一开始最初问的问题,我感觉虚拟机所在的层级越高,损耗其实越大。

Michael:对,这就是为什么以太坊虚拟机效率低的一个原因,它是在OS之上的。以太坊的客户端有两个,一个是Geth,一个是 Parity。你要 run 一个以太坊的权限,你要么run Geth,要么 run Parity,下载很大的一个数据包下来。新的 Transaction 进来后要出块后,你计算机的以太坊虚拟机,也要全部进行一遍,要跟其他网络上的东西对得上你才能够继续往下走,不然你就不在这个网络上了。

小明:所以我们虚拟机也是一样的?

Michael Yuan 博士:一样的,但是我们的虚拟机有加密算法 LibENI。为什么叫LibENI?ENI就是说以太坊本地接口,它往底下的操作系统,是我们用 C++语言打出的一条路来,这就是以太坊不愿意干的,以太坊东西全部是自洽的,全部都是在操作系统以上的,全部是数学可以证明的东西。我们在上面弄了一个 C++的口,所以说我们要算加密解密,我们就通过那个口,给撞到操作系统的层面之下,那当然性能比它快多了。

小明:这样如果我们底层操作系统不一样,或者低层的硬件也不一样,不会导致你刚刚说的不一致吗?

Michael :对,所以这就是 LibENI 里面的内部机制,所以LibENI出模块的时候,需要出好几个系统模块。比如说 Ubuntu Linux,windows什么的都有。但我们有一个好处,因为我们超级节点是可控的,我们有些数量的超级节点,我们可以要求超级节点必须用这些操作系统。

小明:可以总结一下 LibENI 吗?

Michael :它包括两块。一块是Lity 层面,在虚拟机语言里面看见的是什么东西,这个需要定义一下。如果这个东西来了之后,在C++层面需要引进这东西,就是两块。然后让超级节点同意。这个过程中,超级节点会看是否支持自身操作系统,否则做不了。

小明:所以我们有些东西很快,是 LibENI 决定的?

Michael :就是LibENI往里加东西。写 DApp 是用 Lity 写,在虚拟机 CVM run。可是你要改虚拟机就是另外一个东西叫 LibENI。LibENI 是 Lity 的扩展,这种是用 C++语言。他等于改造虚拟机本身,虚拟机是用C++写的,就等于把 C++封装成一个模块架上去。

小明:既然这是一个调用底层 C++ 语言的接口,为什么那个函数不能让所有的东西都调用它呢?

Michael :你是说把整个虚拟机都改装成这样模块化是吧?不是所有功能都能用函数,虚拟机里面有规则还有其他结构。如果能够用函数解决问题,我们就能解决。什么是函数呢?有输入和输出的东西。比如说一个私钥和一个文本,就出来一个加密的文本。

小明:能举一个普通人能感知到的例子?不能通过函数完成的。

Michael :比如说刚讲的 rules,就是跟 control 有关的东西,比如从一到十的循环。刚讲的规则引擎其实就是,这件事干完,干这件事。这里面的每一个要干的事情都是一个函数,但整体结构不是一个函数。

小明:所以函数很多时候是单一的东西。

Michael :单一的东西,就是给个输入,给个输出。

语言的可扩展性与治理机制之间的关系

小明:CyberMiles 强调是面向电商场景定制的,但又强调扩展性比较强,我有一点不是很理解这里。

Michael:因为可扩展性比较强,所以 CyberMiles 的链使用跟 CVM 里面加的功能全是跟电商有关的。但是,我可以用LibENI 跟 CVM 造另外一个公链出来,那个公链可以是外卖的、打车的,或者是发证券代币的。在技术上我们提供这个,可以按照你自己的需求去扩展CVM。

这种是超过了 CyberMiles 的范围,因为 CyberMiles 想运营一个电商的公链和一个生态。可是,我们开发的软件,比这个更通用,这就是我刚刚讲的,我们非常希望大家来抄我们的东西,如果有一天大家不抄你的代码,大家来抄我的代码,我觉得这就是我们成功的标志。

小明:你提到我们的语言扩展性强,那什么样的语言扩展性不强呢?或者定义一个语言强或不强的标准是什么?

Michael :EVM和Solidity就是没有扩展性的,就是你不能改,你需要改的话,你是要把整个软件系统都更新。EVM软件大概一年要更新一次。你在EVM上更改东西的话,你基本上必须要自己认识Vitalik,所有的核心开发他都会参与。

我们把虚拟机这个东西变成一个大家都可以改的东西。比如,我们就在 Solidity 开了个口,我可以让你直接把 C++ 的口给放进来,所以这个东西用 C++来做,只是在以太虚拟机上没办法而已。在PoW上实现不了,因为你需要在不更新软件的情况下去更新软件上的一个虚拟机,这就是软件里面的一个核心成分,这个需要全网所有节点的共识。在以太上需要所有矿工要共识这一点是非常难的,但我们做DPoS,所以我们用超级节点共识做这件事就可以了。

小明:这是你刚刚提到的,我们有很多功能可以让开发者自己提,让节点去接受。

Michael:我们提供了一个方法,能够用封装好的工具感知你的痛点,我们虚拟机里面加工的,比如我虚拟机里面以前可以做 RSA 算法的加密,我现在想做 DES 算法的加密,那就是另外一个功能。你可以把它打成包,让它们超级节点来同意,同意了之后就加密去了。飞机一边飞,一边换引擎。

小明:所以其实我们扩展性强,并不是由语言决定,而是由我们治理机制决定的?

Michael :我们语言跟虚拟机和治理机制是一起工作的,不可分割的。因为我们这个语言里面可以去加这种关键词,我有个模块化的方法,可以把这个关键词的功能直接加到虚拟机里来,这在现在来讲以太坊都做不到,因为不支持。


关于虚拟机的灵活与安全之争

小明:很多人批评现在以太坊智能合约本身有很多漏洞,包括整数溢出这些,都是因为虚拟机本身设计可能没有做好?

Michael :我觉得是这样,写虚拟机或者写语言的人,会说是写智能合约的人的问题,你们程序员太差,所以有这个问题。如果所有人都犯一样的错误,那就说明你这个东西设计的不行,所以你就要想办法去改设计。之前我们在Java的时候,也遇到这种问题。这个Bug出现是不是因为程序员的问题呢?是因为程序员的问题,也是因为你的语言没有防止这个问题,所以一直以为有这个问题。

这就是工程解法跟科学解法的区别,或者叫学院派思维跟工程思维的区别。

我以前在大学很清楚,学院派思维会说,我们设计出来东西是图灵完备的、数学可以证明的。比如说整数溢出这件事,你凭什么说它是个bug?因为我的语言里面允许这样写。程序员把它写成这样,就是证明他想干这个事。但是,在现实生活中,99.99%的情况下,程序员不是要干这件事,而是把它写错了。

我们就干了一件 Java 以前干的事情。就是整数溢出了之后,我们不能执行下去了,我们虚拟机就报错了。

小明:以前 Java 的虚拟机是允许这个事情的?

Michael :所有虚拟机都经过这个争论:这东西到底是bug还是个feature?我们允许大家这么干。

小明:灵活的“坏处”。既然虚拟机又是在操作系统之上的,那就意味着操作过程中,其实操作系统可能也有虚拟机,下层不能知道发生这件事吗?不能阻止吗?

Michael :底层的虚拟机你愿不愿意干这事?越底层的虚拟机就越有可能想干这个事。在你看来是整数溢出的东西,也许在下面并不是整数溢出。所以你越往下走,你就越需要给人自由。所以越底层的软件,对程序员的要求越高。你比如说你要用机器语言写东西是非常非常容易出错,但是你有最大的灵活性,你有最大的优化能力,整个系统所有的资源你都可以用。但是你要到了Java这一层,或者EVM这一层,你系统很多东西根本看不见了。内存在哪里你根本就不知道,因为它都会抽象化。

小明:那假设下层的虚拟机不允许某种行为,但上层的虚拟机允许,那他又写了,下层会阻止吗?

Michael :在某些情况下会阻止,这个就是如果不同的情况,就比如我们刚才讲的,你在CVM里整数溢出了,在操作系统里面看不一定是整数溢出。

我是Odaily星球日报编辑卢晓明,探索真实区块链,爆料、交流请加微信lohiuming,烦请备注姓名、单位、职务和事由。

小明学习笔记 | 一文看懂区块链虚拟机参考文章:

Docker和虚拟机的区别

虚拟机与Docker有何不同?

虚拟机概论(九)——虚拟机总结:简单介绍了当今正在使用的四种虚拟机概念模型

虚拟机概论(四)——虚拟机的历史:虚拟机重大历史事件附录

虚拟机的历史:简单的虚拟机历史

深入理解计算机系统(3.1)------汇编语言和机器语言

维基百科:指令集架构

OTA本质与实现流程分析

OTA制作及升级过程笔记

OPCode详解及汇编与反汇编原理

Vper 智能合约指南

也来谈一谈以太坊虚拟机EVM的缺陷与不足

以太坊虚拟机,你真的懂吗?

原创文章,作者:卢晓明。转载/内容合作/寻求报道请联系 report@odaily.com ;违规转载法律必究。

参与讨论

登录后参与讨论

卢晓明

资深编辑

卢晓明

主要职责蹭热点,关注金融、电商、旅游等领域。交流可加微信lohiuming,请务必注明公司、职务与事由。

总文章数: 106


分享至

微信扫一扫分享

0
前沿科技区块链