• solidity 学习笔记(6)call 函数


    call() 方法

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

    简单说 根据地址调用指定合约的方法。

    pragma solidity ^0.4.24;
     
    contract cat{
        
        function eat(uint a) public view returns(uint){
            return a;
        }
        
    }
     
     
    contract Animal{
        
        cat c;
        constructor(address _add){
            c = cat(_add);
        }
       
       function test()public view returns(uint) { //普通实例化合约调用
           return c.eat(1);
       }
       
       function test2()public view returns(bool) {  //通过call方法调用
           return c.call(bytes32(keccak256("eat()")),2);//通过bytes32(keccak256("eat()"指定方法,后面的是参数
    } }

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

     
        bytes fail;
        
        function(){
            fail = msg.data;
        }

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

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

    call()的返回结果即使成功,并不能说操作成功了,只是没有出现异常,有可能调用到了fallback()函数。

    delegatecall()

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

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

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

    二者执行代码的上下文环境的不同,当使用call调用其它合约的函数时,代码是在被调用的合约的环境里执行,对应的,使用delegatecall进行函数调用时代码则是在调用函数的合约的环境里执行。

  • 相关阅读:
    VMware安装Centos7超详细过程
    LVS+Keepalived小试牛刀
    Spring入门之AOP篇
    Spring学习笔记及资源
    Spring入门第一例
    Mybatis学习手记(二)
    Mybatis学习手记(一)
    java web 开发入门实例
    关于JAVA编译时找不到自定义包的问题
    Java 学习笔记及资源
  • 原文地址:https://www.cnblogs.com/gzhlt/p/9997798.html
Copyright © 2020-2023  润新知