Solidity 全局变量与函数

发布于 2024-08-31 12:06:47 字数 6035 浏览 7 评论 0

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

区块与交易相关

block

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

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

提示:

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

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

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

提示:

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

msg

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

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

提示:

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

tx

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

名称类型 / 函数签名说明
tx.gaspriceuint当前交易中的 gas 的价格
tx.originaddress当前交易发送者的地址(位于完整调用链的最顶层)

错误处理

本书有专门的章节讲解 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)) 相等。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

娇女薄笑

暂无简介

0 文章
0 评论
23 人气
更多

推荐作者

新人笑

文章 0 评论 0

mb_vYjKhcd3

文章 0 评论 0

小高

文章 0 评论 0

来日方长

文章 0 评论 0

哄哄

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文