diff --git a/FFFFourwood.md b/FFFFourwood.md
index 91bb496f..dc3c288b 100644
--- a/FFFFourwood.md
+++ b/FFFFourwood.md
@@ -393,6 +393,31 @@ IERC721函数
- `setApprovalForAll`:将自己持有的NFT批量授权给某个地址。
- `isApprovedForAll`:查询某地址的NFT是否已批量授权给另一个地址。
- `safeTransferFrom`:带有额外`data`参数的安全转账函数。
+
+### 2024.09.30
+
+Error
+`error` 是 Solidity 0.8.4 版本新加的内容,方便且高效(省 gas)地向用户解释操作失败的原因,同时还可以在抛出异常的同时携带参数
+
+Require
+`require` 命令是 Solidity 0.8 版本之前抛出异常的常用方法,目前很多主流合约仍然还在使用它。它很好用,唯一的缺点就是 gas 随着描述异常的字符串长度增加,比 `error` 命令要高。使用方法:`require(检查条件, "异常的描述")`,当检查条件不成立的时候,就会抛出异常。
+
+Assert
+`assert` 命令一般用于程序员写程序 debug,因为它不能解释抛出异常的原因(比 `require` 少个字符串)。它的用法很简单,`assert(检查条件)`,当检查条件不成立的时候,就会抛出异常。
+
+
+三种方法的 gas 比较
+我们比较一下三种抛出异常的 gas 消耗,通过 remix 控制台的 Debug 按钮,能查到每次函数调用的 gas 消耗分别如下:(使用 0.8.17 版本编译)
+
+- `error` 方法 gas 消耗:24457 (加入参数后 gas 消耗:24660)
+- `require` 方法 gas 消耗:24755
+- `assert` 方法 gas 消耗:24473
+
+我们可以看到,`error` 方法 gas 最少,其次是 `assert`,`require` 方法消耗 gas 最多!因此,`error` 既可以告知用户抛出异常的原因,又能省 gas
+
+备注: Solidity 0.8.0 之前的版本,`assert` 抛出的是一个 panic exception,会把剩余的 gas 全部消耗,不会返还。更多细节见官方文档。
+
+
diff --git a/Yuchen.md b/Yuchen.md
index 11821263..1c9815be 100644
--- a/Yuchen.md
+++ b/Yuchen.md
@@ -667,6 +667,123 @@ abstract contract InsertionSort{
function insertionSort(uint[] memory a) public pure virtual returns(uint[] memory);
}
```
+### 2024.09.30
+
+#### 接口(interface)
+類似抽象合約,但不實現任何功能。
+* 規則:
+ 1. 不能包含狀態變量
+ 2. 不能包含構造函數
+ 3. 不能繼承接口以外的其他合約
+ 4. 所有函數都必須是external且不能有函數體
+ 5. 繼承 interface 的非抽象合約必須實現 interface 定義的所有功能
+
+interface 是智能合約的骨架,定義了合約的功能及如何觸發,若合約實現了某種接口,ex.`ERC20`、`ERC721`,其他`Dapps`和合約就知道該如何與此智能合約交互。
+* 作用:
+ 1. 標準化交互:
+ 如果某個智能合約實現了一個通用的接口(如 ERC20 或 ERC721),那麼其他合約或應用程序就能根據這個接口來與其互動,有助於跨平台、跨合約之間的兼容性。
+ 2. 定義合約中的功能:
+ 接口會定義每個函數的名稱和參數類型,以及這些函數如何被調用,這相當於描述了合約的公共 API。
+ 3. 定義每個函數哈希(`bytes4`選擇器)、函數簽名(`函數名(每個參數類型)`),以通過對函數的簽名進行哈希後得到獨特的4字節哈希。
+ ```Solidity
+ keccak256("transfer(address,uint256)").slice(0, 4)
+ ```
+ 4. 接口 ID:
+ 接口 ID 是一個唯一的標識符,用來表示某個合約是否實現了某個接口。
+
+
+```Solidity
+interface IERC721 is IERC165 {
+ 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);
+
+ function safeTransferFrom( address from, address to, uint256 tokenId, bytes calldata data) external;
+}
+```
+
+#### 什麼時候使用interface?
+若知道一個合約實現了`IERC721`,不需要知道他的具體程式實現就可以與之交互。
+ex.
+```Solidity
+contract interactBAYC {
+ // 利用BAYC地址创建接口合约变量(ETH主网)
+ IERC721 BAYC = IERC721(0xBC4CA0EdA7647A8aB7C2061c2E118A18a936f13D);
+
+ // 通过接口调用BAYC的balanceOf()查询持仓量
+ function balanceOfBAYC(address owner) external view returns (uint256 balance){
+ return BAYC.balanceOf(owner);
+ }
+
+ // 通过接口调用BAYC的safeTransferFrom()安全转账
+ function safeTransferFromBAYC(address from, address to, uint256 tokenId) external{
+ BAYC.safeTransferFrom(from, to, tokenId);
+ }
+}
+```
+
+#### 異常
+異常命令可以幫助尋找錯誤。
+* `error`:可以在`contract`之外拋出異常,高效且方便的向用戶解釋操作失敗的原因,且在拋出異常時可攜帶參數。
+ex.定義`TransferNotOwner`異常,當用戶不是貨幣`owner`時轉帳會拋出錯誤。
+ ```Solidity
+ error TransferNotOwner(); // 自定义error
+
+ // 攜帶參數的異常,以提示轉帳的帳戶地址
+ error TransferNotOwner(address sender); // 自定义的带参数的error
+ ```
+ `error`需搭配`revert`命令使用:
+ 當用戶不是貨幣`owner`時轉帳會拋出錯誤,否則成功轉帳。
+ ```Solidity
+ function transferOwner1(uint256 tokenId, address newOwner) public {
+ if(_owners[tokenId] != msg.sender){
+ revert TransferNotOwner();
+ // revert TransferNotOwner(msg.sender);
+ }
+ _owners[tokenId] = newOwner;
+ }
+ ```
+* `require`:消耗的gas比`error`高,且會隨著描述異常的字符串長度增加,gas也隨之增加。
+ * 使用方法:`require(檢查條件,"異常的描述")`,檢查條件不成立時,拋出異常。
+ ```Solidity
+ function transferOwner2(uint256 tokenId, address newOwner) public {
+ require(_owners[tokenId] == msg.sender, "Transfer Not Owner");
+ _owners[tokenId] = newOwner;
+ }
+ ```
+* `assert`:不能解釋拋出異常的原因(相較`require`少了字符串),但仍會在檢查條件不成立時拋出異常。
+ ```Solidity
+ function transferOwner3(uint256 tokenId, address newOwner) public {
+ assert(_owners[tokenId] == msg.sender);
+ _owners[tokenId] = newOwner;
+ }
+ ```
+#### 驗證
+輸入任意數字、非0地址,呼叫以各種語法寫的異常訊息。
+
+
+
+
+* `error`方法`gas`消耗:24457(加入參數後`gas`消耗:24660)
+* `require`方法`gas`消耗:24755
+* `assert`方法`gas`消耗:24473
+`error`方法`gas`消耗最少,`require`方法消耗最多,因此在求最小`gas`消耗下可以多加使用`error`。
diff --git a/jaxrunboo.md b/jaxrunboo.md
index 1570bc9e..9ecb393e 100644
--- a/jaxrunboo.md
+++ b/jaxrunboo.md
@@ -398,4 +398,34 @@ function getString2(uint256 _number) public pure returns(string memory){
###
+### 2024.09.29
+
+#### 导入
+
+关键词 import
+
+导入方式:
+
+1. 通过文件的相对位置导入
+2. 通过全局符号,导入合约特定的全局符号
+3. 通过网址引入
+4. 通过npm的目录导入
+
+```solidity
+
+//1
+import './3_Ballot.sol';
+//2
+import {Ballot} from './3_Ballot.sol';
+//3
+import 'https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/Address.sol';
+//4
+import '@openzeppelin/contracts/access/Ownable.sol';
+
+```
+
+接下来就可以很简单的像使用库一样,通过using for语句或者直接静态函数引用的方式来使用。
+
+###
+