全局变量与函数

在全局命名空间上,存在许多特殊的变量及函数,这些函数多用做提供与区块链相关的信息。

区块与交易相关
block

block 包含了各种与当前或早前区块相关的信息

名称 类型 / 函数签名 说明
block.blockhash function (uint blockNumber) returns(bytes32) 返回区块数为 blockNumber 的区块的哈希值。只能用于当前区块之前的 256 个区块,查询当前区块在内的其他区块都会返回 0。一定程度可以受到矿工的影响
block.coinbase address 挖出当前区块的矿工的地址
block.difficulty uint 当前区块的区块难度
block.gaslimit uint 所有交易在内,当前区块允许消耗的 gas 的最大数目
block.number uint 当前区块的区块数
block.timestamp
now
uint 当前区块的时间戳,一定程度可以受到矿工的影响

提示:

除非清楚在做什么,不要依靠 block.timestampnow 或者 block.blockhash 作为随机数的来源。

时间戳和区块的哈希都能在一定程度上受到矿工的影响。如果将这些作为随机数的来源,会有被不怀好意的矿工利用,"随机"出对他们更有利的结果。

以太坊规定当前区块的时间戳必须严格大于上一个区块的时间戳。但这只能保证当前区块的时间戳在社区中较权威的链中,大小在相邻的两个区块的时间戳之间。

提示:

出于规模的考虑,调用 block.blockhash 只能获取当前区块之外的最近的 256 个区块的哈希值。查询其他任何区块(包括当前区块)的哈希值都只会得到 0。

msg

msg 包含了各种与当前合约调用者所发消息有关的信息

名称 类型 / 函数签名 说明
msg.data bytes 存放了完整的 calldata
msg.gas uint 剩余可以使用的 gas。已被弃用,由 gasleft 函数代替。
gasleft function() returns(uint256) 返回剩余可以使用的 gas
msg.sender address (当前调用中)消息发送者的地址
msg.sig bytes4 calldata 的首四字节(即,函数的标识符)
msg.value uint 消息中附带的 wei 的数量

提示:

msg 中的任何成员,包括 msg.sendermsg.value 随时都会因调用外部函数而改变,这也包括调用中的函数。

tx

tx 包含了各种与当前交易相关的信息

名称 类型 / 函数签名 说明
tx.gasprice uint 当前交易中的 gas 的价格
tx.origin address 当前交易发送者的地址(位于完整调用链的最顶层)
错误处理

本书有专门的章节讲解 Solidity 的错误处理机制。在此,仅仅列出全局中用于处理错误的三个函数

函数 说明
assert(bool condition) 如果不符合 condition,抛出—用于处理内部错误。 调用 assert 不会归还调用者剩余的 gas
require(bool condition) 如果不符合 condition,抛出—用于处理在输入中或外部组件中的错误。调用 require 会归还调用者剩余的 gas
revert() 终止执行,撤销当前调用中的任何状态改变。调用 revert 会归还调用者剩余的 gas
数学与密码学相关函数
函数 说明
addmod(uint x, uint y, uint k) returns (uint) 计算 (x + y) % k,加法运算不会失去精度,也无需考虑溢出问题。Solidity 0.5.0 起,将会假设 k != 0
mulmod(uint x, uint y, uint k) returns (uint) 计算 (x * y) % k,乘法运算不会失去精度,$2^{256}$ 及以为的值无需考虑溢出。Solidity 0.5.0 起,将会假设 k != 0
keccak256(...) returns (bytes32)
sha3(...) returns (bytes32)
计算参数紧密打包后的 Ethereum-SHA-3 (Keccak-256) 哈希值
sha256(...) returns (bytes32) 计算参数紧密打包后的 SHA-256 哈希值
ripemd160(...) returns (bytes20) 计算参数紧密打包后的 RIPEMD-160 哈希值
ecrecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) returns (address) 椭圆曲线签名恢复与公钥相关联的地址。若遇到错误,则返回 0

在一些私有区块链上,调用 sha256ripemd160ecrecover 可能会遇到 Gas 不足 (Out-of-Gas) 的问题。出现此类问题是这些操作采用称为预编译合约的方式实现。这些合约只有在受到第一条消息后才会存在,而对不存在的合约发送消息有着更高昂的开销,因而出现 Gas 不足的错误。一种 workaround 是先向那些要用到的合约转一笔小钱(如 1 wei)。这类问题不会在以太坊官方及测试网络中出现。s

紧密打包 (tightly packed)

上表的"紧密打包"是指将各个参数紧密相连,没有填充。例如,以下语句都是相同的:

keccak256("Zz", "zz")
keccak256("Zzzz")
keccak256(0x5A7A7A7A)
keccak256(90, 122, 122)

如果需要填充,可以使用显式类型转换,例如:keccak256("\x00\x12") 等同于 keccak256(uint16(0x12))

此外,常量在打包时会使用最小可能的空间,因此,keccak256(0)keccak256(uint8(0)) 相等,keccak256(0x12345678)keccak256(uint32(0x12345678))相等。

results matching ""

    No results matching ""