货币单位
一个常量的数字,可以使用后缀wei,finney,szabo或ether来在不同面额中转换。如2 ether == 2000 finney的结果是true。
- 1 ether==10^3 finney
- 1 ether==10^6 szabo
- 1 ether==10^18 wei
注意:
不含任何后缀的默认单位是wei
时间单位
seconds,minutes,hours,days,weeks,years均可做为后缀,并进行相互转换。
- 1 == 1 seconds
- 1 minutes == 60 seconds
- 1 hours == 60 minutes
- 1 days == 24 hours
- 1 weeks == 7 days
- 1 years == 365 days
注意
- 不含任何后缀的默认单位是seconds
- 如果你需要进行使用这些单位进行日期计算,需要特别小心,因为不是每年都是365天,且并不是每天都有24小时,因为还有闰秒。
- years 后缀已经不推荐使用了,因为从 0.5.0 版本开始将不再支持。
范例
后缀不能用于变量。如果你想对输入的变量说明其不同的单位,可以使用下面的方式
pragma solidity ^0.5.0;
contract DeleteExample{
function nowInSeconds() public returns (uint256){
return now;
}
function f(uint start, uint daysAfter) public {
if (now >= start + daysAfter * 1 days) {
}
}
}
特殊的变量及函数
在全局命名空间中已经存在了(预设了)一些特殊的变量和函数,他们主要用来提供关于区块链的信息或一些通用的工具函数。
区块和交易属性
- block.blockhash(uint blockNumber) returns (bytes32):指定区块的区块哈希——仅可用于最新的 256 个区块且不包括当前区块;而 blocks 从 0.4.22 版本开始已经不推荐使用,由 blockhash(uint blockNumber) 代替
- block.coinbase(address): 挖出当前区块的矿工地址
- block.difficulty (uint): 当前区块难度
- block.gaslimit (uint): 当前区块 gas 限额
- block.number (uint): 当前区块号
- block.timestamp (uint): 自 unix epoch 起始当前区块以秒计的时间戳
- gasleft() returns (uint256):剩余的 gas
- msg.data (bytes): 完整的 calldata
- msg.sender (address): 消息发送者(当前调用)
- msg.sig (bytes4): calldata 的前 4 字节(也就是函数标识符)
- msg.value (uint): 随消息发送的 wei 的数量
- now (uint): 目前区块时间戳(block.timestamp)
- tx.gasprice (uint): 交易的 gas 价格
- tx.origin (address): 交易发起者(完全的调用链)
区块链交易属性说明
- 对于同一个链上连续的区块来说,当前区块时间戳总是大于上一个区块的时间戳。
- 只能查最近256个块,所有其它的将返回0
- msg的所有成员的值,包括msg.sender和msg.value会在每个external函数调用中改变。
错误处理
错误处理是指程序发生错误时的处理方式,Solidity处理错误和我们常见的语言不一样,它是通过回退状态的方式处理错误,在发生异常时会撤销当前调用(及其所有子调用)所改变的状态,同时给调用者返回一个错误标识。(没有try catch 不可能捕获异常)
assert(bool condition)
如果条件不满足,则使当前交易没有效果——用于检查内部错误。
特点:
会消耗掉全部的gas
在下述场景中自动产生assert类型的异常:
-
访问数组的索引太大或为负数(例如 x[i] 其中 i >= x.length 或 i < 0)。
-
访问定长字节数组的索引太大或为负数。
-
用零当除数做除法或模运算(例如 5 / 0 或 23 % 0 )。
-
移位负数位。
-
将一个太大或负数值转换为一个枚举类型。
-
调用 assert 的参数(表达式)最终结算为 false。
require(bool condition)
如果条件不满足则撤销状态更改——用于检查由输入或者外部组件引起的错误。
特点:
不会消耗全部gas
在下述场景中自动产生require类型的异常:
- 调用 throw 。
- 调用 require 的参数(表达式)最终结算为 false 。
- 通过消息调用调用某个函数,但该函数没有正确结束(它耗尽了 gas,没有匹配函数,或者本身抛出一个异常),上述函数不包括低级别的操作 call , send , delegatecall 或者 callcode 。低级操作不会抛出异常,而通过返回 false 来指示失败。
- 使用 new 关键字创建合约,但合约没有正确创建
- 对不包含代码的合约执行外部函数调用。
- 合约通过一个没有 payable 修饰符的公有函数(包括构造函数和 fallback 函数)接收 Ether。
- 合约通过公有 getter 函数接收 Ether 。
- transfer() 失败。
require(bool condition, string message)
如果条件不满足则撤销状态更改——用于检查由输入或者外部组件引起的错误,可以同时提供一个错误消息。
revert()
终止运行并撤销状态更改。
特点:
返还剩余的gas
revert(string reason)
终止运行并撤销状态更改,可以同时提供一个解释性的字符串。
数学和加密函数
- addmod(uint x, uint y, uint k) returns (uint) 计算(x + y)%k的值,其中加法以指定精度执行,并且不超过2 ** 256。从版本0.5.0开始断言k!= 0。
- mulmod(uint x, uint y, uint k) returns (uint) 计算(x * y)%k的值,其中乘法以指定精度执行,并且不超过2 ** 256。从版本0.5.0开始断言k!= 0
- keccak256(…) returns (bytes32) 计算(紧凑排列的)参数的Ethereum-SHA-3的Hash值
- sha256(…) returns (bytes32) 计算(紧凑排列的)参数的SHA-256 的Hash值
- sha3(…) returns (bytes32) keccak256的别名
- ripemd160(…) returns (bytes20) 计算(紧凑排列的)参数的 RIPEMD-160 的Hash值
- ecrecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) returns (address) 从椭圆曲线签名中恢复与公钥相关的地址,或在错误时返回零
合约相关
- selfdestruct(address recipt):销毁当前合约,并把它所有资金发送到给定的地址(如果是合约地址,即使该合约没有payable的fallback函数也可以收以太币)。