Move lahir pada tahap awal proyek Libra pada tahun 2018 - dua pendiri Mysten (Evan dan I) juga merupakan tim pendiri Libra. Sebelum kami memutuskan untuk membuat bahasa baru, tim awal Libra secara intensif mempelajari kasus penggunaan dan bahasa kontrak pintar yang ada untuk memahami apa yang ingin dilakukan pengembang dan di mana bahasa yang ada tidak dapat diterapkan. Masalah utama yang kami temukan adalah bahwa kontrak pintar adalah tentang aset dan kontrol akses, namun bahasa kontrak pintar awal tidak memiliki representasi tipe/nilai untuk keduanya. Hipotesis kami adalah jika kami menyediakan abstraksi kelas satu untuk konsep-konsep utama ini, kami dapat meningkatkan keamanan kontrak pintar dan produktivitas pemrogram kontrak pintar secara signifikan - memiliki kosakata yang tepat untuk tugas yang ada dapat membuat perbedaan besar. Selama bertahun-tahun, banyak orang telah berkontribusi pada desain dan implementasi Move seiring dengan berkembangnya bahasa tersebut dari ide utama menjadi bahasa kontrak cerdas yang tidak bergantung pada platform dengan tujuan yang berani untuk menjadi "JavaScript dari web3".
Hari ini, kami sangat gembira mengumumkan pencapaian dalam integrasi Move dan Sui. Fungsionalitas Sui Move lengkap, didukung oleh alat-alat canggih, dan memiliki dokumentasi dan contoh yang luas, termasuk bagian berikut:
Serangkaian tutorial pemrograman menggunakan objek Sui Move. Dokumen pengembangan tentang pengetahuan dasar, pola desain, dan contoh Sui Move. Sebuah plug-in peningkatan VSCode yang dikembangkan oleh tim Mysten Move, yang mendukung analisis kode dan diagnosis kesalahan, dan terintegrasi konstruksi, pengujian dan manajemen paket Move. , pembuatan dokumentasi dan validator Move yang terintegrasi dengan sui CLI
Apa yang membuat Move unik
Move adalah bahasa tertanam lintas platform. Sintaks intinya sendiri sangat sederhana: ia memiliki konsep umum seperti struct, integer, dan alamat, namun tidak memiliki konsep khusus blockchain seperti akun dan transaksi), waktu, kriptografi, dll. Fungsi-fungsi ini harus disediakan oleh platform blockchain yang terintegrasi dengan Move. Yang penting, blockchain ini tidak memerlukan Move forknya sendiri - setiap platform menggunakan mesin virtual Move, validator bytecode, compiler, validator, manajer paket, dan CLI yang sama, namun dengan membangun Kode di atas komponen inti ini untuk menambahkan fungsionalitas khusus blockchain . Diem adalah blockchain pertama yang menyematkan Move, dan blockchain berbasis Move berikutnya (termasuk 0L, StarCoin, dan Aptos) sebagian besar mengadopsi pendekatan gaya Diem. Meskipun Diem-style Move memiliki beberapa kualitas hebat, baik sifat Diem yang diizinkan maupun detail implementasi tertentu dari blockchain Diem (terutama model penyimpanan) membuat beberapa kasus penggunaan kontrak pintar dasar sulit untuk diterapkan. Secara khusus, desain asli Move dan Diem mendahului ledakan popularitas NFT dan memiliki beberapa keunikan yang membuat penerapan kasus penggunaan terkait NFT menjadi sangat rumit. Dalam postingan ini, kami akan mendemonstrasikan masalah penyematan Move gaya Diem asli melalui tiga contoh tersebut dan menjelaskan bagaimana kami memecahkan masalah ini di Sui Move. Kami mengasumsikan beberapa pemahaman dasar tentang Move, namun semoga poin-poin penting ini dapat dipahami oleh siapa pun yang memiliki latar belakang pemrograman.
Pengalaman halus saat membuat aset dalam skala besar
Kemampuan untuk membuat dan mendistribusikan aset secara massal sangat penting baik untuk orientasi maupun keterlibatan pengguna web3. Mungkin streamer Twitch ingin mendistribusikan NFT peringatan, pembuat konten ingin mengirimkan tiket untuk acara khusus, atau pengembang game ingin mengirimkan item baru ke semua pemain. Berikut adalah upaya (gagal) untuk menulis kode untuk pencetakan aset secara massal dalam Gerakan gaya Diem. Kode ini mengambil input vektor alamat penerima, menghasilkan aset untuk setiap penerima, dan mencoba mentransfer aset.
Dalam perpindahan gaya Diem, penyimpanan global diketik berdasarkan pasangan (alamat, nama tipe) - yaitu, setiap alamat dapat menyimpan paling banyak satu aset dari tipe tertentu. Oleh karena itu, move_to(receiverient, CoolAsset { ...} mencoba memindahkan CoolAsset dengan menyimpannya di alamat penerima. Namun, kode ini gagal dikompilasi pada baris move_to(receiverient, ...). Pertanyaan kuncinya adalah , di Perpindahan gaya Diem, Anda tidak dapat mengirim nilai bertipe CoolAsset ke alamat A, kecuali transaksi dikirim dari alamat selain A, dan pemilik akun yang dibuat di A mengirimkan transaksi dan secara eksplisit memilih untuk menerima CoolAsset. jenis objek. Ini adalah dua transaksi, hanya untuk menerima aset! Keputusan untuk melakukan ini masuk akal untuk Diem, yang merupakan sistem berizin yang perlu membatasi pembuatan akun dengan hati-hati dan mencegah akun dibatasi oleh sistem penyimpanan. Namun, alih-alih menyimpan terlalu banyak aset, untuk sistem terbuka yang ingin menggunakan alokasi aset sebagai mekanisme orientasi, atau secara umum mengizinkan aset mengalir bebas antar pengguna, seperti yang dilakukan pada Ethereum dan blockchain serupa, hal ini sangat terbatas .
Kode untuk mengimplementasikan fungsi yang sama di Sui Move adalah sebagai berikut:
Penyimpanan global Sui Move dikunci oleh ID objek. Setiap struktur dengan pasangan nilai kunci adalah "objek Sui", yang harus memiliki bidang id unik secara global. Sui Move memperkenalkan transfer primitif yang dapat digunakan pada objek Sui apa pun, alih-alih menggunakan struktur move_to yang membatasi. Di balik terpal, primitif ini memetakan id ke CoolAsset di penyimpanan global dan menambahkan metadata untuk menunjukkan bahwa nilai tersebut dimiliki oleh penerima. Properti menarik dari Mass_mint versi Sui adalah ia ditukar dengan semua transaksi lainnya (termasuk transaksi lain yang memanggil Mass_mint!). Runtime Sui akan memperhatikan hal ini dan mengirimkan transaksi yang memanggil fungsi ini melalui siaran konsensus Bizantium "jalur cepat" yang tidak memerlukan konsensus. Transaksi tersebut dapat dilakukan atau dieksekusi secara paralel. Ini tidak memerlukan usaha dari pemrogram (mereka hanya menulis kode di atas dan runtime menangani sisanya.) Mungkin secara halus, hal ini tidak terjadi pada varian Diem dari kode ini -- meskipun kode di atas berfungsi, ada dan guid::create panggilan akan menimbulkan perselisihan dengan transaksi lain yang menghasilkan GUID atau sumber daya akun sentuh. Dalam beberapa kasus, dimungkinkan untuk menulis ulang kode Move gaya Diem untuk menghindari argumen, namun banyak cara penulisan konvensional Move gaya Diem menimbulkan hambatan kecil yang menghambat eksekusi paralel.
Kepemilikan dan transfer aset lokal
Mari kita perluas kode Move gaya Diem dengan solusi yang benar-benar dikompilasi dan dijalankan. Cara umum untuk melakukan hal ini adalah dengan "pola pembungkus": karena Bob tidak dapat memindahkan CoolAsset secara langsung ke alamat Alice, kami meminta Alice untuk "ikut serta" untuk menerima CoolAsset, terlebih dahulu memublikasikan jenis pembungkus CoolAssetStore, yang berisi jenis Koleksi (meja). Alice dapat melakukan ini dengan memanggil fungsi opt_in. Kami kemudian menambahkan kode yang memungkinkan Bob untuk memindahkan CoolAsset dari CoolAssetStore miliknya ke CoolAssetStore Alice. Dalam kode ini, mari tambahkan kerutan tambahan: kami hanya akan mengizinkan transfer CoolAssets jika dibuat setidaknya 30 hari yang lalu. Kebijakan semacam ini penting bagi kreator yang (misalnya) ingin menghentikan spekulan membeli/berlebihan tiket acara sehingga lebih mudah bagi penggemar sejati untuk mendapatkan tiket tersebut dengan harga yang wajar.
Kode ini valid. Tapi ini cara yang agak rumit untuk menyelesaikan tugas mentransfer aset dari Alice ke Bob! Mari kita lihat implementasi Sui Move lainnya
Kode ini jauh lebih pendek. Hal utama yang perlu diperhatikan di sini adalah cool_transfer adalah fungsi entri (artinya dapat dipanggil langsung oleh runtime Sui melalui transaksi), namun ia memiliki parameter bertipe CoolAsset sebagai input. Ini adalah keajaiban Sui Runtime lagi. Suatu transaksi menyertakan sekumpulan ID objek yang ingin dioperasikannya, dan ketika Sui Runtime:
Parsing ID menjadi nilai objek (tidak perlu bagian Bor_global_mut dan table_remove dalam kode gaya Diem di atas). Memeriksa apakah objek tersebut dimiliki oleh pengirim transaksi (menghilangkan kebutuhan akan bagian penandatangan::alamat_of dan kode terkait di atas). Bagian ini sangat menarik dan kami akan segera menjelaskannya: Di Sui, pemeriksaan kepemilikan objek yang aman adalah bagian dari runtime. Periksa jenis nilai objek sesuai dengan tipe parameter dari fungsi yang disebut cool_transfer ke cool_transfer parameter dan panggil fungsinya
Hal ini memungkinkan pemrogram Sui Move untuk melewatkan templat untuk bagian logika "Penarikan" dan langsung beralih ke bagian yang menyenangkan: memeriksa kebijakan kedaluwarsa 30 hari. Demikian pula, bagian "deposit" juga sangat disederhanakan dengan struktur transfer Sui Move yang dijelaskan di atas. Terakhir, tidak perlu memperkenalkan tipe pembungkus dengan koleksi internal seperti CoolAssetStore - penyimpanan global Sui yang diindeks id memungkinkan satu alamat untuk menyimpan sejumlah nilai dari tipe tertentu. Perbedaan lain yang perlu diperhatikan adalah cool_transfer gaya Diem memiliki 5 cara untuk membatalkan (yaitu gagal dan membebankan biaya bahan bakar kepada pengguna tanpa menyelesaikan transfer), sedangkan Sui Move cool_transfer hanya memiliki 1 cara untuk membatalkan: ketika melanggar kebijakan 30 hari. Membongkar pemeriksaan kepemilikan objek ke runtime merupakan sebuah keuntungan besar, tidak hanya dari segi ergonomis, namun juga dari segi keamanan. Menerapkan keamanan pada tingkat runtime mencegah kesalahan dalam menerapkan pemeriksaan ini pada konstruksi (atau melupakannya sepenuhnya!). Terakhir, perhatikan bahwa tanda tangan fungsi titik masuk Sui Move cool_transfer( aset: CoolAsset, ...) memberi kita banyak informasi tentang apa yang akan dilakukan fungsi ini (lebih buram daripada tanda tangan fungsi gaya Diem). Kita dapat berpikir bahwa fungsi ini meminta izin untuk mentransfer CoolAsset, sementara fungsi lain f(asset: &mut CoolAsset, ...) meminta izin untuk menulis (tetapi tidak mentransfer) CoolAsset, dan g(asset: &CoolAsset, . ..) hanya meminta izin membaca.
Karena informasi ini tersedia langsung di tanda tangan fungsi (tidak diperlukan eksekusi atau analisis statis!), informasi ini dapat digunakan langsung oleh dompet dan alat klien lainnya. Di Sui Wallet, kami sedang mengerjakan permintaan tanda tangan yang dapat dibaca manusia, memanfaatkan fungsi tanda tangan terstruktur ini untuk memberikan permintaan izin gaya iOS/Android kepada pengguna. Dompet dapat mengatakan sesuatu seperti: "Transaksi ini memerlukan izin untuk membaca CoolAsset Anda, menulis ke AssetCollection Anda, dan mentransfer ConcertTicket Anda. Lanjutkan?".
Permintaan tanda tangan yang dapat dibaca manusia menyelesaikan vektor serangan berskala besar yang ada di banyak platform yang ada, termasuk platform yang menggunakan Move gaya Diem!, di mana pengguna dompet harus menandatangani transaksi secara membabi buta tanpa memahami dampak yang mungkin ditimbulkannya. Kami percaya membuat pengalaman dompet lebih kecil risikonya adalah langkah penting dalam mempromosikan adopsi utama dompet mata uang kripto, dan merancang Sui Move untuk mendukung tujuan ini dengan mengaktifkan fitur seperti permintaan tanda tangan yang dapat dibaca manusia.
Gabungkan aset yang berbeda
Terakhir, mari kita perhatikan contoh penggabungan berbagai jenis aset. Ini adalah kasus penggunaan yang cukup umum: pemrogram mungkin ingin mengemas berbagai jenis NFT ke dalam sebuah koleksi, menggabungkan item untuk dijual di pasar, atau menambahkan lampiran ke item yang sudah ada. Misalkan kita mempunyai situasi berikut:
Alice mendefinisikan objek karakter untuk digunakan dalam game. Alice ingin mendukung dekorasi karakternya dengan berbagai jenis aksesori pihak ketiga yang kemudian dibuat. Siapa pun dapat membuat aksesori, tetapi pemilik karakter harus memutuskan apakah akan menambahkan aksesori. Mentransfer karakter akan secara otomatis mentransfer semua aksesorinya.
Kali ini, mari kita mulai dengan kode untuk Sui Move. Kita akan memanfaatkan aspek lain dari fungsionalitas kepemilikan objek yang dibangun dalam runtime Sui: satu objek dapat dimiliki oleh objek lain. Setiap objek memiliki pemilik unik, namun objek induk dapat memiliki sejumlah objek anak. Hubungan objek induk/anak dibuat dengan menggunakan fungsi transfer_to_object, yang merupakan objek terkait dari fungsi transfer yang diperkenalkan di atas.
Dalam kode ini, modul peran menyertakan fungsi accessorize yang memungkinkan pemilik peran menambahkan objek aksesori jenis apa pun sebagai objek anak. Hal ini memungkinkan Bob dan Clarissa untuk membuat jenis ornamen mereka sendiri dengan properti dan fungsi berbeda yang tidak dimiliki Alice, tetapi didasarkan pada apa yang telah dilakukan Alice. Misalnya, kemeja Bob hanya dapat digunakan jika itu adalah warna favorit karakter, dan pedang Clarissa hanya dapat digunakan jika karakter tersebut cukup kuat. Berikut ini adalah demonstrasi praktis dari Gerakan Gaya Diem, namun tidak ada satupun yang berhasil, artinya Gerakan Gaya Diem tidak dapat mencapai skenario di atas.
Terlihat permasalahan pada Move ala Diem adalah sebagai berikut
Hanya koleksi dengan tipe yang sama yang didukung (seperti yang ditunjukkan pada pengujian pertama), tetapi aksesori pada dasarnya bukanlah suatu tipe objek. Hubungan antar objek hanya dapat dicapai melalui "pembungkusan" (yaitu menyimpan satu objek di dalam objek lain tetapi). kumpulan objek yang dapat dibungkus harus ditentukan sebelumnya (seperti pada percobaan kedua), atau ditambahkan sementara, dan komposisi objek tambahan tidak didukung (seperti pada pengujian ketiga).
Meringkaskan
Sui adalah platform pertama yang menyimpang secara signifikan dari desain Diem asli dalam cara penggunaan Move. Merancang kombinasi yang memanfaatkan sepenuhnya Move dan kemampuan unik platformnya adalah sebuah seni sekaligus sains, yang memerlukan pemahaman mendalam tentang bahasa Move dan kemampuan blockchain yang mendasarinya. Kami sangat gembira dengan kemajuan yang dicapai Sui Move dan kasus penggunaan baru yang dimungkinkannya! ". [1] Argumen lain yang mendukung kebijakan Pemindahan gaya Diem adalah "Anda harus ikut serta sebelum Anda dapat menerima jenis aset tertentu." Ini adalah mekanisme yang baik untuk mencegah spam. Namun, kami memikirkan pencegahan spam sebagai bagian dari lapisan aplikasi, dibandingkan mengharuskan pengguna mengirim transaksi yang membutuhkan uang nyata untuk ikut serta dalam menerima aset, spam dapat dengan mudah ditangani di (misalnya) tingkat dompet dengan kebijakan kaya yang ditentukan pengguna dan filter spam otomatis. .


