长安链Docker Java智能合约引擎的架构、应用与规划
#功能发布
长安链3.0正式版发布了多个重点功能,包括共识算法切换、支持java智能合约引擎、支持后量子密码、web3生态兼容等。我们接下来为大家详细介绍新功能的设计、应用与规划。
在《2022年度长安链开源社区开发者调研报告》中,对Java合约语言支持是开发者更为普遍的需求;《2023年中国开发者调研报告》显示,熟悉Java语言的开发者占到40%以上,尤其在传统行业应用中为应对使用区块链技术进行数字化转型的需求,支持java语言合约将使区块链技术更快的渗透到各行各业。
Docker Go上线以来,因其良好的可移植性,可扩展性和安全性获得较多使用,更因其支持使用原生的Go语言编写合约,有更好的易用性。
在企业客户的使用中Java语言的使用更为广泛,因此在长安链v3.0.0正式版中新增Docker Java合约引擎,支持使用原生Java语言编写合约。
1. 整体架构
Docker Java合约引擎的设计复用了Docker Go的架构。依然是采用抢占式任务调度和多个合约进程并发,单个合约进程串行执行交易的形式运行。更详细的设计可以参考长安链 VM Engine架构设计深度解读。
Docker Java 和 Docker Go 合约引擎互不冲突,可以同时启用。部署和连接方式如下图所示:
2. 编写Java合约
2.1 版本和工具
当前合约执行环境为JDK 11,推荐使用JDK 11编写合约;推荐使用 IDEA 或 Vscode等IDE编写和编译Java合约。
2.2 引用合约sdk
2.2.1 添加依赖包
在gradle项目中使用SDK
在build.gradle 中添加dependencies:
implementation group:'org.chainmaker', name:'contracts-sdk-java', version:'1.0'
在Maven项目中使用SDK
在pom.xml 中添加dependencies:
<dependency>
<groupId>org.chainmaker</groupId>
<artifactId>contracts-sdk-java</artifactId>
<version>1.0</version>
</dependency>
2.2.2 本地编译包
将项目引入到本地并编译安装到本地maven库:
git clone -b v3.0.0 https://git.chainmaker.org.cn/chainmaker/contract-sdk-java.git
cd contract-sdk-javamvn clean install
'-Dmaven.test.skip=true'
然后通过添加依赖包引入到合约开发项目。
2.3 合约编写规则
2.3.1 合约必须实现接口 IContract
合约必须需要实现合约初始化方法(initContract) 和合约升级方法(upgradeContract)。
IContract 中定义了默认的 initContract 和 upgradeContract 的接口。默认这两个接口只返回成功的message。
合约可以根据需求自行实现这两个接口。
2.3.2 代码的执行入口
在合约类定义的main方法中,需要将合约实例作为参数传给sanbox.serve:
publicclass fact implementsIContract{
// ...
publicstaticvoidmain(String[] args){
Sandbox.serve(args,newfact());
}
}
2.3.3 定义合约方法
在合约类中定义合约方法,方法权限必须是public,返回值为Response,并且使用@ContractMethod注解标识。在链上调用中,指定的合约方法名与定义的方法名同名(区分大小写):
@ContractMethod
publicResponsesave()throwsIOException,
ContractException{
SDK.putState("key1","field1",
SDK.getParam("value"));
return SDK.success("store success");
}
2.3.4 获取合约的调用参数
(1)使用SDK.getArgs()获取参数map
// 获取参数map
Map<String, ByteString> args = SDK.getArgs();
// 获取参数 key的值, 如果不存在则报错
ByteString getKey = args.get("key");
if(getKey ==null){
return SDK.error("key not exist");
}
String key = getKey.toStringUtf8();
// 获取参数 value 的值, 如果不存在使用空字符串
ByteString getField = args.get("field");
String field = getField ==null?"": getField.toStringUtf8();
(2)使用SDK.getParam() 和 SDK.getParamBytes()
注意:getParam 和 getParamBytes 不做null值的判断,假如参数值没有传递,则分别返回空字符串和空字节数组:
String key = SDK.getParam("key");
byte[] value = SDK.getParamBytes("value");
2.3.5 错误捕获
合约报错中ContractException中包含了正常逻辑的报错,主要包括参数的合法性检查(比如key 和field),和链上接口访问遇到的报错(比如访问的value不存在等)。因此在合约逻辑中,建议捕获ContractException,并在合约里做相应的处理。
2.4 合约编译
合约需要编译成可独立运行的jar包(包含运行所需的依赖,也叫fat jar 或uber jar)。由于包含了所有依赖,因此合约体积也较大,大概30MB左右。
2.4.1 gradle 打包方式
配置示例如下,执行./gradlew uberJar,默认生成的jar包在build/libs目录下,文件名以-uber.jar为结尾。
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.4.0</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<filters>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/*.SF</exclude>
<exclude>META-INF/*.DSA</exclude>
<exclude>META-INF/*.RSA</exclude>
</excludes>
</filter>
</filters>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>org.chainmaker.examples.demo</mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
2.4.2 maven 打包方式
使用maven-shade-plugin。配置示例如下。
执行 mvn package,默认生成的jar包在target目录下:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.4.0</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<filters>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/*.SF</exclude>
<exclude>META-INF/*.DSA</exclude>
<exclude>META-INF/*.RSA</exclude>
</excludes>
</filter>
</filters>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>org.chainmaker.examples.demo</mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
示例合约
示例合约可以直接查看仓库的样例contracts-sdk-java(链接地址:https://git.chainmaker.org.cn/chainmaker/contract-sdk-java/-/tree/v3.0.0/src/main/java/org/chainmaker/examples)。
一个完整的简单存证合约可以如下:
packageorg.chainmaker.examples;
importcom.google.protobuf.ByteString;
importorg.chainmaker.contracts.docker.java.pb.proto.Response;
importorg.chainmaker.contracts.docker.java.sandbox.IContract;
importorg.chainmaker.contracts.docker.java.sandbox.ContractException;
importorg.chainmaker.contracts.docker.java.sandbox.SDK;
importorg.chainmaker.contracts.docker.java.sandbox.Sandbox;
importorg.chainmaker.contracts.docker.java.sandbox.annotaion.ContractMethod;
importjava.io.IOException;
// 实现智能合约接口 IContract
publicclass fact implementsIContract{
// 使用@ContractMethod注解定义合约方法:save
@ContractMethod
publicResponsesave()throwsIOException,ContractException{
// 获取参数:key
String key = SDK.getParam("key");
// 获取参数:value
byte[] value = SDK.getParamBytes("value");
// 将键值对存储到链上
SDK.putState(key, value);
// 返回成功信息
return SDK.success("store success");
}
// 定义合约方法:get
@ContractMethod
publicResponseget()throwsIOException,InterruptedException,ContractException{
// 获取参数:key
String key = SDK.getParam("key");
// 从链上获取对应的值并返回
return SDK.success(SDK.getState(key));
}
// 主函数,启动智能合约
publicstaticvoidmain(String[] args){
Sandbox.serve(args,newfact());
}
}
接口支持
目前提供了与Docker Go接口功能一致的所有接口。但是为了遵循Java语言的风格,与Docker Go接口略有不同:
1. 支持函数重载,因此没有Go接口中略显冗余的GetState,GetStateByte,GetStateFromKey,GetStateFromKeyByte等接口,而是函数名统一使用getState。
2. 2. 函数名首字母使用小写。
具体接口列表可以查看文档链接:https://docs.chainmaker.org.cn/v3.0.0/html/instructions/%E4%BD%BF%E7%94%A8Java%E8%BF%9B%E8%A1%8C%E6%99%BA%E8%83%BD%E5%90%88%E7%BA%A6%E5%BC%80%E5%8F%91.html#id15
下一步规划
目前对于Docker Java下一步的主要规划是:
1. 优化合约创建效率。因Docker Java的合约体积较大,未来会选择支持源码安装的合约创建方案,以降低创建合约对其他交易产生的性能影响;
2. 优化Docker Java交易执行效率。因JVM的启动相对较慢,以进程方式做调度对Docker Java的交易执行效率影响较大。
如果您对Docker Java有更多建议,欢迎提交issue或在社群联系我们。
相关文章:

长安链Docker Java智能合约引擎的架构、应用与规划
#功能发布 长安链3.0正式版发布了多个重点功能,包括共识算法切换、支持java智能合约引擎、支持后量子密码、web3生态兼容等。我们接下来为大家详细介绍新功能的设计、应用与规划。 在《2022年度长安链开源社区开发者调研报告》中,对Java合约语言支持是开…...

STM32 ESP8266模块的曲折探索
这是本文的配套资料,最终工程请参考 新_ESP8266资料\stm32f103成功移植的项目 【免费】stm32f103c8t6esp8266资料资源-CSDN文库 一、等到了ready 产品参数 我使用的是ai-thinker的esp8266-01s,以下为产品规格书 引脚定义: 依据引脚定义&…...

letcode::根据二叉树创建字符串
根据二叉树创建字符串 题目描述: 给你二叉树的根节点 root ,请你采用前序遍历的方式,将二叉树转化为一个由括号和整数组成的字符串,返回构造出的字符串。 空节点使用一对空括号对 “()” 表示,转化后需要省略所有不影…...

6个免费的ChatGPT网站
AI 大模型的出现给时代带来了深远的影响: 改变了产业格局:AI 大模型的发展推动了人工智能技术在各行业的广泛应用,改变了传统产业的运作方式,促进了新兴产业的崛起,如智能驾驶、医疗健康、金融科技等。提升了科学研究…...
每天几道面试题|Kafka(一)基础概念
文章目录 什么是 Apache Kafka?它是用来解决什么问题的?Kafka 的主要组件有哪些?它们各自的作用是什么?Kafka 中的生产者和消费者是什么?它们之间的关系是怎样的?Kafka 中的分区是什么?为什么要…...

PLC与智能制造——蛋糕增大?谁来先行?
PLC的特点 图1 PLC的特点 PLC与智能制造 “中国制造2025”把智能制造作为自动化和信息化深度融合的主攻方向,其支撑在于强大的工业自动化系统,而PLC是工业自动化系统的“大脑”,它不仅可控制机械装备和生产线,还是信息的采集器和…...

基于spring boot框架的发艺美发店管理系统
摘 要 系统根据现有的管理模块进行开发和扩展,采用面向对象的开发的思想和结构化的开发方法对发艺美发店管理的现状进行系统调查。采用结构化的分析设计,该方法要求结合一定的图表,在模块化的基础上进行系统的开发工作。在设计中采用“自下而…...
Linux - IO
目录 四种典型IO方式阻塞IO非阻塞IO信号驱动异步IO 多路转接IOselect模型接口 四种典型IO方式 IO:输入输出–过程:等待IO就绪,进行数据拷贝 阻塞:为了完成某功能,发起一个调用,若完成功能条件不具备&#…...

Cmake和opencv环境安装
1 Cmake下载及安装 Download CMake 根据需要下载,历史版本下载方法如下 CMake 的版本号中的后缀 "rc1" 和 "rc2" 表示 Release Candidate 1 和 Release Candidate 2,它们都是候选版本,用于测试新功能和修复 bug。通常情…...
Redis是如何避免“数组+链表”的过长问题
目录 一、扩展和收缩 二、使用高质量的哈希函数 三、使用跳跃表(skiplist)或其他数据结构 四、哈希表分片 一、扩展和收缩 Redis通过动态调整哈希表的大小来解决“数组链表”的长度问题,这涉及到两个过程:扩展(Expand)和收缩(S…...

Grass手机注册使用教程,利用闲置手机WiFi带宽赚钱
文章目录 Grass是什么? 项目介绍Grasss手机使用步骤第一步:下载狐猴浏览器第二步:注册账户(已注册直接跳过)第三步:安装Grass Chrome插件1、推荐离线安装2、在线安装 第四步:登录第五步…...

java NIO群聊系统
demo要求: 1)编写一个NIO群聊系统,实现服务器端和客户端之间的数据简单通讯(非阻塞) 2)实现多人群聊 3)服务器端:可以监测用户上线,离线,并实现消息转发功…...
ZCC5429 异步升压芯片
一、产品综述 ZCC5429 芯片是一款自动调频、最高 600KHz 工作频率、高效率、宽输入电压范围的电流模式异步升压(BOOST)芯片,且可调输入限流功能。用户可灵活地通过外部补偿建立动态环路,获得在所有条件下最优瞬态性能。 ZCC5429…...
复试专业前沿问题问答合集10-1——区块链与加密货币
复试专业前沿问题问答合集10-1——区块链与加密货币 区块链与加密货币安全以及6G通信的基础知识问答: 区块链以及加密货币相关的基础安全知识 包括区块链如何确保交易安全、共识机制的作用、加密货币钱包的保护措施、智能合约的工作原理以及如何防范潜在的网络攻击。这些知…...
redis【面试题】
目录 Java全技术栈面试题合集地址Redis篇1.Redis 的数据类型?2.Redis 是单进程单线程的?3.一个字符串类型的值能存储最大容量是多少?4.Redis 的持久化机制是什么?各自的优缺点?5.redis 过期键的删除策略?6.…...
linux下使用 tar 来压缩和解压 tar.gz 和 tar.xz 文件
linux下使用 tar 来压缩和解压 tar.gz 和 tar.xz 文件 文章目录 linux下使用 tar 来压缩和解压 tar.gz 和 tar.xz 文件1. 压缩 tar.gz 文件2. 解压 tar.gz 文件3. 压缩 tar.xz 文件4. 解压 tar.xz 文件 1. 压缩 tar.gz 文件 要创建 .tar.gz 文件(即使用 gzip 压缩的…...

Python环境下基于1D-CNN的轴承故障诊断及TSNE特征可视化
1D CNN 处理一维信号具有显著优势,已在很多领域得到初步应用: 心电图监测:将1DCNN应用于心脏病监测,其方法是针对每一个心脏病人的,即对于每个心律失常患者使用该患者特有的训练数据,专门训练出一个紧凑的…...

进程的调度,原则,算法
进程调度 进行上下问切换的时候根据什么原则来切换进程呢 进程的什么周期什么时候进行调度 调度原则 评价指标,作为调度算法的参考 调度算法的实现的标准 响应时间越小越好,平均响应时间的波动越小越好,稳定 (不能忽大忽小&am…...

瑞_23种设计模式_状态模式
文章目录 1 状态模式(State Pattern)1.1 介绍1.2 概述1.3 状态模式的结构1.4 状态模式的优缺点1.5 状态模式的使用场景 2 案例一2.1 需求2.2 代码实现(未使用状态模式)2.3 代码实现(状态模式) 3 案例二3.1 …...
system Verilog:clocking中定义信号为input和output的区别
在SystemVerilog中,clocking块用于定义时钟块,这通常用于描述时钟边缘和同步的输入/输出行为,特别是在测试平台和硬件接口描述中。 在下述两个代码示例中,主要区别在于a被定义为一个input还是output。 当a被定义为input时&#x…...

XCTF-web-easyupload
试了试php,php7,pht,phtml等,都没有用 尝试.user.ini 抓包修改将.user.ini修改为jpg图片 在上传一个123.jpg 用蚁剑连接,得到flag...

【HarmonyOS 5.0】DevEco Testing:鸿蒙应用质量保障的终极武器
——全方位测试解决方案与代码实战 一、工具定位与核心能力 DevEco Testing是HarmonyOS官方推出的一体化测试平台,覆盖应用全生命周期测试需求,主要提供五大核心能力: 测试类型检测目标关键指标功能体验基…...

大数据零基础学习day1之环境准备和大数据初步理解
学习大数据会使用到多台Linux服务器。 一、环境准备 1、VMware 基于VMware构建Linux虚拟机 是大数据从业者或者IT从业者的必备技能之一也是成本低廉的方案 所以VMware虚拟机方案是必须要学习的。 (1)设置网关 打开VMware虚拟机,点击编辑…...

Cinnamon修改面板小工具图标
Cinnamon开始菜单-CSDN博客 设置模块都是做好的,比GNOME简单得多! 在 applet.js 里增加 const Settings imports.ui.settings;this.settings new Settings.AppletSettings(this, HTYMenusonichy, instance_id); this.settings.bind(menu-icon, menu…...
【git】把本地更改提交远程新分支feature_g
创建并切换新分支 git checkout -b feature_g 添加并提交更改 git add . git commit -m “实现图片上传功能” 推送到远程 git push -u origin feature_g...
Spring Boot+Neo4j知识图谱实战:3步搭建智能关系网络!
一、引言 在数据驱动的背景下,知识图谱凭借其高效的信息组织能力,正逐步成为各行业应用的关键技术。本文聚焦 Spring Boot与Neo4j图数据库的技术结合,探讨知识图谱开发的实现细节,帮助读者掌握该技术栈在实际项目中的落地方法。 …...
高防服务器能够抵御哪些网络攻击呢?
高防服务器作为一种有着高度防御能力的服务器,可以帮助网站应对分布式拒绝服务攻击,有效识别和清理一些恶意的网络流量,为用户提供安全且稳定的网络环境,那么,高防服务器一般都可以抵御哪些网络攻击呢?下面…...
【HarmonyOS 5 开发速记】如何获取用户信息(头像/昵称/手机号)
1.获取 authorizationCode: 2.利用 authorizationCode 获取 accessToken:文档中心 3.获取手机:文档中心 4.获取昵称头像:文档中心 首先创建 request 若要获取手机号,scope必填 phone,permissions 必填 …...

使用 SymPy 进行向量和矩阵的高级操作
在科学计算和工程领域,向量和矩阵操作是解决问题的核心技能之一。Python 的 SymPy 库提供了强大的符号计算功能,能够高效地处理向量和矩阵的各种操作。本文将深入探讨如何使用 SymPy 进行向量和矩阵的创建、合并以及维度拓展等操作,并通过具体…...

微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据
微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据 Power Query 具有大量专门帮助您清理和准备数据以供分析的功能。 您将了解如何简化复杂模型、更改数据类型、重命名对象和透视数据。 您还将了解如何分析列,以便知晓哪些列包含有价值的数据,…...