Teks asli: "Vanity Addresses" oleh foobar

Kompilasi: Bubur semalam, cara DeFi

160 juta dolar AS hilang, dan Wintermute kehilangan dananya. Wintermute adalah salah satu dana pembuat pasar paling cerdik di industri. Suatu pagi di bulan September, ketika penanggung jawab Wintermute bangun, dia menemukan salah satu dompet penting mereka telah kehilangan 9 angka dana. Jadi apa yang menyebabkan Wintermute dicuri? Hal ini disebabkan oleh keacakan yang buruk pada generator alamat cantik. Peretas topi hitam dengan kasar memaksa pasangan kunci pribadi & alamat publik dari awal, dan kemudian sejumlah besar aset kripto ditransfer.

Ada juga cerita tentang Indexed Finance yang diretas, di mana $16 juta mereka dicuri pada Oktober 2021, dan dana yang dicuri kemudian dipindahkan ke alamat yang dimulai dengan 0xba5ed… . Apa yang tidak mereka ketahui adalah bahwa alamat cantik tersebut juga dipengaruhi oleh kerentanan keacakan buruk yang melanda Wintermute, dan pada bulan September 2022, semua uang itu dicuri lagi, dialihkan ke alamat dompet lain yang diretas. Pencuri itu kejam.

Jadi masalah apa yang dihadapi para pengembang berbakat ini, dan apa yang bisa kita pelajari dari mereka?

Di sebelah kiri adalah alamat normal yang digunakan untuk kontrak WETH. Di sebelah kanan adalah alamat cantik dengan 14 angka nol di depan untuk optimasi robot MEV. Jenis alamat rias yang paling umum adalah alamat dengan banyak angka nol di depannya.

Pertama-tama, apa yang dimaksud dengan alamat rias (juga dikenal sebagai alamat rias)? Alamat cantik mengacu pada alamat publik yang sengaja dibuat pengguna untuk dikaitkan dengan dompet atau kontrak pintar mereka. Mungkin dimulai dengan 0x0000000, mungkin dimulai dengan 0xdeadbeef, mungkin alamat biasa lainnya. Ada beberapa alasan popularitas mereka:

1. Pengoptimalan gas: Wintermute menghemat $15.000 dengan menggunakan alamat EOA dengan beberapa angka nol di depannya. Kedengarannya konyol? Banyak orang setuju, tapi beginilah cara kerja EVM! Jika Anda memiliki banyak angka nol di alamat Anda, biaya bahan bakar transaksi bisa turun. Jadi jika Anda menggunakan alamat kontrak pintar dengan banyak angka nol di depannya, pengguna akan senang saat berinteraksi dengannya karena ini menghemat uang mereka.

Kertas Kuning Ethereum menjelaskan bagaimana alamat nol di depan dapat memungkinkan bahan bakar lebih murah

2. Merek perjanjian. Tahukah Anda bahwa kontrak Token 1 inci dimulai dengan 0x111111111...?

Kontrak Token 1 inci

3. Pengulangan multi-untai. Menurut pendapat saya, ini adalah prioritas utama dan mengapa setiap protokol harus menggunakan alamat cantik untuk penerapannya. Aplikasi Anda dapat ada di 15 rantai EVM yang berbeda dan memiliki alamat yang sama di mana saja! Bukankah ini lebih mudah bagi pengembang dan pengguna?

Jadi kapan alamat cantik itu aman?

Ada dua jenis alamat Ethereum: akun milik eksternal (EOA) dan akun kontrak pintar. Jika Anda pernah menggunakan dompet seperti MetaMask, setiap alamat di dalamnya adalah EOA yang digunakan untuk menandatangani pesan dan memproses transaksi. Bandingkan ini dengan akun kontrak pintar seperti kontrak Uniswap, yang dapat berinteraksi dengan orang-orang tetapi tidak dapat mengambil tindakan sendiri tanpa dipicu. Singkatnya, ini sangat sederhana. Alamat nomor bagus tidak aman untuk akun EOA, tetapi aman untuk akun kontrak pintar.

Jadi mengapa demikian? Kami akan menjelaskannya lebih detail di bawah, namun hal ini bergantung pada cara pembuatan alamat cantik. Untuk akun EOA, Anda menelusuri jutaan kunci pribadi hingga Anda menemukan kunci yang sesuai dengan alamat publik yang bagus. Namun, kunci privat mengontrol dana dalam akun EOA, jadi jika keacakan yang Anda gunakan untuk menelusuri kunci privat terganggu, seluruh akun Anda akan hancur. Di sisi lain, membuat alamat kontrak pintar hanya memerlukan melintasi benih publik, yang tidak memberikan hak administratif apa pun pada kontrak pintar.

Inilah sebabnya mengapa Wintermute gagal dan OpenSea berhasil - menghasilkan kunci pribadi di memori yang tidak aman dengan perangkat lunak yang tidak aman adalah hal yang buruk. Namun menghasilkan benih publik dengan cara ini cukup bagus! Oleh karena itu, alamat EOA yang baik adalah jalan menuju kebangkrutan, sedangkan alamat kontrak pintar yang baik adalah jalan menuju kesuksesan.

Mengapa protokol memerlukan alamat yang cantik?

Dokumentasi yang lebih sederhana! Anda dapat menunjuk ke alamat kontrak di semua jaringan;

Dapat diverifikasi pengguna! Alamat kontrak yang sama akan muncul hanya jika dan hanya jika bytecode cocok byte demi byte;

Pengembang dapat memverifikasi! Karena alamat kontrak yang identik hanya muncul jika sama persis, Anda dapat melihat modifikasi kecil yang rumit dalam skrip penerapan Anda;

Integrasi lebih mudah! Protokol lain dapat melakukan hardcode alamat kontrak Anda ke dalam kode multi-rantainya tanpa harus menggunakan pernyataan if berbasis chainId.

CATATAN: Kami akan mempelajari instruksi manual terperinci. Dengan menyatukan seluruh bagian untuk pertama kalinya, kami menyelam jauh ke dalam ruang teknis dan menargetkan pengembang kontrak pintar yang berpengalaman menerapkan kontrak pintar secara on-chain. Jika Anda tertarik, teruslah membaca, tetapi jika Anda tidak tertarik, jangan khawatir untuk terus mengikuti! Ada tantangan teknis tambahan di bagian akhir (dengan hadiah).

Alamat indah kontrak pintar

Ada cara untuk menghasilkan alamat kontrak pintar yang 100% aman, apa pun perangkat lunak yang Anda gunakan, tidak masalah jika teknologi berulang tersebut bocor ke publik. Ini disebut “metode pabrik CREATE2” dan tidak hanya memberikan alamat yang cantik, ini juga merupakan cara yang sangat mudah untuk memastikan Anda memiliki alamat penerapan kontrak yang sama di banyak rantai. Hal ini juga memungkinkan orang lain untuk menyebarkan kode tanpa kepercayaan atas nama Anda tanpa adanya pembagian kunci pribadi atau asumsi nonce.

Pertama, gambaran singkat tentang cara memilih alamat kontrak pintar. Ada dua opsi penerapan, CREATE dan CREATE2. Saat Anda menerapkan kontrak pintar langsung dari EOA, proses defaultnya adalah CREATE. Alamat ditentukan dengan melakukan hashing alamat pembuat kontrak dengan nonce pembuat kontrak. Nonce ini mengacu pada berapa banyak transaksi yang telah dikirim oleh suatu alamat, sehingga dompet baru dimulai dari 0 dan bertambah 1 setiap kali transaksi baru dikirim. Berikut adalah rumus ajaib untuk alamat kontrak pintar yang diterapkan oleh CREATE:

alamat_baru = hash(pengirim, nonce)

Yang kurang umum, namun lebih menarik, adalah alamat kontrak pintar yang diterapkan menggunakan CREATE2, dan berikut rumusnya:

alamat_baru = hash(0xFF, pengirim, garam, bytecode)

Yang pertama tampaknya lebih sederhana, bukan? Namun, mari kita berikan contoh dimana kesederhanaan ini dapat merugikan dibandingkan dengan proses CREATE2 yang lebih kuat.

Airy Alice: Ada masalah dengan multi-rantai

Bayangkan seorang pengembang kripto bernama Alice membuat dua kontrak pintar: garpu Uniswap yang disebut GriddleSwap, dan proyek NFT yang disebut ph00ts. Semuanya merupakan primitif independen yang tidak dapat diubah, yang berarti tidak ada ketergantungan eksternal atau risiko jembatan lintas rantai. Alice menerapkan GriddleSwap ke Ethereum menggunakan nonce 0, dan kemudian menerapkan ph00ts ke Ethereum menggunakan nonce 1. Sayangnya, Alice memiliki rentang perhatian yang pendek dan perhatiannya terganggu di Twitter kripto selama beberapa menit sebelum menyebarkan karyanya ke Binance Smart Chain (BSC), platform kontrak pintar terbesar kedua.

Ups, mengacaukan urutan penerapan!

Tapi tunggu! Dia mengacaukan perintah penerapan dan menerapkan ph00t sebelum GriddleSwap. Karena alamat kontrak pintar hanya bergantung pada alamat pencipta, dan dalam blockchain yang diterapkan, Ethereum gridleswap memiliki alamat yang sama persis dengan ph00ts BSC! Lebih buruk lagi, alamat ph00ts Ethereum sama dengan alamat BSC GriddleSwap. Berpikir bahwa pengguna akhir akan bingung adalah pernyataan yang meremehkan. Faktanya, hal ini dapat disalahgunakan oleh penyebar jahat untuk mengelabui orang agar berpikir bahwa perilaku kontrak pada rantai tersebut adalah sama - yang merupakan asumsi yang wajar, mengingat alamat yang sama!

Hati-hati Alice: Masih akan ada masalah

Meskipun Alice berhati-hati saat mengerahkan dan tidak pernah mencampuradukkan urutan nonce-nya, masih ada masalah lain. Jika Alice menyebarkan dengan benar ke Ethereum dan BSC, tetapi kemudian membuat transaksi yang tidak terkait di Polygon, maka angka 0 telah habis. Dia tidak akan pernah bisa menerapkan GriddleSwap di sana karena nilai nonce-nya telah bertambah. Oleh karena itu, kunci pribadi penyebar harus dilindungi dengan cara apa pun. Jika Alice membocorkannya, penyabot jahat dapat melakukan transaksi yang tidak berhubungan. Jika Alice kehilangannya, dia juga akan kehilangan kemampuan untuk menyebarkan ke alamat tersebut lagi pada rantai baru. Ini adalah kerentanan permanen yang bergantung pada individu yang jujur ​​untuk melindungi kunci pribadi. Jika pengembang inti Bitcoin pun tidak bisa melakukannya, bagaimana kita bisa melakukannya?

Solusi: BUAT2

Untungnya, ada cara yang lebih baik untuk mendapatkan alamat yang konsisten di seluruh rantai—cara yang tidak bergantung pada kunci pribadi rahasia, tidak bergantung pada satu penyebar, dan tahan terhadap kesalahan penyebar di sepanjang proses. Ingat rumus untuk menemukan alamat kontrak pintar yang diterapkan menggunakan CREATE2:

alamat_baru = hash(0xFF, pengirim, garam, bytecode)

Parameter pertama 0xFF adalah nilai konstanta yang dapat diabaikan. Parameter kedua (alamat pengirim) dapat dibuat konsisten dengan memilih penerapan CREATE2Factory z0age 0x0000000000FFe8B47B3e2130213B802212439497 di sebagian besar rantai EVM. Parameter ketiga adalah garam yang dipilih pengguna, yang dapat kita gunakan untuk menemukan alamat yang baik dan kemudian menjaganya agar tidak berubah pada rantai. Yang keempat adalah bytecode kontrak, yang berfungsi sebagai pemeriksaan kewarasan yang berguna untuk memastikan kami menerapkan fungsi yang sama persis secara on-chain. Keempat parameter tersebut bisa tetap sama, apa pun yang dilakukan oleh seorang deployer.

Mengapa ini lebih baik? Berbeda dengan kunci pribadi, garam yang dipilih oleh penyebar dapat dipublikasikan! Mengetahui garam memungkinkan Anda menerapkan kontrak, namun Anda tidak memiliki kendali atas aset atau fungsi kontrak. Karena tidak mengikat informasi rahasia apa pun, siapa pun dapat menerapkan kontrak ke rantai baru tanpa mengungkapkan atau membagikan kunci privat. Parameter bytecode juga memastikan bahwa penerapan baru tanpa izin ini akan memiliki alamat yang sama jika dan hanya jika bytecode-nya sama. Hasilnya, pengguna akhir mendapatkan jaminan yang lebih kuat tanpa harus membuat perbedaan kode secara mendetail.

Untuk ikhtisar yang lebih mendalam, lihat artikel sains populer OpenZeppelin‌.

Buat alamat indah Anda sendiri

Apakah Proof of Work (PoW) tidak akan berguna setelah merger Ethereum? Pikirkan lagi! Kemampuan GPU yang sama yang membantu menemukan gambar awal hash dengan banyak angka nol di depan untuk blok Bitcoin juga sangat baik dalam menemukan gambar awal hash dengan banyak angka nol di depan untuk kontrak pintar EVM. z0age dari OpenSea (berkat penjelasannya untuk posting ini) menemukan pengaturan sederhana untuk membuat alamat rias Anda sendiri.

1. Gunakan broad.ai‌ untuk meluncurkan contoh GPU, yang mencoba sekitar 2 miliar kali per detik dan biaya sekitar 25 sen/jam:

Gambar:nvidia / opencl

GPU: 1x RTX 3090

Ruang disk yang perlu dialokasikan: 1,83 GB

2. SSH dan instal karat + create2crunch

sudo apt install build-essential -y; curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y; sumber "$HOME/.cargo/env"; git clone https://github.com/0age/create2crunch && cd create2crunch; sed -i 's/0x4/0x40/g' src/lib.rs

3. Jalankan pencarian benih. Untuk variabel lingkungan, INIT_CODE_HASH adalah keccak256 kode pembuatan kontrak. Cetakan uji pengecoran sampel dapat ditemukan di sini ‌ - pastikan untuk memverifikasinya sebelum menggunakan sumber daya komputasi dalam jumlah besar! LEADING harus berupa jumlah nol byte di depan yang Anda inginkan, dan TOTAL harus menjadi jumlah total nol byte yang Anda inginkan di alamat kontrak.

ekspor PABRIK="0x0000000000ffe8b47b3e2130213b802212439497"; ekspor PANGGILAN="0x00000000000000000000000000000000000000000"; ekspor INIT_CODE_HASH="0xabc...def"; ekspor TERKEMUKA=5; ekspor TOTAL=7; menjalankan kargo --rilis $PABRIK $PANGGILAN $INIT_CODE_HASH 0 $LEADING $TOTAL

Saat z0age pertama kali merilis reponya, ia mampu menjalankan 1,9 miliar percobaan per detik pada perangkat keras AI yang luas tersebut. Sejak itu, vektorisasi menjadi gila pada beberapa inti OpenGL, dan saya telah mengamati 2,15 miliar upaya per detik. Ini berarti bahwa menemukan alamat dengan 5 byte nol di depannya akan memakan waktu 256^5/(2150000000 * 60) ~= 8 menit dan menemukan alamat dengan 6 byte nol di depannya akan memakan waktu 256^6/(2150000000 * 3600) ~ = 36 jam . Alamat 7 byte nol di depan membutuhkan 256^7/(2150000000 * 86400) ~= 387 hari. Perhatikan bahwa satu byte sama dengan dua karakter heksadesimal, jadi alamat 5 byte terdepan akan memiliki 10 angka nol. Tentu saja, pencarian ini dapat diparalelkan sepenuhnya, dan kemungkinan keberhasilan sebenarnya dari waktu ke waktu akan mengikuti distribusi Poisson.

Menyebarkan pabrik CREATE2

Pembaca yang cerdik mungkin telah memperhatikan bahwa Pabrik CREATE2 sudah ada di 0x0000000000FFe8B47B3e2130213B802212439497 di semua rantai. Ini seperti masalah ayam-dan-telur, bagaimana penerapan alamat yang konsisten bergantung pada penerapan alamat yang konsisten?

Ketika saya pertama kali mempelajari pendekatan ini, saya pikir itu hanyalah kunci pribadi yang dipegang oleh seseorang yang lebih pintar dari saya (skenario "Alice yang jeli" di atas). Namun sebenarnya ini jauh lebih kuat dari itu! Pendekatan "transaksi tanpa kunci" pendiri ENS Nick Johnson mengeksploitasi fakta bahwa Anda dapat memulihkan alamat publik dari tanda tangan transaksi apa pun tanpa mengetahui kunci pribadi terkait yang menandatanganinya. Oleh karena itu, dimungkinkan untuk membuat transaksi ("menyebarkan pabrik create2") dan kemudian membuat tanda tangan palsu untuk transaksi tersebut, misalnya yang hanya terdiri dari 2. Kunci pribadi untuk tanda tangan palsu ini ada, tapi tidak ada yang tahu apa itu. Tapi kita bisa memulihkan alamat publik yang sesuai dengan "tanda tangan tanpa kunci", mengirimkannya beberapa ETH, dan kemudian mengirimkan transaksi yang ditandatangani ke mempool. Meskipun metode ini tidak jelas, ini adalah transaksi yang sah, dan faktanya satu-satunya transaksi sah yang dapat dikirim dari alamat publik ini.

Hasilnya? Siapa pun dapat menerapkan pabrik ke rantai baru tanpa informasi kepemilikan apa pun, sekaligus mencegah pelaku jahat menyebabkan kerusakan. Membuat EOA dengan tujuan tunggal yang hanya dapat menyebarkan satu transaksi adalah teknik yang sangat cerdas.

Alamat dan kontrak khusus yang dibuat selama transaksi tanpa kunci

Hal ini dapat dicapai dengan tiga perintah sederhana "forge cast". Bytecode terlalu panjang untuk disalin di sini, tetapi Anda dapat mengikuti petunjuk di https://github.com/ProjectOpenSea/seaport/blob/main/docs/Deployment.md‌ tanpa izin pada rantai mana pun pilihan Anda Terapkan Pabrik CREATE2 dengan mudah!

Tentu saja, jika sudah diterapkan, tidak perlu diterapkan lagi.

Catatan tambahan: Persyaratan EIP-155 sangat buruk

Upaya singkat untuk mendukung petualangan tata kelola L1 saya, silakan lewati saja. EIP-155‌ adalah proposal yang diajukan oleh Vitalik pada tahun 2016, yang memperkenalkan konsep "chain ID" untuk mencegah serangan replay. Setiap rantai memiliki pengidentifikasi uniknya sendiri - 1 untuk Ethereum, 56 untuk BSC, dan 137 untuk Polygon - yang akan disertakan dalam transaksi yang ditandatangani untuk mencegah serangan replay, yang dengan cepat diadopsi oleh Ethereum, dan semua rantai EVM lainnya telah mengikuti proposal ini. Ini bagus, tetapi masalahnya muncul ketika beberapa rantai dipilih, seperti Evmos yang baru-baru ini memutuskan untuk secara eksplisit melarang transaksi sebelum EIP-155‌, yang, karena alasan aneh, mencegah kesalahan operasional ketika Optimisme mengirim 20 juta Token OP ke multisig (ya, lagi) alamat bahwa Wintermute tidak ada, diklaim sebagai miliknya tetapi tidak pernah diinisialisasi. Namun, menonaktifkan transaksi sebelum 155 akan secara signifikan memutus seluruh rangkaian penerapan lintas rantai, seperti pabrik CREATE2 dan proyek terkemuka seperti Seaport. Proposal tata kelola ini harus segera dibatalkan, dan rincian perlindungan seperti ini harus berasal dari dompet (wallet) dan bukan dari lapisan konsensus. Jika multi-rantai adalah masa depan, maka pembatasan yang tidak perlu ini akan menjadi hambatan besar bagi proyek-proyek terkemuka untuk diterapkan di blockchain Anda.

Hal menyenangkan: menyebarkan hadiah

Saat ini https://delegate.cash diterapkan pada 7 rantai EVM yang berbeda (Ethereum, Polygon, Optimism, Celo, Avalanche, Fantom, dan Arbitrum) dan 7 testnet yang sesuai dengan rantai ini. Alamat kontrak untuk semua ini sama: 0x00000000000076A84feF008CDAbe6409d2FE638B.

Jadi apakah ini cukup? Tidak, kita perlu lebih banyak rantai. Karena delegasicash adalah primitif independen dengan ketergantungan nol, ini berarti risiko banyak rantai secara efektif adalah nol. Ini adalah manfaat murni! Oleh karena itu, untuk 5 orang pertama yang menyebarkan dan memverifikasi kontrak pintar delegasicash ke rantai baru dan testnet yang sesuai, saya akan memberikan bonus 100 USDC!

Anda perlu menggunakan skrip penerapan dari repositori sumber terbuka di sini. Ini mungkin memerlukan penerapan Pabrik CREATE2 jika tidak ada, dan jangan lupa verifikasi Etherscan! Selamat penerapan dan nikmati pembelajaran berdasarkan pengalaman!