共六种方法:

// SPDX-License-Identifier:MIT
// 合约调合约方法
// 参考视频

pragma solidity ^0.8;
contract Callee {
uint public x;
uint public value;
function setX(uint _x) public returns (uint){
x = _x;
return x;
}

function setXandSendEther (uint _x) public payable returns (uint, uint){x = _x;value = msg.value;return (x,value);}

}

contract Caller {
address public richest;
uint public mostSent;
constructor() payable {
richest = msg.sender;
mostSent = msg.value;
}
// 第一种合约调合约方法,Callee _callee,隐式转换地址为合约
function callSetx(Callee _callee, uint256 _x) public {
uint256 x = _callee.setX(_x);
}
// 第二种合约调合约方法,Callee(_addr)显式转换地址为合约
function callSeXAddress(address _addr, uint256 _x) public {
Callee callee = Callee(_addr);
callee.setX(_x);
}
// 第三种合约调合约方法,发送ether
function callsetXandSendEther(address _addr, uint256 _x) public payable{
Callee callee = Callee(_addr);
// {value: msg.value} 发送ether或者全局变量
(uint x, uint value) = callee.setXandSendEther{value: msg.value}(_x);
}
}
第四种 继承合约再调用
contract Caller2 is Callee{

//1.is合约 2.constructor 里面new一个实例3.用点语法直接调用Callee private c;// Callee c = new Callee(); //或者直接在状态上new,不用下面constructorconstructor() {c = new Callee();}function callSetx(uint256 _x) public{uint256 x = c.setX(_x);}

}

第五种 继承合约再调用
contract Caller3 is Callee{

//1.is合约 后面2,3步省略(2.constructor 里面new一个实例3.用点语法直接调用)function callSetx(uint256 _x) public{x = _x;}function callsetXandSendEther(uint256 _x) public{setXandSendEther(_x);}

}

第六种,call底层,不推荐使用。 call(abi.encodeWithSignature(“setX(uint256)”,_x));

// contract CallTest{// // // 需要0.4的版本 pragma solidity ^0.8;// function callByFun(address addr, uint256 _x) public returns (bool){// // bytes4 methodId = bytes4(keccak256("increaseAge(string,uint256)"));// // return addr.call(methodId,"jack", 1); // // 下面这句等于上面2行// return addr.call(abi.encodeWithSignature("setX(uint256)",_x));// }// function callData(address addr) public returns (bool){// return addr.call("abc", 256); // 找不到abc函数,会调fallback函数// }// }