智能合约语言 Solidity 教程系列2 - 地址类型介绍
Solidity教程系列第二篇 - Solidity地址类型介绍.
写在前面
Solidity是以太坊智能合约编程语言,阅读本文前,你应该对以太坊、智能合约有所了解,如果你还不了解,建议你先看以太坊是什么
本文前半部分是参考Solidity官方文档(当前最新版本:0.4.20)进行翻译,后半部分是结合实际合约代码实例说明类型的使用(仅针对专栏订阅用户)。
地址类型(Address)
地址类型address是一个值类型,
地址: 20字节(一个以太坊地址的长度),地址类型也有成员,地址是所有合约的基础
支持的运算符:
- <=, <, ==, !=, >= 和 >
注意:从0.5.0开始,合约不再继承自地址类型,但仍然可以显式转换为地址。
地址类型的成员
balance 属性及transfer() 函数
这里是地址类型相关成员的快速索引
balance用来查询账户余额,transfer()用来发送以太币(以wei为单位)。
如:1
2
3address x = 0x123;
address myAddress = this;
if (x.balance < 10 && myAddress.balance >= 10) x.transfer(10);注解:如果x是合约地址,合约的回退函数(fallback 函数)会随transfer调用一起执行(这个是EVM特性),如果因gas耗光或其他原因失败,转移交易会还原并且合约会抛异常停止。
关于回退函数(fallback 函数),简单来说它是合约中无函数名函数,下面代码事例中,进进一步讲解回退函数(fallback) 的使用。
send() 函数
send 与transfer对应,但更底层。如果执行失败,transfer不会因异常停止,而send会返回false。警告:send() 执行有一些风险:如果调用栈的深度超过1024或gas耗光,交易都会失败。因此,为了保证安全,必须检查send的返回值,如果交易失败,会回退以太币。如果用transfer会更好。
call(), callcode() 和 delegatecall() 函数
为了和非ABI协议的合约进行交互,可以使用call() 函数, 它用来向另一个合约发送原始数据,支持任何类型任意数量的参数,每个参数会按规则(ABI协议)打包成32字节并一一拼接到一起。一个例外是:如果第一个参数恰好4个字节,在这种情况下,会被认为根据ABI协议定义的函数器指定的函数签名而直接使用。如果仅想发送消息体,需要避免第一个参数是4个字节。如下面的例子:1
2
3address nameReg = 0x72ba7d8e73fe8eb666ea66babc8116a41bfb10e2;
nameReg.call("register", "MyName");
nameReg.call(bytes4(keccak256("fun(uint256)")), a);call函数返回一个bool值,以表明执行成功与否。正常结束返回true,异常终止返回false。但无法获取到结果数据,因为需要提前知道返回的数据的编码和数据大小(因不知道对方使用的协议格式,所以也不会知道返回的结果如何解析)。
还可以提供.gas()修饰器进行调用:1
namReg.call.gas(1000000)("register", "MyName");类似还可以提供附带以太币:
1
nameReg.call.value(1 ether)("register", "MyName");修饰器可以混合使用,修饰器调用顺序无所谓。
1
nameReg.call.gas(1000000).value(1 ether)("register", "MyName");注解:目前还不能在重载函数上使用gas或value修饰符,A workaround is to introduce a special case for gas and value and just re-check whether they are present at the point of overload resolution.(这句我怕翻译的不准确,引用原文)
同样我们也可以使用delegatecall(),它与call方法的区别在于,仅仅是代码会执行,而其它方面,如(存储,余额等)都是用的当前的合约的数据。delegatecall()方法的目的是用来执行另一个合约中的库代码。所以开发者需要保证两个合约中的存储变量能兼容,来保证delegatecall()能顺利执行。在homestead阶段之前,仅有一个受限的callcode()方法可用,但callcode未提供对msg.sender,msg.value的访问权限。
上面的这三个方法call(),delegatecall(),callcode()都是底层的消息传递调用,最好仅在万不得已才进行使用,因为他们破坏了Solidity的类型安全。
.gas() 在call(), callcode() 和 delegatecall() 函数下都可以使用, delegatecall()不支持.value()注解:所有合约都继承了address的成员,因此可以使用this.balance查询余额。
callcode不鼓励使用,以后会移除。警告:上述的函数都是底层的函数,使用时要异常小心。当调用一个未知的,可能是恶意的合约时,当你把控制权交给它,它可能回调回你的合约,所以要准备好在调用返回时,应对你的状态变量可能被恶意篡改的情况。
地址常量(Address Literals)
一个能通过地址合法性检查(address checksum test)十六进制常量就会被认为是地址,如0xdCad3a6d3569DF655070DEd06cb7A1b2Ccd1D3AF。而不能通过地址合法性检查的39到41位长的十六进制常量,会提示一个警告,被视为普通的有理数常量。
地址合法性检查定义在EIP-55
合约事例讲解
合约事例代码
1 |
pragma solidity ^0.4.0; |
代码运行及讲解
代码运行及讲解,请订阅区块链技术查看。
参考文档
圆方圆区块链汇集大批区块链名师,采取导师值班制,为学员实时解决技术疑难。请关注圆方圆区块链知识星球与导师。(培训咨询请联系船长13826054890微信手机同号)

作者Tiny熊
,专注于 区块链底层技术研究,更多Tiny熊老师的文章和视频请关注圆方圆链圈公众号。

智能合约语言 Solidity 教程系列2 - 地址类型介绍的更多相关文章
- 智能合约语言Solidity教程系列2 - 地址类型介绍
智能合约语言Solidity教程系列第二篇 - Solidity地址类型介绍. 写在前面 Solidity是以太坊智能合约编程语言,阅读本文前,你应该对以太坊.智能合约有所了解,如果你还不了解,建议你 ...
- 智能合约语言 Solidity 教程系列3 - 函数类型
Solidity 教程系列第三篇 - Solidity 函数类型介绍. 写在前面 Solidity 是以太坊智能合约编程语言,阅读本文前,你应该对以太坊.智能合约有所了解,如果你还不了解,建议你先看以 ...
- 智能合约语言 Solidity 教程系列8 - Solidity API
这是Solidity教程系列文章第8篇介绍Solidity API,它们主要表现为内置的特殊的变量及函数,存在于全局命名空间里. 写在前面 Solidity 是以太坊智能合约编程语言,阅读本文前,你应 ...
- 智能合约语言 Solidity 教程系列9 - 错误处理
这是Solidity教程系列文章第9篇介绍Solidity 错误处理. Solidity系列完整的文章列表请查看分类-Solidity. 写在前面 Solidity 是以太坊智能合约编程语言,阅读本文 ...
- 智能合约语言 Solidity 教程系列4 - 数据存储位置分析
写在前面 Solidity 是以太坊智能合约编程语言,阅读本文前,你应该对以太坊.智能合约有所了解, 如果你还不了解,建议你先看以太坊是什么 这部分的内容官方英文文档讲的不是很透,因此我在参考Soli ...
- 智能合约语言 Solidity 教程系列6 - 结构体与映射
写在前面 Solidity 是以太坊智能合约编程语言,阅读本文前,你应该对以太坊.智能合约有所了解, 如果你还不了解,建议你先看以太坊是什么 本系列文章一部分是参考Solidity官方文档(当前最新版 ...
- 智能合约语言 Solidity 教程系列5 - 数组介绍
写在前面 Solidity 是以太坊智能合约编程语言,阅读本文前,你应该对以太坊.智能合约有所了解, 如果你还不了解,建议你先看以太坊是什么 本文前半部分是参考Solidity官方文档(当前最新版本: ...
- 智能合约语言 Solidity 教程系列10 - 完全理解函数修改器
这是Solidity教程系列文章第10篇,带大家完全理解Solidity的函数修改器. Solidity系列完整的文章列表请查看分类-Solidity. 写在前面 Solidity 是以太坊智能合约编 ...
- 智能合约语言 Solidity 教程系列7 - 以太单位及时间单位
这是Solidity教程系列文章第7篇介绍以太单位及时间单位,系列带你全面深入理解Solidity语言. 写在前面 Solidity 是以太坊智能合约编程语言,阅读本文前,你应该对以太坊.智能合约有所 ...
随机推荐
- nyoj222 整数中的1 数位DP
从a枚举到b是一定会超时的.此题应该考虑数位dp,也可以理解为递推,假设给定数n,就能在O(32)复杂度算出所有小于等于n的数中1出现的次数,那么给定区间[a, b],solve(b) - solve ...
- 使用C#解决部分Win8.1系统窗口每隔几秒失去焦点的问题【转】
使用了Win8.1 With Update 1后,发现重启系统后,当前激活的窗口总是每隔几秒失去焦点,过0.5~1秒焦点回来,导致输入无法正常工作,严重影响使用心情和效率. 在网上找了很久,也没找到相 ...
- 老司机教你在windows不用软件隐藏重要文件
每个人电脑里面都有些秘密,但是别人需要使用你的电脑时,有可能会看到,但是我们又不想让别人发现时,我们可以将其隐藏,那么别人就不会看到了.360文件保险柜.腾讯电脑管家等等.使用软件繁琐软件过大还会拖慢 ...
- 我的Java设计模式-原型模式
"不好意思,我是卧底!哇哈哈哈~"额......自从写了上一篇的观察者模式,就一直沉浸在这个角色当中,无法自拨.昨晚在看<使徒行者2>,有一集说到啊炮仗哥印钞票,我去, ...
- R︱高效数据操作——data.table包(实战心得、dplyr对比、key灵活用法、数据合并)
每每以为攀得众山小,可.每每又切实来到起点,大牛们,缓缓脚步来俺笔记葩分享一下吧,please~ --------------------------- 由于业务中接触的数据量很大,于是不得不转战开始 ...
- spring-java项目中连接redis数据库
最近由于项目需要,要从redis数据库中查询一些数据,还没有了解过redis,只好硬着头皮上阵,记录一下连接过程: 1.需要导入两个jar包:jedis.jar,spring-data-redis.j ...
- R语言︱ 数据库SQL-R连接与SQL语句执行(RODBC、sqldf包)
要学的东西太多,无笔记不能学~~ 欢迎关注公众号,一起分享学习笔记,记录每一颗"贝壳"~ --------------------------- 数据库是极其重要的R语言数据导入源 ...
- javax.servlet.JspTagException:Illegal use of <when>-style tag without <choose >as its di
1.错误描述 javax.servlet.JspTagException:Illegal use of <when>-style tag without <choose >as ...
- java访问权限修饰符
作用域 当前类 同一package 子孙类 其他package public √ √ √ √ protected √ √ √ × friendly √ √ × × private √ × × × ja ...
- iOS - Mac 常用设置
1.Finder 中显示资源库 方法一: 在 "终端" 中输入下面的命令: 显示: $ chflags nohidden ~/Library/ 隐藏: $ chflags hidd ...