基于WASM的合约开发

如何开发wasm合约

wasm合约目前有两种不同的编写方式。
非ABI方式 合约接口的入参与返回需开发者自己实现打包与解包,且不支持结构体作为入参,无ABI文件。
ABI方式 实现入参与返回值的自动打包与解包,支持结构体入参,支持多个返回值,生成相关的ABI文件。

Hello Thunderchain

非ABI方式

#ifdef __cplusplus
extern "C" {
#endif
const char* thunderchain_main(const char* action, const char *args) {
    if (strcmp(action, "HelloThunder") == 0)
        return "Hello Thunderchain";
}
#ifdef __cplusplus
}
#endif

其中thunderchain_main为wasm合约入口函数,函数原型如下:

const char* thunderchain_main(const char* action, const char *args);

C++代码中,thunderchain_main要用到extern "C"。其中
action为具体合约方法,args为合约参数。

非ABI方式,生成bytecode体积较小,但代码相对繁琐。

ABI方式 (Beta)

#include "tcmethod.h"
#include "tcapi.h"
class Hello : public TCBaseContract{
public:
    const char* HelloThunder(){
        TC_Payable(false);
        return "Hello Thunderchain";
    }
};
TC_ABI(Hello, (HelloThunder))

用于接收参数的Hello类需继承于TC_BaseContract,方法类的公有的成员函数可设置为合约方法。 TC_ABI宏用来声明合约类与合约方法,只能调用TC_ABI声明过的方法。

TC_ABI(<入口合约类名>, (<方法名>)(<方法名>)(<方法名>)...)。

TC_ABI宏只能使用一次。

ABI方式会生成abi文件,标明输入输出类型与方法,同时代码也相对简洁。 HelloThunderchain合约生成的abi如下,各字段与solidity ABI兼容。

{
    "name":"HelloThunder",
    "payable":false,
    "inputs":[],
    "outputs":[
        {
            "type":"const char *"
        }
    ]
}

ABI方式仅支持C++语言

合约部署

合约部署流程与solidity合约一致,具体见solidity部署合约。 wasm合约当前不支持构造函数入参,部署时需要将params设置为空。

合约初始化说明

创建合约时,wasm虚拟机会调用action = "Init"方法。 如需初始化函数,例子如下

#include "tcapi.h"//wasm api 头文件
#ifdef __cplusplus
extern "C" {
#endif
const char* thunderchain_main(const char* action, const char *arg) {
    if(strcmp(action, "Init")==0){ //action = "Init",初始化函数
        return "Init Success";
    } else if (strcmp(action, "Hello")==0){ //action = "Hello"
        return "Hello Thunderchain";
    }
}
#ifdef __cplusplus
}
#endif

部署合约后,会执行如下代码。

return "Init Success";

调用合约时,禁止action = "init" or "Init"

合约编译

目前仅支持使用Catalyst迅雷链合约IDE线上编译。 参考Catalyst使用指南

合约调用

调用合约时,交易data的数据格式为<action>|<args>,action与args以"|"分割。 具体参考合约例子

合约例子

以具体合约为例,该合约功能为写入/读取短码记录的URL。

合约数据存储采用Key-Value方式,相关api为TC_StorageSet/TC_StorageGet

#include"tcapi.h"
char* init(){return EMPTY_CSTRING;}
#ifdef __cplusplus
extern "C" {
#endif
char* thunderchain_main(char* action, char* args){
    void* root = TC_JsonParse(args);

    //初始化函数,可选
    ACTION_FUNC("Init", init);

    ACTION_CODE("setrecord", {
        //解析入参
        char* recordInfo = TC_JsonGetString(root, "recordInfo");
        char* RCode = TC_JsonGetString(root, "RCode");

        //数据存储
        TC_StorageSet(RCode, recordInfo);

        return EMPTY_CSTRING;
    });

    ACTION_CODE("getrecord", {
        //解析入参
        char* RCode = TC_JsonGetString(root, "RCode");

        //数据读取,并返回
        return TC_StorageGet(RCode);
    });
}
#ifdef __cplusplus
}
#endif

ACTION_FUNC与ACTION_CODE宏定义如下

#define ACTION_FUNC(_a, _fn) do{\
    if (strcmp(action, _a) == 0) {return _fn();}\
}while(0)

#define ACTION_CODE(_a, _code) do{\
    if (strcmp(action, _a) == 0) {_code}\
}while(0)

调用setrecord存入数据

调用setrecord函数,设置 fbac231bc2a 记录的URL为 blockchain.xunlei.com 其中action = setrecord,args = {"recodeInfo":"blockchain.xunlei.com","RCode":"fbac231bc2a"}

最终生成的data数据为 "setrecord|{"recodeInfo":"blockchain.xunlei.com","RCode":"fbac231bc2a"}" 具体交易params json如下,from/gas/gasPrice/value以实际交易为准

{
  "from": "0x54fb1c7d0f011dd63b08f85ed7b518ab82028100",
  "gas": "0x76c00",
  "gasPrice": "0x9184e72a",
  "data": "0x7365747265636F72647C7B227265636F6465496E666F223A226F70656E2E6F6E657468696E67636C6F75642E636F6D222C2252436F6465223A226662616332333162633261227D"
}

实际构造交易时,需将action+args构成的字符串转为十六进制(ascii转hex)
以golang为例
str:="f|{}" h := []byte(str) hexStr := fmt.Sprintf("0x%x", h) //hexStr = "0x667c7b7d" fmt.Println(hexStr)

调用getrecord获取数据

调用getrecord读取数据,读取 fbac231bc2a 记录的URL,其中action为getrecord,args为{"RCode":"fbac231bc2a"} 最终生成的data段数据为 "getrecord|{"RCode":"fbac231bc2a"}" 具体交易params json如下

{
  "from": "0x54fb1c7d0f011dd63b08f85ed7b518ab82028100",
  "gas": "0x76c00",
  "gasPrice": "0x9184e72a",
  "data": "0x6765747265636F72647C7B2252436F6465223A226662616332333162633261227D"
}

catalystIDE中调用合约例子

catelyst中调用wasm合约时,填入Action以及Key-Value,catelyst会自动生成入参action、args。

调用setrecord

  • Action填入 setrecord
  • 点击添加Key
  • Key填入recodeInfo,Value填入blockchain.xunlei.com
  • 点击添加Key
  • Key填入RCode,Value填入fbac231bc2a
  • 点击执行

调用getrecord

  • Action填入 getrecord
  • 点击添加Key
  • Key填入RCode,Value填入fbac231bc2a
  • 点击执行或查询

webAssembly运行与语言限制

wasm运行参数

MinAllocMemSize         = 32//malloc内存最小粒度为32B
FixedStackIdx           = 16*1024//栈大小为16k
MaxDataMemSize          = 16*1024//Data段限制为16k
DefaultMinHeapMemSize   = 64*1024
DefaultMaxHeapMemSize   = 256*1024//默认堆大小最小为64k,最大为256k

C/C++ 不支持特性:

浮点数(float/double)
operator new/delete
typeid/dynamic_cast(-fno-rtti)
try-catch(-fno-exceptions)

Libc 不支持头文件:

signal.h
math.h
locale.h
errno.h
uchar.h
time.h(Incomplete support)

Libc++ 不支持头文件:

rand
atomics
thread
random

WASM 合约 API

区块链相关接口

为方便wasm合约可以方便的访问区块链相关信息,wasm虚拟机对外提供了Storage、Message、Event、Contract相关的接口。

C语言中address定义 typedef char* address;

Storage相关接口

在wasm合约中,需要合约显式的调用Storage接口,实现对数据的持久化存储与读取。

C函数文档

TC_StorageSet

void TC_StorageSet(
    const char *key, 
    const char *val
)

以字符串key为键,持久化存储数据val

参数

  • key - 持久化存储数据val对应的键
  • val - 需要持久化存储的数据

返回值

TC_StorageGet

char* TC_StorageGet(
    const char *key, 
    const char *val
) 

以字符串key为键,查询对应的数据 参数

  • key - 已持久化存储数据对应的键 返回值 已持久化数据

TC_StorageDel

void TC_StorageDel(
    const char *key
) 

删除以字符串key为键的数据 参数

  • key - 已持久化存储数据对应的键 返回值

转账相关接口

C函数文档

TC_Transfer

void TC_Transfer(
    const address to, 
    const BigInt amount
)

当前合约账户给address地址转账amount数额 参数

  • address - 目标账户地址,16进制字符串表示
  • amount - 转账数额

返回值

链Message相关接口

C函数文档

TC_GetMsgData

char* TC_GetMsgData()

获取合约调用的输入数据 参数返回值 合约输入数据,字符串表示

TC_GetMsgGas

uint64 TC_GetMsgGas()

获取合约调用的gas上限 参数返回值 合约调用的gas上限

TC_GetMsgSender

address TC_GetMsgSender()

获取合约调用者 参数返回值 合约调用者地址,16进制字符串表示

TC_GetMsgSign

char* TC_GetMsgSign()

获取合约调用参数中的方法名字段 参数返回值 合约调用参数中的方法名字段

TC_GetMsgValue

char* TC_GetMsgValue()

获取合约调用者转账给合约的数额 参数返回值 16进制字符串表示

TC_GetNumber

uint64 TC_GetNumber()

获取区块链当前区块高度 参数返回值 区块链当前区块高度

TC_GetGasLimit

uint64 TC_GetGasLimit()

获取当前区块的gas上限 参数返回值 当前区块的gas上限

TC_GetCoinbase

char* TC_GetCoinbase()

获取区块链的coinbase账户地址 参数返回值 区块链的coinbase账户地址,16进制字符串表示

TC_BlockHash

char* TC_BlockHash(
    uint64 blockNumber
)

获取指定高度的区块哈希 参数

  • blockNumber - 区块高度 返回值 区块哈希值,16进制字符串表示

TC_GetTxGasPrice

uint64 TC_GetTxGasPrice()

获取合约调用的gas价格 参数返回值 合约调用的gas价格

TC_GetTxOrigin

char* TC_GetTxOrigin()

获取执行的起始地址,即原始交易的sender 参数返回值 区块链的账户地址,16进制字符串表示

TC_GasLeft

uint64 TC_GasLeft()

获取合约当前剩余的gas 参数返回值 合约当前剩余的gas

TC_GetBalance

char* TC_GetBalance(
    const char *address
)

获取指定账户address的余额 参数返回值 address账户的当前余额

TC_GetSelfAddress

char* TC_GetSelfAddress()

获取合约自身地址 参数返回值 16进制字符串表示的合约地址

TC_GetMsgTokenValue

char* TC_GetMsgTokenValue()

获取合约调用者转账给合约的token数额 参数返回值 16进制字符串表示给合约的token数额

Event相关接口

迅雷链事件机制相关函数

C函数文档

TC_Notify

void  TC_Notify(
    const char *eventID, 
    const char *data
)

合约触发事件 参数

  • eventID - 事件标识;
  • data - 事件数据 返回值

TC_Log0

void  TC_Log0(
    const char *data
)

合约触发事件,无事件标识 参数

  • data - 事件数据 返回值

TC_Log1

void TC_Log1(
    const char* data, 
    const char* topic
)

合约触发事件,带一级事件主题标识 参数

  • data - 事件数据
  • topic - 事件标识 返回值

TC_Log2

void TC_Log2(
    const char* data, 
    const char* topic1,
    const char* topic2
)

合约触发事件,带两级主题标识 参数

  • data - 事件数据
  • topic1 - 一级事件标识
  • topic2 - 二级事件标识 返回值

TC_Log3

void TC_Log3(
    const char* data, 
    const char* topic1,
    const char* topic2,
    const char* topic3
)

合约触发事件,带三级主题标识 参数

  • data - 事件数据
  • topic1 - 一级事件标识
  • topic2 - 二级事件标识
  • topic3 - 三级事件标识 返回值

TC_Log4

void TC_Log4(
    const char* data, 
    const char* topic1,
    const char* topic2,
    const char* topic3,
    const char* topic4
)

合约触发事件,带四级主题标识 参数

  • data - 事件数据
  • topic1 - 一级事件标识
  • topic2 - 二级事件标识
  • topic3 - 三级事件标识
  • topic4 - 四级事件标识 返回值

Contract相关接口

C函数文档

TC_SelfDestruct

char* TC_SelfDestruct(
    const char *address
)

销毁合约,并将合约账户剩余的余额转给address账户 参数

  • address - 接收合约账户剩余余额的账户地址 返回值 暂未使用,预留接口

TC_CallContract

char* TC_CallContract(
    address contract, 
    const char* action, 
    const char* args
)

调用外部合约方法,语义与solidaty Call一致 参数

  • contract -外部合约地址
  • action - 外部合约方法名
  • args - 外部合约方法参数,json格式 返回值 与调用的外部合约方法返回值一致

    不支持转账操作

TC_DelegateCallContract

char*   TC_DelegateCallContract(
    address contract, 
    const char* action, 
    const char* args
)

调用外部合约方法,语义与solidaty DelegateCall一致 参数

  • contract -外部合约地址
  • action - 外部合约方法名
  • args - 外部合约方法参数,json格式 返回值 与调用的外部合约方法返回值一致

    不支持转账操作

辅助接口

C函数文档

TC_Assert

void TC_Assert(
    bool condition
)

断言判断,与C语言的assert()接口功能类似,如果输入的condition为false,则触发合约终止并回滚状态 参数

  • condition - 布尔类型的条件变量 返回值

TC_Require

void TC_Require(
    bool condition
)

与TC_Assert()接口一样 参数

  • condition - 布尔类型的条件变量 返回值

TC_RequireWithMsg

void TC_RequireWithMsg(
    bool condition,
    const char *msg
)

与TC_Require()接口功能一样,若condition为false, msg参数将会打印到日志中,方便查看调试 参数

  • condition - 布尔类型的条件变量
  • msg - 调试输出日志信息 返回值

TC_IsHexAddress

bool TC_IsHexAddress(
    const char *address
)

判断输入的字符串是否为地址的16进制字符串表示 参数

  • address - 布尔类型的条件变量
  • msg - 调试输出日志信息 返回值 如果输入的字符串为地址的16进制字符串表示,则返回true,否则返回false

TC_Payable

void TC_Payable(
    bool condition
)

设置当前接口是否可以转账,默认为true,可以转账;若condition为false,且合约调用者传递的msg.Value > 0, 则会抛出异常终止合约执行,并回滚状态 参数

  • condition - 布尔类型的条件变量 返回值

    注意:如果接口A TC_Payable=true 接口B Payable=false, 当msg.value > 0, 接口A调用接口B时,B接口会报错哦 如上情况下,建议对B接口进行封装,对外调用提供不可转账的,对内调用提供可转账的。

TC_Prints

void TC_Prints(
    const char *s
)

打印信息s到日志(非交易事件log)中,方便调试 参数

  • s - 日志信息,字符串表示 返回值

TC_Now

uint64 TC_Now()

返回当前区块的时间戳,以unix时间表示 参数返回值 unix时间戳

TC_Now

int TC_CheckSign(
    const char* pubkey,
    const char* data, 
    const char* sig
)

检查是否为给定公钥pubkey对信息data创建的签名signature,签名算法为secp256k1 参数

  • pubkey - 公钥字符串
  • data - 信息数据
  • signature - 签名 返回值 如果签名匹配,则返回1,否则返回0

token相关接口

迅雷链提供的token发行、余额、转账等函数

C函数文档

TC_Issue

void TC_Issue(
    const BigInt amount
)

发行token 参数

  • amount - 发行token总量 返回值

TC_TokenAddress

address TC_TokenAddress()

查询msg中token类型 参数返回值 token类型

Json编解码接口

为方便编解码json对象,暂时由wasm虚拟机提供json相关的接口。

C函数文档

TC_JsonParse

void* TC_JsonParse(
    const char *s
)

解析输入字符串为json对象,并返回json对象的句柄 参数

  • s - 字符串s 返回值 json对象的句柄,如果失败则返回null

TC_JsonNewObject

void* TC_JsonNewObject()

创建json对象,返回对应的句柄 参数返回值 新创建json对象的句柄

TC_JsonGetInt

int TC_JsonGetInt(
    void *root, 
    const char *key
)

在root指向的json对象中,获取指定key字段的整数值 参数

  • root - TC_JsonParse()接口返回的对象句柄
  • key - 字段的标识符 返回值 字段key对应的整数值

TC_JsonGetInt64

int64 TC_JsonGetInt64(
    void *root, 
    const char *key
)

在root指向的json对象中,获取指定key字段的整数值 参数

  • root - TC_JsonParse()接口返回的对象句柄
  • key - 字段的标识符 返回值 字段key对应的整数值

TC_JsonGetString

char* TC_JsonGetString(
    void *root, 
    const char *key
)

在root指向的json对象中,获取指定key字段的字符串数值 参数

  • root - TC_JsonParse()接口返回的对象句柄
  • key - 字段的标识符 返回值 字段key对应的字符串数值

TC_JsonGetAddress

address TC_JsonGetAddress(
    void *root, 
    const char *key
)

在root指向的json对象中,获取指定key字段的地址数值 参数

  • root - TC_JsonParse()接口返回的对象句柄
  • key - 字段的标识符 返回值 字段key对应的地址数值

TC_JsonGetBigInt

BigInt TC_JsonGetBigInt(
    void *root, 
    const char *key
)

在root指向的json对象中,获取指定key字段的BigInt数值 参数

  • root - TC_JsonParse()接口返回的对象句柄
  • key - 字段的标识符 返回值 字段key对应的BigInt字符串

TC_JsonGetObject

void* TC_JsonGetObject(
    void *root, 
    const char *key
)

在root指向的json对象中,获取指定key字段的子json对象 参数

  • root - TC_JsonParse()接口返回的对象句柄
  • key - 字段的标识符 返回值 字段key对应的json对象句柄

TC_JsonPutInt

void TC_JsonPutInt(
    void *root, 
    const char *key, 
    int val
)

在root指向的json对象中,设置指定key字段的值为val 参数

  • root - TC_JsonParse()接口返回的对象句柄
  • key - 字段的标识符
  • val - 字段值为32位整数 返回值

TC_JsonPutInt64

void TC_JsonPutInt64(
    void *root, 
    const char *key, 
    int64 val
)

在root指向的json对象中,设置指定key字段的值为val 参数

  • root - TC_JsonParse()接口返回的对象句柄
  • key - 字段的标识符
  • val - 字段值为64位整数 返回值

TC_JsonPutString

void TC_JsonPutString(
    void *root, 
    const char *key, 
    const char* val
)

在root指向的json对象中,设置指定key字段的值为val 参数

  • root - TC_JsonParse()接口返回的对象句柄
  • key - 字段的标识符
  • val - 字段值为字符串 返回值

TC_JsonPutAddress

void TC_JsonPutAddress(
    void *root, 
    const char *key, 
    const char* val
)

在root指向的json对象中,设置指定key字段的值为val 参数

  • root - TC_JsonParse()接口返回的对象句柄
  • key - 字段的标识符
  • val - 字段值为address 返回值

TC_JsonPutBigInt

void TC_JsonPutBigInt(
    void *root, 
    const char *key, 
    const char* val
)

在root指向的json对象中,设置指定key字段的值为val 参数

  • root - TC_JsonParse()接口返回的对象句柄
  • key - 字段的标识符
  • val - 字段值为BigInt 返回值

TC_JsonPutObject

void TC_JsonPutObject(
    void *root, 
    const char *key, 
    void* child
)

在root指向的json对象中,设置指定key字段的值为val 参数

  • root - TC_JsonParse()接口返回的对象句柄
  • key - 字段的标识符
  • child - 子json对象句柄 返回值

TC_JsonToString

char* TC_JsonToString(
    void *root
)

把root句柄指向的json对象,转换为字符串 参数

  • root - TC_JsonParse()接口返回的对象句柄 返回值 json对象的字符串

C语言底层函数

wasm虚拟机底层替换的部分C标准库接口,适配wasm虚拟机底层内存模型。

C函数文档

兼容标准库接口函数原型

exit

void exit(int)

正常终止合约的执行并退出 参数 合约终止状态码(暂未使用,可忽略) 返回值

abort

void abort()

异常终止合约的执行并退出,会引起合约状态的回滚 参数返回值

malloc

void* malloc(size_t size)

分配指定大小的内存,并返回内存的起始地址 参数

  • size - 分配的内存大小 返回值 分配的内存起始地址

calloc

void* calloc(
    size_t count, 
    size_t size
)

分配nmemb个元素,每个元素的大小为size字节,并返回内存的起始地址 参数

  • nmemb - 分配的元素个数
  • size - 元素的大小,字节为单位 返回值 内存的起始地址

realloc

void* realloc(
    void *ptr, 
    size_t size
)

调整ptr指向内存的大小为size个字节,并返回新的内存起始地址 参数

  • ptr- 原始内存的起始地址
  • size- 调整大小,以字节为单位 返回值 新的内存起始地址

realloc

void* realloc(
    void *ptr, 
    size_t size
)

调整ptr指向内存的大小为size个字节,并返回新的内存起始地址 参数

  • ptr- 原始内存的起始地址
  • size- 调整大小,以字节为单位 返回值 新的内存起始地址

memcpy

void*  memcpy(
    void* dest, 
    const void* src, 
    size_t n
)

内存拷贝 参数

  • dst - 目标内存起始地址
  • src - 源内存起始地址
  • n - 拷贝的内存大小,以字节为单位 返回值 目标内存的起始地址

    src和dst内存段不可以有重叠

memmove

void*  memmove(
    void* dest, 
    const void* src, 
    size_t n
)

内存拷贝 参数

  • dst - 目标内存起始地址
  • src - 源内存起始地址
  • n - 拷贝的内存大小,以字节为单位 返回值 返回目标内存起始地址

    dst和src内存区域可以重叠

memset

void*  memset(
    void* dest, 
    int c, 
    size_t n
)

填充内存,设置为指定的数值 参数

  • s - 内存起始地址;
  • c - 内存设置为常量字节c;
  • n - 填充的内存长度 返回值 内存的起始地址

strconcat

char*  strconcat(
    const char* str1, 
    const char* str2
)

把s2字符串拼接到s1字符串后面 参数

  • str1 - s1字符串起始地址
  • str2 - s2字符串起始地址 返回值 返回拼接后的字符串起始地址;新地址

    !!strconcat返回的地址一定是新的地址。!! 不可用str1地址

itoa

char * itoa(
    int n
)

32位整数转换为字符串 参数

  • n - 32位整数 返回值 字符串起始地址

签名算法接口

wasm合约提供一些基础的签名算法接口。

C函数文档

TC_Ecrecover

char* TC_Ecrecover(
        const char* hash, 
        const BigInt v, 
        const BigInt r, 
        const BigInt s
)

通过消息的hash和签名(v, r, s)恢复公钥

参数

  • hash - 消息的哈希
  • v - 签名
  • r - 签名
  • s - 签名

返回值 以16进制格式输出公钥字符串

TC_Ripemd160

char* TC_Ripemd160(
    const char* data
)

Ripemd160哈希运算
参数

  • data - 原始数据 返回值 哈希运算结果,以字符串形式保存

TC_Sha256

char* TC_Sha256(
    const char* data
)

Ripemd160哈希运算
参数

  • data - 原始数据 返回值 哈希运算结果,以字符串形式保存

TC_Keccak256

char* TC_Keccak256(
    const char* data
)

参数

  • data - 原始数据 返回值 哈希运算结果,以字符串形式保存

BigInt 操作接口

标准的C库不提供BigInt操作,考虑到区块链底层与余额有关的操作,都是以BigInt作为操作数,而第三方的C库与go本身的BigInt操作会存在不兼容的问题,因此统一由wasm虚拟机提供此类接口,以c字符串形式表示。

C语言中BigInt定义 typedef char* BigInt;

C函数文档

TC_BigIntAdd

BigInt TC_BigIntAdd(
const BigInt a, 
const BigInt b
)

BigInt加法运算,等价于(a + b) 参数

  • a - BigInt数字
  • b - BigInt数字 返回值 加法结果

TC_BigIntSub

BigInt TC_BigIntSub(
    const BigInt a, 
    const BigInt b
)

BigInt减法运算,等价于(a - b) 参数

  • a - BigInt数字
  • b - BigInt数字 返回值 减法结果

TC_BigIntMul

BigInt TC_BigIntMul(
    const BigInt a, 
    const BigInt b
)

BigInt乘法运算,等价于(a * b) 参数

  • a - BigInt数字
  • b - BigInt数字 返回值 乘法结果

    TC_BigIntDiv

    BigInt TC_BigIntDiv(
      const BigInt a, 
      const BigInt b
    ) 

    BigInt除法运算,等价于(a / b) 参数

  • a - BigInt数字
  • b - BigInt数字 返回值 除法结果

    TC_BigIntMod

    BigInt TC_BigIntMod(
      const BigInt a, 
      const BigInt b
    ) 

    BigInt取模运算,等价于(a % b) 参数

  • a - BigInt数字
  • b - BigInt数字 返回值 取模结果

    TC_BigIntCmp

    int TC_BigIntCmp(
      const char *a, 
      const char *b
    ) 

    BigInt大小比较 参数

  • a - BigInt数字
  • b - BigInt数字 返回值
  1. a < b: <0
  2. a = b: =0
  3. a > b: >0

TC_BigIntToInt64

int64  TC_BigIntToInt64(
    const char *s
)

BigInt转换为64位整数,超过64位的数值将会被截断 参数

  • s - BigInt数字 返回值 64位有符号整数