Điều kiện tiên quyết và thiết lập
Trong hướng dẫn này, chúng ta sẽ sử dụng kho lưu trữ workshop làm dự án ví dụ:
đánh thức
Bash
Sao chép
đánh thứcin
Bash
Sao chép
Sao chép
Sao chép
Sao chép
Sao chép
clickimport wake.ir as irimport wake.ir.types as typesfrom rich importprintfrom wake.cli import SolidityNametừ wake.printers nhập Máy in, máy inlớp ListContractsPrinter(Máy in):def print(self) -> Không có:pass @printer.command(name="list-contracts")def cli(self) -> None:pass
Python
Sao chép
Sau đây là chức năng của từng phần trong mẫu:
Triển khai Mẫu Visitor
Wake sử dụng mẫu Visitor để duyệt cây cú pháp trừu tượng (AST) của các hợp đồng. Mẫu Visitor cho phép Wake tự động điều hướng cấu trúc mã của bạn, cho phép bạn phản ứng với các thành phần cụ thể như định nghĩa hợp đồng hoặc hàm.
Để liệt kê các hợp đồng, chúng ta sẽ ghi đè phương thức `visit_contract_definition`, phương thức này sẽ được gọi cho từng hợp đồng trong cơ sở mã. Thêm phương thức này vào lớp ListContractsPrinter của bạn: wake print list-contracts
Bash
Sao chép
Lệnh này chạy máy in của bạn và in tất cả các tên hợp đồng được tìm thấy trong dự án của bạn.
Đầu ra được cải thiện
Triển khai cơ bản hiển thị tất cả các hợp đồng, bao gồm giao diện và hợp đồng kế thừa.
Phần triển khai cơ bản ... Hãy cải thiện nó để chỉ hiển thị các hợp đồng có thể triển khai:
defvisit_contract_definition(self, node: ir.ContractDefinition) -> Không có:iflen(node.child_contracts) != 0:returnif node.kind != ir.enums.ContractKind.CONTRACT:returnprint(node.name)
Python
Sao chép
Lớp ContractDefinition chứa các thuộc tính có thể được sử dụng để lọc kết quả. Để tham khảo đầy đủ, vui lòng xem: https://ackee.xyz/wake/docs/latest/api-reference/ir/declarations/contract-definition/ Triển khai đầy đủ Đây là phiên bản cuối cùng với sự phân tách hợp lý các mối quan tâm—thu thập dữ liệu trong quá trình duyệt và hiển thị dữ liệu trong phương thức `print()`: Hướng dẫn 2: Phân tích các hàm hợp đồng Việc hiểu các hàm nào có thể được gọi từ bên ngoài là rất quan trọng đối với bảo mật: các hàm public 'withdraw' hoặc 'transfer' thường xác định bề mặt tấn công của một hợp đồng. Hãy tạo một máy in để vẽ bề mặt tấn công bằng cách liệt kê tất cả các hàm công khai và bên ngoài.
Đặt hàm máy in
Tạo một máy in mới:
class ListFunctionsPrinter(Printer): contracts: list[ir.ContractDefinition] = []def visit_contract_definition(self, node: ir.ContractDefinition) -> None: `self.contracts.append(node)` (Python) (Sao chép) (Xử lý phân cấp kế thừa) (Trong phương thức `print()`, chúng ta lặp qua phân cấp kế thừa từ hợp đồng cơ sở đến hợp đồng được dẫn xuất, hiển thị các hàm có thể gọi ở mỗi cấp độ:) (def) (get_callable_final_functions(self, contract: ir.ContractDefinition) -> list[ir.FunctionDefinition]:return [\ funny == 0# Là triển khai cuối cùng\và func.visibility trong [ir.enums.Visibility.PUBLIC, ir.enums.Visibility.EXTERNAL]\ ]
Python
Sao chép
Chạy hàm printer
Thực thi máy in để xem hệ thống phân cấp kế thừa và các hàm có thể gọi:
Contract: ContextContract: OwnableCác hàm: chủ sở hữu từ bỏ quyền sở hữu chuyển nhượng quyền sở hữuHợp đồng: SingleTokenVaultCác hàm: hàm tạo tiền gửi rút emergencyWithdraw balanceOf setDepositLimits------------------Hợp đồng: EIP712Ví dụCác hàm: hàm tạo DOMAIN_SEPARATORcastVoteBySignaturegetVoteCounts--------------------------Hợp đồng: Ngữ cảnhHợp đồng: IERC20Hợp đồng: IERC20MetadataHợp đồng: IERC20ErrorsHợp đồng: ERC20Hàm:tênký hiệusố thập phântổng nguồn cungsố dưchuyển khoảntrợ cấpphê duyệt transferFromHợp đồng: IERC20PermitHợp đồng: IERC5267Hợp đồng: EIP712Các hàm: eip712DomainHợp đồng: NoncesHợp đồng: ERC20PermitCác hàm: permit nonces DOMAIN_SEPARATORHợp đồng: PermitTokenCác hàm: constructor--------------------------Hợp đồng: TokenCác hàm: hàm tạo mintTokens transfer transferWithBytes getBalance--------------------------Contract: ContextContract: IERC20Contract: IERC20MetadataContract: IERC20ErrorsContract: ERC20Hàm:namesymbolsố thập phân totalSupplybalanceOftransfer allowance approve transferFromContract: MockERC20Hàm:Hàm khởi tạo---------------------
Bash
Sao chép
Đầu ra cung cấp cho bạn bản đồ trực quan nhanh về các điểm kế thừa và điểm vào có thể gọi được cho mỗi hợp đồng.
Đầu ra cung cấp cho bạn bản đồ trực quan nhanh về các điểm kế thừa và điểm vào có thể gọi được cho mỗi hợp đồng.
@printer.command(name="list-functions")@click.option("--contract-name", type=str, required=False)def cli(self, contract_name: str | Không có) -> Không có: self.contract_name = contract_name
Python
Sao chép
Logic Lọc Có Điều Kiện
print() Phương thức này hiện kiểm tra xem có yêu cầu một hợp đồng cụ thể nào không. Nếu không cung cấp tên hợp đồng, máy in sẽ liệt kê tất cả các hợp đồng có thể triển khai. Nếu tên được chỉ định, nó sẽ chỉ tìm kiếm trong hệ thống phân cấp hợp đồng cho tên đó, ngay cả khi đó không phải là hợp đồng lá.
Triển khai đầy đủ với các tùy chọn CLI
Đây là máy in cuối cùng với tùy chọn lọc hợp đồng. ...
## Phân tích tất cả các hợp đồng có thể triển khaiwakeprint list-functions## Tập trung vào một hợp đồng cụ thểwakeprint list-functions --contract-name Token
Bash
Sao chép
Các bước tiếp theo
Các máy in cung cấp bản đồ; các máy dò tìm ra lỗ hổng. Cùng nhau, chúng biến việc kiểm tra Solidity từ công việc thủ công tẻ nhạt thành một quá trình có cấu trúc, sâu sắc Quy trình. Mỗi máy in bạn viết có thể làm cho mã phức tạp trở nên rõ ràng hơn—và tăng cường bảo mật cho các hợp đồng thông minh mà bạn kiểm toán. Để phát hiện lỗ hổng, Wake cung cấp một hệ thống phát hiện riêng biệt, vượt ra ngoài khả năng trực quan hóa để xác định các vấn đề bảo mật thực tế. Máy in cung cấp bản đồ; máy phát hiện tìm ra vấn đề. Hãy cân nhắc đóng góp máy in của bạn trở lại cộng đồng. Các công cụ phân tích sẽ mạnh mẽ nhất khi được chia sẻ, và máy in tùy chỉnh của bạn có thể giúp các kiểm toán viên khác hiểu các cơ sở mã phức tạp hiệu quả hơn.