CPP合约的库方法
dp
dp 包主要是提供将合约数据存储到链中所需的数据结构的,这里封装了 array、list、map 三种不同的数据结构,以方便对合约数据的操作。
array.hpp
Array简述
array 提供了类似于常规数组的合约数据操作
Array构造
typedef bcwasm::db::Array<arg1,arg2,arg3> testArray_t;
testArray_t testArray
arg1:所构造Array的名字,在同一个合约中,arg1相同的Array所使用的是同一片空间
arg2:存入Array的成员的类型
arg3:Array的长度
Array方法
at 获取指定位置的Array数据
Key& at(size_t pos)
使用方式:
testArray.at(pos)
注解
pos < 0 或 pos > size(Array的长度) 会报越界错误
[] 与数组一样,支持通过[]操作符来取值
Key& operator[](size_t pos)
使用方式:
testArray[pos]
注解
内部调用的是 testArray.at(pos),所以越界一样会报错
size 获取当前 Array 的长度
size_t size() const
使用方式:
testArray.size()
getConst 以常量值的方式获取一个成员,不刷新缓存
Key getConst(size_t pos) const
使用方式:
testArray.getConst(pos)
setConst 设置一个常量值到指定位置,不刷新缓存
void setConst(size_t pos, const Key &key)
使用方式:
testArray.setConst(pos, key)
注解
如果 pos < 0 或 pos > size (Array 的长度)会报越界错误
迭代器
普通迭代器 Iterator
一般用于合约数据的写入操作。
/**
* @brief Construct a new Iterator object
*
* @param array Array
* @param pos position
*/
Iterator(Array<Name, Key, Size> *array, size_t pos)
:array_(array), pos_(pos){
}
反向迭代器 ReverseIterator
其实就是对普通迭代器重命名,把普通迭代器的 end() 当做 反向迭代器的 begin(),把普通迭代器的 begin() 当做反向迭代器的 end()
常量迭代器 ConstIterator
本质上和 Iterator 是一样的,只是一般用于合约数据的读取操作。
/** * @brief Construct a new Const Iterator object * * @param array Array * @param pos position */ ConstIterator(Array<Name, Key, Size> *array, size_t pos) :array_(array), pos_(pos) { }
常量反向迭代器 ConstReverseIterator
操作性质同 ConstIterator,一般用于读取操作,只是迭代顺序与 Iterator 相反。
/** * @brief Construct a new Const Reverse Iterator object * * @param array Array * @param pos position */ ConstReverseIterator(Array<Name, Key, Size> *array, size_t pos) :array_(array), pos_(pos){ }
操作符重载
==
// == 操作符用于比较两个迭代器是否相等 friend bool operator == ( const Iterator& a, const Iterator& b ) { return a.array_ == b.array_ && a.pos_ = b.pos_; }
!=
// != 操作符用于比较两个迭代器是否不相等 friend bool operator != ( const Iterator& a, const Iterator& b ) { return a.array_ != b.array_ || a.pos_ != b.pos_; }
*
// * 和 -> 操作符都是用于获取数组中第 pos 个成员的值 Key& operator*() const { return array_->at(pos_-1); }
->
// * 和 -> 操作符都是用于获取数组中第 pos 个成员的值 Key& operator->() const { return array_->at(pos_-1); }
- - (中间无空格)
// -- 操作符使当前迭代器的 pos -1 Iterator& operator--(){ pos_--; return *this; } // 使用 -- 操作符时,如果 pos < 0 会报错 Iterator operator --(int) { BCWasmAssert(pos_ > 0, "pos can't be negative"); Iterator tmp(array_, pos_--); --tmp; return tmp; }
++
// ++ 操作符是用于使当前迭代器的 pos +1 Iterator& operator ++() { pos_++; return *this; }
list.hpp
List简述
list 提供了类似于常规列表的合约数据操作
List构造
typedef bcwasm::db::List<arg1,arg2> testList_t;
testList_t testList
arg1:所构造List的名字,在同一个合约中,arg1相同的List所使用的是同一片空间
arg2:存入LIst的成员的类型
List方法
push 添加一个成员到 list 中
void push(const Key &k)
使用方式:
testList.push(key)
get 从 list 中获取一个指定下标的成员
Key& get(size_t index)
使用方式:
testList.get(index)
注解
如果 index < 0 或 index > size (List 的长度)会报越界错误
del 删除 list 中指定下标下的成员
void del(size_t index)
使用方式:
testList.del(index)
注解
如果 index < 0 或 index > size (List 的长度)会报越界错误
del 删除 list 中的指定key,如果 key 不存在则不做任何操作
void del(const Key &delKey)
使用方式:
testList.del(key)
[] 与数组一样,支持通过[]操作符来取值
Key& operator[](size_t i)
使用方式:
testList[i]
注解
内部调用的是 testList.get(i),所以越界一样会报错
getConst 以常量值的方式获取一个成员,不刷新缓存
Key getConst(size_t index) const
使用方式:
testList.getConst(index)
注解
如果 index < 0 或 index > size (List 的长度)会报越界错误
setConst 设置一个常量值到指定位置,不刷新缓存
setConst(size_t index , const Key &key)
使用方式:
testList.setConst(index,key)
注解
如果 index < 0 或 index > size (List 的长度)会报越界错误
操作符重载
同 array 的 操作符重载
迭代器
同 array 的 迭代器
map.hpp
Map简述
Map提供了对用户数据通过key-value对的形式存储于与合约地址相关的某地址的方法
Map构造
typedef bcwasm::db::Map<arg1,arg2,arg3> testMap_t;
testMap_t testMap
arg1:所构造Map的名字,在同一个合约中,arg1相同的Map所使用的是同一片空间
arg2:存入的key的类型
arg3:存入的value的类型
Map方法
insert 插入数据
bool insert(const Key &k, const Value &v)
使用方法
testMap.insert(key,value);
注解
insert只能插入新的key,如果key值已存在,则返回false
find 查找数据
const Value* find(const Key &k)const const Value* find(const Key &k)
使用方法
value = *testMap.find(key);
注解
find返回值为指针,解引用之前需要先判断指针是否为空
update 更新数据
bool update(const Key &k,const Value &v)
使用方法
testMap.update(key,value);
注解
如果更新未存在的key,则返回false
del 输出数据
void del(const Key &k)
使用方法
testpMap.del(key);
size 查看Map大小
int size() int size() const
使用方法
testMap.size();
其他注意事项
在使用迭代器期间如果需要进行插入或者删除操作,需要自行对迭代器递增或递减
例如:
for(auto it=testMap.begin(); it!=testMap.end();it++) { std::string a="Hello"; std::string b="world"; testMap.insert(a,b); it--; }
不支持[]操作,如果需要进行修改操作,可以调用update方法
bcwasm.hpp
写合约的命名空间
namespace bcwasm
使用方式:
bcwasm::sm2secSigVerify()
crypto.hpp
简述
对外提供了一些加密方法
方法
smSigVerify
void smSigVerify(const char* _msg, int _msgSize, const char* _userid, int _useridSize, const char* _pubkey, int _pubkeySize, const char * _sig, int _sigSize, char* _result, int _resultSize);
bcwasm 命名空间该方法进行了封装,推荐以 bcwasm 命名空间的方式对该方法进行使用。
std::string sigVerify(const std::string& _msg, const std::string& _userid, const std::string& _pubkey, const std::string& _sig)
使用方式:
bcwasm::sigVerify(msg, userid, pubkey, sig)
sm2secSigVerify
void sm2secSigVerify(const char* _msg, int _msgSize, const char* _pubkey, int _pubkeySize, const char * _sig, int _sigSize, char* _result, int _resultSize);
bcwasm 命名空间该方法进行了封装,推荐以 bcwasm 命名空间的方式对该方法进行使用。
std::string sm2secSigVerify(const std::string& _msg, const std::string& _pubkey, const std::string& _sig)
使用方式:
bcwasm::sm2secSigVerify(msg, pubkey, sig)
secp256r1SigVerify
void secp256r1SigVerify(const char* _msg, int _msgSize, const char* _pubkey, int _pubkeySize, const char * _sig, int _sigSize, char* _result, int _resultSize);
bcwasm 命名空间该方法进行了封装,推荐以 bcwasm 命名空间的方式对该方法进行使用。
std::string secp256r1SigVerify(const std::string& _msg, const std::string& _pubkey, const std::string& _sig)
使用方式:
bcwasm::secp256r1SigVerify(msg, pubkey, sig)
secp256k1SigVerify
void secp256k1SigVerify(const char* _msg, int _msgSize, const char* _pubkey, int _pubkeySize, const char * _sig, int _sigSize, char* _result, int _resultSize);
bcwasm 命名空间该方法进行了封装,推荐以 bcwasm 命名空间的方式对该方法进行使用。
std::string secp256k1SigVerify(const std::string& _msg, const std::string& _pubkey, const std::string& _sig)
使用方式:
bcwasm::secp256k1SigVerify(msg, pubkey, sig)
sm3
void sm3(const char* _msg, int _msgSize, char* _result, int _resultSize);
bcwasm 命名空间该方法进行了封装,推荐以 bcwasm 命名空间的方式对该方法进行使用。
std::string sm3Compute(const std::string& _msg)
使用方式:
bcwasm::sm3Compute(msg)
注解
上述方法只是以接口的形式存在于 C++ 代码中,具体实现是在 Venachain 项目中以 Golang 代码来实现的,运行的时候会自动匹配调用其具体实现。
RLP.h
简述
一种区块链的递归编码规则,可用于编码任意嵌套的二进制数。
其序列化与反序列化方法被封装在 bcwasm/serialize.hpp 中,推荐以 bcmasm 的方式对其进行使用,下面的内容也是以 bcwasm 封装的方式来写的,内容在 bcwasm/serialize.hpp 中。
序列化
定义
#define BCWASM_SERIALIZE( TYPE, MEMBERS )
TYPE:需要进行序列化与反序列化的类
MEMBERS:该类需要序列化的一系列成员名称,传入方式为:(field1)(field2)(field3)
使用方法
// 学生类型属性
struct SudentType
{
string name; // 名称
int age; // 年龄
int gender; // 性别
// RLP 序列化
BCWASM_SERIALIZE(SudentType, (name)(age)(gender));
};
反序列化
定义
#define BCWASM_SERIALIZE_DERIVED( TYPE, BASE, MEMBERS )TYPE:需要进行序列化与反序列化的类
BASE:被序列化的类的成员名称,传入方式为:(field1)(field2)(field3)
MEMBERS:反序列化的类的成员名称,传入方式为:(field1)(field2)(field3)
使用方法
--- TODO
deployedcontract.hpp
简述
deployedcontract.hpp 提供了一些合约间调用的相关方法
方法
bcwasmCallString
调用其他合约的函数,返回的数据类型是 string
char* bcwasmCallString(const uint8_t *address, const uint8_t *args, uint32_t len);
bcwasm 命名空间该方法进行了封装,推荐以 bcwasm 命名空间的方式对该方法进行使用。
inline std::string callString(const std::string &funcName, Args&&... args) const
使用方式:
bcwasm::callString(funcName, arg1, arg2, arg3)
bcwasmCallInt64
调用其他合约的函数,返回的数据类型是 int64
int64_t bcwasmCallInt64(const uint8_t *address, const uint8_t *args, uint32_t len);
bcwasm 命名空间该方法进行了封装,推荐以 bcwasm 命名空间的方式对该方法进行使用。
inline int64_t callInt64(const std::string &funcName, Args&&... args) const
使用方式:
bcwasm::callInt64(funcName, arg1, arg2, arg3)
bcwasmDelegateCallString
代理调用其他合约的函数,返回的数据类型是 string
char* bcwasmDelegateCallString(const uint8_t *address, const uint8_t *args, uint32_t len);
bcwasm 命名空间该方法进行了封装,推荐以 bcwasm 命名空间的方式对该方法进行使用。
inline std::string delegateCallString(const std::string &funcName, Args&&... args) const
使用方式:
bcwasm::delegateCallString(funcName, arg1, arg2, arg3)
bcwasmDelegateCallInt64
代理调用其他合约的函数,返回的数据类型是 int64
int64_t bcwasmDelegateCallInt64(const uint8_t *address, const uint8_t *args, uint32_t len);
bcwasm 命名空间该方法进行了封装,推荐以 bcwasm 命名空间的方式对该方法进行使用。
inline int64_t delegateCallInt64(const std::string &funcName, Args&&... args) const
使用方式:
bcwasm::delegateCallInt64(funcName, arg1, arg2, arg3)
bcwasmCall
调用其他合约的函数,无返回值
void bcwasmCall(const uint8_t *address, const uint8_t *args, uint32_t len);
bcwasm 命名空间该方法进行了封装,推荐以 bcwasm 命名空间的方式对该方法进行使用。
inline void call(const std::string &funcName, Args&&... args) const
使用方式:
bcwasm::call(funcName, arg1, arg2, arg3)
bcwasmDelegateCall
代理调用其他合约的函数,无返回值
void bcwasmDelegateCall(const uint8_t *address, const uint8_t *args, uint32_t len);
bcwasm 命名空间该方法进行了封装,推荐以 bcwasm 命名空间的方式对该方法进行使用。
inline void delegateCall(const std::string &funcName, Args&&... args) const
使用方式:
bcwasm::delegateCall(funcName, arg1, arg2, arg3)
event.hpp
简述
对外提供了事件的定义和触发方法
定义事件
BCWASM_EVENT
BCWASM_EVENT 是用来定义事件的,参数包含事件名称和事件所需的其他参数
#define BCWASM_EVENT(NAME, ...) \ void M_CAT(EVENT, NAME)(VA_F(__VA_ARGS__)) { \ bcwasm::emitEvent(#NAME, PA_F(__VA_ARGS__)); \ }
NAME:事件名称
该事件名称必须是在写合约时,在最后定义的函数所生成的ABI文件里面定义过的事件才能支持。
使用方式:
// 定义Event. BCWASM_EVENT(Notify, uint64_t, const char *)
触发事件
BCWASM_EMIT_EVENT
BCWASM_EMIT_EVENT 是用来触发事件的,参数包含事件名称和事件所需的其他参数
#define BCWASM_EMIT_EVENT(NAME, ...) \ M_CAT(EVENT, NAME)(__VA_ARGS__)
NAME:事件名称
该事件名称必须是在写合约时,在最后定义的函数所生成的ABI文件里面定义过的事件才能支持。
使用方式:
// 触发事件 BCWASM_EMIT_EVENT(Notify, code, (string(json) + string("is not a json object")).c_str());
exception.h
由 bcwasm 封装好的抛异常方法,可以用来手动抛出异常。
template<typename Arg, typename... Args>
void bcwasmThrow(Arg&& a, Args&&... args){
println(a, args...);
abort();
}
使用方式:
bcwasm::bcwasmThrow(a,b,c)
nizkpail.hpp
简述
提供了零知识证明相关的方法。
方法
void pailEncrypt(const char* _number, int _numberSize,
const char* _pubkey, int _pubkeySize,
char* _result, int _resultSize);
void pailHomAdd(const char* _cipher1, int _cipher1Size,
const char* _cipher2, int _cipher2Size,
const char* _pubkey, int _pubkeySize,
char* _result, int _resultSize);
void pailHomSub(const char* _cipher1, int _cipher1Size,
const char* _cipher2, int _cipher2Size,
const char* _pubkey, int _pubkeySize,
char* _result, int _resultSize);
void nizkVerifyProof(const char* _pai, int _paiSize,
const char* _fromBalCipher, int _fromBalCipherSize,
const char* _fromAmountCipher, int _fromAmountCipherSize,
const char* _toAmountCipher, int _toAmountCipherSize,
const char* _fromPubkey, int _fromPubkeySize,
const char* _toPubkey, int _toPubkeySize,
char* _result, int _resultSize);
上述方法 bcwasm 命名空间都对它们做了封装,推荐以 bcwasm 命名空间的方式对它们进行使用。下面是 bcwasm 对它们的封装:
std::string pailEncrypt(const std::string& _number, const std::string& _pubkey)
std::string pailHomAdd(const std::string& _cipher1, const std::string& _cipher2, const std::string& _pubkey)
std::string pailHomSub(const std::string& _cipher1, const std::string& _cipher2, const std::string& _pubkey)
std::string nizkVerifyProof(const std::string& _pai,
const std::string& _fromBalCipher,
const std::string& _fromAmountCipher,
const std::string& _toAmountCipher,
const std::string& _fromPubkey,
const std::string& _toPubkey)
使用方式如:
bcwasm::pailEncrypt(number, pubkey)
print.hpp
提供了一些用于打印输入的方法。
void prints( const char* cstr );
void prints_l( const char* cstr, uint32_t len);
void printi( int64_t value );
void printui( uint64_t value );
void printi128( const int128_t* value );
void printui128( const uint128_t* value );
void printsf(float value);
void printdf(double value);
void printqf(const long double* value);
void printhex( const void* data, uint32_t datalen );
使用方式如:
bcwasm::prints("Hello World!"); // Output: Hello World!
serialize.hpp
是对 RLP 的封装,提供对数据进行 RLP 序列化与反序列化的方法,详情请看前面 RLP.h 的说明。
state.hpp
简述
提供了与链相关的方法
方法
blockHash
获取区块的哈希值
/** * @brief Get block hash * @param number Block height * @return h256 Block hash */ h256 blockHash(int64_t number)
使用方式:
bcwasm::blockHash(number)
coinbase
获取当前区块矿工的地址
/** * @brief Current block miner’s address * @return h160 */ h160 coinbase()
使用方式:
bcwasm::coinbase()
balance
获取链上账号的余额
/** * @brief Get the balance * @return u256 balance */ u256 balance()
使用方式:
bcwasm::balance()
origin
获取事物的发送方
/** * @brief Sender of the transaction (full call chain) * @return h160 */ h160 origin()
使用方式:
bcwasm::origin()
caller
获取调用者地址
/** * @brief Caller address * @return h160 */ h160 caller()
使用方式:
bcwasm::caller()
isOwner
判断帐户是否为合同的创建者
/** * @brief whether account is contract's creator * @return int64_t */ int64_t isOwner(const Address &contract, const Address &account)
使用方式:
bcwasm::isOwner(contract, account)
isFromInit
判断某些方法是否是来自初始化调用
/** * @brief Is from init * @return h160 */ int64_t isFromInit()
使用方式:
bcwasm::isFromInit()
callValue
获取随消息发送的消息数量
/** * @brief Number of wei sent with the message * @return u256 */ u256 callValue()
使用方式:
bcwasm::callValue()
address
获取合约地址
/** * @brief Contract address * @return h160 */ h160 address()
使用方式:
bcwasm::address()
sha3
计算输入数据的Keccak-256哈希
/** * @brief Compute the Keccak-256 hash of the input * @param data String * @return h256 */ h256 sha3(const std::string &data) /** * @brief Compute the Keccak-256 hash of the input * @param data Byte pointer * @param len Length * @return h256 */ h256 sha3(const byte *data, size_t len)
使用方式:
bcwasm::sha3(data) bcwasm::sha3(data, len)
callTransfer
发送指定数量的 Wei 到指定地址
/** * @brief Send given amount of Wei to Address * * @param to Destination address * @param amount Amount * @return int64_t 0 success non-zero failure */ int64_t callTransfer(const Address& to, u256 amount)
使用方式:
bcwasm::callTransfer(to, amount)
ecrecover
回收
/** * @brief ecrecover * @param h, hash of the message * @sig, signature of the message * @return h160 */ h160 ecrecover(const byte* h, const byte* sig) h160 ecrecover(bytes & h, bytes & sig)
使用方式:
bcwasm::ecrecover(h, sig)
storage.hpp
简述
提供数据存储相关的操作方法。
前面的 array、list、map 其实底层都是调用了 storage.hpp 的相关方法的,也可以不使用array、list、map而直接调用 storage.hpp 的方法来直接存储数据。
方法
setState
设置状态对象
/** * @brief Set the State object * * @tparam KEY Key type * @tparam VALUE Value type * @param key Key * @param value Value */ template <typename KEY, typename VALUE> inline void setState(const KEY &key, const VALUE &value)
使用方式:
bcwasm::setState(key, value)
getState
获取状态对象
/** * @brief Get the State object * * @tparam KEY Key type * @tparam VALUE Value type * @param key Key * @param value Value * @return size_t Get the length of the data */ template <typename KEY, typename VALUE> inline size_t getState(const KEY &key, VALUE &value)
使用方式:
bcwasm::getState(key, value)
delState
删除状态对象
/** * @brief delete State Object * * @tparam KEY Key type * @param key Key */ template <typename KEY> inline void delState(const KEY &key)
使用方式:
bcwasm::delState(key)