Văn bản gốc: "Địa chỉ phù phiếm" của foobar
Tổng hợp: Cháo qua đêm, lối đi của DeFi
160 triệu đô la Mỹ đã biến mất và Wintermute bị mất tiền. Wintermute là một trong những quỹ tạo lập thị trường sắc sảo nhất trong ngành. Một buổi sáng tháng 9, khi người phụ trách Wintermute thức dậy, anh ta phát hiện ra rằng một trong những chiếc ví quan trọng của họ đã mất 9 con số. Vậy điều gì đã dẫn đến việc Wintermute bị đánh cắp? Điều này là do tính ngẫu nhiên kém trong trình tạo địa chỉ ảo. Tin tặc mũ đen ép buộc cặp khóa riêng và địa chỉ công khai từ đầu, sau đó một lượng lớn tài sản tiền điện tử sẽ bị chuyển đi.
Ngoài ra còn có câu chuyện về việc Indexed Finance bị tấn công, trong đó họ đã bị đánh cắp 16 triệu đô la vào tháng 10 năm 2021 và số tiền bị đánh cắp sau đó được chuyển đến các địa chỉ bắt đầu bằng 0xba5ed… . Điều họ không biết là địa chỉ ảo cũng bị ảnh hưởng bởi lỗ hổng ngẫu nhiên tồi tệ đã gây ra cho Wintermute và vào tháng 9 năm 2022, tất cả số tiền lại bị đánh cắp, chuyển đến một địa chỉ ví bị hack khác. Kẻ trộm thật tàn nhẫn.
Vậy những nhà phát triển tài năng này đã gặp phải vấn đề gì và chúng ta có thể học được gì từ họ?
Bên trái là địa chỉ thông thường được sử dụng cho hợp đồng WETH. Bên phải là một địa chỉ khá đẹp với 14 số 0 đứng đầu để tối ưu hóa robot MEV. Loại địa chỉ ảo phổ biến nhất là loại có nhiều số 0 đứng đầu.
Trước hết, địa chỉ ảo (còn được gọi là địa chỉ ảo) là gì? Địa chỉ ảo đề cập đến địa chỉ công khai mà người dùng cố tình tạo để liên kết với ví hoặc hợp đồng thông minh của họ. Có thể địa chỉ này bắt đầu bằng 0x0000000, có thể địa chỉ đó bắt đầu bằng 0xdeadbeef, có thể đó là một số địa chỉ thông thường khác. Có một số lý do cho sự phổ biến của họ:
1. Tối ưu hóa gas: Wintermute đã tiết kiệm được 15.000 USD bằng cách sử dụng địa chỉ EOA có nhiều số 0 đứng đầu. Nghe có vẻ ngớ ngẩn? Nhiều người đồng ý, nhưng đây là cách EVM hoạt động! Nếu bạn có nhiều số 0 trong địa chỉ của mình, phí gas giao dịch có thể giảm xuống. Vì vậy, nếu bạn sử dụng địa chỉ hợp đồng thông minh có nhiều số 0 ở đầu, người dùng sẽ rất vui khi tương tác với địa chỉ đó vì nó giúp họ tiết kiệm tiền.
Sách vàng Ethereum mô tả cách các địa chỉ số 0 đứng đầu có thể tạo ra gas rẻ hơn
2. Thỏa thuận nhãn hiệu. Bạn có biết rằng hợp đồng Token 1inch bắt đầu bằng 0x111111111...?
Hợp đồng mã thông báo 1 inch
3. Độ lặp lại nhiều sợi. Theo tôi, đây là ưu tiên hàng đầu và tại sao mọi giao thức nên sử dụng địa chỉ ảo để triển khai. Ứng dụng của bạn có thể tồn tại trên 15 chuỗi EVM khác nhau và có cùng địa chỉ ở mọi nơi! Điều này có dễ dàng hơn cho các nhà phát triển và người dùng không?
Vậy địa chỉ đẹp khi nào mới an toàn?
Có hai loại địa chỉ Ethereum: tài khoản thuộc sở hữu bên ngoài (EOA) và tài khoản hợp đồng thông minh. Nếu bạn đã sử dụng ví như MetaMask thì mỗi địa chỉ trong đó là một EOA, được sử dụng để ký tin nhắn và xử lý giao dịch. So sánh tài khoản này với tài khoản hợp đồng thông minh, chẳng hạn như hợp đồng Uniswap, tài khoản mà mọi người có thể tương tác nhưng không thể tự thực hiện hành động nếu không được kích hoạt. Tóm lại, rất đơn giản. Địa chỉ số tốt không an toàn đối với tài khoản EOA, nhưng chúng an toàn đối với tài khoản hợp đồng thông minh.
Vậy tại sao lại như vậy? Chúng tôi sẽ giải thích điều này chi tiết hơn bên dưới, nhưng nó phụ thuộc vào cách tạo địa chỉ ảo. Đối với tài khoản EOA, bạn duyệt qua hàng triệu khóa riêng tư cho đến khi tìm thấy khóa tương ứng với một địa chỉ công cộng đẹp mắt. Tuy nhiên, khóa riêng sẽ kiểm soát số tiền trong tài khoản EOA, vì vậy nếu tính ngẫu nhiên mà bạn sử dụng để duyệt khóa riêng bị xâm phạm thì toàn bộ tài khoản của bạn sẽ bị hủy hoại. Mặt khác, việc tạo địa chỉ phù hợp với hợp đồng thông minh chỉ yêu cầu duyệt qua các hạt giống công khai, không cấp bất kỳ quyền quản trị nào cho hợp đồng thông minh.
Đây là lý do tại sao Wintermute thất bại và OpenSea thành công - việc tạo khóa riêng trong bộ nhớ không an toàn bằng phần mềm không an toàn là điều không tốt. Nhưng việc tạo ra hạt giống công khai theo cách này khá hay! Do đó, địa chỉ EOA tốt là con đường dẫn đến phá sản, trong khi địa chỉ hợp đồng thông minh tốt là con đường dẫn đến thành công.
Tại sao giao thức yêu cầu một địa chỉ đẹp?
Tài liệu đơn giản hơn! Bạn có thể trỏ đến địa chỉ hợp đồng trên tất cả các chuỗi;
Người dùng có thể xác minh! Địa chỉ hợp đồng tương tự sẽ chỉ xuất hiện khi và chỉ khi mã byte khớp với từng byte;
Các nhà phát triển có thể xác minh! Vì các địa chỉ hợp đồng giống hệt nhau chỉ xảy ra trong trường hợp khớp chính xác, nên bạn có thể nắm bắt được những sửa đổi nhỏ phức tạp trong tập lệnh triển khai của mình;
Tích hợp dễ dàng hơn! Các giao thức khác có thể mã hóa cứng địa chỉ hợp đồng của bạn thành mã đa chuỗi của chúng mà không cần phải sử dụng các câu lệnh if dựa trên chainId.
LƯU Ý: Chúng tôi sắp đi sâu vào hướng dẫn sử dụng chi tiết. Lần đầu tiên kết hợp tất cả các phần lại với nhau, chúng tôi đang đi sâu vào không gian kỹ thuật và nhắm mục tiêu đến các nhà phát triển hợp đồng thông minh có kinh nghiệm triển khai hợp đồng thông minh trên chuỗi. Nếu bạn quan tâm, hãy tiếp tục đọc, nhưng nếu nó không dành cho bạn, đừng lo lắng về việc theo kịp! Cuối cùng sẽ có một thử thách kỹ thuật bổ sung (kèm phần thưởng).
Hợp đồng thông minh địa chỉ đẹp
Có một cách để tạo địa chỉ hợp đồng thông minh an toàn 100%, bất kể bạn sử dụng phần mềm nào, không thành vấn đề nếu công nghệ lặp lại bị rò rỉ công khai. Nó được gọi là “phương thức nhà máy CREATE2” và nó không chỉ cung cấp một địa chỉ đẹp mà còn là một cách dễ dàng để đảm bảo bạn có cùng một địa chỉ triển khai hợp đồng trên nhiều chuỗi. Nó cũng cho phép người khác triển khai mã thay mặt bạn một cách đáng tin cậy mà không cần bất kỳ sự chia sẻ khóa riêng tư hoặc giả định không xác định nào.
Đầu tiên, tổng quan nhanh về cách chọn địa chỉ hợp đồng thông minh. Có hai tùy chọn triển khai là CREATE và CREATE2. Khi bạn triển khai hợp đồng thông minh trực tiếp từ EOA, quy trình mặc định là TẠO. Địa chỉ được xác định bằng cách băm địa chỉ của người tạo hợp đồng với số nonce của người tạo hợp đồng. Số nonce này đề cập đến số lượng giao dịch mà một địa chỉ đã gửi, do đó, một ví mới bắt đầu từ 0 và tăng thêm 1 mỗi lần một giao dịch mới được gửi. Đây là công thức kỳ diệu cho địa chỉ hợp đồng thông minh được CREATE triển khai:
new_address = hàm băm (người gửi, nonce)
Ít phổ biến hơn nhưng thú vị hơn là địa chỉ hợp đồng thông minh được triển khai bằng CREATE2 và đây là công thức của nó:
new_address = hàm băm (0xFF, người gửi, muối, mã byte)
Cái trước có vẻ đơn giản hơn phải không? Tuy nhiên, hãy đưa ra một ví dụ về điểm mà sự đơn giản này có thể gây bất lợi so với quy trình CREATE2 mạnh mẽ hơn.
Airy Alice: Có vấn đề với đa chuỗi
Hãy tưởng tượng một nhà phát triển tiền điện tử tên Alice tạo ra hai hợp đồng thông minh: một nhánh Uniswap có tên GriddleSwap và một dự án NFT có tên ph00ts. Chúng đều là những nguyên thủy độc lập bất biến, có nghĩa là không có sự phụ thuộc bên ngoài hoặc rủi ro cầu nối chuỗi chéo. Alice triển khai GriddleSwap sang Ethereum bằng cách sử dụng nonce 0, sau đó triển khai ph00ts sang Ethereum bằng cách sử dụng nonce 1. Thật không may, Alice có khoảng thời gian chú ý ngắn và bị phân tâm trên Twitter tiền điện tử trong vài phút trước khi triển khai công việc của mình lên Binance Smart Chain (BSC), nền tảng hợp đồng thông minh lớn thứ hai.
Rất tiếc, đã nhầm thứ tự triển khai!
Nhưng chờ đã! Cô ấy đã làm sai thứ tự triển khai và triển khai ph00ts trước GriddleSwap. Vì địa chỉ hợp đồng thông minh chỉ dựa vào địa chỉ của người tạo và trong chuỗi khối được triển khai, Ethereum Gridleswap có cùng địa chỉ với BSC ph00ts! Tệ hơn nữa, địa chỉ của Ethereum ph00ts giống với địa chỉ của BSC GriddleSwap. Nghĩ rằng người dùng cuối sẽ bị nhầm lẫn là một cách đánh giá thấp. Trên thực tế, những kẻ triển khai có ác ý có thể lạm dụng nó để lừa mọi người nghĩ rằng hành vi hợp đồng trên chuỗi là giống nhau - đó là một giả định hợp lý, được cung cấp cùng một địa chỉ!
Alice cẩn thận: Vẫn sẽ có vấn đề
Ngay cả khi Alice cẩn thận khi triển khai và không bao giờ nhầm lẫn thứ tự các nonce của mình thì vẫn có những vấn đề khác. Nếu Alice triển khai đúng cách với Ethereum và BSC, nhưng sau đó thực hiện một giao dịch không liên quan trên Polygon thì số nonce 0 đã được sử dụng hết. Cô ấy không bao giờ có thể triển khai GriddleSwap ở đó vì số nonce của cô ấy đã tăng lên. Do đó, khóa riêng của người triển khai phải được bảo vệ bằng mọi giá. Nếu Alice làm rò rỉ nó, kẻ phá hoại có ác ý có thể thực hiện các giao dịch không liên quan. Nếu Alice làm mất nó, cô ấy cũng sẽ mất khả năng triển khai lại địa chỉ đó trên một chuỗi mới. Đây là một lỗ hổng vĩnh viễn dựa vào một cá nhân trung thực để bảo vệ khóa riêng. Nếu ngay cả các nhà phát triển cốt lõi của Bitcoin cũng không thể làm được thì làm sao những người còn lại trong chúng ta có thể làm được?
Giải pháp: TẠO2
Rất may, có một cách tốt hơn để có được các địa chỉ nhất quán trên các chuỗi—một cách không dựa vào khóa riêng bí mật, không phụ thuộc vào một nhà triển khai duy nhất và có khả năng chống lại lỗi của nhà triển khai trong quá trình thực hiện. Hãy nhớ công thức tìm địa chỉ của hợp đồng thông minh được triển khai bằng CREATE2:
new_address = hàm băm (0xFF, người gửi, muối, mã byte)
Tham số đầu tiên 0xFF là giá trị không đổi có thể bỏ qua. Tham số thứ hai (địa chỉ người gửi) có thể được nhất quán bằng cách chọn triển khai CREATE2Factory của z0age 0x0000000000FFe8B47B3e2130213B802212439497 trong hầu hết các chuỗi EVM. Tham số thứ ba là muối do người dùng chọn, chúng ta có thể sử dụng tham số này để tìm một địa chỉ tốt và sau đó giữ nguyên địa chỉ đó trên chuỗi. Thứ tư là mã byte hợp đồng, đóng vai trò như một biện pháp kiểm tra độ chính xác hữu ích để đảm bảo chúng tôi đang triển khai chính xác chức năng tương tự trên chuỗi. Tất cả bốn tham số có thể giữ nguyên cho dù bất kỳ người triển khai nào cũng có thể làm gì.
Tại sao điều này tốt hơn? Không giống như khóa riêng, muối do người triển khai chọn có thể được công khai! Việc biết muối cho phép bạn triển khai hợp đồng nhưng bạn không có quyền kiểm soát đối với nội dung hoặc chức năng của hợp đồng. Vì nó không ràng buộc bất kỳ thông tin bí mật nào nên bất kỳ ai cũng có thể triển khai hợp đồng lên chuỗi mới mà không cần tiết lộ hoặc chia sẻ khóa riêng. Tham số mã byte cũng đảm bảo rằng các hoạt động triển khai không được phép mới này sẽ có cùng địa chỉ khi và chỉ khi mã byte giống nhau. Do đó, người dùng cuối nhận được sự đảm bảo mạnh mẽ hơn mà không cần phải tạo ra sự khác biệt chi tiết về mã.
Để có cái nhìn tổng quan sâu hơn, hãy xem bài viết khoa học phổ biến của OpenZeppelin.
Tạo địa chỉ đẹp của riêng bạn
Bạn nghĩ Proof of Work (PoW) sẽ vô dụng sau khi sáp nhập Ethereum? Nghĩ lại! Các khả năng tương tự của GPU giúp tìm các tiền tố băm có số lượng lớn các số 0 đứng đầu cho các khối Bitcoin cũng rất xuất sắc trong việc tìm kiếm các tiền tố băm có số lượng lớn các số 0 đứng đầu cho các hợp đồng thông minh EVM. z0age từ OpenSea (nhờ lời giải thích của anh ấy cho bài đăng này) đã tìm thấy một thiết lập đơn giản để tạo địa chỉ ảo của riêng bạn.
1. Sử dụng broad.ai để khởi chạy một phiên bản mẫu GPU, tốc độ này đạt khoảng 2 tỷ lần mỗi giây và tốn khoảng 25 xu/giờ:
Hình ảnh:nvidia / opencl
GPU: 1x RTX 3090
Dung lượng ổ đĩa cần phân bổ: 1,83 GB
2. SSH và cài đặt Rust + create2crunch
sudo apt cài đặt build-essential -y; cuộn tròn --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y; nguồn "$HOME/.cargo/env"; git clone https://github.com/0age/create2crunch && cd create2crunch; sed -i 's/0x4/0x40/g' src/lib.rs
3. Chạy tìm kiếm hạt giống. Đối với các biến môi trường, INIT_CODE_HASH là keccak256 của mã tạo hợp đồng. Bạn có thể tìm thấy bản in của bài kiểm tra đúc mẫu tại đây - hãy đảm bảo xác minh nó trước khi tiêu tốn một lượng lớn tài nguyên máy tính! LEADING phải là số byte 0 ở đầu bạn muốn và TOTAL phải là tổng số byte 0 bạn muốn trong địa chỉ hợp đồng.
xuất NHÀ MÁY="0x0000000000ffe8b47b3e2130213b802212439497"; xuất CALLER="0x0000000000000000000000000000000000000000000"; xuất INIT_CODE_HASH="0xabc...def"; xuất HÀNG ĐẦU=5; xuất TỔNG=7; chạy hàng hóa --giải phóng $ NHÀ MÁY $ NGƯỜI GỌI $INIT_CODE_HASH 0 $ DẪN ĐẦU $ TOTAL
Khi z0age lần đầu tiên phát hành kho lưu trữ của mình, nó có khả năng chạy 1,9 tỷ lần thử mỗi giây trên phần cứng wideAI nói trên. Kể từ đó, việc vector hóa đã phát triển mạnh mẽ trên một số lõi OpenGL và tôi đã quan sát thấy 2,15 tỷ lần thử mỗi giây. Điều này có nghĩa là việc tìm một địa chỉ có 5 byte 0 đứng đầu sẽ mất 256^5/(2150000000 * 60) ~= 8 phút và tìm một địa chỉ có 6 byte 0 đứng đầu sẽ mất 256^6/(2150000000 * 3600) ~ = 36 giờ . Địa chỉ 7 byte hàng đầu mất 256^7/(2150000000 * 86400) ~= 387 ngày. Lưu ý rằng một byte bằng hai ký tự thập lục phân, do đó, địa chỉ 5 byte đầu sẽ có 10 số 0. Tất nhiên, việc tìm kiếm này có thể được thực hiện song song hoàn toàn và xác suất thành công thực tế theo thời gian sẽ tuân theo phân phối Poisson.
Triển khai nhà máy CREATE2
Những độc giả tinh ý có thể nhận thấy rằng Nhà máy CREATE2 đã tồn tại ở 0x0000000000FFe8B47B3e2130213B802212439497 trên tất cả các chuỗi. Đó là một vấn đề hơi giống con gà và quả trứng, việc triển khai địa chỉ nhất quán phụ thuộc vào việc triển khai địa chỉ nhất quán như thế nào?
Khi mới biết đến phương pháp này, tôi đã nghĩ đó chỉ là một khóa riêng được nắm giữ bởi một người thông minh hơn tôi (kịch bản "Alice tinh ý" ở trên). Nhưng nó thực sự mạnh mẽ hơn thế nhiều! Phương pháp "giao dịch không cần chìa khóa" của người sáng lập ENS Nick Johnson khai thác thực tế là bạn có thể khôi phục địa chỉ công khai từ bất kỳ chữ ký giao dịch nào mà không cần biết khóa riêng tương ứng đã ký nó. Do đó, có thể tạo một giao dịch ("triển khai nhà máy create2") và sau đó tạo ra một chữ ký giả mạo cho nó, chẳng hạn như một chữ ký chỉ bao gồm 2 chữ ký. Khóa riêng cho chữ ký giả mạo này tồn tại nhưng không ai biết nó là gì. Nhưng chúng tôi có thể khôi phục địa chỉ công khai tương ứng với "chữ ký không khóa", gửi cho nó một số ETH và sau đó gửi giao dịch đã ký tới mempool. Bất chấp sự mù mờ của phương pháp này, đây là một giao dịch hợp lệ và trên thực tế là giao dịch hợp lệ duy nhất có thể được gửi từ địa chỉ công khai này.
Kết quả là bất kỳ ai cũng có thể triển khai một nhà máy lên một chuỗi mới mà không có bất kỳ thông tin độc quyền nào, đồng thời ngăn chặn các tác nhân độc hại gây thiệt hại. Tạo một EOA mục đích duy nhất có thể triển khai chỉ một giao dịch là một kỹ thuật rất thông minh.
Địa chỉ và hợp đồng cụ thể được tạo trong các giao dịch không cần chìa khóa
Điều này có thể được thực hiện bằng ba lệnh "giả mạo" đơn giản. Mã byte quá dài để sao chép ở đây, nhưng bạn có thể làm theo hướng dẫn tại https://github.com/ProjectOpenSea/seaport/blob/main/docs/Deployment.md mà không cần được phép trên bất kỳ chuỗi nào bạn chọn Triển khai CREATE2 Factory một cách dễ dàng!
Tất nhiên, nếu nó đã được triển khai rồi thì không cần phải triển khai lại.
Lưu ý phụ: Yêu cầu của EIP-155 rất tệ
Một nỗ lực ngắn gọn để hỗ trợ cuộc phiêu lưu quản trị L1 của tôi, vui lòng bỏ qua phần tiếp theo. EIP-155 là một đề xuất được Vitalik đưa ra vào năm 2016, đưa ra khái niệm "ID chuỗi" để ngăn chặn các cuộc tấn công lặp lại. Mỗi chuỗi có số nhận dạng duy nhất riêng - 1 cho Ethereum, 56 cho BSC và 137 cho Polygon - sẽ được bao gồm trong các giao dịch đã ký để ngăn chặn các cuộc tấn công lặp lại, đã nhanh chóng được Ethereum áp dụng và tất cả các chuỗi EVM khác đã tuân theo đề xuất này. Điều này thật tuyệt, nhưng vấn đề xảy ra khi một số chuỗi được chọn, chẳng hạn như Evmos gần đây đã quyết định cấm giao dịch một cách rõ ràng trước EIP-155, vì những lý do kỳ lạ, điều này đã ngăn chặn lỗi vận hành khi Optimism gửi 20 triệu OP Token tới một multisig (vâng, lại là họ) giải quyết rằng Wintermute không tồn tại, tuyên bố sở hữu nhưng chưa bao giờ được khởi tạo. Tuy nhiên, việc vô hiệu hóa các giao dịch trước 155 sẽ phá vỡ đáng kể toàn bộ quá trình triển khai chuỗi chéo, chẳng hạn như nhà máy CREATE2 và các dự án hàng đầu như Cảng biển. Các đề xuất quản trị này phải được khôi phục ngay lập tức và các chi tiết bảo vệ như thế này sẽ đến từ ví thay vì lớp đồng thuận. Nếu đa chuỗi là tương lai, thì những hạn chế không cần thiết này sẽ là trở ngại lớn cho các dự án hàng đầu triển khai trên blockchain của bạn.
Nội dung thú vị: triển khai tiền thưởng
Hiện nay https://delegate.cash được triển khai trên 7 chuỗi EVM khác nhau (Ethereum, Polygon, Optimism, Celo, Avalanche, Fantom và Arbitrum) và 7 testnet tương ứng với các chuỗi này. Địa chỉ hợp đồng cho tất cả những thứ này đều giống nhau: 0x000000000000076A84feF008CDAbe6409d2FE638B.
Vậy thế này đã đủ chưa? Không, chúng ta cần thêm dây chuyền. Bởi vì delegatecash là một tiền nguyên thủy độc lập không có sự phụ thuộc, điều này có nghĩa là rủi ro của nhiều chuỗi trên thực tế là bằng không. Đây là lợi ích thuần túy! Do đó, đối với 5 người đầu tiên triển khai và xác minh hợp đồng thông minh Delecash cho chuỗi mới và mạng thử nghiệm tương ứng, tôi sẽ thưởng 100 USDC!
Bạn cần sử dụng tập lệnh triển khai từ kho lưu trữ nguồn mở tại đây. Điều này có thể yêu cầu triển khai Nhà máy CREATE2 nếu nó không tồn tại và đừng quên xác minh Etherscan! Chúc bạn triển khai vui vẻ và tận hưởng trải nghiệm học tập!
