visual studio网站开发教程,佛山手机建网站,工作服款式图片大全,网站建设的潜规则#功能发布 长安链3.0正式版发布了多个重点功能#xff0c;包括共识算法切换、支持java智能合约引擎、支持后量子密码、web3生态兼容等。我们接下来为大家详细介绍新功能的设计、应用与规划。 在《2022年度长安链开源社区开发者调研报告》中#xff0c;对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 groupIdorg.chainmaker/groupId artifactIdcontracts-sdk-java/artifactId version1.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.skiptrue
然后通过添加依赖包引入到合约开发项目。 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
MapString, 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 groupIdorg.apache.maven.plugins/groupId artifactIdmaven-shade-plugin/artifactId version3.4.0/version executions execution phasepackage/phase goals goalshade/goal /goals configuration filters filter artifact*:*/artifact excludes excludeMETA-INF/*.SF/exclude excludeMETA-INF/*.DSA/exclude excludeMETA-INF/*.RSA/exclude /excludes /filter /filters transformers transformer implementationorg.apache.maven.plugins.shade.resource.ServicesResourceTransformer/ transformer implementationorg.apache.maven.plugins.shade.resource.ManifestResourceTransformer mainClassorg.chainmaker.examples.demo/mainClass /transformer /transformers /configuration /execution /executions
/plugin
2.4.2 maven 打包方式
使用maven-shade-plugin。配置示例如下。
执行 mvn package默认生成的jar包在target目录下
plugin groupIdorg.apache.maven.plugins/groupId artifactIdmaven-shade-plugin/artifactId version3.4.0/version executions execution phasepackage/phase goals goalshade/goal /goals configuration filters filter artifact*:*/artifact excludes excludeMETA-INF/*.SF/exclude excludeMETA-INF/*.DSA/exclude excludeMETA-INF/*.RSA/exclude /excludes /filter /filters transformers transformer implementationorg.apache.maven.plugins.shade.resource.ServicesResourceTransformer/ transformer implementationorg.apache.maven.plugins.shade.resource.ManifestResourceTransformer mainClassorg.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接口中略显冗余的GetStateGetStateByteGetStateFromKeyGetStateFromKeyByte等接口而是函数名统一使用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或在社群联系我们。