智能合约语言 Solidity 教程系列8 - Solidity API
最新内容会更新在主站深入浅出区块链社区
原文链接:智能合约语言 Solidity 教程系列8 - Solidity API
这是Solidity教程系列文章第8篇介绍Solidity API,它们主要表现为内置的特殊的变量及函数,存在于全局命名空间里。
写在前面
Solidity 是以太坊智能合约编程语言,阅读本文前,你应该对以太坊、智能合约有所了解,
如果你还不了解,建议你先看以太坊是什么
欢迎订阅区块链技术专栏阅读更全面的分析文章。
Solidity API 主要表现为Solidity 内置的特殊的变量及函数,他们存在于全局命名空间里,主要分为以下几类:
- 有关区块和交易的属性
- 有关错误处理
- 有关数学及加密功能
- 地址相关
- 合约相关
下面详细讲解下
区块和交易的属性(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开始所经过的秒数)
- 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): 交易的发送者(全调用链)
注意:
msg的所有成员值,如msg.sender,msg.value的值可以因为每一次外部函数调用,或库函数调用发生变化(因为msg就是和调用相关的全局变量)。
不应该依据 block.timestamp, now 和 block.blockhash来产生一个随机数(除非你确实需要这样做),这几个值在一定程度上被矿工影响(比如在赌博合约里,不诚实的矿工可能会重试去选择一个对自己有利的hash)。
对于同一个链上连续的区块来说,当前区块的时间戳(timestamp)总是会大于上一个区块的时间戳。
为了可扩展性的原因,你只能查最近256个块,所有其它的将返回0.
错误处理
- assert(bool condition)
用于判断内部错误,条件不满足时抛出异常 - require(bool condition):
用于判断输入或外部组件错误,条件不满足时抛出异常 - revert():
终止执行并还原改变的状态
数学及加密功能
- 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):
使用以太坊的(Keccak-256)计算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):
通过椭圆曲线签名来恢复与公钥关联的地址,或者在错误时返回零。可用于签名数据的校验,如果返回结果是签名者的公匙地址,那么说明数据是正确的。
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。
用javascript表达如下:
var msg = '0x8CbaC5e4d803bE2A3A5cd3DbE7174504c6DD0c1C'
var hash = web3.sha3(msg)
var sig = web3.eth.sign(address, h).slice(2)
var r = `0x${sig.slice(0, 64)}`
var s = `0x${sig.slice(64, 128)}`
var v = web3.toDecimal(sig.slice(128, 130)) + 27
订阅区块链技术专栏可以参考到完整的使用例子。
紧密打包参数(tightly packed)意思是说参数不会补位,是直接连接在一起的,下面几个是相等的。
keccak256("ab", "c")
keccak256("abc")
keccak256(0x616263) // hex
keccak256(6382179)
keccak256(97, 98, 99) //ascii
如果需要填充,可以使用显式类型转换:keccak256("\x00\x12") 与keccak256(uint16(0x12))相同。
注意,常量将使用存储它们所需的最少字节数来打包,例如keccak256(0) == keccak256(uint8(0))和keccak256(0x12345678) == keccak256(uint32(0x12345678))
在私链(private blockchain)上运行sha256,ripemd160或ecrecover可能会出现Out-Of-Gas报错。因为私链实现了一种预编译合约,合约要在收到第一个消息后才会真正存在(虽然他们的合约代码是硬编码的)。而向一个不存在的合约发送消息,所以才会导致Out-Of-Gas的问题。一种解决办法(workaround)是每个在你真正使用它们之前先发送1 wei到这些合约上来完成初始化。在官方和测试链上没有这个问题。
地址相关
- .balance (uint256):
Address的余额,以wei为单位。
- .transfer(uint256 amount):
发送给定数量的ether到某个地址,以wei为单位。失败时抛出异常。
- .send(uint256 amount) returns (bool):
发送给定数量的ether到某个地址,以wei为单位, 失败时返回false。
- .call(...) returns (bool):
发起底层的call调用。失败时返回false。
- .callcode(...) returns (bool):
发起底层的callcode调用,失败时返回false。
不鼓励使用,未来可能会移除。
- .delegatecall(...) returns (bool):
发起底层的delegatecall调用,失败时返回false
更多信息参考地址篇。
警告:send() 执行有一些风险:如果调用栈的深度超过1024或gas耗光,交易都会失败。因此,为了保证安全,必须检查send的返回值,如果交易失败,会回退以太币。如果用transfer会更好。
合约相关
- this(当前合约的类型):
表示当前合约,可以显式的转换为Address - selfdestruct(address recipient):
销毁当前合约,并把它所有资金发送到给定的地址。 - suicide(address recipient):
selfdestruct的别名
另外,当前合约里的所有函数均可支持调用,包括当前函数本身。
参考视频
我们也推出了目前市面上最全的视频教程:深入详解以太坊智能合约语言Solidity
目前我们也在招募体验师,可以点击链接了解。
参考文档
深入浅出区块链 - 系统学习区块链,打造最好的区块链技术博客。
如果想与我有更密切的交流可以选择加入我的知识星球(星球成员可加入微信技术交流群)
智能合约语言 Solidity 教程系列8 - Solidity API的更多相关文章
- 智能合约语言Solidity教程系列2 - 地址类型介绍
智能合约语言Solidity教程系列第二篇 - Solidity地址类型介绍. 写在前面 Solidity是以太坊智能合约编程语言,阅读本文前,你应该对以太坊.智能合约有所了解,如果你还不了解,建议你 ...
- 智能合约语言 Solidity 教程系列3 - 函数类型
Solidity 教程系列第三篇 - Solidity 函数类型介绍. 写在前面 Solidity 是以太坊智能合约编程语言,阅读本文前,你应该对以太坊.智能合约有所了解,如果你还不了解,建议你先看以 ...
- 智能合约语言 Solidity 教程系列4 - 数据存储位置分析
写在前面 Solidity 是以太坊智能合约编程语言,阅读本文前,你应该对以太坊.智能合约有所了解, 如果你还不了解,建议你先看以太坊是什么 这部分的内容官方英文文档讲的不是很透,因此我在参考Soli ...
- 智能合约语言 Solidity 教程系列6 - 结构体与映射
写在前面 Solidity 是以太坊智能合约编程语言,阅读本文前,你应该对以太坊.智能合约有所了解, 如果你还不了解,建议你先看以太坊是什么 本系列文章一部分是参考Solidity官方文档(当前最新版 ...
- 智能合约语言 Solidity 教程系列5 - 数组介绍
写在前面 Solidity 是以太坊智能合约编程语言,阅读本文前,你应该对以太坊.智能合约有所了解, 如果你还不了解,建议你先看以太坊是什么 本文前半部分是参考Solidity官方文档(当前最新版本: ...
- 智能合约语言 Solidity 教程系列7 - 以太单位及时间单位
这是Solidity教程系列文章第7篇介绍以太单位及时间单位,系列带你全面深入理解Solidity语言. 写在前面 Solidity 是以太坊智能合约编程语言,阅读本文前,你应该对以太坊.智能合约有所 ...
- 智能合约语言 Solidity 教程系列9 - 错误处理
这是Solidity教程系列文章第9篇介绍Solidity 错误处理. Solidity系列完整的文章列表请查看分类-Solidity. 写在前面 Solidity 是以太坊智能合约编程语言,阅读本文 ...
- 智能合约语言 Solidity 教程系列10 - 完全理解函数修改器
这是Solidity教程系列文章第10篇,带大家完全理解Solidity的函数修改器. Solidity系列完整的文章列表请查看分类-Solidity. 写在前面 Solidity 是以太坊智能合约编 ...
- 智能合约语言 Solidity 教程系列2 - 地址类型介绍
Solidity教程系列第二篇 - Solidity地址类型介绍. 写在前面 Solidity是以太坊智能合约编程语言,阅读本文前,你应该对以太坊.智能合约有所了解,如果你还不了解,建议你先看以太坊是 ...
随机推荐
- return的新思考
<!DOCTYPE html><html lang="en"> <head> <meta charset="UTF-8" ...
- Windows下使用Sublime text3快速编辑Linux文件,写Shell
所需要配合的工具是WinSCP 添加完毕之后直接在目录下双击要编辑的shell脚本文件,即可弹出Sublime Text的编辑器 然后咱通过Putty看看Linux虚拟机上的文件有没有发生变化
- (MonoGame从入门到放弃-2) 初识MonoGame
上一节记录了大致的搭建MonoGame的环境,默认大家都是都是使用过Visual Studio的,没使用过的话,可以去https://www.visualstudio.com/下载一个试试,社区版免费 ...
- 剑指offer第五天
28.数组中出现次数超过一半的数字 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字.例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}.由于数字2在数组中出现了5次,超过数 ...
- UVA-12166 天平性质+字符处理
这题思维难度很大,关键是总结这个性质. 1.天平性质:某个秤砣重量为w,高度为h,如果要让这个天平平衡并且以这个秤砣为基准,那么整个天平的总重量为w*(2^h) 2.利用这个性质:题目要求秤砣数量改变 ...
- 一步一步带你实现virtual dom(一)
一步一步带你实现virtual dom(一) 一步一步带你实现virtual dom(二)--Props和事件 要写你自己的虚拟DOM,有两件事你必须知道.你甚至都不用翻看React的源代码,或者其他 ...
- 生活常用类API调用的代码示例合集:邮编查询、今日热门新闻查询、区号查询等
以下示例代码适用于 www.apishop.net 网站下的API,使用本文提及的接口调用代码示例前,您需要先申请相应的API服务. 邮编查询:通过邮编查询地名:通过地名查询邮编 今日热门新闻查询:提 ...
- Frequent Pattern (FP Growth算法)
FP树构造 FP Growth算法利用了巧妙的数据结构,大大降低了Aproir挖掘算法的代价,他不需要不断得生成候选项目队列和不断得扫描整个数据库进行比对.为了达 到这样的效果,它采用了一种简洁的数据 ...
- mysql命令汇总
1.mysql新增.删除用户和权限分配 查看用户及权限 mysql>use mysql mysql>select * from user\G; 新增用户 mysql>insert i ...
- Linux分区和挂载(mount命令的学习)
当Windows系统出现问题的时候,可能需要重装系统,这个时候我们往往会使用系统盘将系统重新安装在C盘上,其他盘上的文件都没有受到重装系统的影 响,这就是分区的好处之一.同样,在Linux中也需要分区 ...