三个方法都是用来进行合约交互的方法。由于没有进行更进一步的封装,不是最好的选择,一般不会直接使用到它们;另外一个显著的问题由于可以使用任意参数类型,在语言层面不能保证类型安全,所以不推荐使用。

call() 方法

call()是一个底层的接口,用来向一个合约发送消息1,也就是说如果你想实现自己的消息传递,可以使用这个函数。函数支持传入任意类型的任意参数,并将参数打包成32字节,相互拼接后向合约发送这段数据。

函数的传输的数据

由于向另一个合约发送数据时,找不到对应的方法签名,会默认调用fallback()函数2,所以我们可以通过这个来看看call()传的具体数据。

pragma solidity ^0.4.0;contract Person{bytes fail;function(){fail = msg.data;}function getFail() returns (bytes){return fail;}}contract CallTest{function callData(address addr) returns (bool){return addr.call("abc", 256);}}

下图实际操作演示。

可以看到,由于没有找到对应的函数调用,最终调用的是fallback()函数,通过fail字段,我们看到了收到msg.data

0x61626300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100

前32字节为abc对应的acii编码值,后32位为256的对应编码值3。

call指定函数

如果第一个参数刚好是四个字节,会认为这四个字节指定的是函数签名的序号值,生成方式参见ABI协议的函数选择器4。由如果你只是想传个参数值,而不是想指定一个函数序号,应避免第一个参数刚好是四个字节。

pragma solidity ^0.4.0;contract Person{uint age = 10;function increaseAge(string name, uint num) returns (uint){return ++age;}function getAge() returns (uint){return age;}}contract CallTest{function callByFun(address addr)returns (bool){bytes4 methodId = bytes4(keccak256("increaseAge(string,uint256)"));return addr.call(methodId,"jack", 1);}
}

通过下图的gif可以看看操作演示:

函数的结果

call()的返回结果是一个bool,表示是否成功的调用,或者是失败引起了EVM异常。该方法无法直接访问函数返回结果(因为需要事前知道编码和返回结果大小)。

call()的返回结果即使成功,并不能说操作成功了,只是没有出现异常,比如我们第一个例子中,实际是调用到了fallback()函数。

delegatecall()

calldelegatecall的功能类似,区别仅在于后者仅使用给定地址的代码,其它信息则使用当前合约(如存储,余额等等)。

函数的设计目的是为了使用存储在另一个合约的库代码。

所以开发者在提供这样的库时,就要如何安排存储来达到这样的目的。

原博客:http://me.tryblockchain.org/Solidity-call-callcode-delegatecall.html


  1. 关于这个的详细说明,可以参考这里。http://ethereum.stackexchange.com/questions/8168/understanding-namereg-callregister-myname-style-call-between-contracts ↩

  2. 类似构造函数的定义方式。 ↩

  3. 参数编码格式与ABI的编码格式一致,直接参考ABI。 ↩

  4. 详细了解ABI格式,可以参考:【文档翻译系列】ABI详解 ↩

solidity之call相关函数相关推荐

  1. Python菜鸟学习手册14----标准库+代码实例

    Python Standard Library 翻译: Python 江湖群 10/06/07 20:10:08 编译 0.1. 关于本书 0.2. 代码约定 0.3. 关于例子 0.4. 如何联系我 ...

  2. Solidity智能合约库:区块链工程师的随身工具箱

    编者荐语: Solidity使用起来不如其他语言那般丝滑顺畅?安全事故难以避免?社区迎来适用于FISCO BCOS的Solidity智能合约库,轻松破解合约的各种小难题,让合约开发更加快速高效.省时省 ...

  3. 微众银行Solidity智能合约库:区块链工程师的随身工具箱

    区块链技术在经历了十余年的发展后,渐呈"燎原之势",不断在各行业落地生根.但同时,从技术的角度看,区块链应用开发仍然有着较高的门槛,存在不少痛点.为了提升应用开发各环节的用户体验, ...

  4. 【solidity】函数修饰器(Function Modifiers)

    修饰符可用于以声明方式更改函数的行为.例如,您可以使用修饰符在执行函数之前自动检查条件. 检查调用者权限 // SPDX-License-Identifier: GPL-3.0 pragma soli ...

  5. 蚂蚁区块链第11课 以租房积分管理系统为例讲透蚂蚁Solidity语言差异精要

    1,摘要 本文以住房租赁积分管理系统为例,给大家演示CLOUD IDE如何编译调试solidity智能合约,并以此为例,给大家分享以太坊SOLIDITY跟蚂蚁区块链SOLIDITY语言的差异点. 2, ...

  6. Solidity智能合约开发(提高篇)

    一.函数 1.1 函数定义 函数的定义格式: function 函数名(参数类型 参数名, ...) 修饰符 [returns(返回类型, ...)] {函数体 }示例: function sum(i ...

  7. RTTI(三)相关函数1【转自大富翁】

    第三部分RTTI相关函数 GetTypeData 函数 GetPropInfo 函数 FindPropInfo 函数 GetPropInfos 函数 SortPropList 函数 GetPropLi ...

  8. Windows/Linux上使用fopen相关函数读取大文件

    在介绍读取大文件之前,先了解下<cstdint>文件,标准头文件,存放固定宽度整数类型,如int32_t, uint32_t,不管在32位上还是64位上,长度都为4个字节:int64_t, ...

  9. C++11容器中新增加的emplace相关函数的使用

    C++11中,针对顺序容器(如vector.deque.list),新标准引入了三个新成员:emplace_front.emplace和emplace_back,这些操作构造而不是拷贝元素.这些操作分 ...

最新文章

  1. volatile修饰变量
  2. mysql gz 安装_Linux下安装mysql 5.7.17.tar.gz的教程详解
  3. 学习Windows2008——常用工具及命令(包括核心版部分命令)
  4. STM32之串口例程
  5. JLINK V9 修复小记
  6. url 微信公众号开发 配置失效_微信公众号开发之授权登录
  7. ORB SLAM 2 demo 复现
  8. input隐藏边框和选中样式
  9. sysbench和lua的简单研究
  10. 白杨SEO:百度移动搜索上百度笔记是什么、收录规则及排名怎么做?
  11. kindle不支持html,你的Kindle不支持夜间模式,也许是这个原因
  12. 怀孕计算机在线,【孕期天数计算器在线计算_孕期天数计算器在线计算专题】- 天鹅到家...
  13. Spring-retry重试组件
  14. Android实现Line登录分享
  15. 简单、强大的swig.js
  16. 基于Android的租车app
  17. JavaScript入门小试,水仙花数的辨别以及再深入学习一些定义区间。
  18. 全球公认的最健康作息时间表(2015就照个来)
  19. 制作可随身携带的Ubuntu系统U盘
  20. 树莓派连接温度传感器实时监控,并上报服务器

热门文章

  1. 小瓦怕扫地机器人_小瓦扫地机器人青春版评测报告
  2. 设计mysql存储过程,MySQL的存储过程设计的例子
  3. C++实现系统性能检测工具
  4. ajax提交手机号到php,ajax怎样申请手机号到数据库验证并且返回数据的状态值
  5. thinkphp 个别字段无法更新_ThinkPHP setField 方法更新个别字段的值
  6. 51nod 1091 线段的重叠(贪心)
  7. 安卓启动相关以及架构设计相关
  8. 虚拟地球原理与实现(转载)
  9. ES6——扩展运算符/三点运算符(...)
  10. 【零基础学Java】—递归(五十一)