transaction
➞ call 合約 function 的細節寫在這
transaction lifecycle 簡化版
requested ➟ included ➟ recognized
function name() public view returns (string)
function symbol() public view returns (string)
function decimals() public view returns (uint8)
function totalSupply() public view returns (uint256)
function balanceOf(address _owner) public view returns (uint256 balance)
function transfer(address _to, uint256 _value) public returns (bool success)
function transferFrom(address _from, address _to, uint256 _value) public returns (bool success)
function approve(address _spender, uint256 _value) public returns (bool success)
function allowance(address _owner, address _spender) public view returns (uint256 remaining)
A 要給 B 10 個 token
A 執行 transfer(B, 10)
或
A 執行 approve(B, 10)
B 再執行 transferFrom(A, someAddress, 10)
A 之前有 approve B 一些 token,假設 10 個
後來 A 發現需要 approve B 更多 token,假設需要 20 個
A 需要再 call approve(B, 20)
題外話
很多合約會直接讓你一開始就 approve 最大值
好處是之後不用再 approve 付 gas fee
壞處是如果那個合約被駭或是有 bug 你的 token 會全部被轉走
.
allowance 10
allowance 20
allowance 0
A 給 B 20 個 token
A call approve(B, 20)
B call transferFrom(A, B, 20)
allowance 10
allowance 20
allowance 0
A 給 B 30 個 token
allowance 0
B call transferFrom(A, B, 10)
A call approve(B, 20)
B call transferFrom(A, B, 20)
複習一下 transaction 的 lifecycle
requested ➟ included ➟ recognized
增加 allowance 前要先改為 0
(弱弱的)
加開 increaseAllowance 跟 decreaseAllowance 兩個 func
處理要增加或減少 allowance 的情形
approve 只用在 initial approve,或是都不要用
OpenZeppelin 的 ERC-20 實作
因為 approve 跟 transferFrom 是兩個 transaction
不是在同一個 transaction 內
所以有了趁虛而入的機會
可以包含好幾個動作
某個人執行 某個 contract 的 某個 function
某個 function 改變了一些值之後 又執行另外一個 function
另外一個 function 也改變了一些值
然後又執行另外一個 contract 的某個 function
...
最後完成
一個 transaction
會都有生效或是都沒生效
而且不必擔心做到一半被別人干擾
block 123
transaction 2345 success
transaction 2346 failed
transaction 2347 success
•
•
•
又想要在同一個 transaction 內的話
可以透過合約來完成
contract A {
function b() {
c();
d();
e();
...
}
}
exactInput
exactOutput
➞ 給定值的 ETH 看能換多少是多少
➞ 要換到定值的 token
假設要用 uniswap 的合約把 ETH 換成某 token
1 個 ETH 能換多少 token 不一定
要給多一些 ETH 才不會失敗
v2 會自動退 ETH
v3 不會 要再 call refundETH
他會把他所有剩的 ETH 給你
如果我先 exactOutput
再執行 refundETH
分 2 個 transaction 的話
中間可能會被別人先 call refundETH
該還我的 可能會被別人拿走
必須要透過合約寫在同一個 function 裡面
才會在同一個 transaction 執行這兩個動作
別人才沒有介入的機會
我們執行合約 A 的 function,把 ETH 附給他
合約 A 用他的名義去換 token 回來
然後再把 token 轉給我們
退我們 ETH
要獲得授權 不一定要 send transaction
只要有簽章就可以確認
好像不行?
因為 approve 還是要我們來 approve?
前面的 approve/transferFrom
授權 跟 讓別人轉走 兩個動作
可以透過合約 在同一個 transaction 完成嗎
對方有你的簽章,再一起拿去 send transaction 就好
可以沒有抵押就借超多錢
只要在同一個 transaction 可以還回去
就不會被 revert
提供 flash loan 的 function 會做三件事
1. 轉錢給 receiver
2. 執行 receiver 準備好的 callback
3. 把錢轉回來
是 DeFi 的最大特色 (之一)
也是 DeFi 的最大衝擊 (嗎)
Flash Loan Attack
操控價格不用本錢
騙 DeFi 合約當韭菜