github.com/n1ghtfa1l/go-vnt@v0.6.4-alpha.6/contracts/vntlib/vntlib.h (about) 1 // vnt合约标准库 2 // 所有vnt合约能够调用的方法都会在标准库中定义 3 // 编写合约代码时需要引用标准库 4 // vnt-wasm虚拟机中实现了标准库中的方法 5 6 //################################################################### 7 8 #include <stdbool.h> //支持bool类型 9 #ifndef _DEFINE_VNTLIB_H 10 #define _DEFINE_VNTLIB_H 11 #define VNT_WASM_EXPORT __attribute__((visibility("default"))) //导出方法 12 #define MUTABLE VNT_WASM_EXPORT //定义需要导出且修改状态变量的方法 13 #define UNMUTABLE \ 14 VNT_WASM_EXPORT //定义需要导出的方法,该方法可以读取状态变量但不会修改状态变量 15 #define EVENT void //空宏,声明Event函数时用的关键字 16 #define indexed //空宏,声明Event函数时,定义需要索引的参数时用到的关键字 17 #define CALL //空宏,声明跨合约调用函数时用到的关键字 18 #define KEY volatile //宏,声明全局变量 19 #define constructor VNT_WASM_EXPORT void //空宏,声明构造函数时使用 20 #define _ VNT_WASM_EXPORT void Fallback //宏,fallback函数符号 21 #define $_ VNT_WASM_EXPORT void $Fallback //宏,payable fallback函数符号 22 #define N(name) (#name) //宏,将输入直接转化为字符串的形式 23 #define CAT(n) n##n 24 #define U256(n) ("u2561537182776" #n) //声明uint256类型时使用的宏 25 #define Address(n) ("address1537182776" n) //声明address类型时使用的宏 26 27 #define now GetTimestamp() //获取区块生成的时间戳 28 29 // Time units 30 //#define years(n) (60 * 60 * 24 * 365 * n)UL; 31 #define years(n) n * 31536000UL 32 //#define weeks(n) (60 * 60 * 24 * 7 * n)UL; 33 #define weeks(n) n * 604800UL 34 //#define days(n) (60 * 60 * 24 * n)UL; 35 #define days(n) n * 86400UL 36 //#define hours(n) (60 * 60 * n)UL; 37 #define hours(n) n * 3600UL 38 //#define minutes(n) (60 * n)UL; 39 #define minutes(n) n * 60UL 40 // seconds为基本单位 41 #define seconds(n) n * 1UL 42 43 //以下为合约支持的类型的定义 44 typedef unsigned long long uint64; 45 typedef unsigned long uint32; 46 typedef long long int64; 47 typedef long int32; 48 typedef char *string; 49 // uint256其实是char数组 50 typedef char *uint256; 51 typedef char *address; 52 53 //二次编译时用到的类型标记 54 #define TY_INT32 1 55 #define TY_INT64 2 56 #define TY_UINT32 3 57 #define TY_UINT64 4 58 #define TY_UINT256 5 59 #define TY_STRING 6 60 #define TY_ADDRESS 7 61 #define TY_BOOL 8 62 #define TY_POINTER 9 63 64 //获取交易发起者地址 65 address GetSender(); 66 //在跨合约调用时,获取交易最初的发起者地址 67 address GetOrigin(); 68 //获取合约创建、调用时,同时发生的vnt转账值,单位为wei 69 uint256 GetValue(); 70 //获取某个地址的vnt余额,单位为wei 71 uint256 GetBalanceFromAddress(address addr); 72 //获取当前正在执行合约的地址 73 address GetContractAddress(); 74 //获取区块hash 75 string GetBlockHash(uint64 blocknumber); 76 //获取区块高度 77 uint64 GetBlockNumber(); 78 //获取区块生成的时间戳 79 uint64 GetTimestamp(); 80 //获取区块生产者的地址 81 address GetBlockProduser(); 82 // SHA3加密运算,返回以0x开头的十六进制字符串 83 string SHA3(string data); 84 // Ecrecover,参数hash,v,r,s都需要转化成十六进制字符串 85 // example 86 // Ecrecover("0x8309e99c09154c8f03d373c270965cf6d2be0af1fc1395e518596c4d7945b989",\ 87 "0x1c","0xdd3d526fb1154524d4c61a9e673d4bfc6fcc9fdcce39108a8486437196dd828b","0x5d7b80ae2985f43a817e1043ac02f6d421e9704b9bb31f4c3211aac9493d0d91") 88 address Ecrecover(string hash, string v, string r, string s); 89 //获取剩余GAS 90 uint64 GetGas(); 91 //获取当前交易的GasLimit 92 uint64 GetGasLimit(); 93 //判断条件,如果失败则返回msg,并且交易失败。该函数通常用来调试,正式环境请使用require 94 void Assert(bool condition, string msg); 95 //交易回滚 96 void Revert(string msg); 97 //判断条件是否成立,如果失败则交易失败 98 void Require(bool condition, string msg) { 99 if (condition != true) { 100 Revert(msg); 101 } 102 } 103 104 //合约向addr转账,转账金额为amount,单位为wei,转账失败会revert,消耗2300gas 105 void SendFromContract(address addr, uint256 amount); 106 //合约向addr转账,转账金额为amount,单位为wei,转账失败返回false,消耗2300gas 107 bool TransferFromContract(address addr, uint256 amount); 108 109 //将int64的数值转化为字符串 110 string FromI64(int64 value); 111 //将uint64的数值转化为字符串 112 string FromU64(uint64 value); 113 //将字符串转化为int64 114 int64 ToI64(string value); 115 //将字符串转化为uint64 116 uint64 ToU64(string value); 117 //连接两个字符串 118 string Concat(string str1, string str2); 119 //判断两个字符串是否相等 120 bool Equal(char *str1, char *str2); 121 122 //以下为调试函数,用于在合约函数中打印一些变量,其中remark为提示文件,后面的变量为打印对象 123 //打印一个地址变量 124 void PrintAddress(string remark, address a); 125 //打印一个字符串变量 126 void PrintStr(string remark, string s); 127 //打印一个uint64数字 128 void PrintUint64T(string remark, uint64 num); 129 //打印一个uint32数字 130 void PrintUint32T(string remark, uint32 num); 131 //打印一个int64数字 132 void PrintInt64T(string remark, int64 num); 133 //打印一个int32数字 134 void PrintInt32T(string remark, int32 num); 135 void PrintUint256T(string remark, uint256 num); 136 137 //将地址字符串转化成地址 138 address AddressFrom(string addrStr); 139 //将地址转化成字符串 140 string AddressToString(address addr); 141 //将字符串转成uint256类型 142 uint256 U256From(string u256Str); 143 //将uint256类型转成字符串 144 string U256ToString(uint256 u256); 145 146 //这是一个mapping类型的宏,用于定义一个mapping变量, 147 //其中key_type为key类型,val_type为value类型 148 #define mapping(key_type, val_type) \ 149 struct { \ 150 key_type key; \ 151 val_type value; \ 152 uint64 mapping1537182776; \ 153 } 154 155 //这是一个array类型的宏,用于定义一个array变量, 156 //其中val_type为数组元素类型 157 #define array(val_type) \ 158 struct { \ 159 uint64 index; \ 160 val_type value; \ 161 uint64 length; \ 162 uint64 array1537182776; \ 163 } 164 165 //以下几个指令为全局变量相关指令,不用在合约中显式 166 //的使用这些指令,而是在二次编译的时候会自动生成 167 168 //用于注册全局变量 169 void AddKeyInfo(uint64 value_address, int32 value_type, uint64 key_address, 170 int32 key_type, bool is_array_index); 171 //写全局变量 172 void WriteWithPointer(uint64 offset, uint64 baseaddr); 173 //读全局变量 174 void ReadWithPointer(uint64 offset, uint64 baseaddr); 175 //用于对全局变量进行初始化 176 void InitializeVariables(); 177 178 // ####math function 179 // uint64位的Pow运算 180 uint64 Pow(uint64 x, uint64 y); 181 182 //以下为uint256类型的数学运算函数 183 // UINT256 184 // uint64转成uint256 185 uint256 U256FromU64(uint64 x); 186 // int64转成uint256 187 uint256 U256FromI64(int64 x); 188 //加法 189 uint256 U256_Add(uint256 x, uint256 y); 190 //减法 191 uint256 U256_Sub(uint256 x, uint256 y); 192 //乘法 193 uint256 U256_Mul(uint256 x, uint256 y); 194 //除法 195 uint256 U256_Div(uint256 x, uint256 y); 196 //取余 197 uint256 U256_Mod(uint256 x, uint256 y); 198 //Pow 199 uint256 U256_Pow(uint256 x, uint256 y); 200 //Left shift 201 uint256 U256_Shl(uint256 value, uint256 shift); 202 //Right shift 203 uint256 U256_Shr(uint256 value, uint256 shift); 204 //And 205 uint256 U256_And(uint256 x, uint256 y); 206 //Or 207 uint256 U256_Or(uint256 x, uint256 y); 208 //Xor 209 uint256 U256_Xor(uint256 x, uint256 y); 210 211 //比较运算 212 // Cmp compares x and y and returns: 213 // 214 // -1 if x < y 215 // 0 if x == y 216 // +1 if x > y 217 // 218 int32 U256_Cmp(uint256 x, uint256 y); 219 220 //增加gas值,此指令不必显式调用,而是会被二次编译加入到wasm代码中 221 //####gas function 222 void AddGas(uint64 gas); 223 224 /* 225 CallParams:跨合约调用的第一个参数 226 _address:被调用的地址 227 _amount:发往被调用地址的代币,单位为wei 228 _gas:为跨合约调用支付的gas 229 */ 230 typedef struct { 231 address _address; 232 uint256 _amount; 233 uint64 _gas; 234 } CallParams; 235 236 //隐式调用WriteWithPointer、ReadWithPointer、AddGas三个指令 237 //使其能被编译到wasm代码中 238 __attribute__((visibility("default"))) void declaredFunction() { 239 WriteWithPointer(0, 0); 240 ReadWithPointer(0, 0); 241 AddGas(0); 242 } 243 244 //########SafeMath For Uint256########### 245 uint256 U256SafeMul(uint256 x, uint256 y) { 246 uint256 z = U256_Mul(x, y); 247 Require(U256_Cmp(x, U256(0)) == 0 || U256_Cmp(U256_Div(z, x), y) == 0, 248 "u256SafeMul overflow"); 249 return z; 250 } 251 uint256 U256SafeDiv(uint256 x, uint256 y) { 252 Require(U256_Cmp(y, U256(0)) == 1, "U256SafeDiv y == 0"); 253 uint256 z = U256_Div(x, y); 254 //这种情况不会出现 255 Require(U256_Cmp(x, U256_Add(U256_Mul(y, z), U256_Mod(x, y))) == 0, 256 "U256SafeDiv overflow"); 257 return z; 258 } 259 uint256 U256SafeSub(uint256 x, uint256 y) { 260 Require(U256_Cmp(x, y) != -1, "U256SafeSub x < y"); 261 return U256_Sub(x, y); 262 } 263 uint256 U256SafeAdd(uint256 x, uint256 y) { 264 uint256 z = U256_Add(x, y); 265 Require(U256_Cmp(z, x) != -1 && U256_Cmp(z, y) != -1, "U256SafeAdd overflow"); 266 return z; 267 } 268 //########################### 269 #endif 270 //################################################################### 271 // 以上为标准库