
Kontrak terverifikasi, proksi, dan kunci peningkatan yang tak disebut siapa pun
Di penjelajah blok ada centang hijau bertuliskan Kode Sumber Kontrak Terverifikasi, dan sangat banyak orang membacanya sebagai «kontrak ini aman».
Bukan itu maknanya. Maknanya jauh lebih sempit dan jauh lebih berguna, dan mengacaukan keduanya adalah cara orang-orang yang berhati-hati akhirnya menyetujui hal-hal yang tak akan pernah mereka setujui.
Apa yang sebenarnya disertifikasi oleh «terverifikasi»
Kontrak digelar sebagai bytecode — instruksi mesin, yang dalam praktiknya tak terbaca. Verifikasi adalah tindakan mengunggah kode sumber aslinya dan membuat penjelajah memastikan bahwa mengompilasinya, dengan versi dan setelan kompiler yang dinyatakan, menghasilkan persis bytecode yang sudah bermukim di alamat itu.
Itulah seluruh klaimnya: kode sumber yang Anda baca sungguh-sungguh kode sumber yang berjalan.
Itu jaminan yang nyata dan berharga. Tanpanya, Anda takkan punya cara mengetahui apakah kode berpenampilan rapi di GitHub sebuah proyek punya hubungan apa pun dengan benda yang sebentar lagi disentuh transaksi Anda.
Tetapi perhatikan segala yang tidak dikatakannya. Verifikasi bukan audit. Tak seorang pun menilai apakah kodenya benar, apakah ia mengandung kutu, atau apakah ia melakukan sesuatu yang mirip dengan yang disiratkan nama-nama fungsinya. Sebuah kontrak dengan fungsi bernama claimRewards yang mentransfer seluruh saldo Anda kepada penggelarnya bisa saja terverifikasi, dan verifikasinya akan sepenuhnya jujur — ia menyatakan dengan benar bahwa pencurian itu persis apa yang kodenya katakan ia lakukan.
Terverifikasi berarti terbaca, bukan tepercaya. Ia memindahkan pertanyaan dari «benda ini apa?» ke «apakah saya paham yang baru saja saya baca?», dan itu kemajuan, tetapi ia tidak menjawab pertanyaan kedua untuk Anda.
Kebalikannya juga penting. Kontrak yang tak terverifikasi bukan bukti niat jahat — banyak penggelaran sah tak pernah sempat diverifikasi. Tetapi itu berarti tak seorang pun — tak ada perkakas yang Anda pakai, tak ada peneliti yang mungkin memperingatkan Anda — dapat membaca apa yang sebentar lagi Anda ajak berinteraksi. Bersikap waspada terhadap itu masuk akal.
Lalu proksi memperburuknya
Di sinilah pijakan bergeser, dan inilah bagian yang paling sering tak disinggung.
Sebagian besar kontrak tak sepele yang akan Anda hadapi bukanlah kontrak tunggal. Mereka adalah proksi. Proksi adalah alamat yang Anda lihat, dan ia memegang semua data — saldo, izin, keadaan. Namun ia nyaris tak memuat logika. Sebaliknya ia meneruskan setiap panggilan ke kontrak implementasi terpisah, dan sekadar menjalankan apa pun kata kontrak itu.
Alasannya adalah kemampuan ditingkatkan. Kontrak yang tak berubah tidak bisa ditambal, jadi sebuah kutu bersifat permanen dan fitur yang hilang hilang selamanya. Mengarahkan proksi ke implementasi baru memungkinkan tim memperbaiki kutu dan mengirimkan perbaikan tanpa meminta setiap pengguna bermigrasi. Mengingat betapa banyak nilai lenyap karena kutu yang tak dapat diperbaiki, ini pilihan rekayasa yang dapat dibela.
Ada akibat yang mudah terlewat. Ketika Anda menelusuri sebuah proksi di penjelajah dan melihatnya terverifikasi, Anda telah memverifikasi logika penerusannya, bukan perilakunya. Kode yang benar-benar memutuskan apa yang terjadi pada uang Anda bermukim di alamat implementasi, yang bisa saja ditampilkan menonjol oleh penjelajah atau tidak, dan yang dapat diganti.
Jadi pertanyaan sebenarnya tak pernah «apakah kontrak ini terverifikasi?». Melainkan:
Siapa yang dapat mengubah perilaku kontrak ini, dan secepat apa?
Kunci admin adalah model keamanan yang sesungguhnya
Setiap kontrak yang dapat ditingkatkan punya seseorang yang bisa melakukan peningkatan. Kewenangan itulah model keamanannya, sebaik apa pun kode yang ada sekarang.
Rentangnya membentang dari mengkhawatirkan sampai masuk akal:
Sebuah akun tunggal milik pihak luar. Satu kunci privat, di mesin seseorang, dapat menukar logika kontrak yang menyimpan dana Anda. Bila kena phishing, dicuri, atau pemiliknya dipaksa, kontrak itu menjadi apa pun yang diinginkan penyerang. Susunan ini lebih umum daripada seharusnya.
Sebuah multisig. Beberapa penanda tangan harus sepakat. Jauh lebih baik — ia menghapus titik kegagalan tunggal — walau patut diketahui berapa banyak penanda tangannya, dan apakah mereka sungguh orang-orang yang mandiri atau empat laptop milik tim yang sama.
Sebuah multisig di balik kunci waktu. Peningkatan diumumkan di rantai dan baru dapat dijalankan setelah penundaan tetap, kerap 24 sampai 72 jam. Inilah yang berarti, karena ia mengubah posisi Anda sepenuhnya: Anda mendapat peringatan dini atas perubahan, dan sebuah jendela untuk menarik dana sebelum perubahan itu berlaku. Kunci waktu tidak menghentikan peningkatan yang jahat. Ia membuatnya dapat dilewati dengan selamat.
Tak ada jalur peningkatan sama sekali. Kontraknya tak berubah. Keterdugaan maksimum, nol jalan keluar bila ditemukan kutu. Pilihan yang sah, biasanya diambil protokol yang sudah teruji cukup lama untuk mempertaruhkannya.
Tak satu pun otomatis benar. Tetapi selisih antara «satu kunci» dan «multisig plus penundaan dua hari» adalah selisih antara berharap tak seorang pun berbuat salah dan punya waktu bereaksi ketika ada yang berbuat salah.
Mengapa ini menggigit tepat pada persetujuan
Inilah bagian yang tersambung ke sesuatu yang benar-benar Anda lakukan secara rutin.
Ketika Anda memberikan persetujuan token, Anda mengizinkan sebuah alamat memindahkan token Anda. Bukan sepotong kode — sebuah alamat. Persetujuan itu bersemayam di penyimpanan kontrak token dan bertahan tanpa batas waktu.
Bila alamat itu sebuah proksi yang dapat ditingkatkan, maka logika yang berhak memindahkan token Anda dapat diganti setelah Anda menyetujuinya, tanpa keterlibatan Anda dan tanpa tanda tangan baru apa pun dari Anda. Anda memeriksa satu hal dan tetap terpapar hal yang berbeda.
Itulah sebabnya nasihat baku untuk mencabut persetujuan yang tak lagi Anda pakai berbobot lebih besar daripada kesan pertamanya. Ini bukan semata soal sebuah kontrak yang ternyata berkutu. Ini soal bahwa izin tanpa batas kepada kontrak yang dapat ditingkatkan adalah izin yang diberikan kepada siapa pun yang menguasai kunci peningkatan, selama Anda membiarkannya terbuka.
Ia juga batas paling tajam bagi simulasi transaksi. Menyimulasikan sebelum menandatangani memberi tahu Anda apa yang dilakukan sebuah transaksi terhadap keadaan saat ini dan implementasi saat ini. Itu sungguh berguna, dan ia tak dapat memberi tahu Anda apa yang akan diizinkan persetujuan yang sama itu bulan depan.
Apa yang SSP tunjukkan, dan di mana ia berhenti
Ketika SSP Key menyajikan sebuah persetujuan, ia menguraikan data panggilan alih-alih menampilkan heksadesimal mentah. Ia mengenali penyeleksi ERC-20 baku — approve, transfer, transferFrom, increaseAllowance, setApprovalForAll — dan menuturkannya dalam bahasa biasa, termasuk menandai izin tanpa batas, yang di dalam kode didefinisikan sebagai jumlah berapa pun yang sama dengan atau di atas 2^255.
Pengurai itu sengaja dibuat berhati-hati. Kepala berkasnya sendiri menggambarkannya sebagai lapisan penyajian belaka: ia tak pernah mengubah apa yang ditandatangani, dan ia gagal dengan menutup. Penyeleksi yang tak dikenal, panjang yang keliru, heksadesimal yang cacat, atau pengisi alamat yang tak baku, semuanya membuatnya tak mengembalikan apa pun dan mundur ke tindakan umum dengan heksadesimal mentah di balik tampilan «Lanjutan». Ia lebih suka mengaku tidak tahu daripada menebak dengan percaya diri lalu keliru. Simbol dan desimal token hanya dilekatkan bila diketahui dari daftar di dalam perangkat, tak pernah dikira-kira.
Kini batas yang jujur. Pengurai itu tak punya gagasan tentang proksi. Tak ada satu pun konsep kontrak implementasi di dalamnya. Ia dapat memberi tahu Anda, dengan benar dan jelas, «Anda memberikan izin USDC tanpa batas kepada 0xABC…» — dan ia tak dapat memberi tahu Anda bahwa 0xABC adalah proksi, siapa memegang kunci peningkatannya, atau bahwa perilakunya bisa sepenuhnya berbeda pekan depan.
Itu bukan sekadar kelalaian, melainkan sebuah batas yang tak bisa diseberangi pengurai dompet mana pun. Menguraikan berarti menggambarkan panggilan yang ada di depan Anda. Apakah pihak lawan dapat ditingkatkan, dan siapa yang mengaturnya, adalah sifat dunia yang lebih luas yang harus diperiksa terpisah. Kami lebih suka menyatakan batasnya daripada membiarkan layar persetujuan yang tampak meyakinkan menyiratkan kelengkapan yang tak dimilikinya.
Pemeriksaan praktis sebelum Anda menyetujui sesuatu yang berarti
Apakah terverifikasi? Bila tidak, pahami bahwa Anda sedang memercayai reputasi semata.
Apakah ia sebuah proksi? Penjelajah menandai ini — cari pemberitahuan proksi, atau pilihan «Read as Proxy». Bila ada, implementasinyalah kode yang penting.
Siapa yang bisa meningkatkannya, dan adakah penundaan? Ini pertanyaan paling bernilai di daftar dan yang nyaris tak seorang pun tanyakan. Proyek yang sudah memikirkannya akan mendokumentasikannya. Yang belum, atau tak mau berkata, sudah mengatakan sesuatu kepada Anda.
Apakah persetujuannya perlu tanpa batas? Biasanya tidak. Menyetujui jumlah yang benar-benar hendak Anda belanjakan membatasi paparan Anda persis pada jumlah itu, apa pun kelak yang menjadi kontrak tersebut.
Cabut bila sudah selesai. Izin yang terbuka adalah kewenangan yang terus berlaku, dan ia hidup lebih lama daripada perhatian Anda.
Penyesuaian pikiran yang layak dilakukan itu kecil tetapi mengubah banyak hal. Verifikasi memberi tahu Anda kode apa yang sedang berjalan saat ini. Kemampuan ditingkatkan memberi tahu Anda siapa yang memutuskan apa yang berjalan besok. Hampir seluruh risiko bermukim di pertanyaan kedua, dan hampir seluruh ketenteraman yang ditawarkan hanya menjawab yang pertama.


