如何使用webase-front交易处理接口(本地签名)调用合约
前提条件
-
部署好fisco-bcos区块链网络,此处是通过webase依赖包一键部署区块链网络
-
在虚拟机或者云服务器部署区块链网络并开放相应的端口,使用windows端导入java项目时,请使用内网IP或公网IP导出项目
注意这里是为了方便,通过webase平台用户导出项目,而webase平台和webase-frong前置两个数据库互相独立,用户公私钥不会共享,所以也要把webase平台的用户导入到webase-front前置。若使用webase-front部署合约,并导出,则不用操作
这里也可以自己在idea新建一个项目,导入相应的配置好相关配置就可以了,不过会相对麻烦一些
1.接口说明
接口描述
此接口为WeBASE-Front使用本地私钥(页面中的测试用户)进行签名
通过合约信息进行调用,前置根据调用的合约方法是否是“constant”方法区分返回信息,“constant”方法为查询,返回要查询的信息。非“constant”方法为发送数据上链,返回块hash、块高、交易hash等信息。
接口URL
http://localhost:5002/WeBASE-Front/trans/handle
调用方法
HTTP POST
请求参数
1)参数列表
序号 | 中文 | 参数名 | 类型 | 最大长度 | 必填 | 说明 |
---|---|---|---|---|---|---|
1 | 用户地址 | user | String | 是 | 用户地址,可通过/privateKey 接口创建 |
|
2 | 合约名称 | contractName | String | 是 | ||
3 | 合约地址 | contractAddress | String | 是 | ||
4 | 方法名 | funcName | String | 是 | ||
5 | 合约编译后生成的abi文件内容 | contractAbi | List | 是 | 合约中单个函数的ABI,若不存在同名函数可以传入整个合约ABI,格式:JSONArray | |
6 | 方法参数 | funcParam | List | 否 | String数组,每个参数都使用String字符串表示,数组也需要放在双引号内,多个参数以逗号分隔(参数为数组时同理),如:set(string s, string[] l) -> [“str1”,“[“arr1”,“arr2”]”],根据所调用的合约方法判断是否必填 | |
7 | 群组ID | groupId | int | 是 | 默认为1 | |
8 | 合约路径 | contractPath | int | 否 | ||
9 | 是否使用cns调用 | useCns | bool | 是 | ||
10 | cns名称 | cnsName | String | 否 | CNS名称,useCns为true时不能为空 | |
11 | cns版本 | version | String | 否 | CNS版本,useCns为true时不能为空 |
2)数据格式
示例:
{
"groupId": "1",
"user": "0x7bfa3539c8761978f0a2a1f7f240bde97819fb03",
"contractName": "HelloWorld",
"contractPath": "/",
"version": "",
"funcName": "set",
"funcParam": ["333"],
"contractAddress": "0xe10441d9179cf0424aae808b51bc85dcbbfe1447",
"contractAbi": [{
"inputs": [{
"internalType": "string",
"name": "n",
"type": "string"
}],
"name": "set",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function",
"funcId": 2
}],
"useAes": false,
"useCns": false,
"cnsName": ""
}
响应参数
a、正确查询交易返回值信息
{"Hi,Welcome!"}
b、正确发送数据上链返回值信息(交易收据)
{
"transactionHash": "0x69ced0162a0c3892e4eaa3091b831ac3aaeb772c062746b20891ceaf8a4fb429",
"transactionIndex": "0x0",
"root": "0x8cbc3f2c0e35a71738909e3b388efa6697084b05badd3a3bd3c64f0575c78c15",
"blockNumber": "2",
"blockHash": "0xf58f4f43b3761f4863ad366c4a7e2a812ed68df9f7bcad6b502fd544665e7625",
"from": "0x9d75e0ee66cfef16897b601624b60413d988ae7d",
"to": "0x0000000000000000000000000000000000000000",
"gasUsed": "316449",
"contractAddress": "0xa8af0ee580d8af674a60341030ddbc45431bc235",
"logs": [],
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"status": "0x0",
"statusMsg": "None",
"input": "0x608060405234801561001057600080fd5b506103e3806100206000396000f300608060405260043610610057576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063299f7f9d1461005c5780633590b49f146100ec57806362e8d6ce14610155575b600080fd5b34801561006857600080fd5b5061007161016c565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156100b1578082015181840152602081019050610096565b50505050905090810190601f1680156100de5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156100f857600080fd5b50610153600480360381019080803590602001908201803590602001908080601f016020809104026020016040519081016040528093929190818152602001838380828437820191505050505050919291929050505061020e565b005b34801561016157600080fd5b5061016a6102c4565b005b606060008054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156102045780601f106101d957610100808354040283529160200191610204565b820191906000526020600020905b8154815290600101906020018083116101e757829003601f168201915b5050505050905090565b7f5715c9562eaf8d524d564edb392acddefc81d8133e2fc3b8125a260b1b413fda816040518080602001828103825283818151815260200191508051906020019080838360005b83811015610270578082015181840152602081019050610255565b50505050905090810190601f16801561029d5780820380516001836020036101000a031916815260200191505b509250505060405180910390a180600090805190602001906102c0929190610312565b5050565b6040805190810160405280600d81526020017f48656c6c6f2c20576f726c6421000000000000000000000000000000000000008152506000908051906020019061030f929190610312565b50565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061035357805160ff1916838001178555610381565b82800160010185558215610381579182015b82811115610380578251825591602001919060010190610365565b5b50905061038e9190610392565b5090565b6103b491905b808211156103b0576000816000905550600101610398565b5090565b905600a165627a7a72305820f3088deb3d14c6893440e4769f2389e9335e04faa10e6de5b4c93af15d1a34e80029",
"output": "0x",
"txProof": null,
"receiptProof": null,
"message": null,
"statusOK": true
}
注:访问 WeBASE-Front Swagger-ui
- 浏览器访问: http://localhost:5002/WeBASE-Front/swagger-ui.html
- 找到**/trans/handle**的 API 接口
- 有相关的测试用例对其进行测试操作
2.编写合约HelloWorld.sol
pragma solidity ^0.4.25;
contract HelloWorld{
string str;
constructor(){
str = "Hello World";
}
function setStr(string memory _str)public {
str = _str;
}
function getStr()public view returns(string memory){
return str;
}
}
3.编译部署合约
4.导出java项目
第一步点击到处java项目
第二步,选择节点,选择用户,选择已编译HelloWorld合约
第三步,把下载好的Java项目导入IDEA
打开IDEA,点击左上角文件,点击打开,然后找到下载好的项目导入,构建项目需要一定的时间下载gradel包管理器和依赖
导入后成功构建,如下所示:
5.通过测试类调用接口
HelloWorldTestByWeBASE_Front
是一个测试类。它主要用于测试与合约进行交互的功能。
类中的注解解释如下:
@RunWith(SpringRunner.class)
:指定使用 SpringRunner 来运行测试,这是一个JUnit运行器,用于运行 Spring Boot 的集成测试。@SpringBootTest(classes = Application.class)
:表示这是一个Spring Boot的集成测试类,并指定了Application
类作为启动类来加载Spring Boot上下文。@WebAppConfiguration
:标记这是一个Web应用程序的配置类,并为测试类提供Web上下文。@PropertySource(value = {"classpath:application.properties"})
:指定了引入的外部属性文件application.properties
。
该类中包含了两个测试方法:
testSet()
方法用于测试调用合约的setStr()
方法testGet()
方法用于测试调用合约的getStr()
方法
这个测试类主要用于验证与合约进行交互的功能是否正常,包括调用合约的方法并获取其返回结果。
代码如下所示:
package org.example.HelloWorld;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.annotation.PropertySource;
import org.springframework.http.*;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.web.client.RestTemplate;
@RunWith(SpringRunner.class)
@SpringBootTest(classes = Application.class)
@WebAppConfiguration
@PropertySource(value = {
"classpath:application.properties"})
public class HelloWorldTestByWeBASE_Front {
@Value("${URL}")
private String URL;
@Value("${system.contract.helloWorldAddress}")
private String CONTRACT_ADDRESS;
private final String CONTRACT_NAME = "HelloWorld";
public static final String ABI = "[{\"constant\":false,\"inputs\":[{\"name\":\"_str\",\"type\":\"string\"}],\"name\":\"setStr\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"getStr\",\"outputs\":[{\"name\":\"\",\"type\":\"string\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"}]";
public static final String FUNC_SETSTR = "setStr";
public static final String FUNC_GETSTR = "getStr";
public static final String TEST_USER_ADDRESS = "0xf6d9791f45c124ad528793aaa559b7bb2c93e190";
@Test
public void testSet(){
// 创建一个RestTemplate实例
RestTemplate restTemplate = new RestTemplate();
// 创建请求头,并设置为JSON格式
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
// 构造请求体
JSONObject requestBody = new JSONObject();
//设置接口参数
JSONArray params = JSONArray.parseArray("[\"Hello FISCO-BCOS\"]");
requestBody.put("contractName",CONTRACT_NAME);
requestBody.put("contractAddress",CONTRACT_ADDRESS);
requestBody.put("funcParam",params);
//此处ABI原为json格式,因为JSONObject对象要序列化为json格式,避免重复序列化所以先将ABI转为java对象
requestBody.put("contractAbi", JSONArray.parseArray(ABI));
requestBody.put("user",TEST_USER_ADDRESS);
requestBody.put("funcName",FUNC_SETSTR);
// 创建HttpEntity对象,将请求体和请求头封装为一个请求实体
HttpEntity<JSONObject> requestEntity = new HttpEntity<>(requestBody, headers);
// 发送POST请求,并获取响应结果
ResponseEntity<String> responseEntity = restTemplate.exchange(URL,HttpMethod.POST, requestEntity, String.class);
System.out.println("responseEntity = " + responseEntity);
System.out.println("responseEntity.getStatusCodeValue() = " + responseEntity.getStatusCodeValue());
if(responseEntity.getStatusCodeValue()==200){
System.out.println("调用合约setStr()成功,结果为:" + responseEntity.getBody());
}
}
@Test
public void testGet(){
// 创建一个RestTemplate实例
RestTemplate restTemplate = new RestTemplate();
// 创建请求头,并设置为JSON格式
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
// 构造请求体
JSONObject requestBody = new JSONObject();
requestBody.put("contractName",CONTRACT_NAME);
requestBody.put("contractAddress",CONTRACT_ADDRESS);
//此处ABI原为json格式,因为JSONObject对象要序列化为json格式,避免重复序列化所以先将ABI转为java对象
requestBody.put("contractAbi", JSONArray.parseArray(ABI));
requestBody.put("user",TEST_USER_ADDRESS);
requestBody.put("funcName",FUNC_GETSTR);
// 创建HttpEntity对象,将请求体和请求头封装为一个请求实体
HttpEntity<JSONObject> requestEntity = new HttpEntity<>(requestBody, headers);
// 发送POST请求,并获取响应结果
ResponseEntity<String> responseEntity = restTemplate.exchange(URL,HttpMethod.POST, requestEntity, String.class);
System.out.println("responseEntity = " + responseEntity);
System.out.println("responseEntity.getStatusCodeValue() = " + responseEntity.getStatusCodeValue());
if(responseEntity.getStatusCodeValue()==200){
System.out.println("调用合约getStr()成功,结果为:" + responseEntity.getBody());
}
// 发送Get请求,并获取响应结果
String response = restTemplate.getForObject("http://47.122.19.138:5002/WeBASE-Front/version", String.class);
System.out.println("version = " + response);
}
}
测试运行结果: