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 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
- Import Web3.js
- Initiate MetaMask login to get the user's account address
- Generate a contract object using ABI + contract address
- Call contract methods:
- Read operation (view/pure):
.methods.funcName().call() - 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
