Teknik Menarik dalam Pengembangan Kontrak: Pelajaran yang Dipelajari dari Kode Uniswap
Baru-baru ini, ketika menulis tutorial pengembangan bursa terdesentralisasi, saya merujuk pada implementasi kode dari DEX terkenal, dan mempelajari banyak pengetahuan baru. Sebagai seorang pengembang yang pernah mengembangkan kontrak NFT sederhana, ini adalah pertama kalinya saya mencoba pengembangan kontrak Defi, saya percaya bahwa trik kecil ini akan sangat membantu bagi pemula yang ingin belajar pengembangan kontrak.
Selanjutnya, mari kita lihat beberapa trik menarik ini, beberapa di antaranya bahkan dapat dianggap sebagai keterampilan yang luar biasa.
Alamat penyebaran kontrak yang dapat diprediksi
Biasanya, alamat yang diperoleh setelah menerapkan kontrak tampak acak, karena terkait dengan nonce, sehingga alamat kontrak sulit diprediksi. Namun, dalam beberapa skenario, kita perlu menginferensikan alamat kontrak melalui pasangan perdagangan dan informasi terkait. Ini sangat berguna dalam banyak kasus, seperti menentukan hak transaksi atau mendapatkan alamat kumpulan likuiditas.
Anda dapat menggunakan metode CREATE2 untuk membuat kontrak dengan menambahkan parameter salt, sehingga alamat kontrak yang dibuat dapat diprediksi. Logika pembuatan alamat adalah: alamat baru = hash("0xFF", alamat pencipta, salt, initcode).
Manfaatkan Fungsi Callback
Dalam Solidity, kontrak dapat saling memanggil. Ada satu skenario di mana A memanggil B dalam suatu metode, dan B memanggil kembali A dalam metode yang dipanggil. Ini sangat berguna dalam beberapa skenario.
Misalnya, ketika Anda memanggil metode swap dari suatu kontrak DEX untuk bertransaksi, ia akan memanggil kembali swapCallback, dengan memasukkan Token yang dibutuhkan untuk transaksi ini. Pihak yang memanggil perlu mentransfer Token yang diperlukan untuk transaksi ke kontrak DEX dalam panggilan balik, bukan membagi metode swap menjadi dua bagian untuk dipanggil oleh pihak pemanggil. Ini memastikan keamanan metode swap, menjamin seluruh logika dieksekusi secara lengkap, tanpa perlu mencatat variabel yang rumit untuk memastikan keamanan.
Menggunakan pengecualian untuk menyampaikan informasi, menggunakan try catch untuk mengimplementasikan estimasi transaksi
Dalam kode beberapa DEX, kami menemukan bahwa metode swap dibungkus dengan try catch untuk dieksekusi. Mengapa demikian? Karena kami perlu mensimulasikan metode swap untuk memperkirakan Token yang diperlukan untuk transaksi, tetapi saat memperkirakan tidak akan terjadi pertukaran Token yang sebenarnya, sehingga akan menghasilkan kesalahan. Ini dilakukan dengan melemparkan kesalahan khusus dalam fungsi callback transaksi, lalu menangkap kesalahan tersebut dan mengurai informasi yang diperlukan dari pesan kesalahan.
Ini terlihat agak curang, tetapi sangat praktis. Dengan cara ini, tidak perlu mengubah metode swap untuk memperkirakan kebutuhan transaksi, logikanya juga lebih sederhana.
Menggunakan angka besar untuk mengatasi masalah presisi
Dalam kode DEX, ada banyak logika perhitungan, seperti menghitung token yang ditukar berdasarkan harga saat ini dan likuiditas. Dalam proses ini, kita harus menghindari kehilangan presisi saat melakukan operasi pembagian. Dalam beberapa implementasi, proses perhitungan sering menggunakan "<< FixedPoint96.RESOLUTION" yang mewakili pergeseran kiri 96 bit, setara dengan mengalikan 2^96. Setelah pergeseran kiri, operasi pembagian dilakukan, sehingga dapat menjamin presisi dalam transaksi normal tanpa meluap ( biasanya dihitung dengan uint256, cukup dalam kasus ).
Menghitung Pendapatan dengan Metode Share
Di DEX, kita perlu mencatat pendapatan biaya dari penyedia likuiditas LP( ). Jelas, kita tidak dapat mencatat biaya masing-masing LP setiap kali transaksi, karena itu akan menghabiskan banyak Gas. Lalu, bagaimana cara mengatasinya?
Dapat mendefinisikan struktur yang berisi feeGrowthInside0LastX128 dan feeGrowthInside1LastX128 dalam Posisi, yang mencatat biaya yang harus diterima oleh setiap likuiditas saat biaya ditarik terakhir kali dari setiap posisi.
Secara sederhana, cukup catat total biaya transaksi dan biaya transaksi yang harus dialokasikan untuk setiap likuiditas. Ketika LP menarik biaya transaksi, biaya yang dapat ditarik dapat dihitung berdasarkan likuiditas yang dimiliki. Ini mirip dengan memiliki saham perusahaan, ketika menarik hasil saham, Anda hanya perlu mengetahui laba per saham historis perusahaan, serta hasil Anda saat terakhir menarik.
Tidak semua informasi perlu diambil dari rantai
Penyimpanan di blockchain relatif mahal, sehingga tidak semua informasi harus disimpan di blockchain atau diambil dari blockchain. Misalnya, banyak antarmuka yang digunakan oleh situs web DEX tertentu adalah antarmuka Web2 tradisional.
Daftar kolam perdagangan, informasi kolam perdagangan, dan lainnya dapat disimpan dalam database biasa, beberapa mungkin perlu disinkronkan secara berkala dari rantai, tetapi tidak perlu memanggil RPC interface yang disediakan oleh rantai atau layanan node secara real-time untuk mendapatkan data terkait.
Tentu saja, transaksi kunci pasti dilakukan di atas blockchain.
Pelajari Pemisahan Kontrak, Manfaatkan Kontrak Standar yang Ada
Sebuah proyek mungkin mencakup beberapa kontrak yang benar-benar diterapkan. Bahkan jika hanya ada satu kontrak yang diterapkan, kita juga dapat memecah kontrak menjadi beberapa kontrak untuk pemeliharaan melalui pewarisan.
Selain itu, Anda dapat langsung menggunakan kontrak standar seperti @openzeppelin/contracts/token/ERC721/ERC721.sol. Dengan cara ini, Anda dapat mengelola posisi dengan cara NFT dan juga meningkatkan efisiensi pengembangan dengan kontrak standar yang sudah ada.
Ringkasan
Pengalaman langsung dalam mengembangkan versi sederhana dari bursa terdesentralisasi akan memungkinkan Anda untuk lebih memahami implementasi kode DEX, serta mempelajari lebih banyak poin pengetahuan dalam proyek nyata. Baik Anda tertarik pada pengembangan proyek Web3 atau DeFi, pengalaman praktis akan sangat membantu Anda.
Halaman ini mungkin berisi konten pihak ketiga, yang disediakan untuk tujuan informasi saja (bukan pernyataan/jaminan) dan tidak boleh dianggap sebagai dukungan terhadap pandangannya oleh Gate, atau sebagai nasihat keuangan atau profesional. Lihat Penafian untuk detailnya.
7 Teknik Pengembangan Kontrak Utama: Belajar Praktik Terbaik Keuangan Desentralisasi dari Kode DEX
Teknik Menarik dalam Pengembangan Kontrak: Pelajaran yang Dipelajari dari Kode Uniswap
Baru-baru ini, ketika menulis tutorial pengembangan bursa terdesentralisasi, saya merujuk pada implementasi kode dari DEX terkenal, dan mempelajari banyak pengetahuan baru. Sebagai seorang pengembang yang pernah mengembangkan kontrak NFT sederhana, ini adalah pertama kalinya saya mencoba pengembangan kontrak Defi, saya percaya bahwa trik kecil ini akan sangat membantu bagi pemula yang ingin belajar pengembangan kontrak.
Selanjutnya, mari kita lihat beberapa trik menarik ini, beberapa di antaranya bahkan dapat dianggap sebagai keterampilan yang luar biasa.
Alamat penyebaran kontrak yang dapat diprediksi
Biasanya, alamat yang diperoleh setelah menerapkan kontrak tampak acak, karena terkait dengan nonce, sehingga alamat kontrak sulit diprediksi. Namun, dalam beberapa skenario, kita perlu menginferensikan alamat kontrak melalui pasangan perdagangan dan informasi terkait. Ini sangat berguna dalam banyak kasus, seperti menentukan hak transaksi atau mendapatkan alamat kumpulan likuiditas.
Anda dapat menggunakan metode CREATE2 untuk membuat kontrak dengan menambahkan parameter salt, sehingga alamat kontrak yang dibuat dapat diprediksi. Logika pembuatan alamat adalah: alamat baru = hash("0xFF", alamat pencipta, salt, initcode).
Manfaatkan Fungsi Callback
Dalam Solidity, kontrak dapat saling memanggil. Ada satu skenario di mana A memanggil B dalam suatu metode, dan B memanggil kembali A dalam metode yang dipanggil. Ini sangat berguna dalam beberapa skenario.
Misalnya, ketika Anda memanggil metode swap dari suatu kontrak DEX untuk bertransaksi, ia akan memanggil kembali swapCallback, dengan memasukkan Token yang dibutuhkan untuk transaksi ini. Pihak yang memanggil perlu mentransfer Token yang diperlukan untuk transaksi ke kontrak DEX dalam panggilan balik, bukan membagi metode swap menjadi dua bagian untuk dipanggil oleh pihak pemanggil. Ini memastikan keamanan metode swap, menjamin seluruh logika dieksekusi secara lengkap, tanpa perlu mencatat variabel yang rumit untuk memastikan keamanan.
Menggunakan pengecualian untuk menyampaikan informasi, menggunakan try catch untuk mengimplementasikan estimasi transaksi
Dalam kode beberapa DEX, kami menemukan bahwa metode swap dibungkus dengan try catch untuk dieksekusi. Mengapa demikian? Karena kami perlu mensimulasikan metode swap untuk memperkirakan Token yang diperlukan untuk transaksi, tetapi saat memperkirakan tidak akan terjadi pertukaran Token yang sebenarnya, sehingga akan menghasilkan kesalahan. Ini dilakukan dengan melemparkan kesalahan khusus dalam fungsi callback transaksi, lalu menangkap kesalahan tersebut dan mengurai informasi yang diperlukan dari pesan kesalahan.
Ini terlihat agak curang, tetapi sangat praktis. Dengan cara ini, tidak perlu mengubah metode swap untuk memperkirakan kebutuhan transaksi, logikanya juga lebih sederhana.
Menggunakan angka besar untuk mengatasi masalah presisi
Dalam kode DEX, ada banyak logika perhitungan, seperti menghitung token yang ditukar berdasarkan harga saat ini dan likuiditas. Dalam proses ini, kita harus menghindari kehilangan presisi saat melakukan operasi pembagian. Dalam beberapa implementasi, proses perhitungan sering menggunakan "<< FixedPoint96.RESOLUTION" yang mewakili pergeseran kiri 96 bit, setara dengan mengalikan 2^96. Setelah pergeseran kiri, operasi pembagian dilakukan, sehingga dapat menjamin presisi dalam transaksi normal tanpa meluap ( biasanya dihitung dengan uint256, cukup dalam kasus ).
Menghitung Pendapatan dengan Metode Share
Di DEX, kita perlu mencatat pendapatan biaya dari penyedia likuiditas LP( ). Jelas, kita tidak dapat mencatat biaya masing-masing LP setiap kali transaksi, karena itu akan menghabiskan banyak Gas. Lalu, bagaimana cara mengatasinya?
Dapat mendefinisikan struktur yang berisi feeGrowthInside0LastX128 dan feeGrowthInside1LastX128 dalam Posisi, yang mencatat biaya yang harus diterima oleh setiap likuiditas saat biaya ditarik terakhir kali dari setiap posisi.
Secara sederhana, cukup catat total biaya transaksi dan biaya transaksi yang harus dialokasikan untuk setiap likuiditas. Ketika LP menarik biaya transaksi, biaya yang dapat ditarik dapat dihitung berdasarkan likuiditas yang dimiliki. Ini mirip dengan memiliki saham perusahaan, ketika menarik hasil saham, Anda hanya perlu mengetahui laba per saham historis perusahaan, serta hasil Anda saat terakhir menarik.
Tidak semua informasi perlu diambil dari rantai
Penyimpanan di blockchain relatif mahal, sehingga tidak semua informasi harus disimpan di blockchain atau diambil dari blockchain. Misalnya, banyak antarmuka yang digunakan oleh situs web DEX tertentu adalah antarmuka Web2 tradisional.
Daftar kolam perdagangan, informasi kolam perdagangan, dan lainnya dapat disimpan dalam database biasa, beberapa mungkin perlu disinkronkan secara berkala dari rantai, tetapi tidak perlu memanggil RPC interface yang disediakan oleh rantai atau layanan node secara real-time untuk mendapatkan data terkait.
Tentu saja, transaksi kunci pasti dilakukan di atas blockchain.
Pelajari Pemisahan Kontrak, Manfaatkan Kontrak Standar yang Ada
Sebuah proyek mungkin mencakup beberapa kontrak yang benar-benar diterapkan. Bahkan jika hanya ada satu kontrak yang diterapkan, kita juga dapat memecah kontrak menjadi beberapa kontrak untuk pemeliharaan melalui pewarisan.
Selain itu, Anda dapat langsung menggunakan kontrak standar seperti @openzeppelin/contracts/token/ERC721/ERC721.sol. Dengan cara ini, Anda dapat mengelola posisi dengan cara NFT dan juga meningkatkan efisiensi pengembangan dengan kontrak standar yang sudah ada.
Ringkasan
Pengalaman langsung dalam mengembangkan versi sederhana dari bursa terdesentralisasi akan memungkinkan Anda untuk lebih memahami implementasi kode DEX, serta mempelajari lebih banyak poin pengetahuan dalam proyek nyata. Baik Anda tertarik pada pengembangan proyek Web3 atau DeFi, pengalaman praktis akan sangat membantu Anda.