# 合约四种 call 区别 **Published by:** [NO ONE](https://paragraph.com/@no-one/) **Published on:** 2022-09-29 **URL:** https://paragraph.com/@no-one/call ## Content CALL|CALLCODE|DELEGATECALL|STATICCALL 四种调用的区别CALL & STATICCALLCALL 调用的上下文环境是被调用合约的环境,修改的是被调用合约的 state,调用者函数不能为 view。CALL ContractBSTATICCALL 只能调用不修改 state 的函数(pure view 修饰的函数),调用者函数可以为 view。STATICCALL ContractB// SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.8.0; // 调用者 contract ContractA { uint256 x; function add(uint256 _num) public { x = x + _num; } function getX() external view returns(uint256) { return x; } } // 被调用者 contract ContractB { function call(address _addr, uint256 _num) external { bytes memory data = abi.encodeWithSignature("add(uint256)", _num); (bool result, ) = _addr.call(data); require(result, "transaction failed"); } function staticcall(address _addr) external view returns(uint256) { bytes memory data = abi.encodeWithSignature("getX()"); (bool result, bytes memory returnNum) = _addr.staticcall(data); require(result, "transaction failed"); return abi.decode(returnNum, (uint256)); } } CALLCODE & DELEGATECALLCALLCODE已被DELEGATECALL取代,区别就是 msg.sender不同。DELEGATECALL会一直使用原始调用者的地址,而CALLCODE不会。委托调用的上下文环境是调用者合约的环境,也就是说msg.sender是用户。通常用在可升级的代理合约中。 ## Publication Information - [NO ONE](https://paragraph.com/@no-one/): Publication homepage - [All Posts](https://paragraph.com/@no-one/): More posts from this publication - [RSS Feed](https://api.paragraph.com/blogs/rss/@no-one): Subscribe to updates