# Solidity low-level call 直接通过合约地址和 calldata 读写其他合约

Original: <https://lifelonglearn.ing/solidity-low-level-call>

Author: [奶爸](https://lifelonglearn.ing/users/3b04650c-8231-499b-8ef0-381fc4d7efb0)

Published: 2022-02-14T06:33:06Z

Updated: 2026-09-27T06:57:43Z

Version: 1

有时候遇到一些没开源且没有找 ABI 的项目，可以通过此技术直接去调用合约，进而实现一些操作。

直接上代码，注意注释中的说明。

```solidity
// SPDX-License-Identifier: UNLICENSED
pragma solidity >=0.8.0;

contract TestCall {
    // 调用其他合约的接口，注意不要被滥用，这个接口可以让调用人以当前合约地址的身份执行任意操作
    function call(address payable to, bytes calldata data)
        public
        returns (bool, bytes memory)
    {
        return to.call(data);
    }

    // 测试的读接口，测试时直接部署两个实例互相调用即可
    function testRead(uint256 x) public pure returns (uint256) {
        return x;
    }

    uint256 public y;

    // 测试的写接口，从 A 合约的 call 调用 B 合约的写接口，然后看 B 合约的 y 值是否成功被更新
    function testWrite(uint256 x) public {
        y = x;
    }

    // 计算方法的 sig，注意参数是不需要名称的，也不需要返回值，只需要方法名和参数类型列表
    function getFuncSig(string calldata sig) public pure returns (bytes4) {
        // testRead(uint256)
        // testWrite(uint256)
        return bytes4(keccak256(bytes(sig)));
    }

    // 编码要调用的方法和参数
    function getCallData(bytes4 sig, uint256 x)
        public
        pure
        returns (bytes memory)
    {
        return abi.encodeWithSelector(sig, x);
    }
}

```

当我们学会这种 low-level call 之后后面遇到想要操作的项目，不需要知道 abi 也可以操作了。
