A合约调用B合约的四种方法 / 学习智能合约#69
在Solidity中,合约间的调用非常普遍且重要。这里就做个总结。以前的文章有些零散,归纳下,且做些参考。
A合约调用B合约有四种方法,如下:
1.合约对象,2.继承,3.接口, 4.低级调用,call和delegatecall
这些调用方法可以增强合约的灵活性,使其能够执行跨合约操作,比如获取数据、转移资金或触发其他合约的功能。具体的应用场景需具体实现。
1.合约对象
直接生成合约对象来调用。这和很多语言的对象化编程是相通的。
contract FuncAdd {
uint x = 263;
function add(uint x, uint y) external returns(uint) {
return x;
};
}
contract TestAdd {
//用合约地址来实例化接口
FuncAdd t = FuncAdd(0x3dA5048CE9384a35fF4F3AAF0B4804114e584039);
function test(uint x, uint y) public returns(uint){
return t.add(x, y);
}
}
2.继承
继承A合约中的方法,可以直接调用。
contract A {
uint public x;
function setValue(uint _x) public {
x = _x;
}
}
contract B is A {
function modify(uint _y) public {
setValue(_y); //可以直接调用A合约中的方法
}
}
3.接口
接口有点类似抽象合约的功能,可用于两个合约间的调用。是非侵入式接口,也就是不用显式的调用接口。在ERC20合约中比较常见。
注意:B中引用A的接口,A的函数仍会在A的环境中执行。
一个合约想调用另一个合约的方法时,尽量用接口来调用,不要用call, delegatecall。
interface IFuncAdd {
function add(uint x, uint y) external returns(uint);
}
contract TestAdd {
//用合约地址来实例化接口
IFuncAdd t = IFuncAdd(0x3dA5048CE9384a35fF4F3AAF0B4804114e584039);
function test(uint x, uint y) public returns(uint){
return t.add(x, y);
}
}
4. call和delegatecall
call 会切换到被调合约中去执行方法,会切换上下文。msg.sender是主调合约地址。
delegatecall 则是将被调合约中的方法调到本合约中执行,也就是不会切换上下文。msg.sender是发起者本人。
另外,还有staticcall是 call 的只读版本,适用于调用不会修改状态的函数。在调用期间,合约的状态无法被改变。
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
contract SetNum {
uint256 public n = 20;
address public sender;
function setN(uint256 _n) public {
n = _n;
sender = msg.sender;
}
}
contract CallSet {
uint256 public n = 15;
address public sender;
function CallTest(address _addr, uint256 _n) public {
_addr.call(abi.encodeWithSignature("setN(uint256)", _n)); //改变SetNum中的n值
sender = msg.sender; //是调用者本人,同时会改变SetNum的sender地址
//(bool success, bytes memory returnData) = _addr.staticcall(data);
}
function delegatecallTest(address _addr, uint256 _n) public {
_addr.delegatecall(abi.encodeWithSignature("setN(uint256)", _n)); //改变自身的n值
//(bool success, bytes memory data) = _contract.delegatecall(
// abi.encodeWithSignature("setVars(uint256)", _num)
// );
sender = msg.sender; //是调用者本人,不会改变SetNum的sender地址
}
}
// 注意: delegatecall是相当于将被调合约的函数引入自身中执行,所以,这两个合约中的状态变量要一致!否则容易出错。
// 传入的参数(address _addr)是合约地址。
Solidity提供了这四种主要的合约间的调用方法,包括合约对象调用、合约继承,低级调用和接口调用。每种方法都有其适用的场景和特点。开发时要根据具体需求选择合适的调用方式。在合约调用过程中,安全性问题要特别重视,尤其是低级调用中会有重入攻击等危险性,要做好合约的安全工作。
Leave A合约调用B合约的四种方法 / 学习智能合约#69 to:
Read more #cn posts
Best Posts From lemooljiang
We have not curated any of lemooljiang's posts yet. But you can encourage our curation team to review posts by visiting them regularly and by referring other readers. Because we give priority to frequently read content.
More Posts From lemooljiang
- Nextjs初体验,和Nuxt的异同
- DeepTutor:AI个性化辅导平台 / ai #57
- ComfyUI:可编程和自动化的PS / ai #56
- 将Neo4j封装进Agent / ai #55
- 闲鱼省钱大法:极限0.5折!
- 对Neo4j批量导入结构化数据 / ai #54
- langchain对neo4j进行交互,写入和查询数据 / ai #53
- 知识图谱和图数据库Neo4j的作用和使用场景 / ai #52
- SpaceX、美股和比特币
- 又是币圈血洗日!
- 链股合流,当币安也开始卖股票啰
- 天涯社区重启,爷青回?
- 诺基亚在AI时代重新杀回来啦
- 《2049:未来10000天的可能》书中的镜像世界为什么不叫元宇宙
- 今天适合吃披萨
- 开通即被封,别再给Claude送人头了!
- 两根内存条引发的“官司”
- AI·Joe V12更新, 更新GPT-5.5和DeepSeek V4 等
- 中医进校园活动反响热烈
- 猪价低伤农,猪价贵伤民