區塊鏈知識:什麼是 approve ?
從結論來說,區塊鏈的 approve 是指允許某個地址,不管是合約或是哪個特定人士的地址,來操作你的某個 token ,在 approve 時可以設定允許的數量,這個數量代表了某個地址可以在不經過你同意的情況下操作你有限量的資產。
如果對某個不明的合約 approve 了會怎麼樣?
對方的地址會有權限使用你的特定資產,比如你 approve 他操作你的 USDT 100 個,那他就可以在你沒有同意的情況下轉移 100 個 USDT 。
approve 是怎麼運作的?
現在的 token 主要有三大類,ERC-20 、ERC-721、ERC1155 三種,三種的 approve 邏輯都差不多,以下我們將使用 ERC-20 的程式碼來說明 approve 的邏輯。
以上這份是來自 openzeppelin 的 ERC-20 標準函式庫,它實作了 ERC-20 所有需要的接口,讓我們先仔細看看 approve 的程式碼,他在這邊單純指定了 owner 等於 msgSender() 的值,這個 msgSender() 是來自 Context 合約的 function,他單純就是取得目前與合約互動的地址,並且把這些值往下傳至 _approve function ,可以看到它在這裡做的事情就是改寫了 _allowance 的值,把 amount 的值寫給 owner 指向的 spender 。
讓我們來看看這個 _allowance ,他是一個 mapping 資料,也就是一個 key — value 的資料對,且是一個二層的資料對,直接在該頁面搜尋 _allowance 搜尋可以得知總共有 increaseAllowance 及 decreaseAllowance 及 allowance 這三個 function 有用到這筆資料,其中 allowance 這個 function 可以取得 owner 對 spender 對應的值,也在 _spendAllowance 這邊被呼叫到,用於取得 approve 的值,而這個 function 最後再呼叫到 _approve 改寫原本的寫在 _allowance 裡面的值。
而唯一有用到 _spendAllowance 這個 function 的地方僅有在 transferFrom ,且這也是花費 token 的 function。
我們先回頭看看一般的 transfer 做了什麼,transfer 做的事情就只有把 owner 這個變數賦予調用者的地址,並且拿著這些值去呼叫真正執行交易的 _transfer。
而 transferFrom 與這裡最大的不同就是他可以多帶一個 form 的地址參數,這個 from 決定了 token 從哪邊消耗,to 則決定了 token 要去哪裡,可以看到在 163 行的地方把 spender 指定為調用該 function 的地址,也就是說,調用這個 function 的人 並不用是 from 的地址本人 。
transferFrom 接下來做的事情就是先呼叫到 _spendAllowance 檢查 _allowance 的值是不是大於等於這次要消費的值,如果檢查沒問題則會將元先的 _allowance 減掉這次消費的值,並且接著執行 _transfer。
由上述的邏輯可以知道,當你 approve 了某個地址,這個地址就可以利用 transferFrom 這個 function 直接調用你的 token。因此請絕對不要隨意 approve 來路不明的合約,你的地址會有巨大的安全風險。
如果已經 approve 了某些網站可以怎麼做?
如果已經自覺地址處在高度的風險下的話,建議直接換一個錢包地址轉移資產是最萬無一失的辦法。
或是可以參考這邊的教學確保自己的資產處於安全狀態。