【Solidity智能合约系列】08--Solidity API

前言

这一节主要会介绍一些Solidity API,也就是一些特殊的变量及函数。

特殊的变量和函数(Special Variables and Functions)

Solidity的API中内置了一些特殊的变量及函数,他们存在于全局命名空间(namespace)里,主要用于提供区块链(blockchain)相关的信息,或者是一些通用的函数。大概分为如下几类:

1、有关区块和交易的属性
2、有关错误处理
3、有关数学及加密功能
4、地址相关
5、合约相关

区块和交易属性(Block And Transaction Properties)

  • block.blockhash(uint blockNumber) returns (bytes32):返回给定区块号的哈希值,只支持最近256个区块,且不包含当前区块。

  • block.coinbase (address):当前区块的矿工地址

  • block.difficulty (uint): 当前区块的难度值

  • block.gaslimit (uint): 当前区块的gaslimit

  • block.number (uint): 当前区块的块号

  • block.timestamp (uint): 当前块的Unix时间戳(从1970/1/1 00:00:00 UTC开始所经过的秒数)

  • gasleft() returns (uint256):剩余的gas

  • msg.data (bytes):完整的调用数据calldata

  • msg.gas (uint):剩余的gas,在0.4.21版本中已经弃用,并有gasleft()代替

  • msg.sender (address):当前调用发起人的地址

  • msg.sig (bytes4):调用数据(calldata)的前四个字节(例如为:函数标识符)

  • msg.value (uint):发送这个消息所附带的以太币的数量,单位是wei

  • now (uint):当前块的时间戳(block.timestamp的别名)

  • tx.gasprice (uint):交易的gas价格

  • tx.origin (address):交易发送者的地址(full call chain)

注意以下几点:

1、msg的所有成员值,包括 msg.sendermsg.value都可以因为每一次 external 函数(或library库函数)的调用被改变。

2、不应该依据 block.timestamp(时间戳), nowblock.blockhash(区块哈希)来产生一个随机数,除非你确实需要这样做。
block.timestamp(时间戳)block.blockhash(区块哈希)在一定程度上会受矿工的影响。比如在赌博合约里,不诚实的矿工可能会尝试去选择一个对自己有利的hash。

3、对于同一个链上连续的区块来说,当前区块的时间戳(timestamp)必然是大于上一个区块的时间戳。

4、由于可扩展性的原因,你只能查到最近的256个区块的hash值,所有其它的将返回0.

ABI编码函数(ABI Encoding Functions)

  • abi.encode(...) returns (bytes):

  • abi.encodePacked(...) returns (bytes):

  • abi.encodeWithSelector(bytes4 selector, ...) returns (bytes):

  • abi.encodeWithSignature(string signature, ...) returns (bytes):

注意:
这些编码函数可以在不实际调用函数的情况下,为函数调用创建数据。此外,keccak256(abi.encodePacked(a, b))是计算keccak256(a, b)更明确的方式,keccak256(a, b)在以后的版本中会被废弃。

关于编码的信息,大家可以参考ABI
tightly packed encoding的文档

错误处理(Error Handling)

assert(bool condition)
用于判断内部错误,如果条件不满足时,会使事物无效(抛出异常)
require(bool condition)
用于判断输入或外部组件错误,如果条件不满足时,会回滚
require(bool condition, string message)
用于判断输入或外部组件错误,如果条件不满足时,会回滚。同时会显示错误信息
revert():
终止执行并恢复改变的状态
revert(string reason)
终止执行并恢复改变的状态,并且会提供一个解释的信息

数学及加密函数(Mathematical and Cryptographic Functions)

addmod(uint x, uint y, uint k) returns (uint):
计算(x + y) % k,加法支持任意的精度且不会在2**256(2的256次方)处溢出,从0.5.0版本开始插入 assert(k != 0)

mulmod(uint x, uint y, uint k) returns (uint):
计算 (x * y) % k, 乘法支持任意的精度且不会在2*256处溢出, 从0.5.0版本开始插入 assert(k != 0)

keccak256(…) returns (bytes32):
计算 (tightly packed) argumentsEthereum-SHA-3 (Keccak-256) hash值

sha256(…) returns (bytes32):
使用SHA-256计算tightly packed) arguments
的hash值

sha3(…) returns (bytes32):
keccak256的别名

ripemd160(…) returns (bytes20):
使用RIPEMD-160计算(tightly packed) arguments
的HASH值

ecrecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) returns (address):
通过椭圆曲线签名来恢复与公钥关的地址,或者在错误时返回0(参考示例
)。
可用于签名数据的校验,如果返回结果是签名者的公匙地址,那么说明数据是正确的。

ecrecover函数需要四个参数,需要被签名数据的哈希结果值,r,s,v分别来自签名结果串。
r = signature[0:64]
s = signature[64:128]
v = signature[128:130]
其中v取出来的值或者是00或01。要使用时,我们先要将其转为整型,再加上27,所以我们将得到27或28。在调用函数时v将填入27或28。

在上面,“tightly packed”意思是说参数不会补位,是直接连接在一起的,下面几个是相等的。

keccak256("ab", "c")
keccak256("abc")

keccak256(0x616263)  // hex16进制数
keccak256(6382179)
keccak256(97, 98, 99)   //ascii码,97代表a

如果需要填充,可以使用显式类型转换:keccak256(“\x00\x12”) 与keccak256(uint16(0x12))相同。

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

在私有链(private blockchain)上运行sha256,ripemd160ecrecover可能会出现Out-Of-Gas错误。因为私链实现了一种预编译合约,合约要在收到第一个消息后才会真正存在(即使它们的合约代码是硬编码的)。向一个不存在的合约发送消息时非常昂贵的,并且会导致Out-Of-Gas的问题。一种解决办法是在你真正使用这些合约之前,给每个合约地址发送1 wei。在官方和测试链上没有这个问题。

地址相关(Address Related)

<address>.balance (uint256):
指定以太坊地址的余额,单位是wei

<address>.transfer(uint256 amount):
发送给定数量的ether到某个地址,以wei为单位。失败时抛出异常,还会转发2300 gas,这是不可调节的。

<address>.send(uint256 amount) returns (bool):
发送给定数量的ether到某个地址,以wei为单位, 失败时返回false,还会转发2300 gas,这是不可调节的。

<address>.call(...) returns (bool):
发起底层的call调用,失败时返回false,会花费掉所有可用的gas,可以调节

<address>.callcode(...) returns (bool):
发起底层的callcode调用,失败时返回false,会花费掉所有可用的gas,可以调节。不鼓励使用,未来可能会移除

<address>.delegatecall(...) returns (bool):
发起底层的delegatecall调用,失败时返回false,会花费掉所有可用的gas,可以调节

更多的信息,参考Address.

警告:
使用send()会有一些危险:如果调用栈的深度超过1024或接收方耗光了gas,交易都会失败。所以,为了确保Ether交易安全,必须检查send的返回值,如果交易失败,会回退以太币。使用transfer或许是更好的选择。

合约相关(Contract Related)

this (current contract’s type):
表示当前合约,可以显式的转换为Address

selfdestruct(address recipient):
销毁当前合约,并把所有资金发送到指定的地址。

suicide(address recipient):
selfdestruct的别名(废弃)

此外,当前合约里的所有函数均可支持调用,包括当前函数本身。

参考:
https://solidity.readthedocs.io/en/develop/units-and-global-variables.html#units-and-globally-available-variables

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 200,527评论 5 470
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,314评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 147,535评论 0 332
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,006评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,961评论 5 360
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,220评论 1 277
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,664评论 3 392
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,351评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,481评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,397评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,443评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,123评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,713评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,801评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,010评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,494评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,075评论 2 341

推荐阅读更多精彩内容