前提条件とセットアップ
このチュートリアルでは、サンプルプロジェクトとしてワークショップリポジトリを使用します。span>
起動
Bash
コピー
wake プリント
wake プリント
Bash
コピー
名前で特定のプリンタを実行する:
チュートリアル1: 最初のプリンタを作成する - 契約の一覧表示
プロジェクト内のすべての契約を一覧表示する簡単なプリンタから始めましょう。この例では、より複雑な分析で使用する核となる概念を紹介します。
プリンター構造を作成する
次のコマンドを実行して、最初のプリンターを作成します。
from __future__ インポート annotationsインポート networkx as nxインポート rich_click as clickimport weak.ir asとなります。 irimport wake.ir.types as ;typesfrom rich importprintfrom wake.cli import SolidityNamefrom wake.printers import Printer, printerclass ListContractsPrinter(Printer):def print(self) -> なし:パス @printer.command(name="契約一覧")def cli(self)-&。gt; なし:パス
Python
コピー
以下は、テンプレートのそれぞれの部分です。の部分です:
ビジターモードの実装
Wakeは、コントラクトの抽象構文木(AST)をトラバースするためにビジターパターンを使用します。Visitor パターンにより、Wake はコードの構造を自動的にナビゲートし、コントラクトや関数定義などの特定の要素に反応できるようになります。
コントラクトを一覧表示するには、オーバーライドします。code> メソッドをオーバーライドします。
このメソッドを ListContractsPrinterに追加します。span leaf=""> Class:
wake print list-contracts
Bash
Copy
このコマンドは、プリンタを起動し、すべての契約を印刷します。コマンドはプリンタを実行し、プロジェクトで見つかったすべての契約名を印刷します。
出力を改善する
基本実装では、インターフェイスや継承されたコントラクトを含むすべてのコントラクトが表示されます。
def visit_contract_definition(self, node: ir.ContractDefinition) -> なし:iflen(node.child_contracts) != 0:returnif ノード.kind !=ir.enums.ContractKind.CONTRACT:returnprint(node.name)
Python
copy
ContractDefinitionクラスには、結果をフィルタリングするために使用できるプロパティが含まれています。完全なリファレンスについては、 を参照してください。https://ackee.xyz/wake/docs/latest/api-reference/ir/declarations/contract-definition/
完全な実装
これは最終版で、適切な関心事の分離がなされています。span>print() メソッドで表示します:
チュートリアル2コントラクト関数を分析する
外部から呼び出せる関数を知ることは、セキュリティにとって不可欠です。すべてのパブリック関数と外部関数をリストアップすることで、攻撃対象領域をマッピングするプリンタを作成しましょう。
ファンクションプリンターのセットアップ
新しいプリンターの作成:
クラス ListFunctionsPrinter(Printer): コントラクト: リスト[ir.ContractDefinition]=[]定義 visit_する。contract_definition(self, node: ir.ContractDefinition) -> なし:&。nbsp; self.contracts.append(node)
Python
コピー継承された階層の処理
print() メソッドでは、基本契約から派生契約までの継承階層を繰り返し、呼び出し可能な関数の各レベルを表示します。
def get_callable_final_functions(self, contract: ir.ContractDefinition) -> list[ir.FunctionDefinition]:return [ func forfunc in contract.functionsiflen<(func.child_functions) == 0#が最終実装かつ func.visibility in [ir.enums.Visibility.PUBLIC、ir.enums.Visibility.EXTERNAL]です。Pythonコピー
関数プリンターの実行
プリンターを実行して、継承階層と呼び出し可能な関数を確認します:
契約: コンテキストContract: Ownable関数: owner renounceOwnership<コンストラクタ 預金 出金 緊急出金 緊急出金 緊急出金  balanceOf setDepositLimits--------------------契約:EIP712Example関数: コンストラクタ DOMAIN_SEPARATOR castVoteBySignature getVoteCounts-----------------.契約:コンテキスト契約:IERC20契約:IERC20メタデータContract: IERC20ErrorsContract: ERC20機能: 名前 symbol decimals totalSupply balanceOf balanceOf transfer allowance approve transferFrom契約: IERC20Permit契約: IERC5267契約。EIP712機能: eip712Domain契約: Nonces契約: ERC20Permit機能: permit nonces DOMAIN_SEPARATOR契約: PermitToken関数: コンストラクタ permit コンストラクタ--------------------契約: トークン関数: コンストラクタ mintTokens transfer transferWithBytes mintToken: transferWithBytes getBalance--------------------契約: Context<契約: IERC20契約: IERC20Metadata契約: IERC20ErrorsContract: ERC20関数: 名前 シンボル 小数 totalSupply balanceOf transfer allowance approve transferFrom契約。MockERC20関数: コンストラクタ--------------------
バッシュ
コピー
出力は、各契約の継承と呼び出し可能なエントリポイントの視覚的なマップを素早く提供します。
@printer.command(name="list-functions"関数の呼び出し)@click.option("--contract-name", )タイプ=str, required=False)def cli(self, contract_name: str | なし) -> なし: self.contract_name = contract_name
Python
コピー
条件付きフィルタリングロジック
print() このメソッドは、特定の契約が要求されたかどうかをチェックします。コントラクト名が提供されない場合、プリンタはすべてのデプロイ可能なコントラクトをリストします。名前が指定された場合、リーフ契約でなくても、その契約の階層にドリルダウンします。
CLIオプションによる完全な実装
これは、オプションのコントラクトフィルタリングを備えた最終的なプリンターです!.
## 展開可能なすべてのコントラクトを分析するwake print< list-functions## 特定の契約に焦点を当てるwake print list-functions --contract-name Token
Bash<
コピー
以下の手順
プリンターはマップを提供し、検出器は脆弱性を探します。一緒に使用することで、Solidity の監査を手作業から構造化された洞察力のあるプロセスに変えます。あなたが書くすべてのプリンターは複雑なコードを明確にし、あなたがレビューするスマートコントラクトのセキュリティを強化します。
脆弱性検出のために、Wakeは視覚化を超えて実際のセキュリティ問題を特定する検出器の独立したシステムを提供します。プリンターは地図を提供し、検出器は問題を見つけます。
プリンターをコミュニティに還元することを検討してください。分析ツールは共有されたときに最も強力であり、あなたのカスタム プリンタは、他の監査人が複雑なコード ベースをより効果的に理解するのに役立つかもしれません。