使用 Slither 來檢測你的 Solidity 智能合約程式碼

  • FrankFrank
  • /
  • 7 分鐘閱讀
  • /
  • Sep 22, 2021
  • /
  • - views

以太坊的智能合約程式一旦發佈便無法更改,因此程式的安全性尤為重要。因此,使用檢測工具對程式碼進行檢測,可以發現一些常見的安全隱患,避免因程式漏洞引致的各種損失。

Slither

Slither 是一個用 Python 編寫的 Solidity 的「靜態」檢測工具,可以偵測常見的 Solidity 程式漏洞。其功能包括:

  • 檢測 Solidity的常見程式漏洞,誤報率低;
  • 標識錯誤在源程式中發生的位置;
  • 可以集成到 CICD 中使用;
  • 正確解析 99.9% 的所有公共 Solidity 程式;
  • 掃描速度快,每個智能合約平均執行時間少於 1 秒;

安裝

官網提供了多種安裝方式,因為考慮到有太多的依賴和開發環境設定,作為一個懶人,本人認為用 docker 方式安裝會最方便,因此本文就以 docker 安裝來舉例,其他安裝方式可以查閱官網的說明。

安裝 docker image:

docker pull trailofbits/eth-security-toolbox

安裝 docker image 之後就可以運行 slither 了,但要記得指定 docker 共享 volume,這樣才可以在 docker 容器內訪問到電腦中的檔案:

docker run -it -v /your/share/folder:/share trailofbits/eth-security-toolbox

執行上述指令後便進入了 slither 的 container 中:

檢查 solc 版本

這裡要注意,因為 solidity 有很多不同的版本,掃描時最好根據要掃描的 solidity 檔案指定對應版本的 solc 編譯器。而預設的 image 中未必有你想要的 solc 編譯器版本,你可以在 container 內運行以下指令,可以查看已經安裝的 solc 編譯器:

solc-select -l

如果發現沒有安裝對應的 solc 版本,則需要先安裝 solc 後再繼續。

# 將下面的 v0.4.15 更改為你所需要的版本

curl -L https://github.com/ethereum/solidity/releases/download/v0.4.15/solc-static-linux --output solc-v0.4.15

sudo mv ./solc-v0.4.15 /usr/bin/

chmod +x /usr/bin/solc-v0.4.15

掃描本地 sol 檔案

因為共享了共享目錄,我們在 container 就可以直接運行 slither 指令:

slither path_to_your_contract.sol --solc /usr/bin/solc-v0.4.15 

其中 path_to_your_contract.sol 是你要掃描的 solidity 檔案, --solc /usr/bin/solc-v0.4.15 則是指定 solc 編譯器的版本。

如上圖所示, slither 會在熒幕上顯示出掃描結果。根據問題的嚴重程度,會有不同的顏色表示。同時亦會給出問題的解釋,可以點開相應的連結查看。

如果想要將掃描結果以 json 形式輸出到檔案中,可以執行:

slither path_to_your_contract.sol --solc /usr/bin/solc-v0.4.15 --json result.json

如果你的智能合約中使用了類似 import @openzeppelin/xxx 等的以 “@” 開頭的 import 語句,可能會出現 File not found 的錯誤:

Error: Source "@openzeppelin/contracts/utils/Counters.sol" not found: File not found.
  --> /src/contracts/BaseERC721.sol:12:1:
   |
12 | import "@openzeppelin/contracts/utils/Counters.sol";
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

解決方法是需要指定 --solc-remaps 來告訴編譯器 openzeppelin 的具體位置:


slither path_to_your_contract.sol --solc /usr/bin/solc-v0.4.15 --solc-remaps @openzeppelin/=/src/node_modules/@openzeppelin/

掃描已經發佈的合約

slither 亦支援掃描已經將原始碼發佈到 etherscan 上的合約, 運行:

# 0x7F37f78cBD74481E593F9C737776F7113d76B315 是合約地址。
slither 0x7F37f78cBD74481E593F9C737776F7113d76B315

# 若是 testnet 網絡,地址前加上網絡名稱
slither rinkeby:0x7F37f78cBD74481E593F9C737776F7113d76B315

如果運行出現錯誤,可能是 solc 版本不相符, 使用 solc-select 切換到對應版本後再運行即可。如果對應版本沒有安裝,請參考上一節的做法安裝即可。