solidity学习笔记(12)—— 单位和全局可变量

单位和全局可变量

Ether单元
一个字面上的数字可以带有wei,finney,szabo或者以太网的后缀,可以在以太网的子目录之间进行转换,其中没有后缀的以太网货币号被假定为魏。 2 ether == 2000 finney评估为true。

时间单位
可以使用文字数字后的秒,分,小时,天,周和年份进行后缀转换,其中以秒为单位,以下列方式将单位视为天真的时间单位:
1 == 1 seconds
1 minutes == 60 seconds
1 hours == 60 minutes
1 days == 24 hours
1 weeks == 7 days
1 years == 365 days
如果您使用这些单位执行日历计算,请小心,因为不是每年等于365天,甚至每天都没有24小时,因为闰秒。 由于无法预测闰秒的事实,必须由外部的oracle更新精确的日历库。

这些后缀不能应用于变量。 如果你想解释某些输入变量,例如。 天,你可以通过以下方式做到:

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

特殊变量和函数

有一些特殊的变量和函数总是存在于全局命名空间中,主要用于提供关于块链的信息。

块和事务属性

block.blockhash(uint blockNumber) returns (bytes32) 给定块的哈希 - 仅适用于256个不包括当前最新块
block.coinbase (address) 当前块矿工地址
block.difficulty (uint) 当前块难度
block.gaslimit (uint) 当前块gaslimit
block.number (uint) 当前数据块号
block.timestamp (uint) 当前块时间戳从unix纪元开始为秒
msg.data (bytes) 完整的calldata
msg.gas (uint) 剩余gas
msg.sender (address) 该消息(当前呼叫)的发送者
msg.sig (bytes4) 呼叫数据的前四个字节(即功能标识符)
msg.value (uint) 发送的消息的数量
now (uint) 当前块时间戳(block.timestamp的别名)
tx.gasprice (uint) gas价格的交易
tx.origin (address) 交易的发送者(全调用链)

msg的所有成员的值(包括msg.sender和msg.value)可以针对每个外部函数调用进行更改。 这包括对库函数的调用。
如果要使用msg.sender在库函数中实现访问限制,则必须手动提供msg.sender的值作为参数。

错误处理

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

数学和加密功能

addmod(uint x, uint y, uint k) returns (uint)
计算(x + y)%k,其中以任意精度执行加法,并且不在2 ** 256处围绕
mulmod(uint x, uint y, uint k) returns (uint)
计算(x * y)%k,其中乘法以任意精度执行,并且不会在2 ** 256处循环。
keccak256(...) returns (bytes32)
计算的(紧凑)参数的Ethereum-SHA-3(Keccak-256)的散列
sha256(...) returns (bytes32)
计算(紧密包装)参数的SHA-256散列
sha3(...) returns (bytes32)
keccak256的别名
ripemd160(...) returns (bytes20)
计算(紧密包装)参数的RIPEMD-160哈希值
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("\x00\x12") 与keccak256(uint16(0x12))相同。

请注意,常量将使用存储它们所需的最少字节数来打包。 这意味着,例如keccak256(0) == keccak256(uint8(0))和keccak256(0x12345678) == keccak256(uint32(0x12345678))

扫描二维码关注公众号,回复: 3667733 查看本文章

这可能是你在一个私人的块上遇到了sha256,ripemd160或ecrecover的Out-of-Gas。 这样做的原因是那些被实现为所谓的预编译合同,这些合同在收到第一条消息之后才真正存在(尽管他们的合同代码是硬编码的)。 对非现有合约的消息更昂贵,因此执行将会进入“Out-of-Gas”错误。 这个问题的解决方法是首先发送例如 在您将实际合同中使用这些合约之前,每个合约1 Wei。 官网或测试网不是问题。

地址相关

<address>.balance (uint256)
平衡地址在Wei
<address>.transfer(uint256 amount)
发送一定量wei向地址,抛出失败
<address>.send(uint256 amount) returns (bool)
发送一定量wei向地址,失败时返回false
<address>.call(...) returns (bool)
发出低级CALL,失败返回false
<address>.callcode(...) returns (bool)
发出低级CALLCODE,失败时返回false
<address>.delegatecall(...) returns (bool)
发出低级DELEGATECALL,失败返回false

有关详细信息,请参阅地址部分。

使用send有一些危险:如果调用堆栈深度为1024(这可以始终被呼叫者强制),则传输失败,如果接收方耗尽gas,则传输失败。 所以为了使安全的以太网传输,始终检查发送的返回值,使用转移甚至更好:使用接收方提取钱的模式。

不鼓励使用callcode,将来会被删除。

合约相关

this
当前合约,明确转换为地址
selfdestruct(address recipient)
摧毁目前的合同,将资金送到给定的地址
suicide(address recipient)
selfdestruct的别名
此外,当前合约的所有功能都可以直接调用,包括当前的功能。

猜你喜欢

转载自blog.csdn.net/lj900911/article/details/83038035