전제 조건 및 설정
이 자습서에서는 워크샵 리포지토리를 샘플 프로젝트로 사용합니다:
wake up
Bash
복사
깨우기프린트
깨우기 출력
Bash
copy
이름별로 특정 프린터 실행:
자습서 1: 첫 번째 프린터 만들기 - 계약 나열
프로젝트의 모든 계약을 나열하는 간단한 프린터부터 시작해 보겠습니다. 이 예에서는 보다 복잡한 분석에서 사용할 핵심 개념을 소개합니다.
프린터 구조 만들기
다음 명령을 실행하여 첫 번째 프린터를 빌드합니다: span>
from __future__ import annotationsimport networkx as nximport rich_click as< span leaf=""> clickimport wake.ir as irimport wake.ir.types as typesfrom rich importprintfrom wake.cli import SolidityNamefrom wake.printers import 프린터, 프린터class ListContractsPrinter(Printer):def print( self) ->없음:pass @printer. command(name="list-contracts")def cli(self) -& gt; 없음:pass
< span leaf="">파이썬
복사
이 템플릿의 각 템플릿의 템플릿의 일부입니다:
방문자 모드 구현
Wake는 방문자 패턴을 사용하여 컨트랙트의 추상 구문 트리(AST)를 트래버스합니다. 방문자 패턴을 사용하면 Wake가 코드의 구조를 자동으로 탐색하여 컨트랙트나 함수 정의와 같은 특정 요소에 반응할 수 있습니다.
컨트랙트를 나열하기 위해 visit_contract_definition> 코드 베이스의 각 컨트랙트에 대해 호출되는 메서드를 재정의합니다.
이 메서드를 ListContractsPrinter에 추가하세요. span leaf=""> 클래스:
wake print list-contracts
Bash
복사
이번 명령은 프린터를 실행하여 프로젝트에 있는 모든 컨트랙트 이름을 인쇄합니다.
출력 개선
기본 구현은 인터페이스와 상속된 컨트랙트를 포함한 모든 컨트랙트를 표시합니다. 배포 가능한 컨트랙트만 표시하도록 개선해 보겠습니다.
def visit_contract_. 정의(self, 노드: ir.ContractDefinition) -> 없음:if< span leaf="">len(node.child_contracts) ! = 0:returnif node. kind! = ir.enums.ContractKind.CONTRACT:returnprint(node.name) p>
파이썬
복사
계약 정의 클래스에는 결과를 필터링하는 데 사용할 수 있는 속성이 포함되어 있습니다. 전체 참조는 다음을 참조하세요:. https://ackee.xyz/wake/docs/latest/api-reference/ir/declarations/contract-definition/
완전한 구현
이것이 최종 버전으로, 우려 사항을 적절히 분리하여 트래버스 중에 데이터가 수집되고 span>print() 표시 방법:
튜토리얼 2 컨트랙트 함수 분석
보안에는 외부에서 호출할 수 있는 함수를 아는 것이 필수적입니다. 공개 '인출' 또는 '전송' 함수는 종종 컨트랙트의 공격 표면을 정의합니다. 모든 공개 및 외부 함수를 나열하여 공격 표면을 매핑하는 프린터를 만들어 보겠습니다.
함수 프린터 설정
새 프린터 생성하기:
class ListFunctionsPrinter(Printer): 계약: 계약:list[ir.ContractDefinition] = []def visit_. contract_definition(self, node: ir.ContractDefinition) -> 없음:& self.contracts.append(node)
Python
복사
상속된 계층 처리
print()메서드에서는 기본 계약에서 파생 계약으로 상속 계층 구조를 반복하여 각 수준을 표시합니다. 호출 가능한 함수의 각 수준을 보여줍니다:
def get_callable_final_functions(self, contract: ir. ContractDefinition) -> list[ir.FunctionDefinition]:return [\ func for func in contract.functions\iflen< (func.child_functions) == 0#은 최종 구현이고< span leaf=""> func.visibility in [ir.enums.Visibility.PUBLIC, ir.enums. Visibility.EXTERNAL]\ ]
. Python
복사
함수 프린터 실행
프린터를 실행하여 상속 계층 구조 및 호출 가능한 함수 보기:
Contract: Context컨트랙트: 소유 가능함수: 소유자 소유권 포기< span leaf=""> transferOwnership계약: 단일 토큰 저장소함수: 생성자 입금 출금 비상출금 비상출금 s span> balanceOf setDepositLimits--------------------계약: EIP712예시함수: 생성자 DOMAIN_. SEPARATOR castVoteBySignature getVoteCounts----------------- ---계약: 컨텍스트계약: IERC20계약: IERC20Metadata계약: IERC20Errors계약: ERC20기능: 이름 기호 소수점 totalSupply balanceOf . balanceOf transfer allowance approve transferFrom계약: IERC20Permit계약: IERC5267계약. EIP712기능: eip712도메인계약: Nonces. 계약: ERC20Permit기능: 허가 nonces DOMAIN_SEPARATOR계약: 허가 토큰기능: constructor permit  생성자--------------------컨트랙트: 토큰함수: constructor mintTokens transfer transferWithBytes mintToken: . transferWithBytes getBalance--------------------컨트랙트: 컨텍스트< 계약: IERC20계약: IERC20Metadata계약: IERC20Errors컨트랙트: ERC20기능: 이름 기호 소수점 totalSupply balanceOf transfer allowance approve transferFromContract. MockERC20함수: constructor--------------------
Bash
Copy
이 출력은 각 계약의 상속 및 호출 가능한 진입점에 대한 빠른 시각적 맵을 제공합니다.
@printer.command(name="list-functions")@click.option("--contract-name", type=str, required=False)def cli(self, contract_name: str | span>없음) -> 없음:  . ; self.contract_name = contract_name
Python
복사
조건부 필터링 로직
< span leaf="">print()이 메서드는 이제 특정 컨트랙트가 요청되었는지 확인합니다. 컨트랙트 이름이 제공되지 않으면 배포 가능한 모든 컨트랙트를 나열합니다. 이름이 지정되면 리프 계약이 아니더라도 해당 계약의 계층 구조로만 드릴다운합니다.
CLI 옵션으로 전체 구현
이것이 옵션 계약 필터링이 있는 최종 프린터입니다! .
## 배포 가능한 모든 컨트랙트 분석wake print< list-functions## 특정 컨트랙트에 집중wake print list-functions --contract-name Token
Bash<
복사
다음 단계
프린터는 지도를 제공하고, 탐지기는 취약점을 찾습니다. 이 두 가지를 함께 사용하면 솔리디티 감사가 수작업의 번거로움에서 체계적이고 인사이트가 풍부한 프로세스로 전환됩니다. 모든 프린터는 복잡한 코드를 더 명확하게 만들고 검토하는 스마트 계약의 보안을 강화합니다.
취약점 탐지를 위해 Wake는 시각화를 넘어 실제 보안 문제를 식별하는 별도의 탐지기 시스템을 제공합니다. 프린터가 지도를 제공하면 탐지기가 문제를 찾아냅니다.
프린터를 커뮤니티에 다시 기여하는 것을 고려하세요. 분석 도구는 공유할 때 가장 강력하며, 사용자 지정 프린터는 다른 감사자가 복잡한 코드 베이스를 더 효과적으로 이해하는 데 도움이 될 수 있습니다.