接口 #
一、接口概述 #
1.1 什么是接口 #
接口定义了合约的外部API,是一组函数签名的集合,不包含实现。
solidity
interface IERC20 {
function totalSupply() external view returns (uint256);
function balanceOf(address owner) external view returns (uint256);
function transfer(address to, uint256 value) external returns (bool);
}
1.2 接口的作用 #
| 作用 | 说明 |
|---|---|
| 定义标准 | 如ERC20、ERC721等标准 |
| 合约交互 | 调用其他合约的函数 |
| 类型安全 | 确保函数签名正确 |
| 文档化 | 明确合约的外部API |
二、接口定义 #
2.1 基本语法 #
solidity
interface InterfaceName {
function functionName(parameters) external returns (returnTypes);
}
2.2 接口限制 #
solidity
interface IExample {
// ✓ 允许:函数声明
function getValue() external view returns (uint256);
// ✓ 允许:事件声明
event ValueChanged(uint256 newValue);
// ✗ 不允许:状态变量
// uint256 value;
// ✗ 不允许:构造函数
// constructor() {}
// ✗ 不允许:函数实现
// function foo() external { }
// ✗ 不允许:修饰器
// modifier onlyOwner() { _; }
}
2.3 接口示例 #
solidity
interface IERC20 {
function totalSupply() external view returns (uint256);
function balanceOf(address owner) external view returns (uint256);
function allowance(address owner, address spender) external view returns (uint256);
function transfer(address to, uint256 value) external returns (bool);
function approve(address spender, uint256 value) external returns (bool);
function transferFrom(address from, address to, uint256 value) external returns (bool);
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
}
interface IERC721 {
function balanceOf(address owner) external view returns (uint256);
function ownerOf(uint256 tokenId) external view returns (address);
function transferFrom(address from, address to, uint256 tokenId) external;
function approve(address to, uint256 tokenId) external;
event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);
event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);
}
三、接口实现 #
3.1 实现接口 #
solidity
interface IERC20 {
function totalSupply() external view returns (uint256);
function balanceOf(address owner) external view returns (uint256);
function transfer(address to, uint256 value) external returns (bool);
}
contract MyToken is IERC20 {
uint256 private _totalSupply;
mapping(address => uint256) private _balances;
constructor(uint256 supply) {
_totalSupply = supply;
_balances[msg.sender] = supply;
}
function totalSupply() external view override returns (uint256) {
return _totalSupply;
}
function balanceOf(address owner) external view override returns (uint256) {
return _balances[owner];
}
function transfer(address to, uint256 value) external override returns (bool) {
require(_balances[msg.sender] >= value, "Insufficient balance");
_balances[msg.sender] -= value;
_balances[to] += value;
return true;
}
}
3.2 多接口实现 #
solidity
interface IERC20 {
function totalSupply() external view returns (uint256);
function transfer(address to, uint256 value) external returns (bool);
}
interface IERC20Metadata {
function name() external view returns (string memory);
function symbol() external view returns (string memory);
function decimals() external view returns (uint8);
}
contract MyToken is IERC20, IERC20Metadata {
string private _name;
string private _symbol;
uint8 private _decimals;
uint256 private _totalSupply;
mapping(address => uint256) private _balances;
constructor(
string memory name_,
string memory symbol_,
uint8 decimals_,
uint256 totalSupply_
) {
_name = name_;
_symbol = symbol_;
_decimals = decimals_;
_totalSupply = totalSupply_;
_balances[msg.sender] = totalSupply_;
}
function name() external view override returns (string memory) {
return _name;
}
function symbol() external view override returns (string memory) {
return _symbol;
}
function decimals() external view override returns (uint8) {
return _decimals;
}
function totalSupply() external view override returns (uint256) {
return _totalSupply;
}
function transfer(address to, uint256 value) external override returns (bool) {
require(_balances[msg.sender] >= value, "Insufficient balance");
_balances[msg.sender] -= value;
_balances[to] += value;
return true;
}
}
四、接口使用 #
4.1 调用其他合约 #
solidity
interface IERC20 {
function transfer(address to, uint256 value) external returns (bool);
function balanceOf(address owner) external view returns (uint256);
}
contract TokenUser {
IERC20 public token;
constructor(address tokenAddress) {
token = IERC20(tokenAddress);
}
function transferTokens(address to, uint256 amount) public returns (bool) {
return token.transfer(to, amount);
}
function getBalance(address owner) public view returns (uint256) {
return token.balanceOf(owner);
}
}
4.2 类型转换 #
solidity
interface IERC20 {
function totalSupply() external view returns (uint256);
}
contract InterfaceCast {
function getTotalSupply(address tokenAddress) public view returns (uint256) {
IERC20 token = IERC20(tokenAddress);
return token.totalSupply();
}
}
五、常见标准接口 #
5.1 ERC20接口 #
solidity
interface IERC20 {
function totalSupply() external view returns (uint256);
function balanceOf(address account) external view returns (uint256);
function transfer(address recipient, uint256 amount) external returns (bool);
function allowance(address owner, address spender) external view returns (uint256);
function approve(address spender, uint256 amount) external returns (bool);
function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
}
5.2 ERC721接口 #
solidity
interface IERC721 {
event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);
event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);
event ApprovalForAll(address indexed owner, address indexed operator, bool approved);
function balanceOf(address owner) external view returns (uint256 balance);
function ownerOf(uint256 tokenId) external view returns (address owner);
function safeTransferFrom(address from, address to, uint256 tokenId) external;
function transferFrom(address from, address to, uint256 tokenId) external;
function approve(address to, uint256 tokenId) external;
function getApproved(uint256 tokenId) external view returns (address operator);
function setApprovalForAll(address operator, bool _approved) external;
function isApprovedForAll(address owner, address operator) external view returns (bool);
}
5.3 ERC165接口 #
solidity
interface IERC165 {
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}
contract MyNFT is IERC165 {
function supportsInterface(bytes4 interfaceId) public pure override returns (bool) {
return
interfaceId == type(IERC721).interfaceId ||
interfaceId == type(IERC165).interfaceId;
}
}
六、最佳实践 #
6.1 接口命名 #
solidity
// 推荐:使用I前缀
interface IERC20 {}
interface IERC721 {}
interface IAccessControl {}
// 推荐:使用大驼峰
interface ITokenReceiver {}
6.2 接口分离 #
solidity
// 推荐:分离核心接口和扩展接口
interface IERC20 {
function totalSupply() external view returns (uint256);
function balanceOf(address account) external view returns (uint256);
function transfer(address recipient, uint256 amount) external returns (bool);
}
interface IERC20Metadata {
function name() external view returns (string memory);
function symbol() external view returns (string memory);
function decimals() external view returns (uint8);
}
七、总结 #
接口要点:
| 特性 | 说明 |
|---|---|
| 定义 | interface InterfaceName { ... } |
| 函数 | 只声明,不实现 |
| 事件 | 可以声明 |
| 实现 | 使用is关键字 |
| 限制 | 无状态变量、构造函数、实现 |
使用建议:
- 使用接口定义标准
- 使用I前缀命名
- 分离核心和扩展接口
- 实现标准接口确保兼容性
接下来,让我们学习多态!
最后更新:2026-03-27