Linee guida di sicurezza per gli Smart Contract
Segui questi consigli di alto livello per creare Smart Contract più sicuri.
Linee guida di progettazione
La progettazione del contratto deve essere discussa in anticipo, prima di scrivere la prima riga di codice.
Documentazione e specifiche
La documentazione può essere scritta su diversi livelli e deve essere aggiornata durante l'implementazione dei contratti:
- Una descrizione semplice in inglese del sistema, che descriva cosa fanno i contratti e tutte le ipotesi sulla base di codice.
- Schema e diagrammi architettonici, incluse le interazioni del contratto e la macchina a stati del sistema. Le stampanti Slither(opens in a new tab) possono aiutare a generare questi schemi.
- Documentazione approfondita sul codice, il formato Natspec(opens in a new tab) si può usare per Solidity.
Calcolo sulla catena ed esterno alla catena
- Mantieni quanto più codice possibile al di fuori della catena. Il livello sulla catena deve essere il più ridotto possibile. Elabora anticipatamente i dati con il codice esternamente alla catena così che la verifica su di essa sia semplice. Ti serve un elenco ordinato? Ordina l'elenco esternamente alla catena, poi controlla solo l'ordine sulla catena.
Aggiornabilità
Abbiamo discusso le diverse soluzioni di aggiornabilità nel nostro post di blog(opens in a new tab). Fai una scelta deliberata per supportare l'aggiornabilità o non prima di scrivere codice. La decisione influirà su come strutturi il tuo codice. In generale, consigliamo:
- Prediligere la migrazione del contratto(opens in a new tab) rispetto all'aggiornabilità. I sistemi di migrazione presentano molti vantaggi identici a quelli aggiornabili, senza i loro svantaggi.
- Usare lo schema di separazione dei dati rispetto a quello delegatecallproxy. Se il progetto ha una chiara separazione dell'astrazione, l'aggiornabilità che usa la separazione dei dati necessiterà solo di poche modifiche. delegatecallproxy richiede esperienza con l'EVM ed è altamente incline a errori.
- Documentare la procedura di migrazione/aggiornamento prima della distribuzione. Se dovrai reagire sotto pressione senza linee guida, commetterai degli errori. Scrivi in anticipo la procedura da seguire. Deve includere:
- Le chiamate che inizializzano i nuovi contratti
- Dove sono memorizzate le chiavi e come accedervi
- Come controllare la distribuzione. Sviluppa e testa uno script post-distribuzione.
Linee guida per l'implementazione
Punta alla semplicità. Usa sempre la soluzione più semplice adatta al tuo scopo. Tutti i membri del team devono essere in grado di comprendere la tua soluzione.
Composizione della funzione
L'architettura della base di codice deve rendere il codice semplice da controllare. Evita le scelte architettoniche che riducono la capacità di ragionare sulla sua correttezza.
- Dividi la logica del tuo sistema, tramite più contratti o raggruppando le funzioni simili (ad esempio, autenticazione, aritmetica, ...).
- Scrivi funzioni piccole, con uno scopo chiaro. Questo faciliterà il controllo e consentirà di testare singoli componenti.
Ereditarietà
- Rendi gestibile l'ereditarietà. L'ereditarietà deve essere usata per dividere la logica, tuttavia, il progetto deve puntare a ridurre la profondità e la larghezza dell'albero d'ereditarietà.
- Usa la stampante dell'ereditarietà(opens in a new tab) di Slither per verificare la gerarchia dei contratti. La stampante dell'ereditarietà ti aiuterà a controllare la dimensione della gerarchia.
Eventi
- Registra tutte le operazioni cruciali. Gli eventi aiuteranno ad eseguire il debug del contratto durante lo sviluppo e a monitorarlo dopo la distribuzione.
Evita trappole note
- Sii consapevole dei problemi di sicurezza più comuni. Ci sono molte risorse online per saperne di più sui problemi più comuni, come Ethernaut CTF(opens in a new tab), Capture the Ether(opens in a new tab), o Not so Smart Contract(opens in a new tab).
- Sii consapevole delle sezioni di avviso nella documentazione di Solidity(opens in a new tab).Le sezioni di avviso ti informeranno del comportamento non ovvio del linguaggio.
Dipendenze
- Usa librerie ben testate. Importare il codice da librerie ben testate ridurrà la possibilità di scrivere codici con bug. Se vuoi scrivere un contratto ERC20, usa OpenZeppelin(opens in a new tab).
- Usa un gestore di dipendenze; evita il copia-incolla del codice. Se ti basi su un'origine esterna, mantieni sempre il codice aggiornato rispetto all'origine.
Test e verifica
- Scrivi test unitari approfonditi. Un'ampia serie di test è cruciale per craare software di alta qualità.
- Scrivi controlli e proprietà personalizzati in Slither(opens in a new tab), Echidna(opens in a new tab) e Manticore(opens in a new tab). Gli strumenti automatizzati contribuiranno a garantire la sicurezza del contratto. Consulta il resto di questa guida per imparare a scrivere controlli e proprietà efficienti.
- Usa crytic.io(opens in a new tab). Crytic si integra con GitHub, fornisce accesso a rilevatori privati di Slither ed esegue controlli personalizzati delle proprietà da Echidna.
Solidity
- Preferisci Solidity 0.5 rispetto a 0.4 e 0.6. Secondo noi, Solidity 0.5 è più sicuro e contiene prassi meglio integrate rispetto a 0.4. Solidity 0.6 si è dimostrato troppo instabile per la produzione e ha bisogno ancora di tempo per maturare.
- Usa una versione stabile per compilare; usa l'ultima versione per controllare gli avvisi. Controlla che per il tuo codice non vengano segnalati problemi con l'ultima versione del compiler. Solidity però ha un ciclo di rilascio veloce e una lunga cronologia di bug del compilatore, quindi non consigliamo l'ultima versione per la distribuzione (vedi i consigli sulla versione solc(opens in a new tab) di Slither).
- Non usare l'assembly inline. Assembly richiede esperienza con l'EVM. Non scrivere il codice dell'EVM se non ha una conoscenza approfondita dello yellow paper.
Linee guida di distribuzione
Una volta sviluppato e distribuito il contratto:
- Monitora i contratti. Guarda i registri e reagisci con prontezza in caso di compromissione del contratto o del portafoglio.
- Aggiungi le tue informazioni di contatto in blockchain-security-contacts(opens in a new tab). Questo elenco aiuta terze parti a contattarti se viene scoperto un difetto nella sicurezza.
- Proteggi i portafogli degli utenti privilegiati. Segui le nostre best practice(opens in a new tab) se memorizzi chiavi in portafogli hardware.
- Prepara una risposta con un piano per gli incidenti. Tieni presente che gli Smart Contract che crei possono essere compromessi. Anche se i contratti sono privi di bug, un aggressore potrebbe assumere il controllo delle chiavi del proprietario del contratto.
Ultima modifica: @pettinarip(opens in a new tab), 8 dicembre 2023