Appearance
合约调用
智能合约引擎基于 RSocket 通信协议,推荐使用异步方式进行调用以提高性能
使用 RestTemplate 进行同步调用
// 声明一个配置类,并注册 RestTemplate 对象
@Configuration
public class RestTemplateConfig {
@Bean
public RestTemplate getRestTemplate(){
return new RestTemplate();
}
}
// 批量数据上链调用方法如下
public void testContract() {
// 创建请求头,设置 ContentType 为 JSON 数据格式
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
List<Dataset> list = Lists.newArrayList();//构建上链数据列表,可从数据库获取,或通过循环创建如下
for (int i = 0; i < 50; i++) {
Dataset dataset = new Dataset();
dataset.setCstr("所需属性");
dataset.setKeyword("所需属性");
dataset.setTitle("所需属性");
list.add(dataset);
}
// 数据批量上链地址 - 合约部署地址
String url = "https://api.odc.cn/***"
// 创建请求 HttpEntity
HttpEntity<List<Dataset>> httpEntity = new HttpEntity<>(list, headers);
// 发送数据
ODCResponse[] rs = restTemplate.postForObject(url, httpEntity, ODCResponse[].class);
// 遍历获取合约响应数据
Arrays.stream(AssertUtils.notEmpty(rs)).forEach(odcResponse -> {
log.debug("智能合约响应数据 : {}", odcResponse.getBody());
});
}
使用 WebClient 进行异步调用
// 批量数据上链调用异步方法如下
public Flux<ODCResponse> testReactiveContract() {
List<Dataset> list = Lists.newArrayList();// 获取数据上链列表
// 创建 WebClient
WebClient webClient = WebClient.builder()
.baseUrl("https://api.opendatachain.cn")
.build();
// 发送请求并获取合约响应数据
return webClient.post().uri("/test.upsert.batch")
.contentType(MediaType.APPLICATION_JSON)
.bodyValue(list)
.retrieve()
.bodyToFlux(ODCResponse.class);
}
// 调用异步反方并处理返回数据
@Test
void testContract() throws InterruptedException {
//调用批量数据上链方法;
Flux<ODCResponse> results = testContract.testReactiveContract();
// 获取并打印合约响应数据
results.toIterable().forEach(response -> {
log.debug("智能合约响应数据: " + response.getBody());
});
}
将智能合约响应结果转换为对象
// 使用 fastjson 转换智能合约响应结果为对象
ODCRequest request = JSON.parseObject(response.getBody(), ODCRequest.class);
// ODCRequest 包含属性信息
public class ODCRequest {
// UID 唯一标识
private String uid;
// 上链数据 json 格式
private String data;
// 签名,基于 SM2 算法实现
private String sign;
// 交易 ID
private String txId;
// 交易事件
private String transactionEvent;
// 合约名称
private String contractName;
// 子链名称
private String channelName;
// 节点名称
private String nodeName;
// 数据是否加密
private String isEncrypt;
// 时间戳
private long timestamp;
}