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()
call与delegatecall的功能类似,区别仅在于后者仅使⽤给定地址的代码,其它信息则使⽤当前合约(如存储,余额等等)。
solidity
函数的设计⽬的是为了使⽤存储在另⼀个合约的库代码。
所以开发者在提供这样的库时,就要如何安排存储来达到这样的⽬的。
⼆者执⾏代码的上下⽂环境的不同,当使⽤call调⽤其它合约的函数时,代码是在被调⽤的合约的环境⾥执⾏,对应的,使⽤delegatecall进⾏函数调⽤时代码则是在调⽤函数的合约的环境⾥执⾏。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。