在Solidity中,import语句可以帮助我们在一个文件中引用另一个文件的内容,提高代码的可重用性和组织性。
- 通过源文件相对位置导入,例子:
文件结构
├── Import.sol
└── Yeye.sol
// 通过文件相对位置import
import './Yeye.sol';
- 通过源文件网址导入网上的合约的全局符号,例子:
// 通过网址引用
import 'https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/Address.sol';
- 通过npm的目录导入,例子:
import '@openzeppelin/contracts/access/Ownable.sol';
- 通过指定全局符号导入合约特定的全局符号,例子:
import {Yeye} from './Yeye.sol';
Solidity支持两种特殊的回调函数,receive()和fallback() 他们主要在两种情况下被使用: 1. 接收ETH 2. 处理合约中不存在的函数调用(代理合约proxy contract)
receive()函数是在合约收到ETH转账时被调用的函数。一个合约最多有一个receive()函数,声明方式与一般函数不一样,不需要function关键字:receive() external payable { ... }。receive()函数不能有任何的参数,不能返回任何值,必须包含external和payable。
// 定义事件
event Received(address Sender, uint Value);
// 接收ETH时释放Received事件
receive() external payable {
emit Received(msg.sender, msg.value);
}
fallback()函数会在调用合约不存在的函数时被触发。可用于接收ETH,也可以用于代理合约proxy contract。fallback()声明时不需要function关键字,必须由external修饰
event fallbackCalled(address Sender, uint Value, bytes Data);
// fallback
fallback() external payable{
emit fallbackCalled(msg.sender, msg.value, msg.data);
}
触发fallback() 还是 receive()?
接收ETH
|
msg.data是空?
/ \
是 否
/ \
receive()存在? fallback()
/ \
是 否
/ \
receive() fallback()
简单来说,合约接收ETH时,msg.data为空且存在receive()时,会触发receive();msg.data不为空或不存在receive()时,会触发fallback(),此时fallback()必须为payable。