Cara menentukan alamat kontrak pintar sebelum penerapan: menggunakan CREATE2 untuk pertukaran kripto

Topik blockchain tidak berhenti menjadi sumber tidak hanya segala macam hype, tetapi juga ide-ide yang sangat berharga dari sudut pandang teknologi. Oleh karena itu, dia tidak mengabaikan penduduk kota yang cerah itu. Orang-orang melihat lebih dekat, mempelajari, mencoba mengalihkan keahlian mereka dalam basis informasi tradisional ke sistem blockchain. Sejauh ini, salah satu perkembangan Rostelecom-Solar adalah mampu memeriksa keamanan perangkat lunak berbasis blockchain. Dan seiring berjalannya waktu, beberapa pemikiran muncul untuk memecahkan masalah terapan komunitas blockchain. Salah satu peretasan kehidupan ini - cara menentukan alamat kontrak pintar sebelum penerapan menggunakan CREATE2 - hari ini saya ingin berbagi dengan Anda.

Cara menentukan alamat kontrak pintar sebelum penerapan: menggunakan CREATE2 untuk pertukaran kripto
Opcode CREATE2 ditambahkan di hard fork Konstantinopel pada 28 Februari tahun ini. Sebagaimana dinyatakan dalam EIP, opcode ini diperkenalkan terutama untuk saluran negara. Namun, kami menggunakannya untuk memecahkan masalah yang berbeda.

Ada pengguna dengan saldo di bursa. Kami harus memberi setiap pengguna alamat Ethereum, yang mana siapa pun dapat mengirim token, sehingga dapat mengisi ulang akun mereka. Sebut saja alamat ini "dompet". Ketika token tiba di dompet, kita harus mengirimkannya ke satu dompet (hotwallet).

Di bagian berikut, saya menganalisis opsi untuk menyelesaikan masalah ini tanpa CREATE2 dan menjelaskan mengapa kami mengabaikannya. Jika Anda hanya tertarik pada hasil akhirnya, Anda dapat menemukannya di bagian Solusi Akhir.

Alamat Ethereum

Solusi paling sederhana adalah membuat alamat ethereum baru untuk pengguna baru. Alamat-alamat ini akan menjadi dompetnya. Untuk mentransfer token dari dompet ke hotwallet, Anda perlu menandatangani transaksi dengan memanggil fungsinya transfer() dengan kunci pribadi dompet dari backend.

Pendekatan ini memiliki keuntungan sebagai berikut:

  • itu mudah
  • biaya transfer token dari dompet ke hotwallet sama dengan biaya pemanggilan fungsi tersebut transfer()

Namun, kami mengabaikan pendekatan ini karena memiliki satu kelemahan signifikan: Anda perlu menyimpan kunci pribadi di suatu tempat. Dan bukan hanya kunci tersebut yang bisa hilang, tetapi Anda juga perlu mengelola akses ke kunci ini dengan hati-hati. Jika setidaknya salah satu dari mereka disusupi, maka token pengguna tertentu tidak akan mencapai dompet panas.

Cara menentukan alamat kontrak pintar sebelum penerapan: menggunakan CREATE2 untuk pertukaran kripto

Buat kontrak pintar terpisah untuk setiap pengguna

Menyebarkan kontrak pintar terpisah untuk setiap pengguna memungkinkan Anda untuk tidak menyimpan kunci pribadi dari dompet di server. Pertukaran akan memanggil kontrak pintar ini untuk mentransfer token ke hotwallet.

Kami juga mengabaikan solusi ini, karena pengguna tidak dapat diperlihatkan alamat dompetnya tanpa menerapkan kontrak pintar (ini sebenarnya mungkin, tetapi dengan cara yang agak rumit dengan kelemahan lain yang tidak akan kami bahas di sini). Di bursa, pengguna dapat membuat akun sebanyak yang dia butuhkan, dan setiap orang membutuhkan dompetnya sendiri. Artinya, kita perlu mengeluarkan uang untuk menerapkan kontrak tanpa yakin bahwa pengguna akan menggunakan akun ini.

Opcode BUAT2

Untuk memperbaiki masalah metode sebelumnya, kami memutuskan untuk menggunakan opcode CREATE2. CREATE2 memungkinkan Anda menentukan terlebih dahulu alamat tempat kontrak pintar akan diterapkan. Alamat dihitung menggunakan rumus berikut:

keccak256 (0xff ++ address ++ salt ++ keccak256 (init_code)) [12:]


, di mana:

  • alamat β€” alamat kontrak pintar yang akan memanggil CREATE2
  • garam - nilai acak
  • init_code - bytecode kontrak pintar untuk penerapan

Ini memastikan bahwa alamat yang kami berikan kepada pengguna benar-benar berisi bytecode yang diinginkan. Selain itu, kontrak pintar ini dapat diterapkan kapan pun kita membutuhkannya. Misalnya, ketika pengguna memutuskan untuk menggunakan dompetnya untuk pertama kali.
Cara menentukan alamat kontrak pintar sebelum penerapan: menggunakan CREATE2 untuk pertukaran kripto
Selain itu, Anda dapat menghitung alamat kontrak pintar setiap saat alih-alih menyimpannya, karena:

  • alamat dalam rumusnya konstan karena merupakan alamat pabrik dompet kami
  • garam - hash_pengguna
  • init_code bersifat permanen karena kami menggunakan dompet yang sama

Lebih banyak perbaikan

Solusi sebelumnya masih memiliki satu kelemahan: Anda harus membayar untuk penerapan kontrak pintar. Namun, Anda bisa menghilangkannya. Untuk ini, Anda dapat memanggil fungsinya transfer(), seorang pria Penghancuran diri() di konstruktor dompet. Dan kemudian bahan bakar untuk penerapan kontrak pintar akan dikembalikan.

Bertentangan dengan kepercayaan umum, Anda dapat menerapkan kontrak pintar ke alamat yang sama beberapa kali dengan opcode CREATE2. Hal ini karena CREATE2 memeriksa bahwa nonce dari alamat target adalah nol (diberi nilai "1" di awal konstruktor). Pada saat yang sama, fungsinya Penghancuran diri() me-reset alamat nonce setiap kali. Jadi, jika Anda memanggil CREATE2 lagi dengan argumen yang sama, pemeriksaan nonce akan lolos.

Harap dicatat bahwa solusi ini mirip dengan solusi alamat ethereum, tetapi tanpa perlu menyimpan kunci pribadi. Biaya mentransfer uang dari dompet ke hotwallet kira-kira sama dengan biaya memanggil suatu fungsi transfer(), karena kami tidak membayar untuk penerapan kontrak pintar.

Keputusan akhir

Cara menentukan alamat kontrak pintar sebelum penerapan: menggunakan CREATE2 untuk pertukaran kripto

Awalnya disiapkan:

  • berfungsi untuk mendapatkan garam user_id
  • kontrak pintar yang akan memanggil opcode CREATE2 dengan garam yang sesuai (yaitu pabrik dompet)
  • bytecode dompet yang sesuai dengan kontrak dengan konstruktor berikut:

constructor () {
    address hotWallet = 0x…;
    address token = 0x…;
    token.transfer (hotWallet, token.balanceOf (address (this)));
    selfdestruct (address (0));
}


Untuk setiap pengguna baru, kami menunjukkan alamat dompetnya dengan menghitung

keccak256 (0xff ++ address ++ salt ++ keccak256 (init_code)) [12:]


Saat pengguna mentransfer token ke alamat dompet yang sesuai, backend kami melihat acara Transfer dengan parameternya _untuksama dengan alamat dompet. Pada titik ini, sudah dimungkinkan untuk meningkatkan saldo pengguna di bursa sebelum menggunakan dompet.

Ketika cukup banyak token yang terkumpul di alamat dompet, kami dapat mentransfer semuanya sekaligus ke hotwallet. Untuk melakukan hal ini, backend memanggil fungsi pabrik kontrak pintar, yang melakukan tindakan berikut:

function deployWallet (соль uint256) {
    bytes memory walletBytecode =…;
    // invoke CREATE2 with wallet bytecode and salt
}


Dengan demikian, konstruktor kontrak pintar dompet disebut, yang mentransfer semua tokennya ke alamat hotwallet dan kemudian menghancurkan dirinya sendiri.

Kode lengkap dapat ditemukan di sini. Harap dicatat bahwa ini bukan kode produksi kami, karena kami memutuskan untuk mengoptimalkan bytecode dompet dan menuliskannya dalam opcode.

Penulis Pavel Kondratenkov, spesialis Ethereum

Sumber: www.habr.com

Tambah komentar