长安链Docker Java智能合约引擎的架构、应用与规划

news2024/11/28 1:43:46

#功能发布

长安链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或在社群联系我们。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1530359.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

ideaSSM 财务凭证管理系统bootstrap开发mysql数据库web结构java编程计算机网页源码maven项目

一、源码特点 idea 开发 SSM 财务凭证管理系统是一套完善的信息管理系统&#xff0c;结合SSM框架和bootstrap完成本系统&#xff0c;对理解JSP java编程开发语言有帮助系统采用SSM框架&#xff08;MVC模式开发&#xff09;&#xff0c;系统具有完整的源代码和数据库&#xff…

[Qt学习笔记]Qt下使用Halcon实现采图时自动对焦的功能(Brenner梯度法)

目录 1、介绍2、实现方法2.1 算法实现过程2.2 模拟采集流程 3、总结4、代码展示 1、介绍 在机器视觉的开发中&#xff0c;现在有很多通过电机去做相机的聚焦调节&#xff0c;对比手工调节&#xff0c;自动调节效果更好&#xff0c;而且其也能满足设备自动的需求&#xff0c;尤…

高效的Gitlab Flow最佳实践

文章目录 一、git flow二、github flow三、gitlab flow四、基于gitlab flow的最佳实践1.语义化版本号2.测试发布3.bug修复 参考 业界包含三种flow&#xff1a; Git flowGithub flowGitlab flow 三种工作流程&#xff0c;有一个共同点&#xff1a;都采用"功能驱动式开发&…

圆弧齿的模型怎么建立?

今天咱们聊一聊圆弧齿的相关内容&#xff0c;有兴趣的小伙伴一起来看看吧。 圆弧齿轮发展历史 早期齿轮传动的速度较低、传递的功率小&#xff0c;长期的生产实践使得人们开始意识到对齿轮单个轮齿形状&#xff08;轮齿齿形&#xff09;的研究的重要性&#xff0c;齿轮的齿形…

5G安全技术新突破!亚信安全5G安全迅龙引擎正式发布

5G专网应用飞速增长&#xff1a;2020年5G专网数量800个&#xff0c;2021年2300个&#xff0c;2022年5325个&#xff0c;2023年已经超过16000个&#xff0c;5G与垂直行业的融合快速加深&#xff0c;5G带来的变革正加速渗透至各行各业。 5G网络出现安全问题&#xff0c;将是异常严…

MNN createFromBuffer(一)

系列文章目录 MNN createFromBuffer&#xff08;一&#xff09; MNN createRuntime&#xff08;二&#xff09; MNN createSession 之 Schedule&#xff08;三&#xff09; MNN createSession 之创建流水线后端&#xff08;四&#xff09; MNN Session::resize 之流水线编码&am…

C语言例3-12:自增和自减运算的例子

i 先引用后加1--i 先减1后引用 代码如下&#xff1a; #include<stdio.h> int main(void) {int i2, j2;char c1d, c2D; //d(100) D(68)printf("i %d\n",i); //3, i3printf("j-- %d\n",j--); …

Design Script之案例练习:曲线组合

让我们来探索一下如何创建分组曲线函数。这个函数将取一个无序曲线列表(必须是连续的),并将它们组合成分组的循环。 在这个例子中,我们将采取一系列的9个爆炸矩形,并洗牌合成曲线。这给了我们36条单独的曲线,它们可以正确地组合回各自的矩形中。 一些分散的曲线显示在右边…

发布镜像到阿里云仓库

发布上一篇Dockerfile实战-自定义的centos镜像。 1、登录阿里云 2、找到容器镜像服务 3、创建命令空间 4、创建镜像仓库 5、点击进入这个镜像仓库&#xff0c;可以看到所有的信息 6、根据操作指南测试推送发布 6.1登录阿里云 [rootzhoujunru home]# docker login --usernam…

数据仓库系列总结

一、数据仓库架构 1、数据仓库的概念 数据仓库&#xff08;Data Warehouse&#xff09;是一个面向主题的、集成的、相对稳定的、反映历史变化的数据集合&#xff0c;用于支持管理决策。 数据仓库通常包含多个来源的数据&#xff0c;这些数据按照主题进行组织和存储&#x…

mapboxgl添加雪碧图 addImage loadImage png/jpg svg

一、mapboxgl可以添加png或者jpg类型的图片到雪碧图中 async function addPng(id, url) {const img await new Promise((resolve) > {map.loadImage(url, (error, image) > {if (error) throw error;resolve(image);});});if (!map.hasImage(id)) {map.addImage(id, img…

【链表】算法例题

目录 八、 链表 57. 环形链表 ① 58. 两数相加 ② √ 59. 合并两个有序链表 ① √- 60. 随机链表的复制 ② 61. 反转链表II ② 62. K个一组翻转链表 ③ 63. 删除链表的倒数第N个结点 ② √- 64. 删除排序链表中的重复元素II ② √- 65. 旋转链表 ② √- 66. 分隔链…

【目标检测】图解 YOLOv3 的网络结构(Darknet-53 作为 backbone)

到了 YOLOv3&#xff0c;backbone 从 YOLOv2 的 Darknet-19 升级到了 Darknet-53。 下面一张完整的结构示意图来一起理解一下 YOLOv3 的网络结构。 我们怎么理解最后输出的 3 个特征图&#xff08;feature map&#xff09;的这个 255&#xff1f; 同 YOLOv2 一样&#xff0c;…

常见传感器的原理 和 常见滤波算法实现

阅读引言&#xff1a; 分析常见的传感器的电路原理、向大家提供一些ADC常见的滤波算法的实现, 介绍声、光、热、电、力、气和磁传感器的大致工作原理。 目录 一、常见传感器工作原理 1.声音传感器-动圈&电容咪头 2.光传感器-光敏电阻 3.热传感器-热电偶 4.电传感器-电…

YOLOv8改进 | 主干篇 | 利用图像分割网络UNetV2改善图像分割检测性能(全网独家首发)

一、本文介绍 本文给大家带来的改进机制是利用图像分割网络UNetV2的主干来改进我们的YOLOv8分割模型&#xff08;本文的内容虽然YOLOv8所有的功能的用户都能使用&#xff0c;但是还是建议分割的用户使用&#xff09;&#xff0c;U-Net v2 旨在改进医学图像分割的性能&#xff…

Spring-Gateway服务网关

一、网关介绍 1. 为什么需要网关 Gateway网关是我们服务的守门神&#xff0c;所有微服务的统一入口。 网关的核心功能特性&#xff1a; 请求路由 权限控制 限流 架构图&#xff1a; 权限控制&#xff1a;网关作为微服务入口&#xff0c;需要校验用户是是否有请求资格&am…

Zerotier 异地组网方案初探

前言 我之前想要异地组网的话&#xff0c;一般都采用内网穿透的方法&#xff0c;但是这个内网穿透有弊端就是都是要通过公网服务器转发流量&#xff0c;对于大流量的传输就比较不方便&#xff0c;我发现了Zerotier 这个工具非常的好用&#xff0c;是基于p2p的 这是一个类似于…

【SpringBoot3+Mybatis】框架快速搭建

文章目录 GitHub 项目一、依赖二、 配置文件三、启动类四、SpringBoot3兼容Druid报错五、工具类5.1 结果封装类5.2 解决枚举类5.3 MD5加密工具类 GitHub 项目 springboot-part——springboot-integrate-07 Mybatis-plus版完整CRUD项目文档记录&#xff1a; 【SpringBoot3Myba…

【项目实践Day06】异步请求与同步请求+Ajax+微信小程序上实现发送异步请求

什么是同步和异步 同步 在主线程上排队执行的任务&#xff0c;只有前一个任务执行完毕&#xff0c;才能继续执行下一个任务。也就是一旦调用开始&#xff0c;就必须等待其返回结果&#xff0c;程序的执行顺序和任务排列顺序一致。客户端必须等待服务器端的响应。在等待的期间客…

【保姆级】前端使用node.js基础教程

文章目录 安装和版本管理&#xff1a;npm 命令&#xff08;Node 包管理器&#xff09;&#xff1a;运行 Node.js 脚本&#xff1a;调试和开发工具&#xff1a;其他常用命令&#xff1a;模块管理&#xff1a;包管理&#xff1a;调试工具&#xff1a;异步编程和包管理&#xff1a…