怎么实现区块链中的JVM

介绍

这篇文章主要介绍了怎么实现区块链中的JVM,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获、下面让小编带着大家一起了解一下。

虚拟机是区块链中的一个关键组件,用来执行智能合约,需要满足安全性和一致性,所谓的安全性一般是指合约代码需要在隔离的沙箱环境中运行,以免错误或恶意代码造成对区块链系统的损害。而一致性是指区块链网络中任意诚实的节点执行同一个合约,如果输入参数一致,输出结果都应该是一致的。目前比较主流的虚拟机实现包括维生素,WASM,其他的实现还有如星云链的谷歌V8,紧张的RISC-V,索拉纳的带通滤波器等,设计如此众多不同虚拟机的目的,主要是对区块链系统互操作性、安全性,执行性能,硬件兼容性等因素的考量。如维生素更注重的是安全性,虽然可靠性设计是图灵完备的语言,但是通过自身限定的最小语法集,来保证合约的安全可控,而星云链采用V8,更多的一方面也是考虑智能合约的互操作性,使用javascript降低了合约的编写门槛。尽管可靠性也是javascript类语言,并且入门门槛也不是很高,但是对于很多想入行区块链的程序员来说,学习一门新的语言还是需要一些成本的。

JVM为何在区块链中使用的较少
JVM本身就是一种虚拟机,而且java语言又是最为流行的几大语言之一,为什么区块链中使用的较少呢?个人总结主要包含如下几个原因:

1,语言的可控性,同c++/golang/生锈等主流开发语言类似,java也是系统级语言,可以访问嘉盛中文网http://www.jiasheng-chn.com操作系统的任意资源,例如读写文件,访问网络等
2,执行性能,java是解释性语言,JVM载入的类文件是一种中间语言,真正执行的时候才会进一步解释成机器码执行,所以主流的JVM都会引入JIT对热点代码进行及时编译来提高执行效率
3,语言的复杂性,java有很多复杂的语法,比如支持OOP的接口,多态,反射和多线程控制等,对于更注重过程化执行的智能合约用处不大,而且容易影响合约执行的一致性。
那如果能解决这些问题,针对JVM做一个自定义的最小集合裁剪,那对于很多java开发者来说,还是比较有吸引力的。

区块链中JVM的方案应如何实现?

如何传递参数
java是OOP的,如果编写合约,需要先定义一个合约类,合约类中定义的类方法就是合约能够执行的方法。区块链上合约执行都是通过交易触发的,而合约地址,输入参数需要通过交易携带,首先要解决的问题就是如何传递这些信息给合约,对于基本类型处理比较简单,可以都编码成字符串进行传递,合约执行的时候根据方法的参数类型解析成对应的结果,而对于自定义类的对象如何处理呢?可以使用json、xml、试制等编码方式对类对象进行逐字段编码,如果字段也是个自定义类对象,那就递归进行编码。这几种编码方式的有点是利于阅读,但是缺点就是空间占用较大,对于区块链这种冗余分布式存储机制来讲,占用空间越少越好,所以可以采用以太坊中使用的RLP(递归长度前缀)编码方式。

如何载入java系统类

参考JVM。去代码库,可以在目标节点上预安装一个jdk环境,然后在节点应用启动时把需要用到java的系统类包预加载入内存的一个地图中。这里可以根据实际情况对导入进来的系统类包做一些选择裁剪,同时过滤掉容易造成执行结果不一致的包,比如随机数,多线程,IO操作等。
如何模拟离线沙盒执行环境
笔者采用的是如上裁剪系统类包的做法,限制了用户合约直接引用网络,读写,cmd等操作权限,同时不允许用户合约直接引用第三方jar包或本地执行第三方库等,保证合约的安全性。这种方式比较简单粗暴并不是特别好的方案,对于恶意代码跳过系统包,自己实现类似的访问资源的操作,就无法检测出来,并不是一个好的方案,如果有好的方案可以一起讨论。
如何屏蔽随机数,多线程等容易造成执行结果不一致的语法执行
同上也是限制引入包的做法屏蔽,对于恶意代码自己实现随机数,这个也同样无法检测出来。

如何启动合约执行

jvm执行是需要找到主要入口,而合约代码可以不提供主要函数,我们可以在生成合约包的工具中自动生成相应的主要函数,添加新合约对象,然后调用对应方法的代码。

如何读写合约状态变量
java存取的指令码主要是加载和存储系列指令。但是对于合约启动执行时,需要先从数据库中读取到历史的状态,比如合约中的余额变量,如上自动生成的主要函数中会先新建一个合约对象,于是我们可以捕获到合约对象的构造函数,注入读取数据库代码,并将合约对象的成员变量全部恢复。这里也可以参考坚固的方法,区分内存和存储变量,可以通过注解来实现.jvm可以解析变量的注解,如果注解是仓储费,就存取数据库,否则从当前内存获取。

怎么实现区块链中的JVM