Mengapa pertukaran atom itu buruk dan bagaimana saluran akan membantu mereka, apa yang penting terjadi di garpu keras Konstantinopel dan apa yang harus dilakukan ketika tidak ada yang membayar untuk gas.
Motivasi utama setiap profesional keamanan adalah keinginan untuk menghindari tanggung jawab.
Providence ramah, saya meninggalkan ICO, tidak menunggu transaksi ireversibel pertama, tetapi segera menemukan diri saya di belakang pengembangan pertukaran mata uang kripto.
Saya jelas bukan Malchish Kibalchish, dan satu pandangan ketat sudah cukup bagi saya untuk melewati semua kunci dan kata sandi. Oleh karena itu, tujuan utama saya sebagai seorang arsitek adalah untuk menempatkan sengatan merah kriptanalisis sejauh mungkin dari elemen infrastruktur yang saya sayangi.
Bukan kunci Anda, bukan masalah Anda
Kami sedang membangun sistem pertukaran aset dan ingin mengecualikan penyimpanan perantara dari aset-aset ini di rumah, tetapi kami harus memastikan keamanan transaksi.
Anda dapat bertindak sebagai hakim dalam situasi kontroversial dan melakukan transaksi dengan dompet yang memerlukan dua dari tiga tanda tangan: pembeli, penjual, dan escrow.
Namun, jika peserta berhasil menyerang escrow, maka ia menerima dua tanda tangan yang diperlukan.
Atomic swap adalah skema pertukaran di mana kontrak pintar bertindak sebagai penjamin, yang hanya memungkinkan perilaku jujur.
Seolah-olah dalam sebuah teka-teki tentang seekor kambing serigala dan kubis, Anda dapat bertindak hanya berdasarkan satu-satunya skenario yang benar dan menanggung kerugian jika Anda mundur darinya.
Hanya alih-alih hewan yang rakus, perintah ini menyediakan fungsi hash di mana sangat sulit untuk menemukan tabrakan sehingga tidak layak untuk memulai.
Langkah Satu: Teka-Teki
Misalkan Alice ingin memberikan Bitcoin kepada Bob untuk beberapa "crypto yuan" suatu pagi yang cerah.
- Dia membuat rahasia besar
- Menerima hash darinya
- Ini mentransfer bitcoin ke kontrak pintar, dari mana Bob dapat mengambil uang dengan menghadirkan sebuah rahasia (hash dari itu harus sama dengan yang ditentukan dalam kontrak)
- Jika Bob tidak berada di bitcoin di malam hari, Alice dapat mengambilnya kembali untuk dirinya sendiri.
Langkah Dua: Umpan
Bob memasuki permainan dan mentransfer "cryptoeuro" ke kontraknya, yang ditulis sedemikian rupa sehingga:
- Alice dapat mengambil "crypto-coin" dengan menghadirkan nomor rahasia
- Tidak lebih awal dari makan siang, Bob, jika Alice tidak muncul, dapat mengembalikan deposit
Langkah Tiga: Solusi dalam Umpan
Alice datang untuk mengambil uangnya dan mengambil uang dari kontrak Bob, sembari mengungkapkan rahasianya.
Langkah terakhir: teka-teki terpecahkan
Bob melihat transaksi itu, dan dengan tatapan tajamnya ia mengisolasi rahasia yang dihadirkan Alice pada kontrak. Dia menggunakan rahasia ini untuk mengumpulkan bitcoin-nya.
Ketika terjadi kesalahan
Jika Alice tiba-tiba berubah menjadi fana, Bob mengambil yuan untuk makan siang.
Pada gilirannya, Alice pada malam hari mengembalikan bitcoin jika Bob yang pengkhianat memutuskan untuk menahan uang itu sampai waktu yang lebih baik.
Jika Anda lebih suka gambar daripada teks, di Habré ada penjelasan yang lebih rinci dan jelas
tentang pekerjaan pertukaran atom untuk Anda .
Perbedaan antara batas waktu dirancang untuk melindungi kita dari Alice yang jahat, yang mengambil uang Bob pada saat-saat terakhir, dan batas waktu berakhir ketika dia mengarahkan hex ke dalam transaksi dengan jari-jari yang gemetar.
Peserta tidak dapat kehilangan uang mereka, maksimum harus menunggu pengembalian.
Dukungan BlockchainIni adalah skema sederhana seperti sepatu bot felt, yang tidak membutuhkan apa pun dari blockchain yang berinteraksi:
- Dukungan untuk kontrak pintar dengan setidaknya satu cabang
- Kedua blockchain harus mendukung algoritma hashing yang sama (jangan lupa untuk memeriksa panjang rahasianya)
- Timelocks.
Pada pandangan pertama, orang sudah bisa mengatakan kepada pertukaran "selamat tinggal, pertemuan kami adalah kesalahan", tetapi tidak ada di sana.
Untuk semua manfaatnya, solusi pertukaran atom tidak menyerang dengan likuiditas. Sebagian besar karena dalam pasangan BTC-USD paling populer, bagian fiat tidak sepenuhnya tokenized.
Keberhasilan USDT telah menghasilkan gelombang koin stabil dalam format ERC20 untuk setiap selera, dari USDC penahanan hingga DAI paling algoritmik.
Oleh karena itu, untuk kesederhanaan, kami lebih lanjut berpendapat bahwa Alice menjual Bobcoins ke Bob untuk beberapa token ERC20, dan kami berharap untuk keberhasilan stabilisator, karena kami memiliki lebih banyak masalah teknis.
Kecepatan
Bitcoin dan Ethereum saja tidak terlalu cepat, tetapi di sini kita harus menunggu dulu untuk satu setoran dengan semua konfirmasi, lalu yang kedua.
Ini semua karena peserta yang mengetahui rahasia pertama-tama menghasilkan uang, dan lawan menunggu untuk final dan baru kemudian mentransfer bagiannya.
Selain itu, kami berhadapan dengan aset yang sangat fluktuatif, sehingga selama ini kursus dapat berubah secara signifikan, dan mengubah kondisinya tidak mudah.
Kerahasiaan
Setiap pertukaran meninggalkan artefak di kedua blockchain. Seorang pengamat yang penuh perhatian dapat melihat hash yang sama dalam kontrak pintar dan membuat kesimpulan logis bahwa kesepakatan telah dibuat di sini, yang darinya banyak kesimpulan dapat dibuat dari nilai tukar hingga pajak.
Ketika pertukaran tahu tentang urusan Anda - ini sangat tidak menyenangkan, ketika semua orang tahu tentang hal itu - itu sangat tidak menyenangkan.
Kegunaan
Kuda blockchain pada umumnya dan eter pada khususnya. Mari kita lihat gerakan tubuh apa yang harus dilakukan penjual dan pembeli.
Dari sudut pandang penjual, semuanya relatif sederhana: Anda hanya perlu mentransfer Bitcoin ke alamat p2sh. Dengan eter semuanya jauh lebih rumit.
KontrakPertimbangkan kontrak swap rata-rata gigab:
contract iERC20 { function totalSupply() public view returns (uint256); function transfer(address receiver, uint numTokens) public returns (bool); function balanceOf(address tokenOwner) public view returns (uint); function approve(address delegate, uint numTokens) public returns (bool); function allowance(address owner, address delegate) public view returns (uint); function transferFrom(address owner, address buyer, uint numTokens) public returns (bool); } contract Swapper { struct Swap { iERC20 token; bytes32 hash; uint amount; uint refundTime; bytes32 secret; } mapping (address => mapping(address => Swap)) swaps; function create(iERC20 token, bytes32 hash, address receiver, uint amount, uint refundTime) public { require(swaps[msg.sender][receiver].amount == 0); // check is swap with given hash already exists require(token.transferFrom(msg.sender, address(this), amount)); // transfer locked tokens to swap contract swaps[msg.sender][receiver] = Swap(token, hash, amount, refundTime, 0x00); //create swap } function hashOf(bytes32 secret) public pure returns(bytes32) { return sha256(abi.encodePacked(secret)); } function withdraw(address owner, bytes32 secret) public { Swap memory swap = swaps[owner][msg.sender]; require(swap.secret == bytes32(0)); require(swap.hash == sha256(abi.encodePacked(secret))); // swap exists swaps[owner][msg.sender].secret = secret; swap.token.transfer(msg.sender, swap.amount); } function refund(address receiver) public { Swap memory swap = swaps[msg.sender][receiver]; require(now > swap.refundTime); delete swaps[msg.sender][receiver]; swap.token.transfer(msg.sender, swap.amount); } }
Perhatian! Jangan gunakan ini dan kontrak lain dari artikel tentang produksi, mereka ditulis hanya untuk demonstrasi.
Terutama yang ini .
- Bob harus memanggil metode yang
approve
pada kontrak token, memberikan akses kontrak swap ke tokennya
- Bob membuat swap dan kontrak menggunakan metode
transferFrom
mengambil token pengirim ke alamatnya
- Alice yang
withdraw
mengungkapkan sebuah rahasia dan kontrak itu meminta transfer
Sebagian besar dompet dan
approve
tidak mendukung token yang
approve
, dan untuk alasan yang baik.
Pengguna sendiri sering keliru dan hanya mentransfer token ke kontrak, setelah itu token hilang begitu saja. Komentar di Etherscan penuh dengan ratapan menyedihkan.
Dan untuk memanggil kontrak, Anda harus membayar komisi dalam ETH, sehingga kedua peserta harus menyimpannya sebelum dimulainya transaksi, dan sedikit orang yang ingin melakukan ini.
Pemegang gas
Untuk memulainya, ada baiknya menghapus cek pengirim sedapat mungkin dan dengan asumsi bahwa kita memiliki seseorang yang menderita kelebihan gas dan menyebabkan kontrak untuk semua orang.
Kontrak yang ditingkatkan contract Swapper { struct Swap { iERC20 token; address receiver; uint amount; address refundAddress; uint refundTime; } mapping (bytes32 => Swap) swaps; function create(iERC20 token, bytes32 hash, address receiver, uint amount, address refundAddress, uint refundTime) public { require(swaps[hash].amount == 0); // use hash once require(token.transferFrom(msg.sender, address(this), amount)); swaps[hash] = Swap(token, receiver, amount, refundAddress, refundTime); } function withdraw(bytes memory secret) public { bytes32 hash = sha256(secret); Swap memory swap = swaps[hash]; require(swap.amount > 0); delete swaps[hash]; swap.token.transfer(swap.receiver, swap.amount); } function refund(bytes32 hash) public { Swap memory swap = swaps[hash]; require(now > swap.refundTime); delete swaps[hash]; swap.token.transfer(swap.refundAddress, swap.amount); } }
Dualisme Kontrak-Kunci dan EIP 712
Seperti yang kita ketahui, alamat yang disiarkan dapat berupa kontrak, atau dapat menjadi subjek, dengan kata lain, kunci.
Pekerjaan utama kunci adalah menandatangani pesan apa pun.
Kita dapat menggunakan kontrak Bob sebagai pengirim, yang membuat semua lintasan yang diperlukan, sebelum memeriksa tanda tangan kunci Bob.
Sekarang, siapa pun dapat mensponsori komisi anggota, tetapi hanya orang yang tahu kunci yang membuat keputusan.
Kontrak Bob library EIP712ProxyLibrary { function hashCommand(address sender, iERC20 token, Swapper swapper, bytes32 hash, address receiver, uint amount, address refundAddress, uint refundTime) public view returns(bytes32); } contract ProxyBob { address owner; constructor(address _owner) public { owner = _owner; } function createSwap(Swapper swapper, iERC20 token, bytes32 hash, address receiver, uint amount, address refundAddress, uint refundTime, uint8 v, bytes32 r, bytes32 s) public { require(owner == ecrecover(EIP712ProxyLibrary.hashCommand(address(this), token, swapper, hash, receiver, amount, refundAddress, refundTime), v, r, s)); token.approve(address(swapper), amount); swapper.create(token, hash, receiver, amount, refundAddress, refundTime); } }
Ethereum memiliki standar
EIP 712 untuk bekerja dengan tanda tangan dari struktur data yang kompleks. Anda dapat membacanya lebih lanjut di
blog dompet Metamask.Bagilah dan taklukkan
Seringkali skenario peretasan kontrak Ethereum terlihat seperti ini:
- Peserta membayar dana untuk kontrak
- Lalu ambil uangnya
- Ada yang salah
- Seorang penyerang mengambil uang lagi dan lagi
Jika kita kembali ke contoh pertama kita, ada yang salah jika teka-teki itu adalah byte kosong.
Cara mencuri satu jutaBuat swap dengan hash 0x66687aadf862bd776c8fc18b8e9f8e20089714856ee233b3902a591d0d5f2925
Ini adalah sha256 dari 0x0000000000000000000000000000000000000000000000000000000000000000
Kami melewati rahasia dan mengumpulkan token kami
Kami lulus lagi dan mengambil orang asing, semua karena 0 = 0
Dengan membuat kontrak terpisah untuk setiap transaksi, kami dapat mengisolasi kontrak di level EVM.
Tapi ini belum semuanya: sekarang setiap transaksi memiliki alamatnya sendiri, di mana Anda dapat mentransfer token dari dompet atau pertukaran apa pun.
Kontrak dan penciptaan yang ditinggalkan2
Tapi sekarang untuk setiap transaksi kita harus membuat kontrak dan menunggu pembeli untuk mentransfer tenaga kerja "cryptofening" di sana. Dalam skema "kontrak pagi, uang malam" selalu ada bahaya bahwa pembeli akan jatuh, dan eter telah dihabiskan untuk membuat kontrak.
Apakah mungkin menghasilkan uang di pagi hari dan byte di malam hari?
Dalam fork Konstantinopel, pengembang
EIP 1014 menambahkan pernyataan create2 yang menciptakan kontrak baru pada alamat deterministik
keccak256( 0xff ++ address ++ salt ++ keccak256(init_code))[12:]
Dimana
- alamat - alamat kontrak pabrik
- salt - sejumlah angka, artinya kita akan pelajari di seri selanjutnya
- init_code - kontrak bytecode dan parameter konstruktor.
PabrikInstruksi hanya bekerja melalui perakitan, sehingga pabrik terlihat agak menakutkan:
contract Factory { event Deployed(address addr, uint256 salt); function create2(bytes memory code, uint256 salt) public { address addr; assembly { addr := create2(0, add(code, 0x20), mload(code), salt) } emit Deployed(addr, salt); } }
Kode kontrak Anda dapat diperoleh menggunakan web3:
const MyContract = new web3.eth.Contract(ABI, {}) const ode = MyContract.deploy({ data: BYTECODE, arguments: contructorArgs }).encodeABI(); const factory = new web3.eth.Contract(FACTORY_ABI, factoryAddress); tx = factory.methods.create2(ode, salt);
Karena dukungan yang terbatas dalam soliditas, gas untuk kontrak mungkin tidak dapat dihitung dengan benar karena beberapa seluk eter.
Sangat menyenangkan bahwa jika terjadi kekurangan gas, kontrak jatuh dengan kesalahan internal, tanpa memberi tahu bahwa tidak ada cukup gas, seperti yang diharapkan.
Sekarang kita dapat mentransfer token ke kontrak tanpa membuatnya terlebih dahulu, dan sampai kita mempublikasikannya di jaringan, tidak ada yang akan menebak apa sebenarnya yang dilakukan kontrak.
Gagak tidak akan mematuk gagak
Jelas bahwa trik anak-anak seperti itu tidak akan menghentikan seorang analis sungguhan, terutama yang telah menerima investasi bagus dalam memerangi
musuh -
musuh rezim pencucian uang, dan setelah membuat kontrak ia masih akan melihat hash.
Bagaimana memastikan hash tidak menyala?
Kami mentransfer swap itu sendiri ke rantai: peserta bertukar tanda tangan untuk transfer ke kontrak swap, dan kemudian rahasianya diungkapkan secara pribadi.
Langkah demi langkahDua "multisig" dibuat, dari mana Anda dapat menarik dana jika Anda memiliki tanda tangan Alice dan Bob.
Agar offline, salah satu peserta tidak menjadi tragedi, kami menambahkan batas waktu lama yang baik.
Alice dan Bob melakukan deposit secara paralel
- Alice membuat rahasia dan memberi Bob hash rahasia dan tanda tangan transaksi, yang mentransfer bitcoin ke alamat swap
- Bob memberi Alice tanda tangan pada penarikan token pada kontrak swap dengan hash tersembunyi.
- Alice memberi tahu Bob rahasia.
Pada saat ini, harmoni terjadi: Alice dan Bob dapat menyelesaikan kesepakatan kapan saja. Dalam lingkungan yang bersahabat seperti itu, mereka dapat bertukar tanda tangan dari menarik uang ke alamat akhir mereka.
Bagi pengamat luar, sepertinya uang itu melewati kontrak dengan tanda tangan 2 dari 2.
Dan juga skema semacam itu memungkinkan kedua belah pihak untuk melakukan deposit pada saat yang sama, karena rahasia sudah dibuat setelah semua konfirmasi.
Level 2
Karena kita dapat menarik uang ke satu alamat dan tidak mempublikasikan transaksi perantara, tidak ada yang menghalangi kita untuk menarik uang ke beberapa alamat dan membuat transaksi perantara dalam jumlah tak terbatas. Bukan berarti itu diperlukan untuk pertukaran, tetapi jika Anda mulai mengumpulkan swap, sulit untuk berhenti.
Sekarang Alice dan Bob akan dapat berbalik dengan kekuatan dan main. Misalnya, secara otomatis menghitung harga rata-rata dengan menukarkan Satoshi per detik, atau cukup langsung menghubungkan pembuat pasar dan penerima likuiditas.
Langkah demi langkah- Penjual membuat rahasia dan memberi pembeli hash rahasia dan tanda tangan transaksi di mana sebagian dana ditransfer ke alamat swap p2sh, dan sisanya dikembalikan ke alamat penjual
- Pembeli mentransmisikan tanda tangan yang memungkinkan untuk menarik token pada swap dan pengiriman ke alamat penerima.
- Penjual mengungkapkan rahasia
- Kisah ini diulangi dengan rahasia baru, sementara pada swap dan menyerah ditambahkan output yang sebelumnya dibeli ke alamat pembeli dan sudah dibayarkan ke alamat penjual
Sekarang kami memiliki akses ke perdagangan P2P kecepatan tinggi, yang utama adalah memantau waktu dan menutup kesepakatan sebelum waktu habis.
Namun, setelah sedikit menyesuaikan kontrak kami, kami dapat memberikan keabadian saluran kami, yang akan sangat menyederhanakan pembuatan jaringan bagi kami.
Tapi kita akan membicarakan ini di seri berikutnya.