有一些变量和函数存在于¥全局上下文中。主要用来提供一些区块链当前的信息。
- 区块和交易的属性(Block And Transaction Properties)
- block.blockhash(uint blockNumber) returns (bytes32),给定区块号的哈希值,只支持最近256个区块,且不包含当前区块。
- block.coinbase (address) 当前块矿工的地址。
- block.difficulty (uint)当前块的难度。
- block.gaslimit (uint)当前块的gaslimit。
- block.number (uint)当前区块的块号。
- block.timestamp (uint)当前块的时间戳。
- msg.data (bytes)完整的调用数据(calldata)。
- msg.gas (uint)当前还剩的gas。
- msg.sender (address)当前调用发起人的地址。
- msg.sig (bytes4)调用数据的前四个字节(函数标识符)。
- msg.value (uint)这个消息所附带的货币量,单位为wei。
- now (uint)当前块的时间戳,等同于block.timestamp
- tx.gasprice (uint) 交易的gas价格。
- tx.origin (address)交易的发送者(完整的调用链)
msg的所有成员值,如msg.sender,msg.value的值可以因为每一次外部函数调用,或库函数调用发生变化(因为msg就是和调用相关的全局变量)。
如果你想在库函数中,用msg.sender实现访问控制,你需要将msg.sender做为参数(就是说不能使用默认的msg.value,因为它可能被更改)。
为了可扩展性的原因,你只能查最近256个块,所有其它的将返回0.
asser(bool condition):
如果条件不满足,抛出异常。
addmod(uint x, uint y, uint k) returns (uint):
计算(x + y) % k。加法支持任意的精度。但不超过(wrap around?)2**256。
mulmod(uint x, uint y, uint k) returns (uint):
计算(x * y) % k。乘法支持任意精度,但不超过(wrap around?)2**256。
keccak256(...) returns (bytes32):
使用以太坊的(Keccak-256)计算HASH值。紧密打包。
sha3(...) returns (bytes32):
等同于keccak256()。紧密打包。
sha256(...) returns (bytes32):
使用SHA-256计算HASH值。紧密打包。
ripemd160(...) returns (bytes20):
使用RIPEMD-160计算HASH值。紧密打包。
ecrecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) returns (address):
通过签名信息恢复非对称加密算法公匙地址。如果出错会返回0,附录提供了一个例子1.
revert():
取消执行,并回撤状态变化。
需要注意的是参数是“紧密打包(tightly packed)”的,意思是说参数不会补位,就直接连接在一起的。下面来看一个例子:
keccak256("ab", "c")
keccak256("abc")
//hex
keccak256(0x616263)
keccak256(6382179)
//ascii
keccak256(97, 98, 99)
上述例子中,三种表达方式都是一致的。
如果需要补位,需要明确的类型转换,如
keccak256("\x00\x12")等同于keccak256(uint16(0x12))
需要注意的是字面量会用,尽可能小的空间来存储它们。比如,
keccak256(0) == keccak256(uint8(0)),keccak256(0x12345678) == keccak256(uint32(0x12345678))
在私链(private blockchain)上运行sha256,ripemd160或ecrecover可能会出现Out-Of-Gas报错。因为它们实现了一种预编译的机制,但合约要在收到第一个消息后才会存在。向一个不存在的合约发送消息,非常昂贵,所以才会导致Out-Of-Gas的问题。一种解决办法是每个在你真正使用它们前,先发送1 wei到这些合约上来完成初始化。在官方和测试链上没有这个问题。
<address>.balance (uint256):
Address的余额,以wei为单位。
<address>.transfer(uint256 amount):
发送给定数量的ether,以wei为单位,到某个地址。失败时抛出异常。
<address>.send(uint256 amount) returns (bool):
发送给定数量的ether,以wei为单位,到某个地址。失败时返回false。
<address>.call(...) returns (bool):
发起底层的call调用。失败时返回false。
<address>.callcode(...) returns (bool):
发起底层的callcode调用,失败时返回false。
<address>.delegatecall(...) returns (bool):
发起底层的delegatecall调用,失败时返回false。
更多信息参加Address章节。
使用send方法需要注意,调用栈深不能超过1024,或gas不足,都将导致发送失败。使用为了保证你的ether安全,要始终检查返回结果。当用户取款时,使用transfer或使用最佳实践的模式2。
this(当前合约的类型)
当前合约的类型,可以显式的转换为Address
selfdestruct(address recipt):
销毁当前合约,并把它所有资金发送到给定的地址。
另外,当前合约里的所有函数均可支持调用,包括当前函数本身。