Chuỗi bảo mật Web3: Liệu tiền bị chuyển nhầm sang các blockchain khác có thể được khôi phục không?
Trong thế giới tiền điện tử, chỉ một cú nhấp chuột sai cũng có thể gây ra "thảm họa kỹ thuật số". Một trong những cơn ác mộng phổ biến nhất là gửi tài sản đến nhầm blockchain. Ví dụ: bạn có thể định gửi ETH đến một địa chỉ trên mạng thử nghiệm Ethereum Sepolia, nhưng lại vô tình gửi đến một địa chỉ trên mạng chính Ethereum. Trong trường hợp này, liệu có thể khôi phục số tiền đã chuyển nhầm từ mạng chính Ethereum hay không? Việc khôi phục tài sản có thể thực hiện được hay không phụ thuộc vào loại địa chỉ nhận. Bài viết này sẽ phân tích các tình huống khác nhau.
1. Tình huống 1: Địa chỉ nhận là EOA
EOA (Tài khoản sở hữu bên ngoài) là thứ chúng ta thường gọi là địa chỉ ví thông thường được kiểm soát trực tiếp bằng khóa riêng hoặc cụm từ ghi nhớ.
Điều kiện tiên quyết để thu hồi tài sản:
- Bạn đã chuyển tài sản của mình đến địa chỉ EOA.
- Bạn sở hữu khóa riêng hoặc cụm từ ghi nhớ cho địa chỉ EOA mục tiêu này. (Thông thường, đây là một địa chỉ ví khác của bạn hoặc địa chỉ của bạn bè mà họ sẵn sàng hợp tác).
- Chuỗi mục tiêu là chuỗi tương thích với EVM.
Các phương pháp thu hồi tài sản:
Người nắm giữ khóa riêng tư của địa chỉ EOA nhận có thể trực tiếp rút tiền trên blockchain mục tiêu.
2. Tình huống 2: Địa chỉ nhận là hợp đồng.
Đây là một trong những tình huống nguy hiểm nhất. Vì địa chỉ của hợp đồng thông minh không được tạo bởi khóa riêng, nên không ai sở hữu khóa riêng của hợp đồng thông minh và do đó không thể kiểm soát hợp đồng theo cách họ kiểm soát EOA. Hơn nữa, nếu hợp đồng không có chức năng cứu hộ được viết sẵn để xử lý "tài sản bị chuyển nhầm", số tiền bị chuyển nhầm có thể bị khóa vĩnh viễn trong hợp đồng và không ai có thể lấy lại được.
Tuy nhiên, trong một số trường hợp, thực sự vẫn có một tia hy vọng. Tiếp theo, chúng tôi sẽ xây dựng một kịch bản trong đó ETH bị khóa trên mạng chính Ethereum, và sau đó giải thích cách giải cứu tiền.
2.1. Giới thiệu cảnh
Tóm lại, kịch bản này liên quan đến việc người dùng dự định kích hoạt hợp đồng trên mạng thử nghiệm Sepolia để chuyển ETH vào hợp đồng đào token. Tuy nhiên, trong quá trình khởi tạo giao dịch, một kết nối không chính xác đã xảy ra với mạng chính, dẫn đến việc ETH bị khóa trong hợp đồng mạng chính. Quy trình xây dựng kịch bản cụ thể như sau:

1. Trên mạng thử nghiệm Ethereum Sepolia, nhóm dự án (EOA) đã triển khai một hợp đồng triển khai . Giả sử chức năng chính của hợp đồng này là cho phép người dùng gửi ETH để đúc AToken tương ứng, với mã tương tự như hàm "mintTokens". Giả sử địa chỉ triển khai là A. Lưu ý rằng A không có hàm nào cho phép rút ETH trực tiếp.

2. Trên mạng thử nghiệm Ethereum Sepolia, nhóm dự án (EOA) đã triển khai một hợp đồng nhà máy . Chức năng của hợp đồng này là triển khai một hợp đồng proxy trỏ đến hợp đồng triển khai (như được hiển thị trong hàm "deployProxyByImplementation") bằng cách sử dụng các hợp đồng proxy tối thiểu (Bản sao) dựa trên địa chỉ hợp đồng triển khai và salt được cung cấp. Giả sử địa chỉ triển khai là B. Ở đây, chúng tôi gọi hàm "deployProxyByImplementation", truyền địa chỉ hợp đồng triển khai A là `_implementation`, để triển khai một hợp đồng proxy trỏ đến A tại địa chỉ C.

3. Một người dùng muốn đúc AToken trên mạng thử nghiệm Sepolia bằng cách chuyển ETH. Người dùng khởi tạo một lệnh gọi đến hợp đồng proxy C. Thông thường, hợp đồng proxy C sẽ tiếp tục gọi hàm "mintTokens", hàm này thực thi hợp đồng A, để hoàn tất thao tác của người dùng. Tuy nhiên, trong quá trình gọi, người dùng đã kết nối sai với mạng chính Ethereum. Do đó, người dùng đã trực tiếp chuyển ETH đến địa chỉ C trên mạng chính Ethereum. Tại thời điểm này, không có hợp đồng nào được triển khai trên địa chỉ C trên mạng chính Ethereum, và không ai sở hữu khóa riêng cho địa chỉ C. Do đó, tiền của người dùng tạm thời bị khóa tại địa chỉ C trên mạng chính.
2.2. Các điểm kiến thức chính
Trước khi giới thiệu kế hoạch cứu hộ cụ thể, trước tiên chúng ta hãy giới thiệu một số kiến thức cơ bản cần thiết cho công tác cứu hộ.
2.2.1. tạo & tạo2
`create` và `create2` là hai cách phổ biến để triển khai hợp đồng trong Solidity.
- Khi triển khai hợp đồng bằng hàm `create`, địa chỉ hợp đồng được xác định bởi địa chỉ của người khởi tạo giao dịch và số lượng giao dịch của tài khoản (nonce) và không liên quan đến nội dung của hợp đồng.
- Khi triển khai hợp đồng bằng create2, việc tính toán địa chỉ hợp đồng không còn phụ thuộc vào nonce của người khởi tạo giao dịch nữa mà liên quan đến bốn tham số sau.
- 0xff
- Địa chỉ hợp đồng để tạo hợp đồng mới.
- Giá trị làm tối nghĩa (muối) được sử dụng làm tham số
- Mã bytecode tạo (init_code) của hợp đồng cần tạo.
2.2.2. Hợp đồng đại lý tối thiểu (Bản sao)
https://docs.openzeppelin.com/contracts/4.x/api/proxy#clones
Hợp đồng proxy tối thiểu, còn được gọi là hợp đồng bản sao, dựa trên ý tưởng triển khai một hợp đồng proxy với chi phí cực thấp (Gas) trỏ đến một hợp đồng triển khai cụ thể. Trong hợp đồng bản sao, hợp đồng proxy có thể được triển khai bằng phương thức `create` hoặc `create2`. Ví dụ: việc triển khai hợp đồng proxy bằng hàm `cloneDeterministic` sử dụng phương thức `create2`.
Trong hàm "cloneDeterministic", mã bytecode của hợp đồng proxy đã tạo rất ngắn, theo định dạng: "0x363d3d373d3d3d363d73<địa chỉ hợp đồng triển khai>5af43d82803e903d91602b57fd5bf3". Địa chỉ của hợp đồng triển khai được mã hóa cứng trực tiếp vào mã bytecode, và tất cả các lệnh gọi đến hợp đồng proxy đều được chuyển giao cho hợp đồng triển khai.
Như có thể thấy từ hàm "cloneDeterministic", nó sử dụng phương thức create2 để tạo hợp đồng proxy. Địa chỉ của hợp đồng proxy được tạo có liên quan đến địa chỉ của người tạo hợp đồng, salt, địa chỉ của hợp đồng triển khai và một chuỗi bytecode cố định, nhưng không liên quan đến bytecode của hợp đồng triển khai.

2.3. Kế hoạch giải cứu
Tiếp theo, chúng tôi sẽ giải thích cách giải cứu ETH của người dùng được lưu giữ trong địa chỉ C của mạng chính. Ý tưởng chính là triển khai mã hợp đồng trên địa chỉ C của mạng chính Ethereum để tiếp quản địa chỉ và trích xuất ETH. Các bước cụ thể như sau:

1. Triển khai hợp đồng nhà máy trên mạng chính với cùng địa chỉ B như trên mạng thử nghiệm. Lý do cần cùng địa chỉ hợp đồng nhà máy là vì khi gọi "cloneDeterministic" để triển khai hợp đồng proxy sau đó, việc tính toán địa chỉ của hợp đồng proxy sẽ liên quan đến địa chỉ hợp đồng nhà máy. Bằng cách kiểm tra giao dịch triển khai hợp đồng nhà máy trên mạng thử nghiệm Sepolia, hãy lấy nonce của người triển khai (địa chỉ dự án) trong giao dịch này. Trên mạng chính, hãy nâng cấp nonce của địa chỉ chủ sở hữu dự án (EOA) lên nonce trước khi triển khai hợp đồng nhà máy. Sau đó, triển khai hợp đồng nhà máy trên mạng chính. Vì địa chỉ và nonce của người triển khai giống với giao dịch triển khai trên mạng thử nghiệm, địa chỉ hợp đồng nhà máy được triển khai trên mạng chính cũng sẽ là B.
2. Triển khai hợp đồng triển khai trên mainnet tại cùng địa chỉ A như trên testnet. Như đã đề cập trong phần #Minimum Proxy Contract (Clones)#, việc triển khai hợp đồng proxy bằng hàm "cloneDeterministic" của hợp đồng bản sao sẽ tính toán địa chỉ hợp đồng proxy. Địa chỉ hợp đồng proxy được tính toán phụ thuộc vào tham số đầu vào `salt` và địa chỉ hợp đồng triển khai, nhưng độc lập với mã bytecode của hợp đồng triển khai. Do đó, chúng ta chỉ cần triển khai một hợp đồng trên địa chỉ A; nội dung cụ thể của hợp đồng không ảnh hưởng đến việc tính toán địa chỉ hợp đồng proxy. Sau đó, chúng ta có thể triển khai trực tiếp một hợp đồng với chức năng trích xuất ETH trên địa chỉ A, như được hiển thị trong mã bên dưới.
Trên mạng thử nghiệm, hợp đồng triển khai A được triển khai theo địa chỉ chủ sở hữu dự án (EOA). Do đó, địa chỉ của hợp đồng triển khai A chỉ liên quan đến người khởi tạo giao dịch và nonce của nó. Bằng cách quan sát các giao dịch triển khai hợp đồng triển khai A trên mạng thử nghiệm, tìm nonce liên quan, đẩy địa chỉ chủ sở hữu dự án (EOA) trên mạng chính đến nonce đã chỉ định, và sau đó triển khai hợp đồng triển khai A, bạn có thể tiếp tục.

3. Triển khai hợp đồng proxy trên mạng chính tại cùng địa chỉ C với mạng thử nghiệm. Quan sát các giao dịch của hợp đồng proxy C được triển khai trên mạng thử nghiệm, lấy thông tin salt và gọi hàm "deployProxyByImplementation" của hợp đồng nhà máy B, truyền địa chỉ của hợp đồng triển khai A và salt làm tham số. Thao tác này sẽ triển khai hợp đồng proxy tại địa chỉ C trên mạng chính.
4. Hợp đồng proxy mainnet C được kích hoạt để rút tiền. Địa chỉ dự án (EOA) gọi hàm rút tiền của hợp đồng proxy C, chỉ định người nhận tiền, rút thành công số ETH bị đóng băng khỏi hợp đồng proxy C, sau đó trả lại cho người dùng có liên quan.
2.4. Tóm tắt
Như có thể thấy từ kế hoạch giải cứu trên, tiền chỉ có thể được thu hồi nếu nhiều điều kiện được đáp ứng đồng thời, chẳng hạn như nonce có liên quan của người triển khai hợp đồng trên chuỗi mục tiêu không được sử dụng, hợp đồng bẫy tiền có chức năng rút tiền hoặc có thể triển khai chức năng rút tiền theo nhiều cách khác nhau (hợp đồng có thể được nâng cấp hoặc có thể sử dụng proxy như Clones, v.v.).
Do đó, mọi người cần hết sức cẩn thận khi giao dịch, kiểm tra kỹ lưỡng từng giao dịch trước khi tương tác với hợp đồng. Trước khi giao dịch, bạn có thể sử dụng công cụ quét lỗ hổng AI SCAN của ZAN để kiểm tra tính bảo mật của hợp đồng. Nếu tiền của bạn vô tình bị khóa, đừng hoảng sợ; bạn có thể liên hệ với đội ngũ kiểm toán bảo mật hợp đồng của ZAN để được hỗ trợ khôi phục tiền.
Bài viết này được viết bởi Cara ( @Cara6289 ) của Nhóm ZAN (tài khoản X @zan_team ) và AntChain OpenLabs (tài khoản X @AntChainOpenLab ).
- 核心观点:误转资产能否找回取决于地址类型。
- 关键要素:
- EOA地址需持有私钥可找回。
- 合约地址无救援函数则永久锁定。
- 特定条件下可通过部署合约救援。
- 市场影响:提升用户操作谨慎性与安全工具需求。
- 时效性标注:长期影响


