Peringatan
Artikel ini bukan peringkat keefektifan analisis otomatis. Saya menerapkannya pada kontrak saya sendiri, dengan sengaja mensintesis kesalahan, dan mempelajari reaksinya. Studi semacam itu tidak dapat menjadi dasar untuk menentukan "lebih baik-lebih buruk", karena ini masuk akal untuk melakukan studi buta pada sampel besar kontrak, yang, mengingat sifat berubah-ubah dari perangkat lunak jenis ini, sangat sulit. Sangat mungkin bahwa kesalahan kecil dalam kontrak dapat menonaktifkan sebagian besar logika penganalisa, dan tanda heuristik sederhana dapat menambahkan sejumlah besar poin ke penganalisis dengan menemukan bug yang tersebar luas yang tidak bisa ditambahkan oleh pesaing. Kesalahan dalam persiapan dan penyusunan kontrak juga dapat berperan. Semua perangkat lunak yang dimaksud cukup muda, dan terus dikembangkan, jadi jangan menganggap komentar kritis sebagai masalah yang tidak dapat diperbaiki.
Tujuan artikel ini adalah untuk memberikan pembaca pemahaman tentang bagaimana metode analisis kode bekerja di berbagai analisis dan kemampuan untuk menggunakannya dengan benar, daripada "membuat pilihan." Pilihan yang masuk akal adalah menggunakan beberapa alat sekaligus, dengan fokus pada yang paling cocok untuk kontrak yang dianalisis.
Pengaturan dan persiapan untuk peluncuran
Mythril menggunakan beberapa jenis analisis sekaligus, berikut adalah beberapa artikel bagus tentangnya: yang paling penting , ini atau ini . Sebelum melanjutkan, masuk akal untuk membacanya.
Pertama, mari kita buat gambar Docker kita sendiri tentang Mythril (tidak masalah apa yang ingin kita ubah di dalamnya?):
git clone https://github.com/ConsenSys/mythril-classic.git cd mythril-classic docker build -t myth .
Sekarang coba jalankan di contracts/flattened.sol
kami contracts/flattened.sol
(saya menggunakan kontrak yang sama yang telah dibahas dalam pendahuluan ), di mana ada dua kontrak utama, Ownable
dari Zeppelin dan Booking
kami. Kami masih memiliki masalah dengan versi kompiler, saya memperbaikinya dengan cara yang sama seperti pada artikel sebelumnya, menambahkan baris ke Dockerfile yang akan menggantikan versi kompiler:
COPY --from=ethereum/solc:0.4.20 /usr/bin/solc /usr/bin
Setelah membangun kembali gambar, Anda dapat mencoba menjalankan analisis kontrak. Segera mari kita gunakan -v4
dan -v4
--verbose-report
untuk melihat semua peringatan. Ayo pergi:
docker run -v $(pwd):/tmp \ -w /tmp myth:latest \ -v4 \ --verbose-report \ -x contracts/flattened.sol
Di sini kami bekerja dengan kontrak yang rata tanpa ketergantungan. Untuk menganalisis kontrak Booking.sol
terpisah dan untuk membuat Mythril mengambil semua dependensi, Anda dapat menggunakan sesuatu seperti ini:
docker run -v $(pwd):/tmp \ -w /tmp myth:latest \ --solc-args="--allow-paths /tmp/node_modules/zeppelin-solidity/ zeppelin-solidity=/tmp/node_modules/zeppelin-solidity" \ -v4 \ --verbose-report \ -x contracts/Booking.sol
Saya lebih suka bekerja dengan opsi yang diratakan, seperti kami akan banyak memodifikasi kode. Tapi Mythril juga memiliki mode yang sangat nyaman --truffle
, yang hanya --truffle
segala sesuatu yang truffle
, memeriksa seluruh proyek untuk kerentanan. Fitur penting lainnya adalah kemampuan untuk menentukan nama kontrak yang akan dianalisis melalui titik dua, jika tidak Mythril akan menganalisis semua kontrak yang dihadapinya. Kami percaya bahwa Ownable
's Ownable adalah kontrak yang aman, dan kami hanya akan menganalisis Booking
, jadi baris terakhir yang harus dijalankan adalah:
docker run -v $(pwd):/tmp -w /tmp myth:latest -x contracts/flattened.sol:Booking -v4 --verbose-report
Mulai dan Sebarkan Kontrak
Kami memulai penganalisa dengan baris di atas, lihat output, dan kami mendapatkan, antara lain, baris ini:
mythril.laser.ethereum.svm [WARNING]: No contract was created during the execution of contract creation Increase the resources for creation execution (--max-depth or --create-timeout) The analysis was completed successfully. No issues were detected.
Ternyata kontrak kami tidak dibuat dan "diperbaiki" di emulator. Itulah sebabnya saya merekomendasikan menggunakan flag -v4
untuk semua jenis analisis untuk melihat semua pesan dan tidak ketinggalan satu pun yang penting. Mari kita cari tahu apa yang salah. Solusi untuk masalah praktis ini cukup penting untuk memahami cara menggunakan Mythril dengan benar.
Jadi, kita membaca tentang Mythril: It uses concolic analysis, taint analysis and control flow checking to detect a variety of security vulnerabilities
. Jika Anda tidak terlalu mengenal istilah-istilah ini, saya merekomendasikan wiki tentang pengujian concolic di sini , tetapi di sini ada presentasi yang bagus tentang pengecekan noda untuk x86. Singkatnya: Mythril mengemulasi pelaksanaan kontrak, memperbaiki cabang-cabang di mana eksekusi bisa berjalan dan mencoba untuk mencapai kondisi "rusak" kontrak, memilah-milah berbagai kombinasi parameter dan mencoba untuk mengatasi semua jalur yang mungkin. Berikut ini contoh diagram tindakan dari artikel di atas:
1. . symbolic-, . 2. , , trace . , , . 3. . 4. trace-. 5. symbolic execution trace, symbolic , , , . 6. , . , . 7. : , , input-, , . input- , .6 . 8. .4
Jika Anda sangat menyederhanakannya, maka Mythril, setelah menemukan cabang dalam kode, dapat memahami di bawah set variabel mana dimungkinkan untuk masuk ke satu dan cabang lainnya. Di setiap cabang, Mythril tahu apakah itu mengarah ke assert
, transfer
, selfdestruct
dan opcode yang relevan dengan keamanan lainnya. Oleh karena itu, Mythril menganalisis set parameter dan transaksi mana yang dapat menyebabkan pelanggaran keamanan. Dan cara Mythril memotong cabang yang tidak pernah mendapatkan kontrol dan menganalisis aliran kontrol adalah trik utamanya. Rincian lebih lanjut tentang usus Mythril dan jalan cabang ditulis di sini .
Karena determinisme pelaksanaan kontrak pintar, urutan instruksi yang sama selalu mengarah ketat ke satu set perubahan dalam keadaan, terlepas dari platform, arsitektur, atau lingkungan. Juga, fungsi dalam kontrak pintar agak pendek, dan sumber dayanya sangat terbatas, oleh karena itu analis seperti Mythril, menggabungkan eksekusi simbolis dan asli, dapat bekerja sangat efisien untuk kontrak pintar.
Dalam prosesnya, Mythril menggunakan konsep "negara" - ini adalah kode kontrak, lingkungannya, penunjuk ke perintah saat ini, penyimpanan kontrak, dan status tumpukan. Berikut dokumentasinya:
The machine state Ξ is defined as the tuple (g, pc, m, i, s) which are the gas available, the program counter pc â P256, the memory contents, the active number of words in memory (counting continuously from position 0), and the stack contents. The memory contents Ξm are a series of zeroes of size 256.
Grafik transisi antar negara adalah objek utama penelitian. Jika berhasil meluncurkan analisis, informasi tentang grafik ini ditampilkan dalam log analisis. Juga, Mythril dapat membuat grafik ini dalam bentuk yang dapat dibaca manusia menggunakan opsi --graph
.
Sekarang kurang lebih memahami apa yang akan dilakukan Mythril, kami akan terus memahami mengapa kontrak tidak diuraikan dan dari mana [WARNING]: No contract was created during the execution of contract creation
. Untuk memulai, saya memutar opsi --create-timeout
dan --max-depth
(seperti yang disarankan) dan, tidak mendapatkan hasilnya, saya pikir konstruktor yang harus disalahkan - sesuatu di dalamnya tidak berfungsi. Ini kodenya:
function Booking( string _description, string _fileUrl, bytes32 _fileHash, uint256 _price, uint256 _cancellationFee, uint256 _rentDateStart, uint256 _rentDateEnd, uint256 _noCancelPeriod, uint256 _acceptObjectPeriod ) public payable { require(_price > 0); require(_price > _cancellationFee); require(_rentDateStart > getCurrentTime()); require(_rentDateEnd > _rentDateStart); require(_rentDateStart+_acceptObjectPeriod < _rentDateEnd); require(_rentDateStart > _noCancelPeriod); m_description = _description; m_fileUrl = _fileUrl; m_fileHash = _fileHash; m_price = _price; m_cancellationFee = _cancellationFee; m_rentDateStart = _rentDateStart; m_rentDateEnd = _rentDateEnd; m_noCancelPeriod = _noCancelPeriod; m_acceptObjectPeriod = _acceptObjectPeriod; }
Ingat algoritma tindakan Mythril. Untuk menjalankan penelusuran, Anda perlu memanggil konstruktor kontrak, karena semua eksekusi selanjutnya akan bergantung pada parameter apa yang dipanggil dengan konstruktor. Sebagai contoh, jika Anda memanggil konstruktor dengan _price == 0
, konstruktor akan mengeluarkan pengecualian saat require(_price > 0)
. Bahkan jika Mythril mengulangi banyak nilai _price
, konstruktor akan tetap rusak jika, misalnya, _price <= _cancellationFee
. Dalam kontrak ini, ada selusin parameter yang terkait dengan pembatasan ketat, dan Mythril, tentu saja, tidak dapat menebak kombinasi parameter yang valid. Dia mencoba untuk pergi ke cabang eksekusi berikutnya, memilah-milah parameter konstruktor, tetapi dia praktis tidak punya kesempatan untuk menebak - ada terlalu banyak kombinasi parameter. Oleh karena itu, perhitungan kontrak tidak berhasil - semua cara bertumpu pada beberapa jenis persyaratan require(...)
, dan kami mendapatkan masalah di atas.
Sekarang kita memiliki dua cara: yang pertama adalah untuk menonaktifkan semua yang require
dalam konstruktor dengan berkomentar. Kemudian Mythril akan dapat memanggil konstruktor dengan set parameter dan semuanya akan berfungsi. Tetapi ini berarti bahwa dengan memeriksa kontrak dengan parameter seperti itu, Mythril akan menemukan kesalahan yang mungkin terjadi dengan nilai yang salah diteruskan ke konstruktor. Sederhananya, jika Mythril menemukan bug yang muncul jika pembuat kontrak menentukan _cancellationFee
satu miliar kali harga sewa _mprice
, maka tidak ada gunanya bug semacam itu - kontrak seperti itu tidak akan pernah diblokir, dan sumber daya untuk menemukan kesalahan akan dihabiskan. Kami menyiratkan bahwa kontrak masih terjebak dengan parameter yang kurang lebih konsisten, sehingga untuk analisis lebih lanjut masuk akal untuk menentukan parameter konstruktor yang lebih realistis sehingga Mythril tidak mencari kesalahan yang tidak akan pernah terjadi jika kontrak ditutup dengan benar.
Saya menghabiskan waktu berjam-jam untuk mencoba memahami dengan tepat di mana penempatan rusak, termasuk dan menonaktifkan berbagai bagian konstruktor. Selain masalah saya, konstruktor menggunakan getCurrentTime()
, yang mengembalikan waktu saat ini, dan tidak jelas bagaimana panggilan ini menangani Mythril. Saya tidak akan menggambarkan petualangan ini di sini, karena kemungkinan besar dengan penggunaan reguler, kehalusan ini akan diketahui oleh auditor. Oleh karena itu, saya memilih cara kedua: untuk membatasi input data, dan cukup menghapus semua parameter dari konstruktor, bahkan getCurrentTime()
, cukup hardcoded parameter yang diperlukan langsung di konstruktor (idealnya, parameter ini harus diperoleh dari pelanggan):
function Booking( ) public payable { m_description = "My very long booking text about hotel and beautiful sea view!"; m_fileUrl = "https://ether-airbnb.bam/some-url/"; m_fileHash = 0x1628f3170cc16d40aad2e8fa1ab084f542fcb12e75ce1add62891dd75ba1ffd7; m_price = 1000000000000000000; // 1 ETH m_cancellationFee = 100000000000000000; // 0.1 ETH m_rentDateStart = 1550664800 + 3600 * 24; // current time + 1 day m_rentDateEnd = 1550664800 + 3600 * 24 * 4; // current time + 4 days m_acceptObjectPeriod = 3600 * 8; // 8 hours m_noCancelPeriod = 3600 * 24; // 1 day require(m_price > 0); require(m_price > m_cancellationFee); require(m_rentDateStart > 1550664800); require(m_rentDateEnd > m_rentDateStart); require((m_rentDateStart + m_acceptObjectPeriod) < m_rentDateEnd); require(m_rentDateStart > m_noCancelPeriod); }
Plus, untuk memulai semuanya, Anda juga harus mengatur parameter max-depth
. Ini bekerja untuk saya dengan konstruktor ini dengan --max-depth=34
pada instance AWS t2.medium. Pada saat yang sama, di laptop saya, yang lebih kuat, semuanya dimulai tanpa max-depth
. Menilai dengan menggunakan parameter ini, perlu untuk membangun cabang untuk analisis, dan nilai standarnya adalah tak terhingga ( kode ). Oleh karena itu, putar-putar parameter ini, tetapi pastikan bahwa kontrak yang diinginkan dianalisis. Anda dapat memahami ini dengan pesan seperti:
mythril.laser.ethereum.svm [INFO]: 248 nodes, 247 edges, 2510 total states mythril.laser.ethereum.svm [INFO]: Achieved 59.86% coverage for code: .............
Baris pertama hanya menggambarkan grafik yang akan dianalisis, bacalah sisa baris itu sendiri. Sumber daya komputasi yang serius diperlukan untuk menganalisis berbagai cabang yang dapat dieksekusi, jadi ketika menganalisis kontrak besar, Anda harus menunggu bahkan di komputer yang cepat.
Cari kesalahan
Sekarang kita akan mencari kesalahan dan menambahkan kesalahan kita sendiri. Mythril mencari cabang di mana penyiaran, penghancuran diri sendiri, penegasan, dan tindakan lain yang penting dari sudut pandang keamanan terjadi. Jika salah satu dari instruksi di atas ditemukan di suatu tempat dalam kode kontrak, Mythril mempelajari cara-cara yang memungkinkan untuk datang ke cabang ini dan, terlebih lagi, menampilkan urutan transaksi yang mengarah ke cabang ini!
Pertama, mari kita lihat apa yang dikeluarkan Mythril untuk kontrak Booking
lama menderita. Peringatan pertama:
==== Dependence on predictable environment variable ==== SWC ID: 116 Severity: Low Contract: Booking Function name: fallback PC address: 566 Estimated Gas Usage: 17908 - 61696 Sending of Ether depends on a predictable variable. The contract sends Ether depending on the values of the following variables: - block.timestamp Note that the values of variables like coinbase, gaslimit, block number and timestamp are predictable and/or can be manipulated by a malicious miner. Don't use them for random number generation or to make critical decisions. -------------------- In file: contracts/flattened.sol:142 msg.sender.transfer(msg.value-m_price)
dan itu muncul karena
require(m_rentDateStart > getCurrentTime());
dalam fungsi mundur.
Perhatikan bahwa Mythril menyadari bahwa getCurrentTime()
bersembunyi di getCurrentTime()
. Terlepas dari kenyataan bahwa makna kontrak bukanlah kesalahan, fakta bahwa Mythril mengaitkan block.timestamp
dengan siaran sangat bagus! Dalam hal ini, programmer harus memahami bahwa keputusan dibuat berdasarkan nilai yang dapat dikendalikan oleh penambang. Dan, jika di masa depan suatu pelelangan atau pelelangan lain untuk suatu layanan muncul di tempat kontrak ini, seseorang harus memperhitungkan kemungkinan serangan-serangan yang sedang berlangsung.
Mari kita lihat apakah Mythril melihat ketergantungan pada block.timestamp
jika kita menyembunyikan variabel dalam panggilan bersarang seperti ini:
function getCurrentTime() public view returns (uint256) { - return now; + return getCurrentTimeInner(); } + function getCurrentTimeInner() internal returns (uint256) { + return now; + }
Dan ya! Mythril terus melihat hubungan antara block.timestamp dan transfer siaran, ini sangat penting bagi auditor. Koneksi antara variabel yang dikendalikan oleh penyerang dan keputusan yang dibuat setelah beberapa perubahan dalam status kontrak bisa sangat tertutup oleh logika, dan Mythril memungkinkan Anda untuk melacaknya. Meskipun tidak layak mengandalkan kenyataan bahwa semua koneksi yang mungkin di antara semua variabel yang mungkin akan getCurrentTime()
untuk Anda: jika Anda terus mengolok-olok fungsi getCurrentTime()
dan membuat kedalaman bersarang tiga kali lipat, peringatan itu menghilang. Setiap panggilan fungsi untuk Mythril membutuhkan penciptaan cabang negara baru, jadi menganalisis tingkat sarang yang sangat dalam akan membutuhkan sumber daya yang besar.
Tentu saja, ada peluang yang agak serius bahwa saya hanya salah menggunakan parameter analisis atau cutoff terjadi di suatu tempat di kedalaman alat analisis. Seperti yang saya katakan, produk sedang dalam pengembangan aktif, tepat pada saat penulisan, saya melihat komitmen dalam repositori dengan menyebutkan max-depth
, jadi jangan menganggap serius masalah saat ini, kami telah menemukan cukup bukti bahwa Mythril dapat dengan sangat efektif mencari koneksi implisit antara variabel.
Pertama, tambahkan ke kontrak fungsi yang memberikan siaran kepada siapa pun, tetapi hanya setelah klien mengirim siaran ke kontrak. Kami mengizinkan siapa pun untuk mengambil 1/5 eter, tetapi hanya ketika kontraknya dalam status State.PAID
(yaitu hanya setelah klien membayar nomor sewaan dengan eter). Inilah fungsinya:
function collectTaxes() external onlyState(State.PAID) { msg.sender.transfer(address(this).balance / 5); }
Mythril menemukan masalahnya:
==== Unprotected Ether Withdrawal ==== SWC ID: 105 Severity: High Contract: Booking Function name: collectTaxes() PC address: 2492 Estimated Gas Usage: 2135 - 2746 Anyone can withdraw ETH from the contract account. Arbitrary senders other than the contract creator can withdraw ETH from the contract account without previously having sent a equivalent amount of ETH to it. This is likely to be a vulnerability. -------------------- In file: contracts/flattened.sol:149 msg.sender.transfer(address(this).balance / 5) -------------------- -------------------- Transaction Sequence: { "2": { "calldata": "0x", "call_value": "0xde0b6b3a7640000", "caller": "0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef" }, "3": { "calldata": "0x01b613a5", "call_value": "0x0", "caller": "0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef" } }
Hebat, yaitu Mythril bahkan mengeluarkan dua transaksi, yang mengarah pada fakta bahwa Anda dapat mengambil eter dari kontrak. Sekarang ubah persyaratan State.RENT
ke State.RENT
, seperti ini:
- function collectTaxes() external onlyState(State.PAID){ + function collectTaxes() external onlyState(State.RENT) {
Sekarang collectTaxes()
dapat dipanggil hanya ketika kontrak ada di Negara. State.RENT
negara, dan pada saat ini tidak ada pada keseimbangan, karena kontrak telah mengirimkan seluruh siaran kepada pemilik. Dan yang penting di sini adalah bahwa Mythril kali ini TIDAK menghasilkan kesalahan ==== Unprotected Ether Withdrawal ====
! Di bawah kondisi onlyState(State.RENT)
, penganalisis tidak sampai ke cabang kode yang mengirim eter dari kontrak dengan saldo tidak nol. Mythril pergi melalui opsi yang berbeda untuk parameter, tetapi Anda dapat masuk ke State.RENT
hanya dengan mengirim semua siaran ke lessor. Oleh karena itu, mustahil untuk mencapai cabang kode ini dengan saldo tidak nol, dan Mythril sama sekali tidak mengganggu auditor!
Dengan cara yang sama, Mythril akan menemukan selfdestruct
dan assert
, menunjukkan kepada auditor tindakan apa yang dapat menyebabkan penghancuran kontrak atau rusaknya fungsi yang penting. Saya tidak akan memberikan contoh-contoh ini, hanya mencoba membuat fungsi yang mirip dengan yang di atas, hanya memanggil selfdestruct
, dan memutar logikanya.
Juga, jangan lupa bahwa salah satu bagian dari Mythril adalah eksekusi simbolis, dan pendekatan ini, dengan sendirinya, tanpa meniru eksekusi, dapat menentukan banyak kerentanan. Misalnya, setiap penggunaan "+", "-" dan operator aritmatika lainnya dapat dianggap sebagai kerentanan "Integer overflow" jika salah satu operan dikendalikan oleh penyerang. Tapi saya ulangi lagi, fitur Mythril yang paling kuat adalah kombinasi eksekusi simbolis dan asli dan penentuan nilai parameter yang mengarah ke branching logika.
Kesimpulan
Tentu saja, untuk menunjukkan berbagai potensi masalah yang mampu dideteksi oleh Mythril, dibutuhkan bukan hanya satu, tetapi beberapa artikel. Untuk yang lainnya, dia tahu bagaimana melakukan semuanya dalam blockchain nyata, menemukan kontrak dan kerentanan yang diperlukan dengan tanda tangan, membuat grafik panggilan yang indah, memformat laporan. Mythril juga memungkinkan Anda untuk menulis skrip pengujian Anda sendiri, menyediakan antarmuka berbasis python untuk kontrak dan memungkinkan Anda untuk menguji fungsi individu, memperbaiki nilai parameter, atau bahkan menerapkan strategi Anda sendiri untuk bekerja dengan kode yang dibongkar dengan tingkat fleksibilitas yang sewenang-wenang.
Mythril masih merupakan perangkat lunak yang cukup muda, ini bukan IDA Pro, dan ada sangat sedikit dokumentasi kecuali beberapa artikel. Nilai banyak parameter hanya dapat dibaca dalam kode Mythril, dimulai dengan cli.py. Saya harap penjelasan lengkap dan mendalam tentang operasi setiap parameter muncul dalam dokumentasi.
Selain itu, ketika kontrak lebih atau kurang besar, output dari banyak kesalahan memakan banyak ruang, tetapi saya ingin dapat menerima informasi terkompresi tentang kesalahan yang ditemukan, karena ketika bekerja dengan Mythril, Anda harus melihat jalur analisis, melihat kontrak mana yang telah diuji sebaik kemampuan Anda, dan dapat secara paksa menonaktifkan kesalahan spesifik yang menurut auditor palsu-positif.
Tetapi secara umum, Mythril adalah alat yang sangat baik dan sangat kuat untuk menganalisis kontrak pintar dan saat ini harus menjadi gudang dari setiap auditor. Ini memungkinkan Anda untuk setidaknya memperhatikan bagian-bagian penting dari kode dan mendeteksi hubungan tersembunyi antar variabel.
Untuk meringkas, rekomendasi untuk menggunakan Mythril adalah:
- Persempit kondisi awal kontrak yang diteliti sebanyak mungkin. Jika selama analisis Mythril akan menghabiskan banyak sumber daya pada cabang yang tidak akan pernah diimplementasikan dalam praktik, itu akan kehilangan kemampuan untuk menemukan bug yang sangat penting, jadi Anda harus selalu mencoba mempersempit area cabang potensial.
- Pastikan analisis kontrak telah dimulai, jangan lewatkan pesan seperti
mythril.laser.ethereum.svm [WARNING]: No contract was created during the execution of contract creation Increase the resources for creation execution (--max-depth or --create-timeout)
, jika tidak, Anda mungkin secara keliru menganggap bahwa tidak ada bug. - Anda dapat secara acak menonaktifkan cabang dalam kode kontrak, memberikan variasi Mythril lebih sedikit dalam memilih cabang dan menghemat sumber daya. Cobalah untuk melakukan tanpa batasan pada
max-depth
, agar tidak "memenggal" analisis, tetapi hati-hati untuk tidak menutupi kesalahan. - Perhatikan setiap peringatan, bahkan komentar ringan terkadang sepadan untuk setidaknya menambahkan komentar pada kode kontrak, membuatnya lebih mudah bagi pengembang lain.
Pada artikel berikutnya, kita akan berurusan dengan penganalisa Manticore, tetapi di sini adalah daftar isi untuk artikel yang siap atau direncanakan untuk ditulis:
Bagian 1. Pendahuluan. Kompilasi, perataan, versi Solidity
Bagian 2. Meluncur
Bagian 3. Mythril (artikel ini)
Bagian 4. Manticore (saat menulis)
Bagian 5. Echidna (saat menulis)