Neste tutorial, utilizaremos o repositório workshop como projeto de exemplo:
wake up
Bash
copiar
wake print
Bash
copiar
Executar uma impressora específica pelo nome:
Tutorial 1: Criar a sua primeira impressora – listar contratos
Vamos começar com uma impressora simples que lista todos os contratos no projeto. Este exemplo apresenta os conceitos principais que você usará em análises mais complexas.
Criar a estrutura da impressora
Execute os seguintes comandos para montar sua primeira impressora:
from future import annotations
import networkx as nx
import rich_click as click
import wake.ir as ir
import wake.ir.types as types
from rich import print
from wake.cli import SolidityName
from wake.printers import Printer, printer
class ListContractsPrinter(Printer):
@print
def print(self) -> None:
pass
A seguir, uma explicação do papel de cada parte do modelo:
print(self): método principal que exibe os resultados da análise
cli(): manipulador de interface de linha de comando para personalizar os parâmetros
Implementar o padrão visitante
Wake usa o padrão visitante para percorrer a árvore de sintaxe abstrata (AST) dos contratos. Este padrão permite que o Wake navegue automaticamente na estrutura do seu código, reagindo a elementos específicos (como contratos ou definições de funções).
Para listar contratos, vamos sobrescrever o método visit_contract_definition, que será chamado para cada contrato no código.
Adicione este método à sua classe ListContractsPrinter:
wake print list-contracts
Bash
copiar
Este comando executa sua impressora e imprime todos os nomes de contratos encontrados no seu projeto.
Melhorar a saída
A implementação básica exibe todos os contratos, incluindo interfaces e contratos herdados. Vamos aprimorá-la para mostrar apenas contratos implantáveis:
def visit_contract_definition(self, node: ir.ContractDefinition) -> None:
if len(node.child_contracts) != 0:
return
if node.kind != ir.enums.ContractKind.CONTRACT:
return
print(node.name)
Python
copiar
A classe ContractDefinition possui atributos que podem ser usados para filtrar os resultados. Para uma referência completa, consulte:
Implementação completa
Esta é a versão final, com uma separação adequada de responsabilidades — coletando dados durante a iteração e exibindo-os na função print:
Tutorial 2: Análise de funções de contrato
Saber quais funções podem ser chamadas externamente é fundamental para segurança: funções públicas ‘withdraw’ ou ‘transfer’ geralmente definem a superfície de ataque do contrato. Vamos criar uma impressora que liste todas as funções públicas e externas para mapear essa superfície.
@## Configurar impressora de funções
Crie uma nova impressora:
class ListFunctionsPrinter(Printer):
contracts: list[ir.ContractDefinition] = []
Na função print, percorremos a hierarquia de herança desde o contrato base até os derivados, exibindo cada nível de funções chamáveis:
def get_callable_final_functions(self, contract: ir.ContractDefinition) -> list[ir.FunctionDefinition]:
return [
func for func in contract.functions
if len(func.child_functions) == 0 # é implementação final
and func.visibility in [ir.enums.Visibility.PUBLIC, ir.enums.Visibility.EXTERNAL]
]
Python
copiar
@## Executar a impressora de funções
Execute a impressora para visualizar a hierarquia de herança e as funções chamáveis:
A função print agora verifica se um nome de contrato específico foi solicitado. Se não for fornecido, a impressora listará todos os contratos implantáveis. Se um nome for especificado, ela irá aprofundar apenas nesse contrato, mesmo que ele não seja uma folha na hierarquia.
Implementação completa com opções CLI
Esta é a versão final da impressora com filtragem opcional por contrato:
Focar em um contrato específico
wake print list-functions --contract-name Token
Bash
copiar
Próximos passos
A impressora fornece um mapa; o detector identifica vulnerabilidades. Juntos, eles transformam a auditoria de Solidity de uma tarefa manual árdua para um processo estruturado e perspicaz. Cada impressora que você cria pode tornar o código complexo mais claro — e aumentar a segurança dos contratos inteligentes que você revisa.
Para detectar vulnerabilidades, o Wake oferece um sistema de detectores separado, que vai além da visualização para identificar problemas de segurança reais. As impressoras fornecem o mapa; os detectores procuram por problemas.
Considere contribuir com sua impressora para a comunidade. Ferramentas de análise são mais poderosas quando compartilhadas, e sua impressora personalizada pode ajudar outros auditores a entenderem códigos complexos de forma mais eficiente.
Ver original
Esta página pode conter conteúdo de terceiros, que é fornecido apenas para fins informativos (não para representações/garantias) e não deve ser considerada como um endosso de suas opiniões pela Gate nem como aconselhamento financeiro ou profissional. Consulte a Isenção de responsabilidade para obter detalhes.
Automatizar a auditoria de Solidity com o script Wake Printer
Pré-requisitos e configurações
Neste tutorial, utilizaremos o repositório workshop como projeto de exemplo:
wake up
Bash
copiar
wake print
Bash
copiar
Executar uma impressora específica pelo nome:
Tutorial 1: Criar a sua primeira impressora – listar contratos
Vamos começar com uma impressora simples que lista todos os contratos no projeto. Este exemplo apresenta os conceitos principais que você usará em análises mais complexas.
Criar a estrutura da impressora
Execute os seguintes comandos para montar sua primeira impressora:
from future import annotations import networkx as nx import rich_click as click import wake.ir as ir import wake.ir.types as types from rich import print from wake.cli import SolidityName from wake.printers import Printer, printer
class ListContractsPrinter(Printer): @print def print(self) -> None: pass
Python
copiar
A seguir, uma explicação do papel de cada parte do modelo:
Implementar o padrão visitante
Wake usa o padrão visitante para percorrer a árvore de sintaxe abstrata (AST) dos contratos. Este padrão permite que o Wake navegue automaticamente na estrutura do seu código, reagindo a elementos específicos (como contratos ou definições de funções).
Para listar contratos, vamos sobrescrever o método visit_contract_definition, que será chamado para cada contrato no código.
Adicione este método à sua classe ListContractsPrinter:
wake print list-contracts
Bash
copiar
Este comando executa sua impressora e imprime todos os nomes de contratos encontrados no seu projeto.
Melhorar a saída
A implementação básica exibe todos os contratos, incluindo interfaces e contratos herdados. Vamos aprimorá-la para mostrar apenas contratos implantáveis:
def visit_contract_definition(self, node: ir.ContractDefinition) -> None: if len(node.child_contracts) != 0: return if node.kind != ir.enums.ContractKind.CONTRACT: return print(node.name)
Python
copiar
A classe ContractDefinition possui atributos que podem ser usados para filtrar os resultados. Para uma referência completa, consulte:
Implementação completa
Esta é a versão final, com uma separação adequada de responsabilidades — coletando dados durante a iteração e exibindo-os na função print:
Tutorial 2: Análise de funções de contrato
Saber quais funções podem ser chamadas externamente é fundamental para segurança: funções públicas ‘withdraw’ ou ‘transfer’ geralmente definem a superfície de ataque do contrato. Vamos criar uma impressora que liste todas as funções públicas e externas para mapear essa superfície.
@## Configurar impressora de funções
Crie uma nova impressora:
class ListFunctionsPrinter(Printer): contracts: list[ir.ContractDefinition] = []
Python
copiar
@## Processar hierarquia de herança
Na função print, percorremos a hierarquia de herança desde o contrato base até os derivados, exibindo cada nível de funções chamáveis:
def get_callable_final_functions(self, contract: ir.ContractDefinition) -> list[ir.FunctionDefinition]: return [ func for func in contract.functions if len(func.child_functions) == 0 # é implementação final and func.visibility in [ir.enums.Visibility.PUBLIC, ir.enums.Visibility.EXTERNAL] ]
Python
copiar
@## Executar a impressora de funções
Execute a impressora para visualizar a hierarquia de herança e as funções chamáveis:
Contract: ContextContract Functions: owner, renounceOwnership, transferOwnership
Contract: SingleTokenVault Functions: constructor, deposit, withdraw, emergencyWithdraw, balanceOf, setDepositLimits
Contract: EIP712Example Functions: constructor, DOMAIN_SEPARATOR, castVoteBySignature, getVoteCounts
Contract: ContextContract Contracts: IERC20, IERC20Metadata, IERC20Errors, ERC20 Functions: name, symbol, decimals, totalSupply, balanceOf, transfer, allowance, approve, transferFrom
Contract: IERC20Permit Contracts: IERC5267, EIP712 Functions: eip712Domain, nonces, permit, nonces, DOMAIN_SEPARATOR
Contract: PermitToken Functions: constructor
Contract: Token Functions: constructor, mintTokens, transfer, transferWithBytes, getBalance
Contract: Context Contracts: IERC20, IERC20Metadata, IERC20Errors, ERC20 Functions: name, symbol, decimals, totalSupply, balanceOf, transfer, allowance, approve, transferFrom
Contract: MockERC20 Functions: constructor
Este output fornece uma visualização rápida da hierarquia de herança e pontos de entrada chamáveis de cada contrato.
@## Comando CLI para listar funções
@printer.command(name=“list-functions”) @click.option(“–contract-name”, type=str, required=False) def cli(self, contract_name: str | None) -> None: self.contract_name = contract_name
Python
copiar
Lógica de filtragem condicional
A função print agora verifica se um nome de contrato específico foi solicitado. Se não for fornecido, a impressora listará todos os contratos implantáveis. Se um nome for especificado, ela irá aprofundar apenas nesse contrato, mesmo que ele não seja uma folha na hierarquia.
Implementação completa com opções CLI
Esta é a versão final da impressora com filtragem opcional por contrato:
Focar em um contrato específico
wake print list-functions --contract-name Token
Bash
copiar
Próximos passos
A impressora fornece um mapa; o detector identifica vulnerabilidades. Juntos, eles transformam a auditoria de Solidity de uma tarefa manual árdua para um processo estruturado e perspicaz. Cada impressora que você cria pode tornar o código complexo mais claro — e aumentar a segurança dos contratos inteligentes que você revisa.
Para detectar vulnerabilidades, o Wake oferece um sistema de detectores separado, que vai além da visualização para identificar problemas de segurança reais. As impressoras fornecem o mapa; os detectores procuram por problemas.
Considere contribuir com sua impressora para a comunidade. Ferramentas de análise são mais poderosas quando compartilhadas, e sua impressora personalizada pode ajudar outros auditores a entenderem códigos complexos de forma mais eficiente.