Amalan Terbaik Keselamatan Kontrak
Temui amalan keselamatan penting untuk pembangunan kontrak pintar, termasuk pengawal kemasukan semula, corak semakan-kesan-interaksi dan kawalan akses.
Amalan Terbaik Keselamatan Kontrak ialah pelajaran Asas Pembangunan Web3 & DApp percuma di CoddyKit. Ini ialah pelajaran 2 daripada 3. Sebanyak 3 pelajaran dalam laluan pembelajaran ini boleh dibaca sepenuhnya secara percuma — selepas itu, CoddyKit PRO membuka akses kepada semua pelajaran, serta latihan praktikal dengan penyunting kod terbina dalam dan tutor kecerdasan buatan yang tersedia 24/7. Pelajaran ini merupakan sebahagian daripada laluan pembelajaran Asas Pembangunan Web3 & DApp, dan kemajuan anda disegerakkan merentas web serta aplikasi CoddyKit. Kursus Asas Pembangunan Web3 & DApp merangkumi sejumlah 3 pelajaran.
Pengenalan kepada Keselamatan Kontrak Pintar
Selamat datang ke dunia keselamatan kontrak pintar yang penting! Tidak seperti perisian tradisional, pepijat dalam kontrak pintar boleh menyebabkan kehilangan dana yang tidak boleh dipulihkan.
Oleh sebab kontrak pintar tidak boleh diubah selepas digunakan, pembaikan kerentanan amat sukar dan sering memerlukan mekanisme penaiktarafan yang rumit atau penggunaan semula kontrak baharu.
Dalam pelajaran ini, kami akan meneroka amalan penting untuk membina kontrak pintar yang lebih selamat dan kukuh.
Memahami Serangan Kemasukan Semula
Salah satu kerentanan yang paling terkenal ialah kemasukan semula. Ia berlaku apabila panggilan luaran kepada kontrak atau alamat lain "masuk semula" ke dalam kontrak yang memanggilnya sebelum kemas kini keadaan fungsi asal selesai.
Bayangkan sebuah ATM yang membenarkan anda mengeluarkan wang. Jika ATM menolak jumlah daripada akaun anda *selepas* memberikan wang tunai, serangan kemasukan semula adalah seperti meminta wang tunai berulang kali sebelum sistem mengemas kini baki anda, sehingga mengosongkan ATM.
Kod Pengeluaran yang Rentan
Pertimbangkan kontrak ringkas ini, yang membenarkan pengguna mendeposit dan mengeluarkan Ether. Bolehkah anda mengenal pasti bahayanya?
Fungsi withdraw() mula-mula menghantar Ether, kemudian mengemas kini baki. Penyerang boleh memanggil withdraw() sekali lagi daripada kontrak berniat jahat mereka semasa panggilan luaran berlangsung, sebelum baki mereka ditetapkan kepada sifar.
/// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract VulnerableBank {
mapping(address => uint) public balances;
function deposit() public payable {
balances[msg.sender] += msg.value;
}
function withdraw(uint _amount) public {
require(balances[msg.sender] >= _amount, "Insufficient balance");
// Vulnerable point: send Ether BEFORE updating balance
(bool success, ) = msg.sender.call{value: _amount}("");
require(success, "Failed to send Ether");
balances[msg.sender] -= _amount; // This happens AFTER the external call
}
function getBalance() public view returns (uint) {
return address(this).balance;
}
}Mencegah Kemasukan Semula: Kunci Keadaan
Cara yang biasa dan berkesan untuk mencegah kemasukan semula ialah menggunakan pengawal kemasukan semula. Cara ini melibatkan penguncian keadaan kontrak semasa panggilan luaran dan membukanya semula selepas itu.
Jika panggilan yang cuba masuk semula cuba melaksanakan fungsi yang dikunci, panggilan itu akan dibatalkan. ReentrancyGuard milik OpenZeppelin ialah pelaksanaan yang popular, tetapi anda juga boleh membina pelaksanaan yang ringkas.
Melaksanakan Pengawal Kemasukan Semula
Mari kita tambahkan pengawal kemasukan semula yang ringkas menggunakan penanda boolean. Ini memastikan fungsi withdraw tidak boleh dipanggil semula sehingga pelaksanaan semasa selesai dan keadaan telah dikemas kini.
Pengubah suai nonReentrant menetapkan kunci, melaksanakan operasi, kemudian melepaskan kunci tersebut.
/// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract SecureBank {
mapping(address => uint) public balances;
bool private _locked; // Reentrancy guard flag
modifier nonReentrant() {
require(!_locked, "Reentrant call detected");
_locked = true;
_;
_locked = false;
}
function deposit() public payable {
balances[msg.sender] += msg.value;
}
function withdraw(uint _amount) public nonReentrant {
require(balances[msg.sender] >= _amount, "Insufficient balance");
balances[msg.sender] -= _amount; // Update balance BEFORE external call (CEI)
(bool success, ) = msg.sender.call{value: _amount}("");
require(success, "Failed to send Ether");
}
function getBalance() public view returns (uint) {
return address(this).balance;
}
}Corak CEI
Corak Checks-Effects-Interactions (CEI) ialah amalan terbaik keselamatan yang asas. Corak ini menetapkan susunan khusus untuk operasi dalam sesuatu fungsi:
- Checks: Sahkan syarat (contohnya, pernyataan
require,onlyOwner). - Effects: Kemas kini keadaan kontrak (contohnya,
balances[msg.sender] -= amount). - Interactions: Lakukan panggilan luaran kepada kontrak atau alamat lain.
Mematuhi CEI membantu mencegah pelbagai serangan, termasuk kemasukan semula, dengan memastikan keadaan kontrak dimuktamadkan *sebelum* panggilan luaran.
CEI dalam Fungsi Pengeluaran
Perhatikan bahawa fungsi withdraw milik SecureBank kita sudah mengikuti corak CEI:
- Checks:
require(balances[msg.sender] >= _amount, ...)danrequire(!_locked, ...)daripada pengubah suai. - Effects:
balances[msg.sender] -= _amount;mengemas kini keadaan. - Interactions:
msg.sender.call{value: _amount}("");melakukan pemindahan luaran.
Susunan ini penting untuk mencegah kemasukan semula dan memastikan keadaan kekal konsisten.
/// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract CEIDemo {
mapping(address => uint) public balances;
bool private _locked;
modifier nonReentrant() {
require(!_locked, "Reentrant call detected");
_locked = true;
_;
_locked = false;
}
function deposit() public payable {
balances[msg.sender] += msg.value;
}
function withdraw(uint _amount) public nonReentrant {
// --- CHECKS ---
require(balances[msg.sender] >= _amount, "Insufficient balance");
// --- EFFECTS ---
balances[msg.sender] -= _amount; // State updated BEFORE external call
// --- INTERACTIONS ---
(bool success, ) = msg.sender.call{value: _amount}("");
require(success, "Failed to send Ether");
}
}Mengehadkan Akses
Tidak semua fungsi dalam kontrak pintar patut boleh dipanggil oleh semua orang. Kawalan akses memastikan hanya alamat atau peranan yang dibenarkan boleh melaksanakan operasi sensitif tertentu.
Contoh yang biasa termasuk:
- Pengubah suai
onlyOwneruntuk fungsi pentadbiran. - Kawalan akses berasaskan peranan (RBAC), dengan peranan yang berbeza (contohnya,
MINTER,PAUSER) mempunyai keizinan khusus.
Kawalan akses yang betul amat penting untuk mencegah tindakan tanpa kebenaran dan mengekalkan integriti kontrak.
Fungsi Terhad kepada Pemilik
Berikut ialah cara melaksanakan kawalan akses onlyOwner yang ringkas menggunakan pengubah suai. Kontrak menyimpan alamat pengguna yang menggunakan kontrak sebagai owner, dan hanya alamat ini boleh memanggil fungsi setNewAdmin.
Corak ini digunakan secara meluas untuk fungsi pentadbiran yang kritikal.
/// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract AccessControlled {
address public owner;
address public admin;
constructor() {
owner = msg.sender; // Deployer is the owner
admin = msg.sender;
}
modifier onlyOwner() {
require(msg.sender == owner, "Only owner can call this function");
_;
}
function setNewAdmin(address _newAdmin) public onlyOwner {
admin = _newAdmin;
}
function getAdmin() public view returns (address) {
return admin;
}
}Semakan Amalan Terbaik Keselamatan
Anda telah mempelajari tentang kemasukan semula, corak CEI dan kawalan akses. Antara pernyataan berikut, yang manakah benar berkaitan pembangunan kontrak pintar yang selamat?
Imbas Kembali: Kontrak Selamat
Syabas! Anda telah memahami amalan asas keselamatan kontrak pintar:
- Kemasukan Semula: Kerentanan kritikal apabila panggilan luaran boleh "masuk semula" ke dalam fungsi sebelum keadaan dikemas kini.
- Pengawal Kemasukan Semula: Mekanisme seperti mutex atau pengubah suai untuk mengunci keadaan kontrak semasa panggilan luaran.
- Corak CEI: Susunan operasi yang disyorkan (Checks, Effects, Interactions) untuk memastikan keadaan dikemas kini sebelum panggilan luaran.
- Kawalan Akses: Mengehadkan fungsi sensitif kepada alamat yang dibenarkan, selalunya menggunakan pengubah suai
onlyOwner.
Amalan ini penting untuk membina aplikasi terdesentralisasi yang kukuh dan boleh dipercayai. Teruskan berlatih dan sentiasa berwaspada!
Pelajari Asas Pembangunan Web3 & DApp dengan tutor kecerdasan buatan — percuma
Tulis dan jalankan kod sebenar dalam pelayar anda, dapatkan bantuan segera daripada tutor kecerdasan buatan yang tersedia 24/7, dan sambung semula dari tempat anda berhenti di web atau dalam aplikasi.
- Kursus
- 29
- Pelajaran
- 105
Soalan Lazim
Adakah pelajaran “Amalan Terbaik Keselamatan Kontrak” percuma?
Ya — sebanyak 3 pelajaran dalam laluan pembelajaran Asas Pembangunan Web3 & DApp, termasuk “Amalan Terbaik Keselamatan Kontrak”, boleh dibaca sepenuhnya secara percuma di web ini. Selepas itu, CoddyKit PRO membuka akses kepada semua pelajaran, serta latihan interaktif dengan penyunting kod terbina dalam dan tutor kecerdasan buatan yang tersedia 24/7. Kursus Asas Pembangunan Web3 & DApp merangkumi sejumlah 3 pelajaran.
Apakah yang akan saya pelajari dalam “Amalan Terbaik Keselamatan Kontrak”?
Temui amalan keselamatan penting untuk pembangunan kontrak pintar, termasuk pengawal kemasukan semula, corak semakan-kesan-interaksi dan kawalan akses. Anda berlatih Asas Pembangunan Web3 & DApp menggunakan kod praktikal yang dijalankan terus dalam pelayar, manakala tutor kecerdasan buatan 24/7 menjawab soalan anda semasa anda mengikuti pelajaran.
Adakah saya memerlukan pengalaman untuk memulakan Asas Pembangunan Web3 & DApp?
Tiada pengalaman terdahulu diperlukan. Pembelajaran Asas Pembangunan Web3 & DApp di CoddyKit disusun untuk pelajar daripada peringkat pemula hingga lanjutan, jadi anda boleh bermula di sini atau dari awal dan belajar mengikut kadar anda sendiri. Ini ialah pelajaran 2 daripada 3.
Berapa lamakah pelajaran “Amalan Terbaik Keselamatan Kontrak” diambil?
Kebanyakan pelajaran CoddyKit mengambil masa kira-kira 5–10 minit. Setiap pelajaran ringkas dan interaktif, jadi anda boleh membuat kemajuan secara berterusan dan menyambung tepat dari tempat anda berhenti di web atau aplikasi.
Bolehkah saya menulis dan menjalankan kod dalam pelajaran Asas Pembangunan Web3 & DApp ini?
Ya. Setiap pelajaran Asas Pembangunan Web3 & DApp menyertakan penyunting kod terbina dalam, jadi anda boleh menulis dan menjalankan kod sebenar terus dalam pelayar serta menerima maklum balas kecerdasan buatan serta-merta — tanpa memerlukan persediaan setempat.
Semua pelajaran dalam kursus ini
- Piawaian ERC (ERC-20, ERC-721)
- Amalan Terbaik Keselamatan Kontrak
- Kontrak Boleh Dinaik Taraf