Praktik Keamanan Terbaik untuk Kontrak Badan Berlian

Kontrak proxy adalah alat penting bagi pengembang kontrak pintar. Saat ini, ada banyak mode proxy dan aturan penggunaan yang sesuai dalam sistem kontrak. Kami sebelumnya telah menguraikan praktik terbaik keamanan kontrak proxy yang dapat ditingkatkan.

Pada artikel ini, kami akan memperkenalkan model proxy lain yang populer di komunitas pengembang, yaitu model proxy berlian.

Kontrak proxy berlian, juga dikenal sebagai "berlian", adalah pola desain untuk kontrak cerdas Ethereum yang diperkenalkan oleh Ethereum Improvement Proposal (EIP) 2535.

Mode berlian memungkinkan kontrak memiliki fungsionalitas tak terbatas dengan membagi fungsinya menjadi kontrak yang lebih kecil (juga disebut "aspek"). Diamond bertindak sebagai proxy, fungsi perutean memanggil ke aspek yang sesuai.

Desain model berlian dapat memecahkan masalah batasan ukuran kontrak maksimum jaringan Ethereum. Dengan memecah kontrak besar menjadi aspek-aspek yang lebih kecil, pola berlian memungkinkan pengembang membangun kontrak pintar yang lebih kompleks dan kaya fitur tanpa terpengaruh oleh batasan ukuran.

Diamond Brokerage menawarkan fleksibilitas luar biasa dibandingkan dengan kontrak tradisional yang dapat ditingkatkan. Mereka memungkinkan bagian kontrak untuk ditingkatkan, menambah, mengganti atau menghapus bagian fungsi yang dipilih tanpa menyentuh bagian lain.

Artikel ini memberikan ikhtisar tentang EIP-2535, termasuk perbandingan dengan mode proxy transparan dan mode proxy UUPS yang banyak digunakan, serta pertimbangan keamanannya untuk komunitas pengembang.

Dalam konteks EIP-2535, "berlian" adalah kontrak proksi yang implementasi fungsionalnya disediakan oleh kontrak logis yang berbeda, yang disebut "aspek".

Bayangkan berlian asli memiliki sisi yang berbeda, yang disebut faset, dan kontrak berlian Ethereum yang sesuai juga memiliki sisi yang berbeda. Setiap akad fungsi peminjaman intan memiliki sisi atau segi yang berbeda.

Standar berlian menggunakan analogi untuk memperluas kemampuan "potongan berlian" untuk menambah, mengganti, atau menghapus aspek dan fitur.

Selain itu, Diamond Standard menyediakan fitur yang disebut "Diamond Loupe" yang mengembalikan informasi tentang segi dan keberadaan berlian.

Dibandingkan dengan model proxy tradisional, "berlian" setara dengan kontrak proxy, dan "aspek" yang berbeda sesuai dengan realisasi kontrak. Berbagai aspek agen berlian dapat berbagi fungsi internal, pustaka, dan variabel status. Komponen utama dari berlian adalah sebagai berikut:

Kontrak pusat yang bertindak sebagai proxy, fungsi perutean memanggil ke aspek yang sesuai. Ini berisi pemetaan pemilih fungsi ke alamat "aspek".

Kontrak tunggal yang mengimplementasikan fungsi tertentu. Setiap segi berisi satu set fungsi yang dapat dipanggil oleh berlian.

adalah seperangkat fungsi standar yang didefinisikan dalam EIP-2535 yang memberikan informasi tentang pemilih segi dan fungsi yang digunakan dalam berlian. Diamond Loupe memungkinkan pengembang dan pengguna untuk memeriksa dan memahami struktur berlian.

Fungsi untuk menambah, mengganti, atau menghapus segi dalam berlian dan pemilih fitur yang sesuai. Hanya alamat resmi (misalnya, pemilik berlian atau kontrak dengan banyak tanda tangan) yang dapat melakukan pemotongan berlian.

Mirip dengan agen tradisional, saat pemanggilan fungsi dilakukan pada agen berlian, fungsi fallback agen (fungsi fallback) dipicu. Perbedaan utama dari proxy berlian adalah bahwa dalam fungsi fallback, terdapat pemetaan pemilihToFacet, yang menyimpan dan menentukan alamat kontrak logis mana yang memiliki implementasi dari fungsi yang dipanggil. Itu kemudian menggunakan panggilan delegasi untuk menjalankan fungsi, seperti proxy tradisional.

Semua proxy menggunakan fungsi fallback() untuk mendelegasikan pemanggilan fungsi ke alamat eksternal. Di bawah ini adalah penerapan proxy berlian dan penerapan proxy tradisional.

Perlu dicatat bahwa blok kode perakitan mereka sangat mirip, jadi satu-satunya perbedaan adalah alamat aspek dalam panggilan delegasi proxy berlian dan alamat impl dalam panggilan delegasi proxy tradisional.

Perbedaan utamanya adalah pada proxy berlian, alamat aspek ditentukan oleh peta hash dari pemanggil msg.sig (pemilih fungsi) ke alamat aspek, sedangkan pada proxy tradisional, alamat impl tidak bergantung pada penelepon masuk.

Fungsi fallback agen berlian

Fungsi fallback proxy tradisional

Pemetaan SelectorToFacet menentukan kontrak mana yang berisi implementasi dari setiap pemilih fungsi. Pekerja proyek sering kali perlu menambahkan, mengganti, atau menghapus pemetaan kontrak pemilih-ke-implementasi fungsi ini. EIP-2535 menetapkan: Untuk mencapai tujuan ini, harus ada fungsi diamondCut(). Di bawah ini adalah contoh antarmuka.

Setiap struktur FacetCut berisi alamat faset dan larik pemilih fitur empat byte untuk diperbarui dalam kontrak proxy berlian. FaceCutAction memungkinkan seseorang untuk menambah, mengganti, dan menghapus pemilih fitur. Implementasi fungsi diamondCut() harus mencakup kontrol akses yang memadai, mencegah benturan slot, memulihkan kegagalan, dll.

Untuk menanyakan fungsi dan aspek apa yang dimiliki agen berlian, kami menggunakan "kaca pembesar berlian". "Diamond Loupe" adalah aspek khusus yang mengimplementasikan antarmuka berikut yang ditentukan dalam EIP-2535:

Fungsi facets() harus mengembalikan alamat semua facet dan pemilih fungsi empat bytenya. Fungsi facetFunctionSelectors() harus mengembalikan semua pemilih fungsi yang didukung oleh aspek tertentu. Fungsi facetAddresses() harus mengembalikan semua alamat facet yang digunakan oleh berlian.

Fungsi facetAddress() harus mengembalikan aspek yang mendukung pemilih yang diberikan, atau alamat(0) jika tidak ditemukan. Perhatikan bahwa tidak boleh ada lebih dari satu alamat aspek dengan pemilih fitur yang sama.

Mengingat bahwa proxy berlian mendelegasikan pemanggilan fungsi yang berbeda ke kontrak implementasi yang berbeda, sangat penting untuk mengelola slot penyimpanan dengan benar untuk mencegah konflik. EIP-2535 menyebutkan beberapa metode manajemen slot penyimpanan.

Aspek ini dapat mendeklarasikan variabel status dalam struktur. Aspek ini dapat menggunakan sejumlah struktur, masing-masing dengan lokasi penyimpanan yang berbeda. Setiap struktur memiliki lokasi tertentu dalam penyimpanan kontrak. Aspek dapat mendeklarasikan variabel statusnya sendiri, tetapi tidak boleh bertentangan dengan lokasi penyimpanan variabel status yang dideklarasikan oleh aspek lain. Perpustakaan sampel dan kontrak penyimpanan berlian disediakan di EIP-2535, seperti yang ditunjukkan pada gambar berikut:

Penyimpanan aplikasi adalah versi penyimpanan berlian yang lebih terspesialisasi. Pola ini digunakan untuk berbagi variabel status aspek dengan lebih nyaman dan mudah. Struktur App store didefinisikan untuk memuat nomor dan tipe variabel status apa pun yang diperlukan oleh aplikasi. Sebuah aspek selalu mendeklarasikan struktur AppStorage sebagai variabel status pertama dan satu-satunya, di posisi 0 slot penyimpanan. Aspek yang berbeda kemudian dapat mengakses variabel dari struktur ini.

Ada juga strategi manajemen slot penyimpanan lainnya, termasuk gabungan Diamond Storage dan AppStorage. Misalnya, beberapa struktur dibagi antara aspek yang berbeda, dan beberapa khusus untuk aspek tertentu. Dalam semua kasus, sangat penting untuk mencegah benturan slot yang tidak disengaja.

Perbandingan dengan Proksi Transparan dan Proksi UUPS

Dua mode proxy utama yang saat ini digunakan oleh komunitas pengembang Web3 adalah mode proxy transparan dan mode proxy UUPS. Pada bagian ini, kami secara singkat membandingkan mode proxy berlian dengan mode proxy transparan dan proxy UUPS.

1.EPI-2535:

2.EPI-1967:

3.Pelaksanaan referensi proxy berlian:

4. Implementasi OpenZeppelin:

Proxy dan solusi yang dapat diskalakan adalah sistem yang lebih kompleks, dan OpenZeppelin menyediakan basis kode dan dokumentasi lengkap untuk proksi yang dapat diskalakan UUPS, Transparan, dan Beacon. Namun untuk mode proxy berlian, meskipun OpenZeppelin menegaskan manfaatnya, mereka tetap memutuskan untuk tidak memasukkan implementasi berlian EIP-2535 di perpustakaan mereka.

Oleh karena itu, pengembang yang menggunakan pustaka pihak ketiga yang ada atau mengimplementasikan solusi ini sendiri harus mengimplementasikannya dengan sangat hati-hati. Di sini kami telah menyusun daftar periksa praktik terbaik keamanan untuk dipertimbangkan oleh komunitas pengembang.

Dengan memecah logika kontrak menjadi modul yang lebih kecil dan lebih mudah dikelola, pengembang dapat lebih mudah menguji dan mengaudit kode mereka.

Selain itu, pendekatan ini memungkinkan pengembang untuk fokus pada aspek tertentu dalam membangun dan memelihara kontrak, daripada mengelola basis kode monolitik yang kompleks. Hasil akhirnya adalah basis kode yang lebih fleksibel dan modular yang dapat dengan mudah diperbarui dan dimodifikasi tanpa memengaruhi bagian lain dari kontrak.

Sumber: Aavegotchi Github

Saat kontrak proxy berlian diterapkan, ia harus menambahkan alamat kontrak DiamondCutFacet ke kontrak proxy berlian dan mengimplementasikan fungsi diamondCut(). Fungsi diamondCut() digunakan untuk menambah, menghapus atau mengganti facet dan fungsi, tanpa DiamondCutFacet dan diamondCut(), diamond agent tidak dapat bekerja dengan baik.

Sumber: Mugen's Diamond-3-Hardhat

Saat menambahkan variabel status baru ke struktur penyimpanan dalam smart contract, itu harus ditambahkan di akhir struktur. Menambahkan variabel status baru di awal atau di tengah struktur akan menyebabkan variabel status baru menimpa data variabel status yang ada, dan setiap variabel status setelah variabel status baru dapat merujuk ke lokasi memori yang salah.

Pola AppStorage mengharuskan satu dan hanya satu struktur yang dideklarasikan untuk proxy berlian, dan struktur ini digunakan bersama oleh semua aspek. Jika diperlukan beberapa struktur, pola DiamondStorage harus digunakan.

Jangan letakkan struct langsung di dalam struct lain kecuali Anda yakin Anda tidak bermaksud menambahkan lebih banyak variabel status ke struct bagian dalam. Tidak mungkin menambahkan variabel status baru ke struct internal dalam pemutakhiran tanpa menimpa slot penyimpanan variabel yang dideklarasikan setelah struct.

Solusinya adalah menambahkan variabel status baru ke struct yang dipetakan memori alih-alih menempatkan "struct" langsung di "struct". Slot penyimpanan variabel dalam peta dihitung secara berbeda dan tidak bersebelahan dalam penyimpanan.

Ukuran array akan dipengaruhi oleh ukuran struktur. Saat variabel status baru ditambahkan ke struktur, ia mengubah ukuran dan tata letak struktur tersebut.

Ini dapat menyebabkan masalah jika struktur digunakan sebagai elemen dalam array. Jika ukuran dan tata letak struktur berubah, maka ukuran dan tata letak array juga akan berubah, yang dapat menyebabkan masalah pengindeksan atau operasi lain yang bergantung pada ukuran dan tata letak struktur yang konsisten.

Mirip dengan pola proxy lainnya, setiap variabel harus memiliki slot penyimpanan yang unik. Jika tidak, dua struktur berbeda di lokasi yang sama akan saling menimpa.

Fungsi initialize() biasanya digunakan untuk mengatur variabel penting, seperti alamat peran istimewa. Jika tidak diinisialisasi saat kontrak diterapkan, pelaku jahat dapat memanggil dan mengontrol kontrak.

Direkomendasikan untuk menambahkan kontrol akses yang sesuai ke fungsi inisialisasi/pengaturan, atau memastikan bahwa fungsi tersebut dipanggil saat kontrak diterapkan dan tidak dapat dipanggil lagi.

Jika ada aspek kontrak yang dapat memanggil fungsi selfdestruct(), itu berpotensi menghancurkan seluruh kontrak, yang mengakibatkan hilangnya dana atau data. Ini sangat berbahaya dalam mode proxy berlian, karena banyak aspek dapat mengakses penyimpanan dan data kontrak proxy.

Saat ini, kami melihat semakin banyak proyek yang mengadopsi model proxy berlian dalam kontrak pintar mereka. Ini menawarkan fleksibilitas dan keunggulan lain dibandingkan proxy tradisional.

Namun, fleksibilitas ekstra juga bisa berarti permukaan serangan yang lebih luas bagi penyerang. Kami harap artikel ini membantu komunitas developer memahami mekanisme model proxy berlian dan pertimbangan keamanannya.

Pada saat yang sama, tim proyek harus melakukan pengujian yang ketat dan audit pihak ketiga untuk mengurangi risiko kerentanan terkait pelaksanaan kontrak agen berlian.

Lihat Asli
Konten ini hanya untuk referensi, bukan ajakan atau tawaran. Tidak ada nasihat investasi, pajak, atau hukum yang diberikan. Lihat Penafian untuk pengungkapan risiko lebih lanjut.
  • Hadiah
  • Komentar
  • Bagikan
Komentar
0/400
Tidak ada komentar
  • Sematkan
Perdagangkan Kripto Di Mana Saja Kapan Saja
qrCode
Pindai untuk mengunduh aplikasi Gate.io
Komunitas
Indonesia
  • 简体中文
  • English
  • Tiếng Việt
  • 繁體中文
  • Español
  • Русский
  • Français (Afrique)
  • Português (Portugal)
  • ไทย
  • Indonesia
  • 日本語
  • بالعربية
  • Українська
  • Português (Brasil)