共计 3374 个字符,预计需要花费 9 分钟才能阅读完成。
—— 导读 ——
前文,咱们介绍了对虚拟机的历史、特点、倒退以及 Solidity 和 EVM 进行具体介绍。Solidity 和 EVM 的呈现为区块链的利用场景关上了新的大门,然而合约开发者应用 Solidity 进行智能合约的开发,不可避免地存在着新语言的学习老本问题。
那么,是否有这样一位老朋友,能让「合约开发者」和「区块链」疾速打成一片呢?
家喻户晓,Java 是一种被宽泛应用的、面向对象的编程语言,具备“一次编写,处处执行”的跨平台个性。于是,咱们将 Java 请到了咱们的区块链平台,自研了一套能够执行 Java 智能合约的执行引擎 HVM。将 Java 智能合约引入区块链,次要有以下目标:
升高智能合约开发的老本,让合约开发者能专一于合约逻辑自身而不是语法细节。
为开发者提供相熟的、适宜区块链场景的工具类和办法,防止反复“造轮子”。
解决传统智能合约与账本交互模式繁多的问题,提供多种更不便、更灵便的账本交互的数据结构和办法,更好地满足业务场景的须要。
本文将次要解说如何让 Java 编写的智能合约运行在区块链上,不会波及大量 JVM 细节。从 Java 合约应用、虚拟机适配、账本交互机制三个方面进行介绍。
—— Java 智能合约的应用 ——
从合约开发者的角度来看,Java 智能合约的应用流程通常包含以下三个步骤:合约开发、合约部署、合约调用。
▲Java 合约开发
相比传统智能合约,Java 智能合约的开发和应用更为简略不便,次要体现在:
1)我的项目搭建快:开发者只须要在本地 IDE 中新建 Java 我的项目,引入合约开发依赖包,便能够开发合约。实现编码后,将代码打包成合约 Jar 文件即可用于部署上链。
2)工具办法多:开发者能够应用 JDK 中的类和办法,防止反复”造轮子“的麻烦。
3)学习成本低:Java 语言应用宽泛,大部分开发者只须要理解合约开发依赖包的接口,便能纯熟应用 Java 智能合约。
▲Java 合约部署
对于 Java 智能合约的部署,开发者通过一笔交易将合约 Jar 包上传到链上,区块链会对合约进行初始化,生成一个惟一的合约地址,并通过交易回执将合约地址给开发者。
▲Java 合约调用
开发者能够通过指定合约地址,并输出合约办法名和参数,结构并发送一笔合约调用交易。区块链平台收到交易当前,获取一个 JVM 实例,将合约地址对应的合约 Jar 中的类文件加载 JVM 中,创立一个合约类的实例并调用指定办法,失去执行后果并通过交易回执返回给开发者。
—— HVM 详解 ——
▲JVM 接入区块链
要实现一个 Java 智能合约执行引擎,肯定绕不开将 JVM 接入区块链的问题。目前大部分区块链零碎应用 Golang 开发,而大部分开源的 JVM 通常是 C ++ 编写。如果想要疾速地将 JVM 接入到区块链零碎中,能够通过 CGO 将 Golang 和 C ++ 买通。但思考到在区块链零碎中对 JVM 外部优化的须要,HVM 抉择了通过 Golang 实现了 JVM。尽管本人实现 JVM 会引入大量的开发成本,然而极大中央便了后续针对区块链场景进行性能优化和性能拓展工作的发展。
“当区块链中接入 JVM 后,还须要做些什么让 JVM 成为区块链中的 Java 合约执行引擎呢?”
▲虚拟机平安适配
前文中提到,咱们在区块链的 Java 合约引擎中反对用户应用 JDK 中的类和办法。思考到区块链上的合约执行引擎须要满足执行环境的隔离以及执行后果的确定性,咱们须要对 JDK 和 JVM 进行平安适配。其中包含以下几点:
1)禁用”不平安”类和办法:在智能合约引擎中,可能引起执行后果不统一的办法是”不平安“的。比方 Java 中生成的随机数办法,其执行后果是不确定的,区块链中的 Java 合约引擎会禁用这些”不平安”的类和办法。
2)隔离合约的执行环境:区块链平台中的 Java 智能合约须要一个隔离的执行环境,即 Java 智能合约无奈像一般的 Java 程序应用线程、网络、拜访零碎工夫等性能。此外,咱们在 JDK 中实现了一部分与区块链相干的办法,局部办法不容许被 Java 合约调用。因而,咱们在 HVM 外部实现了办法调用过滤器,拦挡不被容许的办法调用。
3)确定逻辑执行程序:同 EVM 一样,咱们在 HVM 外部实现了一套 Gas 机制,对合约执行进行代价计算。指令执行的不同,会引起不同节点计算的 Gas 值不同。在原始的 JDK 中,局部办法在两次调用时,尽管其后果统一,其逻辑执行的代码门路不同。以应用单例模式的类为例,首次调用这个类的实例办法时,须要创立这个类的实例;之后调用其办法时,不再须要创立实例。这种逻辑的差别,会导致新启动的节点与其余节点的执行的 Gas 值不统一。因而,咱们须要对 JDK 中这类逻辑进行适配,保障逻辑执行程序始终统一。
▲账本交互机制
将 JVM 接入区块链,还须要保障合约与账本数据交互的性能。EVM 中存在账本交互的指令,然而在 JVM 标准中不存在用于账本交互的指令,所以咱们须要提供一套账本数据交互机制,让 Java 智能合约可能操作区块链上的账本数据。
实现账本交互机制能够有两种计划:
1)在 JVM 中实现一套账本交互的自定义指令集。同时提供一种 Java 合约的编译器或插件,在合约字节码中生成专用于区块链中账本交互的自定义指令。
2)在 JDK 中实现一套读写账本数据的工具类和办法,在合约执行过程中,由合约执行引擎来调用这些办法,负责合约长久化字段的读写操作。
HVM 在实现的过程中,抉择了第二种计划。在合约执行的过程中,如果应用到合约的长久化字段,合约执行引擎会调用账本读取的办法从账本中获取其数据。对于账本写入操作,执行引擎会先进行缓存,待合约执行完结后,扫描合约中有数据更新的长久化字段,将字段更新的数据对立刷入到账本中。
相比指令的办法,应用 Java 办法来实现账本数据交互的性能尽管会有更多的指令开销,然而可能为用户提供更敌对地形式操作长久化字段。以 Map 为例,咱们在 Java 智能合约中为 Map 提供了除 Get 和 Put 以外的办法,容许用户应用迭代器等办法不便地操作 Map。思考到读写 Map 的简单场景,保护一个牢靠的迭代器逻辑较为简单。而以指令的形式操作账本数据,那么势必要实现一套简单的账本交互指令集。显然工具类和办法更适宜实现这些简单的逻辑操作,并更容易反对合约数据结构性能的拓展。
通过这种计划,用户在编写 Java 智能合约时,可能选用功能强大的数据结构类操作账本。这些数据结构类,将账本交互的 Java 办法进行封装,使用户无奈感知,并尽可能实现 JDK 中的接口。如 HVMMap、HVMList 等数据结构,别离实现了 JDK 中的 Map 和 List 接口,应用起来与 JDK 提供的其余 Map、List 简直统一。
▲虚拟机比照剖析
除了 HVM 合约以外,常见的合约还有 EVM 的 Solidity 合约、Fabric 的 Chaincode 等等。
EVM 提供了沙盒化的、齐全隔离的合约执行环境。Solidity 从设计初就作为智能合约语言来思考,其在账本操作上有较大劣势。
Fabric 的 Chaincode 反对多种语言编写。Chaincode 运行在一个受爱护的 Docker 容器中,在接管到客户端发送的调用申请后,会在容器中模仿执行出对账本的读写集并返回给客户端,最初由客户端再次发动将模仿交易产生读写集写入账本的申请。
HVM 相比与其余的执行引擎,次要以下个性:
HVM 合约是在平安的封闭式沙箱环境执行,安全性高
执行引擎内嵌于平台,无网络依赖
HVM 提供残缺的合约生命周期管理机制,只需通过 sdk、api 调用就可进行合约的降级
提供丰盛的内置性能,例如日志输入、明码套件、多样化调用合约
除了 Java 语言 JDK 自身提供的性能外,HVM 提供多种基于区块链账本数据操作的数据结构
—— 小结 ——
本文首先从开发者的角度,介绍 Java 智能合约的开发及应用流程,再解说了在区块链中接入 JVM 的技术计划,探讨了对 JDK 的代码革新以及账本交互机制的实现。HVM 始终向着更好的性能和更敌对的应用体验指标摸索后退。与此同时,行业内的合约执行引擎正处于百花齐放的状态,接下来咱们还会对反对 Rust 等语言编写智能合约的 FVM 以及反对区块链上 SQL 执行的 KVSQL 进行具体介绍,敬请期待!
对于虚拟机感兴趣的小伙伴,能够增加小助手桔子(18458407117)退出技术交换群,欢迎您和咱们共享观点,共论区块链的有限将来~
作者简介
卢益铭、姚兵
趣链科技根底平台部区块链虚拟机钻研小组
参考文献
[1] Java 虚拟机标准.