Panduan Utama untuk Keselamatan Kontrak Pintar EOS

Panduan Utama untuk Keselamatan Kontrak Pintar EOS. Komuniti crypto menjadi ragu-ragu apabila ICO terbesar di dunia, EOS dilancarkan pada bulan Jun 2018 dan ia dibekukan selama 2 hari kerana pepijat perisian. Tetapi maju cepat 4 bulan dan EOS hari ini menyumbang lebih daripada menggandakan urus niaga yang dilakukan oleh Ethereum hari ini. Melalui janji transaksi percuma dan lebih pantas, Dapp EOS paling atas mempunyai kira-kira 13,000 pengguna aktif setiap hari berbanding hanya 2,000 dari Dapp teratas Ethereum.

Keselamatan Kontrak Pintar EOS

Oleh Rohan Agarwal

Beberapa kelemahan kontrak pintar umum berlaku untuk hampir semua platform. Seperti Ethereum, kontrak pintar yang ditulis di EOS perlu diaudit sebelum disiarkan secara langsung di mainnet. Kesalahan fatal dalam kontrak dapat dieksploitasi apabila kontrak tidak cukup diuji. Dalam panduan ini, kami akan membantu anda mengelakkan masalah biasa dalam membuat dApp pembunuh seterusnya di EOS.

Sebelum anda membaca panduan ini, penting untuk mengetahui beberapa maklumat prasyarat mengenai pembangunan EOS yang akan berguna semasa anda membaca panduan ini. Pengetahuan mengenai C ++ adalah suatu keharusan. Tempat terbaik untuk memulakan dengan pembangunan kontrak pintar adalah milik EOSIO dokumentasi

Berurusan dengan ABI Dispatcher

luaran "C" {

berlaku tidak sah (penerima uint64_t, kod uint64_t, tindakan uint64_t) {

class_name inikontrak (penerima);

jika ((kod == N (eosio.token)) && (tindakan == N (pemindahan))) {

laksanakan_tindak (&kontrak ini, &class_name :: transfer);

kembali;

}

jika (kod! = penerima) kembali;

tukar (tindakan) {EOSIO_API (class_name, (action_1) (action_n))};

eosio_exit (0);

}

}

Gambar di atas adalah contoh kod penghantar ABI yang diubah suai. Penghantar ABI yang lebih sederhana seperti yang ditunjukkan di bawah digunakan untuk pengendalian kontrak yang lebih mudah.

EOSIO_ABI (class_name, (action_1) (action_n));

Penghantar / pengirim ABI membenarkan kontrak untuk mendengar peristiwa pemindahan eosio.token yang masuk, serta interaksi biasa dengan kontrak pintar. Penting untuk mengikat setiap tindakan dan kod utama untuk memenuhi syarat, untuk mengelakkan panggilan tidak normal dan tidak sah.

Contohnya ialah peretasan yang berlaku pada dApp Kasino EOSBet disebabkan oleh bug dalam kod sumber pemajuan ABI mereka.

jika (kod == diri || kod == N (eosio.token)) {

JENIS kontrak ini (diri);

beralih (tindakan) {

EOSIO_API (JENIS, AHLI)

}

}

Pemeriksaan di atas pada pengendali tindakan gunaan kod sumber pemajuan ABI membolehkan penyerang memintas fungsi eosio.token :: transfer () sepenuhnya, dan secara langsung memanggil fungsi :: transfer () fungsi tanpa memindahkan EOS ke kontrak sebelum meletakkan pertaruhan. Untuk kerugian, dia tidak dibayar apa-apa, tetapi tidak kehilangan apa-apa. Namun, untuk kemenangan dia dibayar EOS sebenar dari kontrak.

Mereka memperbaiki bug di atas dengan menambahkan cek tindakan pemindahan kontrak eosio.token sebelum tindakan masuk meminta kontrak.

jika (kod == diri || kod == N (eosio.token)) {

jika (tindakan == N (pindahan)) {

eosio_assert (kod == N (eosio.token), "Mesti memindahkan EOS");

}

JENIS kontrak ini (diri);

beralih (tindakan) {

EOSIO_API (JENIS, AHLI)

}

}

Penting untuk menggunakan penyataan memerlukan_auth (akaun); menjadi tindakan yang anda mahukan hanya dilakukan oleh akaun yang dibenarkan. memerlukan_auth (_self); digunakan untuk memberi kuasa hanya kepada pemilik kontrak untuk menandatangani transaksi

Kebenaran dalam Tindakan

batal token :: transfer (nama_nama dari, nama_nama ke, kuantiti aset)

{

automatik sym = kuantiti.symbol.name ();

memerlukan_recipient (dari);

memerlukan_recipient (hingga);

pembayar automatik = has_auth (ke)? kepada: dari;

sub-keseimbangan (dari, kuantiti);

add_balance (kepada, kuantiti, pembayar);

}

Contoh kod di atas membolehkan sesiapa sahaja memanggil tindakan tersebut. Untuk menyelesaikannya, gunakan memerlukan_auth (dari); penyataan untuk memberi kebenaran kepada pembayar untuk memanggil tindakan tersebut.

Cuba elakkan mengubah kontrak eosio.token

Seorang penggodam topi putih baru-baru ini berjaya menuntut 1 bilion token dapp kerana panggilan kaedah yang tidak diuji dalam kontrak eosio.token mereka. The Dapp Se7ens (sekarang tidak aktif) menyatakan kaedah baru di dalam kontrak eosio.token untuk memasukkan token mereka ke dalam akaun pengguna. Kontrak tersebut tidak menyebut masalah atau tindakan pemindahan kontrak eosio.token untuk mencerminkan perubahan dan dengan itu dana secara ajaib muncul di akaun pengguna. Kedua, mereka lupa untuk mengesahkan jumlah dalam kaedah sebelum pemindahan yang membolehkan penggodam menuntut 1 bilion token mereka dalam proses.

Selain mengubah bekalan maksimum dan simbol token, disarankan untuk tidak mengubahnya untuk fungsi khusus kerana bug dalam kontrak eosio.token boleh membawa maut. Untuk memfasilitasi titisan udara dengan selamat, pindahkan token udara ke akaun yang berasingan dan sebarkan dari sana.

Pengubahsuaian sifat jadual pelbagai indeks

EOS kini menyimpan data ke pangkalan data memori bersama untuk berkongsi tindakan.

struct [[eosio :: table]] orang {

kunci akaun_nama;

std :: string first_name;

std :: string last_name;

std :: tali jalan;

std :: string city;

std :: keadaan rentetan;

uint64_t primer_key () const {kunci pengembalian; }

};

typedef eosio :: multi_index<N (orang), orang> alamat_indeks;

Contoh kod di atas membuat jadual multi_index bernama orang yang berdasarkan struktur data satu baris jadual itu menggunakan orang struktur. EOS pada masa ini tidak membenarkan pengubahsuaian sifat jadual setelah ia digunakan. Kegagalan penegasan eosio_assert_message akan menjadi kesalahan yang akan dilemparkan. Oleh itu sifat perlu difikirkan sepenuhnya sebelum penyebaran jadual. Jika tidak, jadual baru dengan nama yang berlainan perlu dibuat dan perlu dilakukan dengan berhati-hati ketika berpindah dari meja lama ke meja yang baru. Kegagalan untuk melakukannya boleh mengakibatkan kehilangan data.

Pemeriksaan Limpahan Berangka

Semasa melakukan operasi aritmetik, nilai mungkin meluap jika keadaan sempadan tidak diperiksa dengan cukup bertanggungjawab, menyebabkan kehilangan aset pengguna.

pemindahan batal (simbol simbol_nama, nama_nama akaun dari, nama_nama ke

memerlukan_auth (dari);

akaun dari akaun;

eosio_assert (is_balance_within_range (baki), "baki tidak sah");

eosio_assert (baki > 0, "mesti memindahkan keseimbangan positif"); jumlah uint64_t = baki * 4; // Limpahan pendaraban

}

Dalam kod contoh di atas, menggunakan uint64_t untuk menunjukkan keseimbangan pengguna boleh menyebabkan limpahan apabila nilainya bertambah. Oleh itu elakkan daripada menggunakan uint64_t untuk menunjukkan baki dan melakukan operasi aritmetik padanya sejauh mungkin. Gunakan struktur aset yang ditentukan dalam eosiolib untuk operasi dan bukannya baki tepat yang mengurus keadaan limpahan.

Menjaga Andaian dalam Kontrak

Akan ada andaian yang memerlukan penegasan semasa pelaksanaan kontrak. Menggunakan eosio_assert akan menjaga keadaan terlebih dahulu dan menghentikan pelaksanaan tindakan tertentu sekiranya penegasan tersebut gagal. Sebagai contoh –

batal assert_roll_under (const uint8_t& roll_under) {

eosio_assert (roll_under >= 2 && roll_under <= 96,

"gulung di bawah limpahan, mestilah lebih besar dari 2 dan kurang daripada 96");

}

Pernyataan penegasan di atas membuat andaian bahawa bilangan bulat roll_under lebih besar daripada 2 & kurang dari 96. Tetapi jika tidak, buang mesej di atas dan hentikan pelaksanaannya. Kegagalan untuk menemui kes-kes sudut seperti di atas boleh menjadi bencana bagi rumah yang menetapkan peraturan.

Menjana nombor Rawak Benar

Menjana nombor Rawak Sebenar di EOS Blockchain masih berisiko jika tidak dilakukan dengan tepat. Jika tidak melakukannya dengan betul akan menyebabkan musuh meramalkan hasilnya, mempermainkan keseluruhan sistem dalam prosesnya. Perkhidmatan seperti Oracalize.it wujud untuk memberikan nombor rawak dari sumber luaran tetapi ia mahal dan satu titik kegagalan. Orang telah menggunakan pemboleh ubah kontekstual Blockchain (nombor blok, cap blok dll) pada masa lalu untuk menghasilkan nombor rawak dalam kontrak pintar Ethereum, tetapi telah bermain-main sebelum ini. Untuk melakukan penjanaan dengan betul, program ini harus menyediakan jenis gabungan yang tidak dapat dikendalikan oleh satu pihak sahaja. Salah satu kaedah terbaik saat ini adalah kaedah yang dicadangkan oleh Dan Larimar sendiri ketika menghasilkan nombor rawak antara dua pihak.

Blog BountyOne: Keselamatan Kontrak Pintar EOS

rentetan sha256_to_hex (const checksum256& sha256) {

kembali ke_hex ((char *) sha256.hash, sizeof (sha256.hash));

}

rentetan sha1_to_hex (const checksum160& sha1) {

kembali ke_hex ((char *) sha1.hash, sizeof (sha1.hash));

}

templat <kelas T>

Inline void hash_combine (std :: size_t& biji, const T& v) {

std :: hash<T> pencuci;

seed ^ = hasher (v) + 0x9e3779b9 + (biji << 6) + (biji >> 2);

}

Contoh kod di atas memberikan penjanaan nombor rawak yang dioptimumkan antara 1 hingga 100. seed1 adalah bibit rumah dan seed2 adalah benih pengguna di atas. Untuk rujukan, Dappub dan Kasino EOSBet telah membuka kontrak lengkap mereka dengan pelaksanaan penjana nombor rawak permainan dadu yang adil antara pemain dan rumah (pemaju).

uint8_t compute_random_roll (const checksum256& seed1, const checksum160& biji2) {

size_t hash = 0;

hash_combine (hash, sha256_to_hex (seed1));

hash_combine (hash, sha1_to_hex (seed2));

pulangan hash% 100 + 1;

}

EOSBet baru-baru ini mendapat digodam lagi daripada 65,000 EOS ketika musuh menipu kontrak eosio.token mereka untuk menghantar EOS ke dompetnya setiap kali dia bertransaksi di antara dompetnya sendiri. Kod kontrak eosio.token memberitahu pengirim dan penerima token EOS bahawa terdapat token masuk. Untuk meniru tingkah laku & memudahkan peretasan, musuh membuat dua akaun, mari kita anggap A & B. A mempunyai kontrak pintar dengan tindakan yang mempunyai pernyataan memerlukan_recipient (N (eosbetdice11)). Ketika A memfasilitasi transaksi dari A ke B melalui panggilan tindakan, ia memberitahu fungsi pemindahan dalam kontrak seolah-olah panggilan itu datang dari kontrak eosio.token. Oleh kerana tidak ada pemindahan EOS yang sebenarnya ke dalam kontrak, setiap kali penggodam kehilangan taruhan, dia tidak kehilangan apa-apa, tetapi dia mendapat ganjaran ketika memenangkan taruhan. Oleh itu, hanya memeriksa nama kontrak dan nama tindakan tidak mencukupi.

Menyemak pemberitahuan dari Kontrak

Untuk mengatasi masalah tersebut, fungsi tersebut harus memeriksa sama ada kontrak itu memang penerima token atau tidak.

eosio_assert (transfer_data.from == _self || transfer_data.to == _self, "Mestilah pemindahan masuk atau keluar");

Apakah amalan terbaik yang harus diikuti semasa membuat kontrak pintar di EOS?

Bug tidak dapat dielakkan dari mana-mana perisian. Akibatnya akan diperkuat dalam persekitaran yang terdesentralisasi terutama jika melibatkan transaksi nilai. Selain daripada perlindungan khusus EOS yang dibincangkan di atas, berikut adalah beberapa langkah berjaga-jaga umum dan amalan terbaik yang harus diingat oleh pemaju kontrak pintar baru –

  1. Sentiasa audit kontrak secara bebas daripada firma audit kontrak pintar pihak ketiga sebelum dikeluarkan di mainnet.
  2. Lakukan debug Caveman yang diperlukan (satu-satunya cara untuk menyahpepijat kontrak pada masa ini) kontrak sebelum melepaskan ke testnet. Dokumentasi EOSIO mempunyai panduan hebat untuk ia.
  3. Tetapkan had had transfer pada pengeluaran untuk mengelakkan kerugian yang berlebihan pada hari-hari awal pelancaran mainnet. Mempunyai program bug bounty untuk pendedahan yang bertanggungjawab oleh penggodam topi putih.
  4. Adakan killswitch untuk membekukan kontrak apabila bug dikesan.

Untuk melaksanakannya, kami tetap menggunakan bendera di jadual multi_index. Kami menetapkan bendera menggunakan tindakan yang hanya dapat dipanggil oleh pemilik kontrak. Dan kemudian kami memeriksa setiap tindakan umum sama ada bendera akan dibekukan atau tidak. Contoh pelaksanaan fungsi diberikan di bawah.

struktur st_frozen {

uint64_t dibekukan;

};

singleton typedef<N (beku), st_frozen> tb_frozen;

tb_frozen _frozen;

uint64_t getFreezeFlag () {

st_frozen frozen_st {.frozen = 0};

kembali _frozen.get_or_create (_self, frozen_st);

}

batal setFreezeFlag (const uint64_t& pFrozen) {

st_frozen frozen_st = getFreezeFlag ();

beku_st.frozen = pFrozen;

_frozen.set (beku_st, _self);

}

// Tindakan awam

pembekuan terbatal () {

memerlukan_auth (_self);

setFreezeFlag (1);

}

// Tindakan awam

tidak sah beku () {

memerlukan_auth (_self);

setFreezeFlag (0);

}

// sebarang tindakan awam

tindakan batal (…) {

eosio_assert (getFreezeFlag (). beku == 1, "Kontrak dibekukan!");

}

  1. Terus dapatkan maklumat mengenai peningkatan keselamatan di perpustakaan atau pendedahan kerentanan di platform. Kemas kini perpustakaan anda apabila perlu segera.
  2. Buka sumber kod kontrak sekurang-kurangnya agar keadilan dipertahankan dalam permainan dan pemaju indie dapat membantu mengesan bug dengan lebih cepat.

Keselamatan Kontrak Pintar EOS: Kesimpulan

Baru 5 bulan sejak EOS dilancarkan namun ia telah melampaui jangkaan. Pertukaran yang telah dibuatnya – DPOS, kontrak pintar boleh ubah, 21 nod perlombongan dan lain-lain sudah tentu menghadapi kritikan hebat dari golongan desentralisasi. Walaupun begitu, ia tidak menghentikan dApps berdasarkan Ethereum untuk beralih ke EOS memandangkan skalabiliti yang ditawarkan oleh platform mereka hari ini. Sama ada EOS atau Ethereum yang memenangkan perang masih belum diputuskan, tetapi EOS sudah pasti memenangi pertempuran. Dan akan tetap sama hingga Ethereum berjaya mencapai skalabilitas yang diperlukan dunia untuk menjalankan “The World Computer”.

_________________________________________________________________________________________

Artikel ini ditulis oleh Rohan Agarwal

Bio – #Android Dev # Usahawan # Blockchain Dev & Pengasas bersama Penyelidik @ Cypherock.com – Dompet perkakasan selamat untuk Telefon Pintar.

Linkedin – https://www.linkedin.com/in/rohanagarwal94/

Github – https://github.com/rohanagarwal94

Twitter – https://twitter.com/rohanagarwal94

Mike Owergreen Administrator
Sorry! The Author has not filled his profile.
follow me
Like this post? Please share to your friends:
map