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

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

9.用FFmpeg测试H.264文件的解码时间

1. Essence of Method 要测试对H.264文件的解码时间&#xff0c;可以使用FFmpeg进行操作。FFmpeg是一个开源的多媒体处理工具&#xff0c;可以用来处理视频和音频文件&#xff0c;包括解码H.264文件。以下是使用FFmpeg的命令行来测试解码时间的方法&#xff1a; ffmpeg -i in…

Unity类银河恶魔城学习记录11-2 p104 Inventoty源代码

此章节相对较难理解&#xff0c;有时间单独出一章讲一下 Alex教程每一P的教程原代码加上我自己的理解初步理解写的注释&#xff0c;可供学习Alex教程的人参考 此代码仅为较上一P有所改变的代码 【Unity教程】从0编程制作类银河恶魔城游戏_哔哩哔哩_bilibili InventoryItem.cs…

React的生命周期

生命周期图谱: React lifecycle methods diagram 生命周期三大阶段 挂载阶段 流程: constructor > render > componentDidMount 触发: ReactDOM.render(): 渲染组件元素 更新阶段 流程: render > componentDidUpdate 触发: setState() , forceUpdate(), 组件接收到新…

JS+CSS3点击粒子烟花动画js特效

JSCSS3点击粒子烟花动画js特效 JSCSS3点击粒子烟花动画js特效

【python】Anaconda安装后打不开jupyter notebook(网页不自动跳出)

文章目录 一、遇到的问题&#xff1a;jupyter notebook网页不自动跳出&#xff08;一&#xff09;输入jupyter notebook命令&#xff08;二&#xff09;手动打开网页 二、解决办法&#xff1a;指定浏览器&#xff08;一&#xff09;找文件 jupyter_notebook_config.py&#xff…

JVM常用垃圾收集器

JVM 4.1 哪些对象可以作为GC ROOT? 虚拟机栈&#xff08;栈帧中的局部变量表&#xff09;中引用的对象本地方法栈中引用的对象方法区静态变量引用的对象方法区常量引用的对象被同步锁持有的对象JNI&#xff08;Java Native Interface&#xff09;引用的对象 4.2 常用垃圾收集…

Spring Boot 自动化单元测试类的编写过程

前言 Web环境模拟测试 企业开发不仅要保障业务层与数据层的功能安全有效&#xff0c;也要保障表现层的功能正常。但是我们一般对表现层的测试都是通过postman手工测试的&#xff0c;并没有在打包过程中代码体现表现层功能被测试通过。那么能否在测试用例中对表现层进行功能测…

【重温设计模式】状态模式及其Java示例

状态模式的基本概念 在编程世界的大海中&#xff0c;各种设计模式就如同灯塔&#xff0c;为我们的代码编写指明方向。其中&#xff0c;状态模式是一种行为设计模式&#xff0c;它让你能在一个对象的内部状态改变时改变其行为&#xff0c;使得对象看起来就像改变了其类一样。这…

微信小程序原生<map>地图实现标记多个位置以及map 组件 callout 自定义气泡

一、老规矩先上效果图: 二、在pages文件夹下新建image文件夹用来存放标记的图片。 三、代码片段 也可以参考小程序文档:https://developers.weixin.qq.com/miniprogram/dev/component/map.html index.wxml代码 <mapid="map"style="width: 100%; height:1…

企业专业化管理金字塔:技能进阶与案例分析

在纷繁复杂的企业管理领域中&#xff0c;一套行之有效的管理技能体系对于企业的稳健发展至关重要。本文将深入探讨企业专业化管理金字塔的五个层次&#xff1a;基本的管理技能、业务操作管理技能、组织管理技能、组织开发技能以及管理转变技能&#xff0c;并结合实际案例&#…

mac电脑修改终端zsh显示的用户名

电脑名称一直没有修改&#xff0c;所以电脑名称都是Apple的MacBook Pro&#xff0c;如下图所示&#xff1a; mac电脑终端显示用户名太长一点也不美观&#xff0c;而且占用很长的行&#xff0c;浪费空间&#xff0c;可以通过修改来调整要显示什么内容&#xff1a; 方式一 要想换…

rabbitmq-spring-boot-start配置使用手册

rabbitmq-spring-boot-start配置使用手册 文章目录 1.yaml配置如下2.引入pom依赖如下2.1 引入项目resources下libs中的jar包依赖如下2.2引入maven私服依赖如下 3.启动类配置如下4.项目中测试发送消息如下5.项目中消费消息代码示例6.mq管理后台交换机队列创建及路由绑定关系如下…

信息检索(十三):On Complementarity Objectives for Hybrid Retrieval

On Complementarity Objectives for Hybrid Retrieval 摘要1. 引言2. 相关工作2.1 稀疏和密集检索2.2 互补性 3. 提出方法3.1 Ratio of Complementarity (RoC)3.2 词汇表示&#xff08;S&#xff09;3.3 语义表示&#xff08;D&#xff09;3.4 互补目标 4. 实验4.1 实验设置4.2…

关系数据库:关系数据结构基础与概念解析

✨✨ 欢迎大家来访Srlua的博文&#xff08;づ&#xffe3;3&#xffe3;&#xff09;づ╭❤&#xff5e;✨✨ &#x1f31f;&#x1f31f; 欢迎各位亲爱的读者&#xff0c;感谢你们抽出宝贵的时间来阅读我的文章。 我是Srlua小谢&#xff0c;在这里我会分享我的知识和经验。&am…

Nginx学习与使用

Nginx 什么是NginxNginx命令Nginx 配置文件文件组成全局块&#xff1a;配置服务器整体运行的配置指令Events块&#xff1a;影响Nginx服务器与用户的网络连接Http块Http全局块Server块全局Server快Location块 配置实例Nginx配置实例——反向代理 什么是Nginx Nginx命令 1.使用…

湖北省地质灾害分布数据 崩塌滑坡泥石流空间分布地质灾害详查等数据集

地质灾害是指在自然或者人为因素的作用下形成的&#xff0c;对人类生命财产造成的损失、对环境造成破坏的地质作用或地质现象。地质灾害在时间和空间上的分布变化规律&#xff0c;既受制于自然环境&#xff0c;又与人类活动有关&#xff0c;往往是人类与自然界相互作用的结果。…

数据资产管理解决方案:构建高效、安全的数据生态体系

在数字化时代&#xff0c;数据已成为企业最重要的资产之一。然而&#xff0c;如何有效管理和利用这些数据资产&#xff0c;却是许多企业面临的难题。本文将详细介绍数据资产管理解决方案&#xff0c;帮助企业构建高效、安全的数据生态体系。 一、引言 在信息化浪潮的推动下&a…

Geostationary IR Channel Brightness Temperature - GridSat B1 -- shell下载

进入网页 https://www.ncei.noaa.gov/products/gridded-geostationary-brightness-temperature 然后进入数据目录&#xff0c;通过https的方式进行下载&#xff1a; 点击后进入如下界面&#xff1a; 点击任意年份进行下载 这里以2004年为例&#xff0c;如下所示&#xff1…

Go语言中的锁与管道的运用

目录 1.前言 2.锁解决方案 3.管道解决方案 4.总结 1.前言 在写H5小游戏的时候&#xff0c;由于需要对多个WebSocket连接进行增、删、查的管理和对已经建立连接的WebSocket通过服务端进行游戏数据交换的需求。于是定义了一个全局的map集合进行连接的管理&#xff0c;让所有…

力扣每日一道系列 --- LeetCode 160. 相交链表

&#x1f4f7; 江池俊&#xff1a; 个人主页 &#x1f525;个人专栏&#xff1a; ✅数据结构探索 ✅LeetCode每日一道 &#x1f305; 有航道的人&#xff0c;再渺小也不会迷途。 LeetCode 160. 相交链表 思路&#xff1a; 首先计算两个链表的长度&#xff0c;然后判断两个链…