我们在C++中常用的表示整形的类型有int, long, unsigned long, int64_t等等,这些类型的长度为32位,64位,一般的情况下就能满足我们的需要了,但是在以太坊里这样的精度类型就显得捉襟见肘了,比如以太坊中常用的货币单位为Wei,而以太币1Ether=10的18次方Wei,这是一个非常大的数,普通的数据类型显然不能用了,我们需要更大的数。
boost::multiprecision
好在C++的boost库里提供了这样的数据类型,它们就存在于boost::multiprecision命名空间中,大家可以在这个网页看到定义:
https://www.boost.org/doc/libs/1_65_1/libs/multiprecision/doc/html/boost_multiprecision/tut/ints/cpp_int.html
可以看到里面定义了uint128_t,uint256_t,uint512_t甚至uint1024_t。
在以太坊ethereum代码中也使用了类似的定义,不过名字不同,采用的u128表示128位无符号数,u256表示256位无符号数,以此类推,具体定义在libdevcore\Common.h
文件中。
需要注意的是这种数据类型与字符串类型的转换,因为我们经常需要输出这种数值,转换位字符串会比较方便,这种类型提供了转换为std::string
的方法,那就是str()
函数,比如:
u256 value = *******;
std::string strValue = value.str();
u128,u256等类型在以太坊代码中使用非常频繁,比如区块头BlockHeader.h
中定义了:
u256 m_gasLimit;
u256 m_gasUsed;
u256 m_difficulty;
m_gasLimit
表示gas最大值,m_gasUsed
表示所使用的gas,m_difficulty
表示挖矿难度。
FixedHash类
FxedHash
类是一个模板类,定义于libdevcore\FixedHash.h
中,我们查看这个类定义,可以看到它就只有一个数据成员:
std::array<byte, N> m_data;
所以这就是一个封装的字节数组类,里面重载了==,!=,>=等符号,还提供了一个成员hex()
用于将字节数组转化为字符串数组:
std::string hex();
为了方便使用,该文件中还定义了一些别名,比如:
using h520 = FixedHash<65>;
using h512 = FixedHash<64>;
using h256 = FixedHash<32>;
using h160 = FixedHash<20>;
using h128 = FixedHash<16>;
h256表示32个字节大小的字节数组,其他以此类推。
FixedHash类在以太坊中也经常用到,通常来表示hash值,我们还是以BlockHeader
为例:
h256 m_parentHash;
h256 m_sha3Uncles;
h256 m_stateRoot;
h256 m_transactionsRoot;
h256 m_receiptsRoot;
m_parentHash
表示父块的hash值,m_sha3Uncles
表示叔块的hash值,m_stateRoot
表示state树根hash,m_transactionsRoot
表示交易树根hash,m_receiptsRoot
表示收据树根hash。