单位,和全局可用变量

Ether 单位

字面数字的后缀可以是 weigweiether 指定乙醚的子名称,其中不带后缀的乙醚编号假定为wei。

assert(1 wei == 1);
assert(1 gwei == 1e9);
assert(1 ether == 1e18);

子名称后缀的唯一作用是乘以10的幂。

注解

面额 finneyszabo 已在版本0.7.0中删除。

时间单位

后缀如下 secondsminuteshoursdaysweeks after文字数字可用于指定时间单位,其中秒是基本单位,单位按以下方式简单地视为单位:

  • 1 == 1 seconds

  • 1 minutes == 60 seconds

  • 1 hours == 60 minutes

  • 1 days == 24 hours

  • 1 weeks == 7 days

如果您使用这些单位执行日历计算,请注意,因为不是每年等于365天,甚至不是每天都有24小时,因为 leap seconds .由于无法预测闰秒,因此外部Oracle必须更新准确的日历库。

注解

后缀 years 已在0.5.0版中删除,原因如上。

这些后缀不能应用于变量。例如,如果要以天为单位解释函数参数,可以采用以下方式:

function f(uint start, uint daysAfter) public {
    if (block.timestamp >= start + daysAfter * 1 days) {
      // ...
    }
}

特殊变量和函数

有一些特殊的变量和函数,它们总是存在于全局名称空间中,主要用于提供关于区块链的信息,或者是通用的效用函数。

块和事务属性

  • blockhash(uint blockNumber) returns (bytes32) :给定挡路的散列时间 blocknumber 是最近256个块中的一个;否则返回零

  • block.basefee (uint): current block's base fee (EIP-3198 and EIP-1559)

  • block.chainid (uint): current chain id

  • block.coinbase (address payable): current block miner's address

  • block.difficulty (uint): current block difficulty

  • block.gaslimit (uint): current block gaslimit

  • block.number (uint): current block number

  • block.timestamp (uint): current block timestamp as seconds since unix epoch

  • gasleft() returns (uint256) :剩余气体

  • msg.data (bytes calldata): complete calldata

  • msg.sender (address): sender of the message (current call)

  • msg.sig (bytes4): first four bytes of the calldata (i.e. function identifier)

  • msg.value (uint): number of wei sent with the message

  • tx.gasprice (uint): gas price of the transaction

  • tx.origin (address): sender of the transaction (full call chain)

注解

所有成员的值 msg 包括 msg.sendermsg.value 每个人都可以改变 外部的 函数调用。这包括对库函数的调用。

注解

当对合同进行离链评估时,而不是在挡路中包含的交易上下文中进行评估时,您不应假设 block.*tx.* 指的是任何特定挡路或交易的价值。这些值由执行契约的EVM实现提供,可以是任意的。

注解

不要依赖 block.timestampblockhash 作为随机性的来源,除非你知道你在做什么。

时间戳和块散列在某种程度上都会受到矿工的影响。例如,采矿社区中的坏参与者可以在所选哈希上运行赌场付款函数,如果他们没有收到任何钱,只需重试其他哈希。

当前块时间戳必须严格大于最后一个块的时间戳,但唯一的保证是它将介于规范链中两个连续块的时间戳之间。

注解

由于可伸缩性的原因,块散列不能用于所有块。您只能访问最近256个块的哈希值,所有其他值都将为零。

注解

函数 blockhash 以前被称为 block.blockhash ,在0.4.22版中已弃用,在0.5.0版中已删除。

注解

函数 gasleft 以前被称为 msg.gas ,在0.4.21版中已弃用,在0.5.0版中已删除。

注解

在版本0.7.0中,别名 now (用于 block.timestamp )已删除。

ABI编解码功能

  • abi.decode(bytes memory encodedData, (...)) returns (...): ABI-decodes the given data, while the types are given in parentheses as second argument. Example: (uint a, uint[2] memory b, bytes memory c) = abi.decode(data, (uint, uint[2], bytes))

  • abi.encode(...) returns (bytes memory) :abi对给定参数进行编码

  • abi.encodePacked(...) returns (bytes memory) :执行 packed encoding 给出的参数。请注意,压缩编码可能不明确!

  • abi.encodeWithSelector(bytes4 selector, ...) returns (bytes memory) :abi从第二个开始对给定参数进行编码,并在给定的四字节选择器前面加上前缀。

  • abi.encodeWithSignature(string memory signature, ...) returns (bytes memory): Equivalent to abi.encodeWithSelector(bytes4(keccak256(bytes(signature))), ...)`

注解

这些编码函数可以用来处理外部函数调用的数据,而无需实际调用外部函数。此外, keccak256(abi.encodePacked(a, b)) 是计算结构化数据散列的一种方法(尽管要注意,可以使用不同的函数参数类型来构造“散列冲突”)。

请参阅有关 ABI 以及 tightly packed encoding 有关编码的详细信息。

字节的成员

错误处理

请参见 assert and require 有关错误处理和何时使用哪个函数的详细信息。

assert(bool condition)

导致死机错误,从而在不满足条件时返回状态更改-用于内部错误。

require(bool condition)

如果不满足条件,则返回-用于输入或外部组件中的错误。

require(bool condition, string memory message)

如果不满足条件,则返回-用于输入或外部组件中的错误。还提供错误消息。

revert()

中止执行并还原状态更改

revert(string memory reason)

中止执行并恢复状态更改,提供解释字符串

数学和密码函数

addmod(uint x, uint y, uint k) returns (uint)

计算 (x + y) % k 如果加法是以任意精度执行的,并且在 2**256 .断言 k != 0 从0.5.0版开始。

mulmod(uint x, uint y, uint k) returns (uint)

计算 (x * y) % k 其中乘法是以任意精度执行的,而不是在 2**256 .断言 k != 0 从0.5.0版开始。

keccak256(bytes memory) returns (bytes32)

计算输入的keccak-256哈希

注解

以前有个别名 keccak256 打电话 sha3 ,已在0.5.0版中删除。

sha256(bytes memory) returns (bytes32)

计算输入的sha-256哈希

ripemd160(bytes memory) returns (bytes20)

计算输入的ripemd-160哈希

ecrecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) returns (address)

从椭圆曲线签名中恢复与公钥关联的地址,或者在出错时返回零。函数参数对应签名的ECDSA值:

  • r =签名的前32个字节

  • s =第二个32字节的签名

  • v =签名的最后1个字节

ecrecover 返回一个 address ,而不是 address payable . 见 address payable 转换时,如果您需要将资金转移到恢复的地址。

有关更多详细信息,请阅读 example usage .

警告

如果你使用 ecrecover 请注意,有效签名可以转换为不同的有效签名,而不需要知道相应的私钥。在宅基地的硬叉子里,这个问题被解决了 _transaction_ 签名(参见 EIP-2 ,但ecrecover功能保持不变。

这通常不是问题,除非您要求签名是唯一的或使用它们来标识项目。OpenZeppelin有一个 ECDSA helper library 可以用作包装 ecrecover 没有这个问题。

注解

运行 sha256ripemd160ecrecover 在一 私有区块链 你可能会遇到没油的情况。这是因为这些函数是作为“预编译契约”实现的,并且只在它们收到第一条消息后才真正存在(尽管它们的契约代码是硬编码的)。发送给非现有合同的消息成本更高,因此执行过程中可能会遇到耗尽天然气的错误。解决这个问题的方法是,在实际合同中使用每个合同之前,首先将wei(例如1)发送给每个合同。这不是主网络或测试网络上的问题。

地址类型的成员

<address>.balance (uint256)

平衡 地址 在魏

<address>.code (bytes memory)

代码位于 地址 (可以为空)

<address>.codehash (bytes32)

的代码散列。 地址

<address payable>.transfer(uint256 amount)

将给定数量的wei发送到 地址 ,故障时恢复,向前2300气体津贴,不可调

<address payable>.send(uint256 amount) returns (bool)

将给定数量的wei发送到 地址 回报 false 故障时,向前2300气体津贴,不可调

<address>.call(bytes memory) returns (bool, bytes memory)

发布低级 CALL 对于给定的有效载荷,返回成功条件和返回数据,转发所有可用气体,可调

<address>.delegatecall(bytes memory) returns (bool, bytes memory)

发布低级 DELEGATECALL 对于给定的有效载荷,返回成功条件和返回数据,转发所有可用气体,可调

<address>.staticcall(bytes memory) returns (bool, bytes memory)

发布低级 STATICCALL 对于给定的有效载荷,返回成功条件和返回数据,转发所有可用气体,可调

有关详细信息,请参见 地址 .

警告

你应该避免使用 .call() 尽可能在执行另一个协定函数时,因为它会绕过类型检查、函数存在性检查和参数打包。

警告

使用中有一些危险 send :如果调用堆栈深度为1024,则传输失败(调用方始终可以强制执行此操作),如果收件人耗尽气体,则传输也会失败。因此,为了安全传输 Ether ,请始终检查 send 使用 transfer 或者更好:使用收款人取款的模式。

警告

由于EVM认为对不存在的约定的调用总是成功的,因此稳定性包括使用 extcodesize 执行外部呼叫时的操作码。这可以确保将要调用的协定要么实际存在(它包含代码),要么引发异常。

对地址而不是合同实例进行操作的低级调用(即 .call().delegatecall().staticcall().send().transfer() ) 请勿 包括这张支票,这会使他们的汽油更便宜,但也不太安全。

注解

在0.5.0版本之前,solidity允许合同实例访问地址成员,例如 this.balance .现在禁止这样做,必须进行到地址的显式转换: address(this).balance .

注解

如果状态变量是通过低级的delegatecall访问的,则两个契约的存储布局必须对齐,以便被调用的契约能够按名称正确访问调用契约的存储变量。当然,如果将存储指针作为函数参数传递,就像在高级库中那样,情况就不是这样了。

注解

在0.5.0版之前, .call.delegatecall.staticcall 只返回成功条件,不返回返回数据。

注解

在0.5.0版本之前,有一个成员 callcode 语义学与 delegatecall .

类型信息

表达式 type(X) 可用于检索有关类型的信息 X . 目前,对该功能的支持有限 (X 可以是协定或整数类型),但将来可能会对其进行扩展。

以下属性可用于合同类型 C

type(C).name

合同的名称。

type(C).creationCode

包含协定的创建字节码的内存字节数组。这可以在内联程序集中用于构建自定义创建例程,特别是通过使用 create2 操作码。此属性可以 not 在合同本身或任何派生合同中访问。它使字节码包含在调用站点的字节码中,因此不可能像这样循环引用。

type(C).runtimeCode

包含协定的运行时字节码的内存字节数组。这是通常由 C .如果 C 具有使用内联程序集的构造函数,这可能与实际部署的字节码不同。还请注意,库在部署时修改其运行时字节码,以防止常规调用。与 .creationCode 同时申请此属性。

除上述属性外,以下属性也可用于接口类型 I

type(I).interfaceId

A bytes4 包含 EIP-165 给定接口的接口标识符 I . 此标识符定义为 XOR 在接口本身定义的所有函数选择器中-不包括所有继承的函数。

以下属性可用于整数类型 T

type(T).min

按最小类型表示的值 T .

type(T).max

按类型表示的最大值 T .