地址类型
1. 地址类型
在 Solidity 中,address
类型用于存储以太坊地址。地址可以是外部账户(EOA)或合约账户。地址类型是 Solidity 中最基本的数据类型之一,常用于处理以太坊账户之间的交互。
1.1 地址类型的基本操作
// 声明一个地址变量
address public myAddress;
// 获取当前调用者的地址
address public caller = msg.sender;
// 地址类型之间的比较
function compareAddress(address addr1, address addr2) public pure returns (bool) {
return addr1 == addr2;
}
// 地址类型的转换
function toBytes(address addr) public pure returns (bytes memory) {
return abi.encodePacked(addr);
}
1.2 地址类型的成员变量和方法
// 获取地址的余额
function getBalance(address addr) public view returns (uint256) {
return addr.balance;
}
// 向地址转账
function sendEther(address payable recipient) public payable {
recipient.transfer(msg.value);
}
// 调用地址的代码(低级别调用)
function callContract(address addr, bytes memory data) public returns (bool, bytes memory) {
(bool success, bytes memory result) = addr.call(data);
return (success, result);
}
2. 接口
接口(Interface)是 Solidity 中用于定义合约之间交互的一种方式。通过接口,一个合约可以调用另一个合约的函数,而无需知道其具体实现。
2.1 定义接口
// 定义一个简单的接口
interface IERC20 {
function transfer(address to, uint256 amount) external returns (bool);
function balanceOf(address account) external view returns (uint256);
}
2.2 使用接口
contract MyContract {
// 使用接口与另一个合约交互
function transferToken(address tokenAddress, address to, uint256 amount) public returns (bool) {
IERC20 token = IERC20(tokenAddress);
return token.transfer(to, amount);
}
// 获取代币余额
function getTokenBalance(address tokenAddress, address account) public view returns (uint256) {
IERC20 token = IERC20(tokenAddress);
return token.balanceOf(account);
}
}
2.3 接口的特点
- 接口只能声明函数,不能实现函数。
- 接口中的函数必须标记为
external
。 - 接口不能定义状态变量或构造函数。
- 接口可以继承其他接口。
3. 综合示例
// 定义一个简单的银行接口
interface IBank {
function deposit() external payable;
function withdraw(uint256 amount) external;
function getBalance() external view returns (uint256);
}
// 实现银行接口的合约
contract Bank is IBank {
mapping(address => uint256) public balances;
function deposit() external payable override {
require(msg.value > 0, "存款金额必须大于0");
balances[msg.sender] += msg.value;
}
function withdraw(uint256 amount) external override {
require(balances[msg.sender] >= amount, "余额不足");
balances[msg.sender] -= amount;
payable(msg.sender).transfer(amount);
}
function getBalance() external view override returns (uint256) {
return balances[msg.sender];
}
}
// 使用银行接口的合约
contract BankUser {
function depositToBank(address bankAddress) external payable {
IBank bank = IBank(bankAddress);
bank.deposit{value: msg.value}();
}
function withdrawFromBank(address bankAddress, uint256 amount) external {
IBank bank = IBank(bankAddress);
bank.withdraw(amount);
}
function getBankBalance(address bankAddress) external view returns (uint256) {
IBank bank = IBank(bankAddress);
return bank.getBalance();
}
}