# 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; ```