Contract Interaction and ABI

Contract Interaction and ABI

Learning Objectives

Master the methods of inter-contract calls, interface definition, ABI data structure, and Web3.js methods for accessing contracts.


Basics of Inter-Contract Calls

  • EOA (Externally Owned Account) initiates a call, which may trigger a call chain between contracts
  • The caller must hold the address of the called contract

Method One: Direct Call within the Same File

When two contracts are in the same file, they can be called directly using the contract type and address:

// SPDX-License-Identifier: MIT
pragma solidity >=0.8.2 <0.9.0;

contract Callee {
    uint256 public x;

    function setX(uint _x) public {
        x = _x;
    }
}

contract Caller {
    address calleeAddress;

    constructor(address _callee) {
        calleeAddress = _callee;
    }

    function setCalleeX(uint _x) public {
        Callee callee = Callee(calleeAddress);
        callee.setX(_x);
    }
}

Method Two: Cross-File Import Call

When contracts are distributed in different files, use import to introduce them:

// File: Callee.sol
// SPDX-License-Identifier: MIT
pragma solidity >=0.8.2 <0.9.0;

contract Callee {
    uint256 public x;

    function setX(uint _x) public {
        x = _x;
    }
}
// File: Caller.sol
// SPDX-License-Identifier: MIT
pragma solidity >=0.8.2 <0.9.0;
import "contracts/Callee.sol";

contract Caller {
    address calleeAddress;

    constructor(address _callee) {
        calleeAddress = _callee;
    }

    function setCalleeX(uint _x) public {
        Callee callee = Callee(calleeAddress);
        callee.setX(_x);
    }
}

Method Three: Calling via Interface

An Interface is equivalent to an ABI; it does not depend on the source code of the called contract, only requiring knowledge of the function signature to make a call.

Defining an Interface

// File: ICallee.sol
// SPDX-License-Identifier: MIT
pragma solidity >=0.8.2 <0.9.0;

interface ICallee {
    function setX(uint _x) external;
}

Implementing an Interface (Optional)

// File: Callee.sol
// SPDX-License-Identifier: MIT
pragma solidity >=0.8.2 <0.9.0;
import "contracts/ICallee.sol";

contract Callee is ICallee {
    uint256 public x;

    function setX(uint _x) public {
        x = _x;
    }
}

Calling via Interface

// File: Caller.sol
// SPDX-License-Identifier: MIT
pragma solidity >=0.8.2 <0.9.0;
import "contracts/ICallee.sol";

contract Caller {
    address calleeAddress;

    constructor(address _callee) {
        calleeAddress = _callee;
    }

    function setCalleeX(uint _x) public {
        ICallee callee = ICallee(calleeAddress);
        callee.setX(_x);
    }
}

Practical Example: Accessing the USDT Contract

Only by knowing the contract address and interface can you interact with contracts already deployed on the chain.

  • USDT Contract Address: 0xdAC17F958D2ee523a2206206994597C13D831ec7
// SPDX-License-Identifier: MIT
pragma solidity >=0.8.2 <0.9.0;

interface IERC20 {
    function name() external view returns(string memory);
    function symbol() external view returns(string memory);
    function decimals() external view returns(uint8);
}

Using the interface + address, you can read USDT's name, symbol, and decimals without needing to obtain USDT's source code.


ABI (Application Binary Interface)

ABI is a binary interface description for contracts, and it includes the following characteristics:

  • Only contains function signature information, no implementation code
  • EOA calls contracts via ABI, and contracts call each other via interfaces
  • Automatically generated when compiling contracts

ABI Diagram

ABI JSON Example

{
    "abi": [
        {
            "inputs": [
                {
                    "internalType": "uint256",
                    "name": "_x",
                    "type": "uint256"
                }
            ],
            "name": "setX",
            "outputs": [
                {
                    "internalType": "uint256",
                    "name": "",
                    "type": "uint256"
                }
            ],
            "stateMutability": "nonpayable",
            "type": "function"
        }
    ]
}

Web3.js Contract Access

Web3.js is a JavaScript library for calling contracts on the browser side, supporting two ways of introduction:

  • Direct reference via <script> tag
  • Node.js module (npm install web3)

Usage Steps

  1. Import Web3.js
  2. Initiate MetaMask login to get the user's account address
  3. Generate a contract object using ABI + contract address
  4. Call contract methods:
  5. Read operation (view/pure): .methods.funcName().call()
  6. Write operation (modifies state): .methods.funcName().send({ from: account })

Code Example

// 1. Import Web3 (browser environment, MetaMask injects window.ethereum)
const web3 = new Web3(window.ethereum);

// 2. Request MetaMask authorization and login
const accounts = await window.ethereum.request({
    method: "eth_requestAccounts"
});
const account = accounts[0];

// 3. Create contract object using ABI + contract address
const abi = [ /* 合约 ABI JSON */ ];
const contractAddress = "0x1234...abcd";
const contract = new web3.eth.Contract(abi, contractAddress);

// 4a. Read operation (view function, does not consume gas)
const value = await contract.methods.getX().call();
console.log("当前值:", value);

// 4b. Write operation (modifies state, consumes gas, requires signature)
await contract.methods.setX(42).send({ from: account });

主题测试文章,只做测试使用。发布者:Walker,转转请注明出处:https://walker-learn.xyz/archives/7492

(0)
Walker的头像Walker
上一篇 5 days ago
下一篇 Mar 27, 2025 15:01

Related Posts

EN
简体中文 繁體中文 English