Chuỗi an ninh Web3: Tiền gửi nhầm sang chuỗi khác, còn có thể cứu vãn được không?

Trong thế giới tiền mã hoá, một lần nhấp nhầm có thể gây ra một “thảm hoạ số”. Một trong những cơn ác mộng phổ biến nhất là gửi tài sản đến đúng sai trên blockchain. Ví dụ, ban đầu muốn gửi ETH đến địa chỉ trên mạng thử nghiệm Sepolia của Ethereum, kết quả không cẩn thận gửi nhầm đến địa chỉ trên mạng chính của Ethereum. Trong trường hợp này, liệu có thể lấy lại số tiền đã gửi nhầm từ mạng chính Ethereum không? Liệu có thể khôi phục tài sản hay không, điều quan trọng phụ thuộc vào loại địa chỉ nhận tiền. Bài viết này sẽ phân tích dựa trên các tình huống khác nhau.

1. Tình huống 1: Địa chỉ nhận là EOA

EOA (Externally Owned Account) chính là ví thông thường mà chúng ta thường nói, do khóa riêng hoặc mnemonic kiểm soát trực tiếp.

Điều kiện để lấy lại tài sản:

  • Bạn đã chuyển tài sản đến một địa chỉ EOA.
  • Bạn sở hữu khóa riêng hoặc mnemonic của địa chỉ EOA đích đó. (Thông thường là địa chỉ ví khác của chính bạn, hoặc của bạn bè, và họ sẵn lòng hợp tác).
  • Chuỗi đích là chuỗi tương thích EVM.

Cách lấy lại tài sản:

Chủ sở hữu khóa riêng của địa chỉ EOA nhận tiền có thể trực tiếp rút tiền trên chuỗi đích.

2. Tình huống 2: Địa chỉ nhận là hợp đồng thông minh

Đây là một trong những tình huống tuyệt vọng nhất. Do địa chỉ hợp đồng thông minh không được tạo ra bởi khóa riêng, nên không ai sở hữu khóa riêng của hợp đồng đó, do đó không thể kiểm soát hợp đồng như kiểm soát EOA. Và nếu hợp đồng đó không có sẵn hàm xử lý “chuyển nhầm tài sản”, thì số tiền gửi nhầm có thể bị khoá vĩnh viễn trong hợp đồng, không ai có thể rút ra.

Tuy nhiên trong một số trường hợp, vẫn còn cơ hội cứu vãn. Dưới đây, chúng tôi sẽ xây dựng một tình huống khoá ETH trên mạng chính Ethereum, rồi giới thiệu cách cứu số tiền đó ra.

2.1. Giới thiệu về tình huống

Nói ngắn gọn, trong tình huống này, người dùng ban đầu muốn gọi hợp đồng trên mạng thử nghiệm Sepolia để chuyển ETH vào hợp đồng nhằm đúc token, nhưng khi thực hiện giao dịch, họ đã kết nối nhầm đến mạng chính, dẫn đến ETH bị khoá trong hợp đồng trên mạng chính. Cụ thể, quá trình xây dựng tình huống như sau:

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

2. Trên mạng thử nghiệm Sepolia của Ethereum, dự án (EOA) đã triển khai hợp đồng nhà máy (factory contract), hợp đồng này có chức năng dựa vào địa chỉ hợp đồng thực thi và salt để triển khai hợp đồng trung gian (Clones) trỏ tới hợp đồng thực thi ban đầu (như hàm deployProxyByImplementation). Giả sử địa chỉ triển khai là B. Ở đây, chúng ta gọi hàm deployProxyByImplementation, truyền vào địa chỉ A làm _implementation, đã triển khai hợp đồng trung gian trỏ tới A, địa chỉ là C.

3. Người dùng muốn đúc token trên mạng Sepolia bằng cách gửi ETH vào hợp đồng trung gian C, do đó họ gửi gọi đến địa chỉ hợp đồng trung gian C. Trong tình huống bình thường, hợp đồng trung gian C sẽ gọi tiếp tới hàm mintTokens của hợp đồng A để hoàn tất thao tác. Tuy nhiên, người dùng đã kết nối nhầm đến mạng chính Ethereum. Vì vậy, họ đã gửi trực tiếp ETH đến địa chỉ C trên mạng chính. Lúc này, địa chỉ C trên mạng chính không có hợp đồng nào được triển khai, cũng không ai sở hữu khóa riêng của địa chỉ C, do đó số tiền của người dùng tạm thời bị khoá trong địa chỉ C trên mạng chính.

2.2. Các điểm kiến thức then chốt

Trước khi giới thiệu các phương án cứu hộ cụ thể, hãy cùng điểm qua các kiến thức cơ bản cần thiết cho việc cứu hộ.

2.2.1. create & create2

create và create2 là hai phương thức phổ biến để triển khai hợp đồng trong Solidity.

  • create khi triển khai hợp đồng, địa chỉ hợp đồng được xác định dựa trên địa chỉ của người gửi và nonce của tài khoản đó, không liên quan đến nội dung của hợp đồng.
  • create2 khi triển khai hợp đồng, địa chỉ không còn phụ thuộc vào nonce của người gửi nữa, mà liên quan đến bốn tham số sau:
    • 0xff
    • Địa chỉ hợp đồng tạo ra (address)
    • Giá trị băm của salt (biến số ngẫu nhiên, được truyền vào)
    • Bytecode của hợp đồng sẽ được tạo (init_code)

2.2.2. Hợp đồng trung gian tối thiểu (Clones)

https://docs.openzeppelin.com/contracts/4.x/api/proxy#clones

Hợp đồng trung gian tối thiểu, còn gọi là hợp đồng clone, chủ yếu là triển khai một hợp đồng proxy với chi phí cực thấp (Gas), hợp đồng này trỏ tới hợp đồng thực thi. Trong hợp đồng Clones, có thể dùng create hoặc create2 để triển khai, ví dụ như hàm cloneDeterministic sử dụng create2 để tạo proxy.

Trong hàm cloneDeterministic, bytecode của hợp đồng proxy rất ngắn, định dạng là: 0x363d3d373d3d3d363d73<địa chỉ hợp đồng thực thi>5af43d82803e903d91602b57fd5bf3, trong đó địa chỉ hợp đồng thực thi đã được nhúng trực tiếp vào bytecode, và mọi cuộc gọi tới proxy này sẽ delegatecall tới hợp đồng thực thi.

Hàm cloneDeterministic sử dụng phương thức create2 để tạo proxy, nên địa chỉ của hợp đồng proxy được xác định bởi địa chỉ người tạo, salt, và địa chỉ hợp đồng thực thi, không phụ thuộc vào nội dung của bytecode hợp đồng thực thi.

2.3. Các phương án cứu hộ

Tiếp theo, chúng tôi giới thiệu cách cứu hộ ETH của người dùng trên đị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, để tiếp quản địa chỉ này và rút ETH ra. Các bước cụ thể như sau:

1. Triển khai hợp đồng nhà máy (factory) trên mạng chính, cùng địa chỉ B như trên mạng thử nghiệm. Lý do là, khi gọi hàm cloneDeterministic để triển khai hợp đồng trung gian, địa chỉ của hợp đồng proxy dựa vào địa chỉ của hợp đồng nhà máy. Bằng cách xem các giao dịch triển khai hợp đồng trên mạng thử nghiệm Sepolia, lấy nonce của người triển khai (dự án) trong giao dịch, rồi trên mạng chính, đẩy nonce của địa chỉ dự án (EOA) của dự án về đúng nonce trước khi triển khai hợp đồng nhà máy. Vì nonce và địa chỉ của người triển khai giống như trên mạng thử nghiệm, nên địa chỉ hợp đồng nhà máy triển khai trên mạng chính cũng sẽ là B.

2. Triển khai hợp đồng thực thi (implementation contract) trên mạng chính, cùng địa chỉ A như trên mạng thử nghiệm. Như đã đề cập, hàm cloneDeterministic tính toán địa chỉ hợp đồng proxy dựa vào salt và địa chỉ hợp đồng thực thi, không phụ thuộc vào nội dung bytecode của hợp đồng thực thi. Vì vậy, chỉ cần triển khai một hợp đồng tại địa chỉ A, nội dung không quan trọng, để tính địa chỉ proxy sẽ không bị ảnh hưởng. Có thể triển khai một hợp đồng có chức năng rút ETH tại địa chỉ A, mã nguồn như sau.

Trên mạng thử nghiệm, hợp đồng A được dự án triển khai, do đó địa chỉ của A chỉ phụ thuộc vào người gửi và nonce của họ. Vì vậy, xem giao dịch triển khai hợp đồng A, tìm nonce liên quan, rồi đẩy nonce của địa chỉ dự án trên mạng chính về đúng nonce đó, chỉ cần triển khai hợp đồng A là đủ.

![]#最小代理合约(Clones)#https://img-cdn.gateio.im/webp-social/moments-75bfcbe9932d6fff8befe5ac282e022d.webp(

3. Triển khai hợp đồng trung gian (proxy) trên mạng chính cùng địa chỉ C như trên mạng thử nghiệm. Xem các giao dịch triển khai proxy của C trên mạng thử nghiệm, lấy salt, rồi gọi hàm deployProxyByImplementation của hợp đồng B, truyền vào địa chỉ A và salt, để triển khai hợp đồng proxy trên mạng chính tại địa chỉ C.

4. Gọi rút tiền từ hợp đồng proxy C trên mạng chính. Chủ sở hữu (EOA) gọi hàm withdraw của hợp đồng proxy C, chỉ định người nhận tiền, để rút ETH bị khoá trong hợp đồng proxy C, trả lại cho người dùng liên quan.

)# 2.4. Tóm tắt

Từ các phương án cứu hộ trên, có thể thấy, việc cứu được tiền phụ thuộc vào nhiều điều kiện như: người triển khai hợp đồng trên chuỗi đích chưa sử dụng nonce liên quan, hợp đồng khoá tiền có hàm rút hoặc có thể triển khai hàm rút bằng các phương pháp như nâng cấp hợp đồng hoặc dùng proxy Clones.

Vì vậy, khi giao dịch, mọi người cần cực kỳ cẩn thận, kiểm tra kỹ từng lệnh giao dịch của mình, trước khi tương tác với hợp đồng, có thể dùng công cụ quét lỗ hổng AI SCAN của ZAN để kiểm tra độ an toàn của hợp đồng. Nếu không may bị khoá tiền, cũng đừng hoảng loạn, có thể liên hệ nhóm kiểm toán hợp đồng của ZAN để trợ giúp cứu tiền.

Bài viết do ZANTeam (Tài khoản X @zan_team) & AntChain OpenLabs (Tài khoản X @AntChainOpenLab) cùng Cara (Tài khoản X @Cara6289) viết.

ETH0.62%
Xem bản gốc
Trang này có thể chứa nội dung của bên thứ ba, được cung cấp chỉ nhằm mục đích thông tin (không phải là tuyên bố/bảo đảm) và không được coi là sự chứng thực cho quan điểm của Gate hoặc là lời khuyên về tài chính hoặc chuyên môn. Xem Tuyên bố từ chối trách nhiệm để biết chi tiết.
  • Phần thưởng
  • Bình luận
  • Đăng lại
  • Retweed
Bình luận
0/400
Không có bình luận
  • Gate Fun hotXem thêm
  • Vốn hóa:$3.61KNgười nắm giữ:2
    0.04%
  • Vốn hóa:$3.56KNgười nắm giữ:1
    0.00%
  • Vốn hóa:$3.63KNgười nắm giữ:2
    0.18%
  • Vốn hóa:$3.67KNgười nắm giữ:2
    0.38%
  • Vốn hóa:$3.63KNgười nắm giữ:2
    0.09%
  • Ghim