04-Solidity8.0以太单位Gas和全局变量

Solidity8.0

04-Solidity8.0以太单位Gas和全局变量


在这里插入图片描述


前言

以太和Wei
交易ether.
类似于1美元等于 100 美分,1ether等于 10**18 wei。

Gas

ether您需要为交易支付多少费用?
您支付gas spent * gas price的金额ether,在哪里

gas是一个计算单位
gas spentgas是交易中使用的总金额
gas priceether是你愿意支付多少gas
具有较高gas价格的交易具有更高的优先级被包含在一个块中。
未用完的gas将被退还。

气体限制

您可以花费的汽油量有 2 个上限
gas limit(您愿意为交易使用的最大天然气量,由您设置)
block gas limit(区块中允许的最大气体量,由网络设置)

msg注解

msg的所有成员的值,包括msg.sender和msg.value可以在每个external函数调用中改变。这包括调用库函数。 如果你想在库函数实现访问限制使用msg.sender, 你必须手动设置msg.sender作为参数。

随机源注解

不要依赖block.timestamp,now和block.blockhash作为随机源
时间戳timestamp和区块哈希blockhash在一定程度上会受到矿工的影响。
例如,矿区中的坏节点可以对选定的哈希运行casino payout函数,如果他们没有收到任何钱,只需重试不同的哈希。
当前块时间戳必须严格大于最后一个块的时间戳,但唯一的保证是它将位于规范链中两个连续块的时间戳之间的某处。 由于区块链是增长可变的,所以不能获取整个区块链的哈希值。 您只能访问最近256个区块的哈希值,其他所有值都将为0。

错误处理(Error Handling)

assert(bool condition):如果条件不满足则抛出异常 - 用于内部错误。
require(bool condition):如果条件不满足则抛出异常 - 用于输入或外部组件中的错误。
revert():中止执行并恢复状态更改

数学和加密功能(Mathematical and Cryptographic Functions)

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):
从椭圆曲线签名中恢复与公钥相关的地址,或在错误时返回零
在上述中,“紧凑排列”,意思是没有填充的参数的连续排列,也就是下面表达式是没有区别的:

keccak256(“ab”, “c”)
keccak256(“abc”)
keccak256(0x616263)
keccak256(6382179)
keccak256(97, 98, 99)

如果需要填充,可以使用显式类型转换:keccak256(0) == keccak256(uint8(0)),keccak256(0x12345678) == keccak256(uint32(0x12345678))
在一个私有的blockchain里,你可能在使用sha256, ripemd160 或 ecrecover 的时候碰到”Out-of-Gas”的问题 。原因在于这个仅仅是预编译的合约,合约要在他们接到的第一个消息以后才真正的生成(虽然他们的合约代码是硬编码的)。对于没有真正生成的合约的消息是非常昂贵的,这时就会碰到“Out-of-Gas”的问题。 这一问题的解决方法是事先把1wei 发送到各个你当前使用的各个合约上。这不是官方或测试网的问题。

地址相关(Address Related)

.balance (uint256): 该地址的余额,单位是Wei
.transfer(uint256 amount): 给该地址发送金额,单位是Wei,发送失败抛出异常,消耗2300 gas 费用,不可调整
.send(uint256 amount) returns (bool): 给该地址发送金额,单位是Wei,发送失败返回false,消耗2300 gas 费用,不可调整
.call(...) returns (bool): 发出 low-level CALL, 失败时返回false , 消耗所有可用gas, 可调整
.callcode(...) returns (bool): 发出 low-level CALLCODE, 失败时返回false , 消耗所有可用gas, 可调整
.delegatecall(...) returns (bool): 发出 low-level DELEGATECALL, 失败时返回false , 消耗所有可用gas, 可调整 欲了解更多资料,请参阅地址Address部分。

警告

使用send存在一些危险:如果调用堆栈深度为1024,则转账将失败(调用程序始终强制执行此操作),并且如果接受者的gas耗尽,也会失败。
因此,为了让以太币转账更安全,请务必检查send的返回值,或者直接使用transfer那就更好了。

注解

callcode不建议使用,未来将会移除

合约相关(Contract Related)

this (current contract’s type):
当前的合约,可显式转换为地址Address
selfdestruct(address):
销毁当前合约,其资金发送给指定的地址
suicide(address recipient):
selfdestruct的别名
此外,当前合同的所有函数均可以被直接调用,包括当前函数。


一、Solidity8.0以太单位Gas和全局变量

1.以太单位Gas和全局变量

代码如下(示例):

// SPDX-License-Identifier: MIT
pragma solidity ^0.8;

contract EtherUnits {
    uint public oneWei = 1 wei;
    bool public isOneWei = 1 wei == 1;

    uint public oneEther = 1 ether;
    bool public isOneEther = 1 ether == 1e18;
    // bool public isOneEther1 = 1 ether == 10^3 finney;
    // bool public isOneEther2 = 1 ether == 10^6 szabo;
    bool public isOneEther3 = 1 ether == 1e9 gwei;
    // bool public isOneEther4 = 1 ether == 1e12 mwei;
    // bool public isOneEther5 = 1 ether == 1e15 kwei;

    bool public time = 1 == 1 seconds;
    bool public time1 = 1 minutes == 60 seconds;
    bool public time2 = 1 hours == 60 minutes;
    bool public time3 = 1 days == 24 hours;
    bool public time4 = 1 weeks == 7 days;
    // bool public time5 = 1 years == 365 days;

    // 区块和交易属性(Block and Transaction Properties)
    // block.blockhash(uint blockNumber) returns (bytes32): 给定区块的哈希值 - 仅适用于最新的256个区块,不包括当前区块
    // block.coinbase (address):当前区块的矿工的地址
    // block.difficulty (uint):当前区块的难度系数
    // block.gaslimit (uint):当前区块gas限制
    // block.number (uint):当前区块编号
    // block.timestamp (uint):当前块的时间戳
    // msg.data (bytes):完整的calldata
    // msg.gas (uint):剩余的gas
    // msg.sender (address):消息的发送方(当前调用)
    // msg.sig (bytes4):calldata的前四个字节(即函数标识符)
    // msg.value (uint):所发送的消息中wei的数量
    // now (uint):当前块时间戳(block.timestamp的别名)
    // tx.gasprice (uint):交易的gas价格
    // tx.origin (address):交易发送方(完整的调用链)
}

总结

日拱一卒。