# security_block_chain
**Repository Path**: openharmony-sig/security_block_chain
## Basic Information
- **Project Name**: security_block_chain
- **Description**: No description available
- **Primary Language**: Unknown
- **License**: Apache-2.0
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 2
- **Forks**: 1
- **Created**: 2021-08-16
- **Last Updated**: 2025-05-07
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# OpenHarmony区块链子系统接口文档
- [说明](#section10)
- [概述](#section11)
- [项目功能](#section12)
- [项目结构](#section13)
- [运行环境](#section14)
- [接口说明](#section20)
- [日志打印回调函数](#section21)
- [日志时间回调函数](#section22)
- [日志静默函数](#section23)
- [日志等级函数](#section24)
- [时间戳回调函数](#section25)
- [使用x509证书初始化账户函数](#section26)
- [使用json初始化账户函数](#section27)
- [创建交易函数](#section28)
- [交易格式化为字符串函数](#section29)
- [合约参数结构体内存分配函数](#section210)
- [合约abi结构体内存分配函数](#section211)
- [Abi结构体释放函数](#section212)
- [参数结构体释放函数](#section213)
- [合约增加bytes类型参数函数](#section214)
- [合约增加无符号整数数组类型参数函数](#section215)
- [合约增加带符号整数数组类型参数函数](#section216)
- [合约增加带符号整数类型参数函数](#section217)
- [合约增加无符号整数类型参数函数](#section218)
- [结构体abi的生成函数](#section219)
- [根据abi结构体查找method的函数的inputs](#section221)
- [根据abi结构体查找method的函数的outputs](#section222)
- [初始化合约结构体](#section223)
- [释放合约结构体内的内容](#section224)
- [设置VM类型](#section225)
- [设置合约名](#section226)
- [不带参数的合约部署](#section227)
- [带参数的合约部署](#section228)
- [合约调用的封装函数](#section229)
- [合约update的封装函数](#section230)
- [合约freeze的封装函数](#section231)
- [合约unfreeze的封装函数](#section232)
- [合约destroy的封装函数](#section233)
- [设置合约signature](#section234)
- [初始化合约交易回执结构体的函数](#section235)
- [释放合约交易回执结构体内容的函数](#section236)
- [合约交易回执的ret字符串译码函数](#section238)
- [ret字符串译码结果结构体内存分配函数](#section239)
- [ret字符串译码结果结构体内存释放函数](#section240)
- [交易回执基本结构体生成函数](#section241)
- [打包为要发送到hyperchain的json格式字符串](#section242)
- [打包为要发送到以太坊的json格式字符串](#section243)
- [交易收发函数](#section244)
- [获取交易回执](#section245)
- [轮询获取交易回执](#section246)
- [basic_response_t类型结构体初始化函数](#section247)
- [basic_response_t类型结构体内容释放函数](#section248)
- [设置时间戳函数](#section249)
- [分配内存并复制内容](#section250)
- [ql_strings_t结构体类型内存分配函数](#section251)
- [ql_strings_t结构体类型内存释放函数](#section252)
---
### 说明
#### 概述
本文档是Openharmony上链软件包的接口文档,旨在描述该软件包的使用说明、使用方式,为用户基于该软件包的应用开发提供说明。
OpenHarmony区块链子系统软件包在iot场景下提供了数据格式化和处理的功能,为设备数据上链提供了可能。该软件包采用回调函数方式定义、设置外部接口,支持椭圆曲线密码学算法,编程风格符合《C语言编程规范》,具有便于移植、调试方便、代码轻量化等特点。
#### 项目功能
- 支持keccak256哈希运算。
- 支持secp256k1签名、验签、共享密钥,支持公钥恢复算法,支持rfc6979确定性随机数算法。
- 支持解析pem格式的X.509证书。
- 支持趣链,以太坊jsonrpc接口,实现iot需要的extra存证接口、合约调用与部署。
#### 项目结构
项目主要包含以下内容:
- account:account.c源文件,提供用户与普通交易生成的相关接口。
- base:基本功能相关的源文件,包括hash.c、json.c、log.c、md5.c、x509.c、utils.c。
- contract:contract.c源文件,提供合约封装与合约回执解析的相关接口。
- crypto:加密相关的ecc.c、keccak256.c源文件。
- include:头文件目录。
- services:services.c源文件,提供收发交易,以及对交易回执的基本信息分析的相关接口。
- BUILD.gn:一系列与OpenHarmony系统编译相关的文件。
```
.
├── account
│ ├── account.c # 账户操作相关实现
│ └── BUILD.gn # account的Build.gn构建文件
├── base
│ ├── hash.c # rfc6979 hash计算相关实现
│ ├── json.c # cjson相关调用实现
│ ├── log.c # 日志打印相关实现
│ ├── md5.c # md5计算相关实现
│ └── x509.c # x509证书相关实现
├── BUILD.gn # 整个文件夹的Build.gn构建文件
├── contract
│ ├── BUILD.gn # contract的Build.gn构建文件
│ └── contract.c # 合约调用操作相关实现
├── crypto
│ ├── BUILD.gn # crypto的Build.gn构建文件
│ ├── ecc.c # ecc签名相关实现
│ └── keccak256.c # keccak256 hash算法相关实现
├── include
│ ├── account.h # 账户结构相关头文件
│ ├── contract.h # 合约结构相关头文件
│ ├── ecc.h # ecc签名相关头文件
│ ├── hash.h # rfc6979 hash计算头文件
│ ├── json.h # cjson相关调用头文件
│ ├── keccak256.h # keccak256 hash算法相关头文件
│ ├── log.h # 日志打印相关头文件
│ ├── md5.h # md5计算相关头文件
│ ├── ql_error_type.h # 自定义错误类型
│ ├── ql_type.h # 自定义数据类型
│ ├── services.h # 上链操作相关头文件
│ └── x509.h # x509证书相关头文件
├── ohos.build # build构建文件
└── services
├── BUILD.gn # services的Build.gn构建文件
└── services.c # 上链操作相关实现
```
#### 运行环境
编译环境:gcc 3.0+(支持C99标准)
运行环境:32位单片机裸机、Linux系统、FreeRTOS系统、open Harmony操作系统
---
### 接口说明
#### 日志打印回调函数
项目|内容
:---:|:--:
函数名称|SetPrintLogCallback
功能描述|设置打印日志的回调函数
参数|函数指针
返回值|无
备注|若不设置,则无法打印日志
示例:
```
void print_log_func(char *content){
printf("%s",content);
}
SetPrintLogCallback(print_log_func);
```
#### 日志时间回调函数
项目|内容
:---:|:--:
函数名称|SetGetTimeCallback
功能描述|设置日志打印时间的回调函数
参数|函数指针
返回值|无
备注|若不设置,则日志时间无法正常显示
示例:
```
void print_log_time(char * time_buf, int size){
#if (defined(__unix)) || (defined(_WIN32) || defined(_WIN64))
time_t t = time(NULL);
struct tm* tp = localtime(&t);
time_buf[strftime(time_buf, size, "%H:%M:%S", tp)] = '\0';
#else
time_buf[0] = '\0';
#endif
}
SetGetTimeCallback(print_log_time);
```
#### 日志静默函数
项目|内容
:---:|:--:
函数名称|LogSetQuiet
功能描述|设置日志是否需要静默,即设置是否打印日志
参数|LOG_QUIET_FALSE:不启用,即打印
LOG_QUIET_TRUE:启用,即不打印日志
返回值|无
备注|无
示例:
```
LogSetQuiet(LOG_QUIET_FALSE);
```
#### 日志等级函数
项目|内容
:---:|:--:
函数名称|LogSetLevel
功能描述|设置日志打印的等级
参数|LOG_DEBUG:调试等级
LOG_INFO:信息等级
LOG_WARN:警告等级
LOG_ERROR:错误等级
返回值|无
备注|无
示例:
```
LogSetLevel(LOG_DEBUG);
```
#### 时间戳回调函数
项目|内容
:---:|:--:
函数名称|AccountSetTimeFunc
功能描述|设置时间戳获取函数函数指针
参数|函数指针
返回值|无
备注|单位为ns,若错误设置或不设置,将直接导致数据无法上链。
示例:
```
ql_err_t native_get_time(OhInt64Type *dst) {
struct timeval t;
gettimeofday(&t,NULL);
*dst = (OhInt64Type)t.tv_sec * 1000000000 + (Oh_int64_t)t.tv_usec*1000; // ns
return ACCOUNT_SUCCESS;
}
AccountSetTimeFunc(native_get_time);
```
#### 使用x509证书初始化账户函数
项目|内容
:---:|:----------:
函数名称|AccountInitX509
功能描述|使用x509证书初始化账户
参数|acc:account_t\*类型的账户对象
str: ql_byte_t\*类型的私钥证书
返回值|参见account.h文件内的错误宏定义
备注|需要先声明一个account_t类型的账户,之后再使用私钥证书初始化该账户。
示例:
```
ql_byte_t priKey[] = "-----BEGIN EC PRIVATE KEY-----\n"
"MHQCAQEEIAICAgEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBoAcGBSuBBAAK\n"
"oUQDQgAExUK0Fv9I2BvhZR8lVIwG0ZHPowy4GvUZEYMM8uASzJ/3/Xbd0VlMYHFg\n"
"qXkEMxUZJABjkW2PNh3vU4lzCsLXRA==\n"
"-----END EC PRIVATE KEY-----";
account_t myAccount;
ql_err_t res = AccountInitX509(&myAccount, priKey);
```
#### 使用json初始化账户函数
项目|内容
:---:|:-----:
函数名称|AccountInitJson
功能描述|使用json类型的账户数据初始化账户
参数|acc:account_t\* 类型的账户对象
str: ql_byte_t\* 类型的json账户数据
返回值|参见account.h文件内的错误宏定义
备注|需要先声明一个account_t类型的账户,之后再初始化该账户。
示例:
```
ql_byte_t acc_json[] =
"{\"version\":\"4.0\",\"algo\":\"0x00\",\"privateKey\":\"0202020101010101010101010101010101010101010101010101010101010101\",\"publicKey\":\"04c542b416ff48d81be1651f25548c06d191cfa30cb81af51911830cf2e012cc9ff7fd76ddd1594c607160a97904331519240063916d8f361def5389730ac2d744\",\"address\":\"469339bdf3d3621bebea36c308de77939424e34e\"}";
account_t myAccount;
ql_err_t res = AccountInitJson(&myAccount, acc_json);
```
#### 创建交易函数
项目|内容
:---:|:-----:
函数名称|TxSendNew
功能描述|创建交易
参数|tx:tx_t* 类型,指向交易对象
acc:account_t* 类型,指向账户对象
to:ql_byte_t* 类型,为交易的目的地址
val:ql_int32_t类型,为交易的val值,存证则设置为0
ex:ql_byte_t* 类型,为存证的信息,通常为json格式
exid:ql_byte_t* 类型,为extraid的信息,需要为带[]的字符串格式,中括号内的字符串可以用逗号隔开
返回值|参见account.h文件内的错误宏定义
备注|返回值直接通过http post请求发送至区块链,即可完成数据上链
示例:
```
tx_t tx;
ql_byte_t ex[] = "{\"id\":\"0F384\",\"name\":\"tom\",\"class\":\"0808\"}";
res = TxSendNew(&tx, &myAccount, myAccount.addr, 0, ex, (ql_byte_t *)"[\"123\"]");
```
#### 合约参数结构体内存分配函数
项目|内容
:---:|:-----:
函数名称|CreateArg
功能描述|对合约调用或部署时的参数结构体内存分配并初始化
参数|无
返回值|arg_t*类型,指向需要生成的参数结构体
备注|若返回NULL,则表示内存分配失败
示例:
```
arg_t* my_arg = CreateArg();
```
#### 合约abi结构体内存分配函数
项目|内容
:---:|:-----:
函数名称|CreateAbi
功能描述|abi_t结构体内存分配并初始化
参数|无
返回值|abi_t*类型,指向需要生成的abi结构体
备注|若返回NULL,表示内存分配失败
示例:
```
abi_t *myabi = CreateAbi();
```
#### Abi结构体释放函数
项目|内容
:---:|:-----:
函数名称|AbiFree
功能描述|Abi结构体内存释放
参数|abi:abi_t*类型,指向要释放的abi_t类型结构体链表
返回值|无
备注|每一次CreateAbi一定要AbiFree掉
示例:
```
abi_t *myabi = CreateAbi();
AbiFree(myabi);
myabi = NULL;
```
#### 参数结构体释放函数
项目|内容
:---:|:-----:
函数名称|ArgFree
功能描述|arg_t结构体内存释放
参数|arg:arg_t*类型,指向要释放的arg_t类型结构体链表
返回值|无
备注|每一次CreateArg一定要ArgFree掉
示例:
```
arg_t* my_arg = CreateArg();
ArgFree(my_arg);
my_arg = NULL;
```
#### 合约增加bytes类型参数函数
项目|内容
:---:|:-----:
函数名称|AddBytesArg
功能描述|添加bytes类型的参数到参数链表末尾,适用于bytes,string,bytes[],bytesX
参数|args:arg_t\*类型,指向一个arg_t\*类型链表
val:ql_byte_t\*类型,指向要添加到arg_t*链表里的bytes数组
len:ql_size_t类型,是参数val的长度
返回值|参见contract.h文件内的错误宏定义
备注|返回的arg_t*链表里存的是已经转为十六进制字符串格式的字符串。使用者可以不关心细节。
示例:
```
arg_t* my_arg = CreateArg();
ql_err_t err = AddBytesArg(my_arg, "addHere", strlen("addHere"));
if(err < 0 )printf("err\n");
ql_byte_t s[] = "secondarg";
ql_err_t err = AddBytesArg(my_arg, s, strlen(s));
```
#### 合约增加无符号整数数组类型参数函数
项目|内容
:---:|:-----:
函数名称|AddUnsignedArrayArg
功能描述|添加无符号整型数组到参数链表末尾。并且在添加时按照长度64位十六进制格式字符串格式编码,即与abi调用参数编码一致
参数|args:arg_t\*类型,指向一个arg_t*类型链表
val:ql_void_t\*类型,指向一个无符号整数数组的首地址。每个数组元素的大小由参数size表示
arraylen:ql_size_t类型,是参数val的数组长度
size:ql_size_t类型,是无符号整数数组每个元素所占字节数,size最大是sizeof(uint64)
返回值|参见contract.h文件内的错误宏定义
备注|返回的arg_t*链表里存的是已经转为十六进制字符串格式的字符串。使用者可以不关心细节。
示例:
```
arg_t* my_args = CreateArg();
int arrayLen = 2;
ql_uint32_t un_array[2] = {1, 2};
ql_err_t err = AddUnsignedArrayArg(my_args, un_array, arrayLen, sizeof(un_array[0]) );
if(err < 0 )printf("err\n");
```
#### 合约增加带符号整数数组类型参数函数
项目|内容
:---:|:-----:
函数名称|AddSignedArrayArg
功能描述|添加带符号整型数组到参数链表末尾。并且在添加时按照长度64位十六进制格式字符串格式编码,即与abi调用参数编码一致
参数|args:arg_t\*类型,指向一个arg_t\*类型链表
val:ql_void_t*类型,指向一个带符号整数数组的首地址。每个数组元素的大小由参数size表示
arraylen:ql_size_t类型,是参数val的数组长度
size:ql_size_t类型,是带符号整数数组每个元素所占字节数,size最大是sizeof(int64)
返回值|参见contract.h文件内的错误宏定义
备注|返回的arg_t*链表里存的是已经转为十六进制字符串格式的字符串。使用者可以不关心细节。
示例:
```
arg_t* my_args = CreateArg();
int arrayLen = 2;
ql_uint32_t array[2] = {1, 2};
ql_err_t err = AddSignedArrayArg(my_args, array, arrayLen, sizeof(array[0]) );
if(err < 0 )printf("err\n");
```
#### 合约增加带符号整数类型参数函数
项目|内容
:---:|:-----:
函数名称|AddIntArg
功能描述|添加带符号整数到参数链表末尾。并且在添加时按照长度64位十六进制格式字符串格式编码,即与abi调用参数编码一致
参数|args:arg_t\*类型,指向一个arg_t*类型链表
val:ql_int64_t类型,一个带符号整数
返回值|参见contract.h文件内的错误宏定义
备注|返回的arg_t*链表里存的是已经转为十六进制字符串格式的字符串。使用者可以不关心细节。
示例:
```
arg_t* my_args = CreateArg();
err = AddIntArg(my_args, -100);
if(err < 0)printf("add int arg err\n");
```
#### 合约增加无符号整数类型参数函数
项目|内容
:---:|:-----:
函数名称|AddUintArg
功能描述|添加无符号整数到参数链表末尾。并且在添加时按照长度64位十六进制格式字符串格式编码,即与abi调用参数编码一致
参数|args:arg_t\*类型,指向一个arg_t*类型链表
val:ql_int64_t类型,一个无符号整数
返回值|参见contract.h文件内的错误宏定义
备注|返回的arg_t*链表里存的是已经转为十六进制字符串格式的字符串。使用者可以不关心细节。
示例:
```
arg_t* my_args = CreateArg();
err = AddUintArg(my_args, 100);
if(err < 0)printf("add uint arg err\n");
```
#### 结构体abi的生成函数
项目|内容
:---:|:-----:
函数名称|AbiInitFromString
功能描述|通过cJSON字符串格式的str生成对应的abi结构体
参数|abiroot:abi_t\*类型,指向要生成的abi_t类型链表
str:ql_byte_t*类型,指向以一定格式存储abi信息的字符串
返回值|参见contract.h文件内的错误宏定义
备注|abiroot要事先分配好内存,否则返回错误
示例:
```
char str[] = "[{"
"\"name\":\"simpleFunction\","
"\"constant\":true,"
"\"payable\":true,"
"\"type\":\"function\","
"\"inputs\":[{\"name\":\"_in\",\"type\":\"bytes32\"}],"
"\"outputs\":[{\"name\":\"_out\",\"type\":\"bytes32\"}]}]"
abi_t *myabi = CreateAbi();
err = AbiInitFromString(myabi, str);
if(err < 0)printf("abi init err\n");
```
#### 根据abi结构体查找method的函数
项目|内容
:---:|:-----:
函数名称|GetFunc
功能描述|在abi结构体中找到methodName
参数|abiroot:abi_t\*类型,指向abi_t类型链表
methodName:ql_byte_t\*类型,要查找的methodName,中间不能有多余空格
res:abi_t*类型,返回查找到的method对应的abi结构体
返回值|参见contract.h文件内的错误宏定义
备注|如果methodName没有重载,可以不带参数和括号。特别注意res里面所有的指针指向了abiroot的位置,而不是独立一份空间出来,所以不要对里面的内容进行空间释放操作。
示例:
```
char str[] = "[{"
"\"name\":\"simpleFunction\","
"\"constant\":true,"
"\"payable\":true,"
"\"type\":\"function\","
"\"inputs\":[{\"name\":\"_in\",\"type\":\"bytes32\"}],"
"\"outputs\":[{\"name\":\"_out\",\"type\":\"bytes32\"}]}]"
abi_t *myabi = CreateAbi();
err = AbiInitFromString(myabi, str);
if(err < 0)printf("abi init err\n");
abi_t res;//这样写不用释放内存
err = GetFunc(myabi, "simpleFunction(bytes32)",&res);
if(err < 0)printf("find method err\n");
```
#### 根据abi结构体查找method的函数的inputs
项目|内容
:---:|:-----:
函数名称|GetFuncInput
功能描述|在abi结构体中找到methodName的参数列表
参数|abiroot:abi_t\*类型,指向abi_t类型链表
methodName:ql_byte_t\*类型,要查找的methodName,中间不能有多余空格
res:param_t\*类型,返回查找到的method对应的param_t*类型的链表
返回值|参见contract.h文件内的错误宏定义
备注|如果methodName没有重载,可以不带参数和括号。res里面的指针只是指向abiroot里的内容,不要对res里面的内容进行内存释放操作。
示例:
```
param_t res;//不用释放内存
err = GetFuncInput(myabi, "simpleFunction(bytes32)",&res);
if(err < 0)printf("find method inputs err\n");
```
#### 根据abi结构体查找method的函数的outputs
项目|内容
:---:|:-----:
函数名称|GetFuncOutput
功能描述|在abi结构体中找到methodName的返回值列表
参数|abiroot:abi_t\*类型,指向abi_t类型链表
methodName:ql_byte_t\*类型,要查找的methodName,中间不能有多余空格
res:param_t\*类型,返回查找到的method对应的param_t*类型的链表
返回值|参见contract.h文件内的错误宏定义
备注|如果methodName没有重载,可以不带参数和括号。res里面的指针只是指向abiroot里的内容,不要对res里面的内容进行内存释放操作。
示例:
```
param_t res;//不用释放内存
err = GetFuncOutput(myabi, "simpleFunction(bytes32)",&res);
if(err < 0)printf("find method inputs err\n");
```
#### 初始化合约结构体
项目|内容
:---:|:-----:
函数名称|ContractInit
功能描述|对合约结构体进行初始化
参数|con:contract_t\*类型,指向要初始化的contract_t类型结构体
from:ql_byte_t\*类型,指向要初始化合约的用户address,可以为NULL(不建议)
ex:ql_byte_t\*类型,存证信息,可以为NULL
exid:ql_byte_t*类型,存证id,可以为NULL
返回值|参见contract.h文件内的错误宏定义
备注|要在所有合约相关的操作之前使用。与CleanContract搭配使用。
示例:
```
contract_t con;
err = ContractInit(&con, myaccount.addr, NULL, NULL);
if(err < 0)printf("contract init err\n");
```
#### 释放合约结构体内的内容
项目|内容
:---:|:-----:
函数名称|CleanContract
功能描述|对合约结构体内部分配的内存进行释放
参数|con:contract_t\*类型,指向要清理的contract_t类型结构体
返回值|无
备注|要在每一次完整的合约相关的操作之后使用。与ContractInit搭配使用。注意只是释放合约里面各指针分配的内存,不会释放结构体本身
示例:
```
contract_t con;
err = ContractInit(&con, myaccount.addr, NULL, NULL);
if(err < 0)printf("contract init err\n");
// 一系列操作
CleanContract(&con);
```
#### 释放合约结构体内的内容
项目|内容
:---:|:-----:
函数名称|SetVMtype
功能描述|修改合约运行的VM类型
参数|con:contract_t\*类型,指向contract_t类型结构体
type:VM_TYPE枚举类型
返回值|参见contract.h文件内的错误宏定义
备注|不设置时默认是EVM,目前只支持EVM类型
示例:
```
contract_t con;
err = ContractInit(&con, myaccount.addr, NULL, NULL);
if(err < 0)printf("contract init err\n")
err = SetVMtype(&con, EVM);
if(err < 0)printf("set contract vmtype err\n");
```
#### 设置合约名
项目|内容
:---:|:-----:
函数名称|SetContractName
功能描述|修改合约名
参数|con:contract_t\*类型,指向要设置的contract_t类型结构体
contractName:ql_byte_t*类型,指向一串字符串,为要设置的合约名称
返回值|参见contract.h文件内的错误宏定义
备注|要在ContractInit使用后使用,不设置时为空字符串
示例:
```
contract_t con;
err = ContractInit(&con, myaccount.addr, NULL, NULL);
if(err < 0)printf("contract init err\n")
err = SetContractName(&con, "simpleContract");
if(err < 0)printf("set contract name err\n");
```
#### 不带参数的合约部署
项目|内容
:---:|:-----:
函数名称|DeployEvmWithoutParam
功能描述|部署合约,并且在部署时没有参数
参数|con:contract_t\*类型,指向要封装的contract_t类型结构体
payload:ql_byte_t*类型,指向要部署的合约内容
返回值|参见contract.h文件内的错误宏定义
备注|要在ContractInit使用后使用
示例:
```
contract_t con;
//use contractInit here
ql_byte_t payload[] = "here is your payload";
ql_err_t err = DeployEvmWithoutParam(&con, payload);
```
#### 带参数的合约部署
项目|内容
:---:|:-----:
函数名称|DeployEvmWithParam
功能描述|部署合约,并且在部署时有参数
参数|con:contract_t\*类型,指向要封装的contract_t类型结构体
abiroot:abi_t\*类型,指向要部署的合约相关abi内容,便于对args编码
partOfpayload:ql_byte_t\*类型,指向要部署的合约内容
args:arg_t\*类型,指向部署时带的参数链表(其实可以为NULL,相当于无参部署)
返回值|参见contract.h文件内的错误宏定义
备注|要在ContractInit使用后使用
示例:
```
contract_t con;
//use contractInit here
abi_t *abiroot = CreateAbi();
AbiInitFromString(abiroot, "here is your abi string");
arg_t *args = CreateArg();
//use add**Arg()
ql_byte_t partOfpayload[] = "here is your partof payload";
ql_err_t err = DeployEvmWithParam(&con, abiroot, partOfpayload, args);
if(err < 0)printf("deploy evm err\n");
```
#### 合约调用的封装函数
项目|内容
:---:|:-----:
函数名称|InvokeEVM
功能描述|调用合约
参数|con:contract_t\*类型,指向要封装的contract_t类型结构体
conAddr:ql_byte_t\*类型,指向要调用的合约的地址
methodName:ql_byte_t\*类型,指向的内容是要调用的函数名
abi:abi_t\*类型,指向abi_t结构体
args:arg_t*类型,指向部署时带的参数链表,没有时可以为NULL
返回值|参见contract.h文件内的错误宏定义
备注|如果合约调用函数没有参数args可以为NULL,其他必须不为NULL
示例:
```
contract_t con;
abi_t abi = CreateAbi();
arg_t args = CreateArg()
//contractInit(&con), abiInitFromString(abi),add**Args(args)
ql_err_t err = InvokeEVM(&con, con.to, "here is your methodName", args);
if(err < 0)printf("invok evm err\n");
```
#### 合约update的封装函数
项目|内容
:---:|:-----:
函数名称|ConUpdate
功能描述|合约升级
参数|con:contract_t\*类型,指向要封装的contract_t类型结构体
conAddress:ql_byte_t\*类型,指向要进行update的合约旧地址
payload:ql_byte_t\*类型,指向的内容是新的合约内容
返回值|参见contract.h文件内的错误宏定义
备注|暂未有支持合约升级的发送模块,需要在结构体基础上自己实现
示例:
```
ConUpdate(&con, con.to, payload);
```
#### 合约freeze的封装函数
项目|内容
:---:|:-----:
函数名称|ConFreeze
功能描述|合约冻结
参数|con:contract_t\*类型,指向要封装的contract_t类型结构体
conAddress:ql_byte_t\*类型,指向要进行freeze的合约地址
返回值|参见contract.h文件内的错误宏定义
备注|暂未有支持合约冻结的发送模块,需要在结构体基础上自己实现
示例:
```
ConFreeze(&con, con.to);
```
#### 合约unfreeze的封装函数
项目|内容
:---:|:-----:
函数名称|ConUnfreeze
功能描述|合约解冻
参数|con:contract_t\*类型,指向要封装的contract_t类型结构体
conAddress:ql_byte_t\*类型,指向要进行unfreeze的合约地址
返回值|参见contract.h文件内的错误宏定义
备注|暂未有支持合约解冻的发送模块,需要在结构体基础上自己实现
示例:
```
ConUnfreeze(&con, con.to);
```
#### 合约destroy的封装函数
项目|内容
:---:|:-----:
函数名称|ConDestroy
功能描述|合约销毁
参数|con:contract_t\*类型,指向要封装的contract_t类型结构体
conAddress:ql_byte_t\*类型,指向要进行destroy的合约地址
返回值|参见contract.h文件内的错误宏定义
备注|暂未有支持合约销毁的发送模块,需要在结构体基础上自己实现
示例:
```
ConDestroy(&con, con.to);
```
#### 设置合约signature
项目|内容
:---:|:-----:
函数名称|SetSignature
功能描述|对合约结构体里的内容进行签名
参数|con:contract_t\*类型,指向要设置的contract_t类型结构体
acc:account_t类型,里面有用户信息,用来签名
返回值|参见contract.h文件内的错误宏定义
备注|要在所有合约相关的设置完成后使用。即在调用hpcAdapter或ethAdapter前使用。
示例:
```
ql_err_t err = InvokeEVM(&con, con.to, "here is your methodName", args);
if(err < 0)printf("invok evm err\n");
err = SetSignature(&con, my_account);
```
#### 初始化合约交易回执结构体的函数
项目|内容
:---:|:-----:
函数名称|ReceiptInit
功能描述|把合约回执结构体初始化
参数|receipt:ReceiptResponse_t*类型,指向需要初始化的合约回执结构体
返回值|无
备注|与CleanReceipt搭配使用
示例:
```
ReceiptResponse_t receipt;
ReceiptInit(&receipt);
```
#### 释放合约交易回执结构体内容的函数
项目|内容
:---:|:-----:
函数名称|CleanReceipt
功能描述|把合约回执结构体内为指针的变量的内存释放掉
参数|receipt:ReceiptResponse_t*类型,指向需要释放的合约回执结构体
返回值|无
备注|与ReceiptInit搭配使用,注意并不释放ReceiptResponse_t本身
示例:
```
ReceiptResponse_t receipt;
ReceiptInit(&receipt);
//read message from receipt
CleanReceipt(&receipt);
```
#### 合约交易回执结构体生成函数
项目|内容
:---:|:-----:
函数名称|ReceiptFromJson
功能描述|通过cJSON结构体生成交易回执结构体
参数|receipt:ReceiptResponse_t\*类型,要生成的结构体
result:cJSON*类型,有合约交易回执相关信息
返回值|参见contract.h文件内的错误宏定义
备注|
示例:
```
ReceiptResponse_t receipt;
cJSON *result;
//use receipt
//get result
ReceiptFromJson(&receipt, result);
cJSON_Delete(result);
```
#### 合约交易回执的ret字符串译码函数
项目|内容
:---:|:-----:
函数名称|DecodeRet
功能描述|对于返回的合约回执中,如果有ret相关字符串,则需要用此函数进行译码
参数|abiroot:abt_t\*类型,指向合约相关的abi结构体
methodName:ql_byte_t\*类型,合约里调用的函数名
ret:ql_byte_t\*类型,指向要译码的ret
res:decode_t*类型,指向返回的译码结果
返回值|参见contract.h文件内的错误宏定义
备注|res需要事先分配内存,最后返回的是一个链表
示例:
```
ReceiptResponse_t receipt;
cJSON *result;
//use receipt
//get result
ReceiptFromJson(&receipt, result);
cJSON_Delete(result);
decode_t* res = CreateDecodeT();
ql_err_t err = DecodeRet(abiroot, "your methodName", receipt.ret, res);
if(err < 0)printf("decode err\n");
```
#### ret字符串译码结果结构体内存分配函数
项目|内容
:---:|:-----:
函数名称|CreateDecodeT
功能描述|decode_t结构体内存分配并初始化
参数|无
返回值|decode_t*类型,指向需要生成的decode_t结构体
备注|若返回NULL,表示内存分配失败
示例:
```
decode_t *decodeRes = CreateDecodeT();
```
#### ret字符串译码结果结构体内存释放函数
项目|内容
:---:|:-----:
函数名称|DecodeTFree
功能描述|decode_t结构体内存释放
参数|in:decode_t*类型,指向要释放的decode_t类型结构体链表
返回值|无
备注|每一次CreateDecodeT一定要DecodeTFree掉
示例:
```
decode_t *decodeRes = CreateDecodeT();
DecodeTFree(decodeRes );
decodeRes = NULL;
```
#### 交易回执基本结构体生成函数
项目|内容
:---:|:-----:
函数名称|BasicRspFromString
功能描述|对接收到的字符串,解析生成交易回执的基本结构体,并生成result的cJSON结构体
参数|basicrsp:basic_response_t\*类型,指向交易回执的基本信息结构体
resullt:cJSON\*\*类型,指向要返回的result相关信息的cJSON结构体指针的地址
str:ql_byte_t\*类型,指向交易回执返回的字符串
返回值|参见contract.h文件内的错误宏定义
备注|result不需要事先分配内存,basicrsp需要
示例:
```
//get str
basic_response_t basicrsp;
BasicRspInit(&basicrsp);
ReceiptResponse_t receipt;
cJSON *result;
ql_err_t err = BasicRspFromString(&basicrsp, result, str);
if(err < 0)printf("err\n");
ReceiptFromJson(&receipt, result);
```
#### 打包为要发送到hyperchain的json格式字符串
项目|内容
:---:|:-----:
函数名称|hpcAdapter
功能描述|把内容封装成要发送到hyperchain的json格式的字符串
参数|method:ql_byte_t\*类型,向hyperchain发送的要调用的方法,参考jsonRPC
from:char\*类型,发送方地址。
to:char\*类型,合约地址或转账交易对象地址
value:ql_int32_t类型,如果为转账交易,为要转账的值
payload:char\*类型,为合约相关操作内容
timestamp:ql_uint64_t类型,时间戳(ns)
nonce:ql_int32_t类型
extra:char\*类型,存证信息
extraId:char\*类型,存证id信息
signature:char*交易签名内容
返回值|char*类型的字符串
备注|更多详细内容可以参考jsonRPC文档
示例:
```
contract_t con;
//ContractInit(&con...);
//set timestamp
SetSinature(&con, myaccount);
char *senStr = hpcAdapter("tx_sendTransaction", con.from, con.to, con.value, con.paylod, con.timestamp, con.nonce, con.extra, con.extraId, con.signature);
//send the sendStr
```
#### 打包为要发送到以太坊的json格式字符串
项目|内容
:---:|:-----:
函数名称|ethAdapter
功能描述|把内容封装成要发送到以太坊的json格式的字符串
参数|nonce:ql_int32_t类型,防止重放攻击,每次nonce都需要依次连续递增
gasPrice:ql_int64_t类型,单个gas的价格,单位为Wei
gas:ql_int64_t,愿意支付的最多的gas费用。
to:char\*类型,合约地址或转账交易对象地址
value:ql_int64_t类型,如果为转账交易,为要转账的值
payload:char*类型,为合约相关操作内容
priv:char\*类型,用户私钥,用于签名
返回值|char*类型的字符串
备注|
示例:
```
contract_t con;
//ContractInit(&con...);
char *senStr = ethAdapter(1, 100, 10000, con.to, con.value, con.payload, myaccount.prikey);
//send the sendStr
```
#### 交易收发函数
项目|内容
:---:|:-----:
函数名称|sendToBlockchain
功能描述|发送交易内容,并接收返回信息
参数|url:ql_byte_t\*类型,指向要发送的url,格式为 ip:port
post_Body:ql_strings_t类型,存着要发送的信息
recvbuf:ql_strings_t\*\*类型,存储交易回执对应的字符串内容
返回值|
备注|recvbuf不需要事先分配内存
示例:
```
contract_t con;
//ContractInit(&con...);
char *senStr = ethAdapter(1, 100, 10000, con.to, con.value, con.payload, myaccount.prikey);
ql_string_t Post_body;
Post_body.val = sendStr;
Post_body.len = strlen(sendStr);
ql_string_t *recv;
sendToBlockchain("your url"), &Post_body, &recv);
if(recv != NULL)printf("recv:%s\n", recv.val);
FreeStringsT(recv);//释放内存
```
#### 获取交易回执
项目|内容
:---:|:-----:
函数名称|getReceipt
功能描述|获取交易回执
参数|url:ql_byte_t\*类型,指向要发送的url,格式为 ip:port
txhash:char*类型,要查询的交易回执的txHash,在ReceiptResponse_t结构体中
返回值|char*类型的字符串
备注|查询刚发送的交易可能失败,完成交易需要一定的时间,可以使用pollingReceipt来轮询获得
示例:
```
//str = recv.val;
basic_response_t basicrsp;
BasicRspInit(&basicrsp);
ReceiptResponse_t receipt;
cJSON *result;
ql_err_t err = BasicRspFromString(&basicrsp, result, str);
if(err < 0)printf("err\n");
ReceiptFromJson(&receipt, result);
char *myreceipt = getReceipt("your url here", receipt.txHash);
```
#### 轮询获取交易回执
项目|内容
:---:|:-----:
函数名称|pollingReceipt
功能描述|通过轮询获取交易回执
参数|url:ql_byte_t\*类型,指向要发送的url,格式为 ip:port
txhash:char*类型,要查询的交易回执的txHash,在ReceiptResponse_t结构体中
返回值|char*类型的字符串
备注|查询刚发送的交易可能失败,完成交易需要一定的时间,可以使用pollingReceipt来轮询获得
示例:
```
//str = recv.val;
basic_response_t basicrsp;
BasicRspInit(&basicrsp);
ReceiptResponse_t receipt;
cJSON *result;
ql_err_t err = BasicRspFromString(&basicrsp, result, str);
if(err < 0)printf(“err\n”);
ReceiptFromJson(&receipt, result);
char *myreceipt = pollingReceipt(“your url here”, receipt.txHash);
```
#### basic_response_t类型结构体初始化函数
项目|内容
:---:|:-----:
函数名称|BasicRspInit
功能描述|初始化basic_rsponse_t类型结构体
参数|basicrsp:basic_rsponse_t*类型,指向要初始化的结构体的地址
返回值|无
备注|
示例:
```
basic_response_t basicrsp;
BasicRspInit(&basicrsp);
```
#### basic_response_t类型结构体内容释放函数
项目|内容
:---:|:-----:
函数名称|CleanBasicrsp
功能描述|释放basic_rsponse_t类型结构体内部为指针类型变量的内容
参数|basicrsp:basic_rsponse_t*类型,指向要释放内容的结构体的地址
返回值|无
备注|要释放的是结构体内部各变量的内存,不释放结构体本身
示例:
```
basic_response_t basicrsp;
BasicRspInit(&basicrsp);
//your operation
CleanBasicrsp(&basicrsp);
```
#### 设置时间戳函数
项目|内容
:---:|:-----:
函数名称|setTimestamp
功能描述|获取当前时间戳(ns)
参数|dst:long long *类型,获取的时间戳所存储的地址
返回值|无
备注|该函数不一定有效,需要考虑不同操作系统。目前默认实现是Linux操作系统。(对于OpenHarmony系统,需要定义宏OpenHarmony_SYS,并事先调用void setCurrentTime(void))。用户也可以自己实现来设置timestamp,只要在setSignature操作之前设置即可。
示例:
```
ifdef OpenHarmony_SYS
setCurrentTime();
#endif
contract_t con;
//contractInit here
setTimestamp(&con.timestamp);
```
#### 分配内存并复制内容
项目|内容
:---:|:-----:
函数名称|StrMalloc
功能描述|分配一定空间内存并复制内容
参数|str:要复制的内容,可以是字符串
slen:要复制的内容的长度。同时意味着分配了slen+1字节的内存。
返回值|ql_byte_t*类型,指向分配的空间
备注|若返回NULL,表示内存分配失败;若str为NULL,则只分配内存并初始化,不复制内容;若slen大于复制内容的长度,也会使用memcpy复制,因为复制的内容可以不限于字符串,所以不进行str长度检验。
示例:
```
ql_byte_t *mystr = StrMalloc("aabbcc", strlen("aabbcc"));
```
#### ql_strings_t结构体类型内存分配函数
项目|内容
:---:|:-----:
函数名称|CreateStringsT
功能描述|ql_strings_t结构体类型的内存分配并初始化
参数|无
返回值|ql_strings_t*类型,指向需要生成的ql_strings_t结构体
备注|若返回NULL,表示内存分配失败
示例:
```
ql_strings_t *str = CreateStringsT();
```
#### ql_strings_t结构体类型内存释放函数
项目|内容
:---:|:-----:
函数名称|FreeStringsT
功能描述|ql_strings_t结构体类型的内存释放
参数|ql_strings_t*类型,指向需要释放的ql_strings_t结构体指针
返回值|无
备注|每一次CreateStringsT一定要FreeStringsT掉
示例:
```
ql_strings_t *str = CreateStringsT();
FreeStringsT(str);
str= NULL;
```