2021SC@SDUSC
智能合约 1. 简介JD Chain 智能合约系统由5个部分组成:合约代码语言、合约引擎、合约账户、合约开发框架、合约开发插件。
合约代码语言是用来编写智能合约的编程语言,合约引擎是解释和执行合约代码的虚拟机。
JD Chain 账本中以合约账户的方式对合约代码进行管理。一份部署上链的合约代码需要关联到一个唯一的公钥上,并生成与公钥对应的区块链账户地址,在账本中注册为一个合约账户。在执行之前,系统从账本中读出合约代码并将其加载到合约引擎,由交易执行器调用合约引擎触发合约执行。
JD Chain 账本定义了一组标准的账本操作指令,合约代码的执行过程实质上是向账本输出一串操作指令序列,这些指令对账本中的数据产生了变更,形成合约执行的最终结果。
合约开发框架定义了进行合约代码开发中需要依赖的一组编程接口和类库。合约开发插件提供了更方便与IDE集成的合约编译、部署工具,可以简化操作,并与持续集成过程结合。
JD Chain 以 Java 语言作为合约代码语言,合约引擎是基于 JVM 构建的安全沙盒。为了实现与主流的应用开发方式无缝兼容, JD Chain 支持以 Maven 来管理合约代码的工程项目,并提供相应的 maven 插件来简化合约的编译和部署。
智能合约是一种可以由计算机执行的合同/协议。不同于现实生活中的合同是由自然语言来编写并约定相关方的权利和义务,智能合约是用合约代码语言来编写,以合约代码的形式存在和被执行。通过账本中的数据状态来表示合同/协议相关条款信息,合约代码的运行过程体现了合同/协议条款的执行,并记录相应的结果。
2. 快速入门 2.1. 准备开发环境按照正常的 Java 应用开发环境要求进行准备,以 Maven 作为代码工程的构建管理工具,无其它特殊要求。
检查 JDK 版本不低于 1.8 ,Maven 版本不低于 3.0。
2.2. 创建合约代码工程创建一个普通的 Java Maven 工程,打开 pom.xml 把 packaging 设为 contract .
2.3. 加入合约开发依赖4.0.0 your.group.id your.project 0.0.1-SNAPSHOT contract
在合约代码工程 pom.xml 加入对合约开发 SDK 的依赖:
2.4. 加入合约插件com.jd.blockchain contract-starter ${jdchain.version}
在合约代码工程的 pom.xml 加入 contract-maven-plugin 插件:
com.jd.blockchain contract-maven-plugin ${jdchain.version} true
完整的 pom.xml 如下:
4.0.0 your.group.id your.project 0.0.1-SNAPSHOT contract 1.4.2.RELEASE com.jd.blockchain contract-starter ${jdchain.version} org.apache.maven.plugins maven-compiler-plugin 3.8.1 1.8 1.8 UTF-8 false true false false com.jd.blockchain contract-maven-plugin ${jdchain.version} true
2.5.2. 声明合约
@Contract
public interface AssetContract {
@ContractEvent(name = "transfer")
String transfer(String address, String from, String to, long amount);
}
2.5.3. 实现合约
public class AssetContractImpl implements AssetContract, EventProcessingAware {
// 合约事件上下文;
private ContractEventContext eventContext;
public String transfer(String address, String from, String to, long amount) {
//当前账本的哈希;
HashDigest ledgerHash = eventContext.getCurrentLedgerHash();
//当前账本上下文;
LedgerContext ledgerContext = eventContext.getLedger();
//做操作;
// ledgerContext.
//返回合约操作的结果;
return "success";
}
@Override
public void beforeEvent(ContractEventContext eventContext) {
this.eventContext = eventContext;
}
@Override
public void postEvent(ContractEventContext eventContext, Exception error) {
this.eventContext = null;
}
}
账本数据可见范围:
ContractEventContext中getUncommittedLedger方法可访问执行中的未提交区块数据,此方法的合理使用可以解决客户并发调用合约方法涉及数据版本/事件序列冲突的问题。
LedgerQueryService getUncommittedLedger();
ContractEventContext中getLedger方法访问的是链上已提交的最新区块数据,不包含未提交交易,所以存在未提交交易中多个合约方法调用操作间数据不可见,导致并发时数据版本等冲突问题。
LedgerContext getLedger();
合约方法中对账本的操作通过调用LedgerContext中相关方法,可参照示例合约
2.6. 编译打包合约代码合约代码工程的编译打包操作与普通的 maven 工程是相同的,在工程的根目录下输入以下命令:
mvn clean package
执行成功之后,在 target 目录中输出合约代码文件
如果合约代码加入了除 com.jd.blockchain:contract-starter 之外的其它依赖,默认配置下,第三方依赖包将与 .car 文件一起打包一起部署。



