timezone |
---|
Asia/Shanghai |
- 自我介绍 資安研究員 WEB3新手
- 你认为你会完成本次残酷学习吗? 會
進度: Solidity 101 1~4
https://docs.soliditylang.org/en/v0.8.27/types.html#value-types
- 值 (Value Types)
- 布林 (Booleans):
true
,false
- 整數 (Integers)
- 32 種有號整數:
int8
,int16
,int24
,int32
,...int256
(8bit to 256bit) - 32 種無號整數:
uint8
,uint16
,uint24
,uint32
,...uint256
- 沒有浮點數型別, 除法之後結果會取整數
- 32 種有號整數:
- 地址 (Address)
address
: 20 Byte 值- 可以將
uint160
,整數,bytes20
,合約類型轉型為address// uint160 <-> address uint160 number = 123456789; address addr = address(number); uint160 backToUint = uint160(addr); // integer literals address addr = address(123456789); // bytes20 -> address bytes20 b = bytes20(address(0x1234567890abcdef1234567890abcdef12345678)); address addr = address(b); // contract types contract MyContract { // 合约内容 } MyContract myContract = MyContract(0x1234567890abcdef1234567890abcdef12345678); address addr = address(myContract);
- 可以將
address payable
: 具有成員函數transfer
及send
- 合約 (Contract Types)
- 可以與
address
型別互相轉換
- 可以與
- 位元組陣列 (Fixed-size byte arrays)
bytes1
,bytes2
,bytes3
, …,bytes32
- 枚舉 (Enum)
- 函數 (Function Types)
https://docs.soliditylang.org/en/v0.8.27/types.html#function-types
function (<parameter types>) {internal|external} [pure|view|payable] [returns (<return types>)]
- 存取控制
{internal|external|public|private}
- 權限
[pure|view|payable]
- 可讀可寫合約狀態:
payable
(修改全域變數) - 只可讀不可寫:
view
(可讀取全域變數) - 不可讀不可寫:
pure
(不可讀取全域變數)
- 可讀可寫合約狀態:
- 返回語法
- 只定義返回型別 (類似大部分程式語言)
- 命名式返回: 定義返回型別及返回變數名稱,不須在程式碼中多一行指定 return
- 命名式返回要在程式碼中多一行指定 return 回傳值也可以
- 解構式取得回傳值
- 可取得全部
(_number, _bool, _array) = returnNamed();
- 或對位取得部分
(, _bool2, ) = returnNamed();
- 可取得全部
- 存取控制
- 布林 (Booleans):
進度: Solidity 101 5~6
- 資料位置 (Data Location)
https://docs.soliditylang.org/en/v0.8.27/types.html#data-location
- 分三種
storage
儲存在鏈上memory
儲存在記憶體中 不上鏈calldata
儲存在記憶體中 不上鏈 不能修改 (一般用於函數的參數)
- 不同資料類型相互賦值時,會產生獨立的副本,修改新變數不會改到原數值
- 相同資料類型相互賦值時,會建立引用,修改新變數會改到原變數值
- 分三種
- 變數作用範圍
- 狀態變數: 儲存在鏈上的變數
- 全域變數: 作用範圍在整個合約中
- 區域變數: 作用範圍僅在函數中
- 乙太單位
wei
: 1gwei
: 1e9ether
: 1e18
- 時間單位
seconds
minutes
hours
days
weeks
- 引用 (Reference Types)
array
- 宣告
- 固定長度
uint[5] arr1;
- 可變長度
uint[] arr2;
- 固定長度
- 初始化
- 可用 new
uint[] memory arr1 = new uint[](5); bytes memory arr2 = new bytes(9);
- 可用 new
- 成員函數
length
push()
在 array 最後添加 0push(3)
在 array 最後添加 3pop()
移除最後一個元素
- 宣告
struct
struct Student{ uint256 id; uint256 score; } Student student; function initStudent1() external{ Student storage _student = student; // _student = reference of student _student.id = 11; _student.score = 100; }
進度: Solidity 101 7~8
-
映射 (Mapping Types)
https://docs.soliditylang.org/en/latest/types.html#mapping-types
mapping(_KeyType => _ValueType)
_KeyType
只能使用內建的值類型, 不能使用結構_ValueType
可以使用結構
- 儲存位置必須為
storage
- 不能用於
public
函數的參數或回傳值
-
變數初始值
- 值類型
boolean
:false
string
:""
int
:0
uint
:0
enum
: 第一個元素address
:0x0000000000000000000000000000000000000000
(address(0)
)function
- 引用類型
mapping
key/value的初始值的映射struct
成員類型的初始值array
- 動態
[]
- 靜態
- 動態
delete a
會使變數a
的值變為初始值
- 值類型
進度: Solidity 101 9~11
-
常數
constant
須在宣告時賦值, 後續不能改TypeError: Cannot assign to a constant variable.
immutable
可在宣告時或在建構函數中賦值, 後續不能改TypeError: Immutable state variable already initialized.
string
和bytes
可以宣告為constant
, 但不能為immutable
-
流程控制
if-else
for
loopwhile
loopdo-while
loop
-
建構函數
- 合約布署時會執行的函數
- 0.4.22 版本後, 以
constructor
關鍵字定義建構函數, 避免出現因 typo 造成漏洞example: Ethernaut CTF Fal1out
-
修飾器 (Modifier)
- 控制合約權限
進度: Solidity 101 12
-
事件
event
: EVM 上日誌的抽象概念- Example
event Transfer(address indexed from, address indexed to, uint256 value);
- 釋放事件
// 定义_transfer函数,执行转账逻辑 function _transfer( address from, address to, uint256 amount ) external { _balances[from] = 10000000; // 给转账地址一些初始代币 _balances[from] -= amount; // from地址减去转账数量 _balances[to] += amount; // to地址加上转账数量 // 释放事件 emit Transfer(from, to, amount); }
- Example
-
日誌 (Log)
topics
: 函數簽名 e.g.keccak256("Transfer(address,address,uint256)")
data
: 事件中不含index
的資料會儲存在 data
進度: Solidity 101 13~15
-
繼承
inheritance
- 合約繼承
contract ChildContract is ParentContract { }
- 父合約中希望子合約重寫的函數, 要加上
virtual
關鍵字function hip() public virtual { emit Log("Parent"); }
- 子合約內重寫合約函數, 要加上
override
關鍵字function hip() public override { emit Log("Child"); }
- 多重繼承
contract ChildContract is GrandParentContract, ParentContract, { }
- 輩分高 -> 輩分低
- 若函數在多個繼承的合約都存在, 子合約裡必須重寫
override(GrandParent, Parent)
- 父合約中希望子合約重寫的函數, 要加上
- 修飾器繼承
- 在繼承的合約中, 可以直接用父合約中的修飾器, 也可以重寫
modifier exactDividedBy2And3(uint _a) override { }
- 在繼承的合約中, 可以直接用父合約中的修飾器, 也可以重寫
- 建構函數
- 繼承時宣告父建構函數的參數
contract DeFiHackLabsToken is ERC20("DeFiHackLabs", "HACK") { constructor(uint256 initialSupply) { _mint(msg.sender, initialSupply * 10 ** decimals()); } function decimals() public view virtual override returns (uint8) { return 18; } }
- 在子合約的建構函數中宣告建構函數的參數
contract DeFiHackLabsToken is ERC20 { constructor(uint256 initialSupply) ERC20("DeFiHackLabs", "HACK") { _mint(msg.sender, initialSupply * 10 ** decimals()); } function decimals() public view virtual override returns (uint8) { return 18; } }
- 繼承時宣告父建構函數的參數
- 於子合約中呼叫父合約函數
- 直接呼叫
ParentContract.func();
- 使用
super
關鍵字,會呼叫到最近的父合約函數super.func(); // ParentContract.func() 而不是 GrandParent.func()
- 直接呼叫
- 鑽石/菱形繼承: 繼承自兩個以上的合約
- 注意使用
super
關鍵字的呼叫順序
- 注意使用
- 合約繼承
-
抽象合約
- 合約中有未實現的函數, 需標註為抽象
abstract
, 該為實現函數需標註virtual
abstract contract InsertionSort{ function insertionSort(uint[] memory a) public pure virtual returns(uint[] memory); }
- 合約中有未實現的函數, 需標註為抽象
-
接口/介面 (Interface)
- 性質
- 不能包含狀態變數
- 不能包含建構函數
- 只能繼承接口合約
- 所有函數必須為
external
, 不能有功能 - 繼承接口的非抽象合約必須實現接口內功能
- 資訊
- 每個函數的
bytes4
選擇器, 函數簽名 - 接口 id
- 每個函數的
- 不須知道原始碼即可與之互動, 且與 ABI 可互相轉換
- 性質
-
異常種類
error
: solidity 0.8.4 新增, 可以在合約外定義error
, 在合約內搭配revert
使用, 較省 gasrequire
: solidity 0.8 之前, gas 隨著描述異常的字數增加而增加- e.g.
require(_owners[tokenId] == msg.sender, "Transfer Not Owner");
- e.g.
assert
: 確認某些已知條件, 常用於除錯- e.g.
assert(檢查條件);
- e.g.
進度: 複習 Solidity 101, 完成 Bootcamp 作業
進度: Solidity 102 16
- 函數重載 (overloading)
- 相同函數名稱,不同參數類型
modifier
無法 overloading- 如果出現多個匹配的函數, 會報錯
- e.g.
function f(uint8 _in) public pure returns (uint8 out) { out = _in; } function f(uint256 _in) public pure returns (uint256 out) { out = _in; } f(50);
- e.g.