IT knowledge base
CTRL+F per cercare la tua parola chiave

Immergiti in ICO

In questo articolo considereremo gli aspetti tecnici della preparazione e della conduzione di un ICO. Questa è una continuazione dell'articolo del mio collega “ Caratteristiche tecniche dell'ICO. Beginning ”, e qui parleremo più nel dettaglio di alcune delle problematiche tecniche legate agli smart contract della rete Ethereum.

Sviluppo di un progetto tecnico

Prima di sviluppare uno smart contract, sarebbe bene fare un progetto tecnico. Questo è un diagramma schematico del tuo sistema contrattuale, che, rispondendo a domande tecniche chiave, mostra la fattibilità dell'economia del progetto e il tuo scenario ICO.

Cosa è solitamente incluso in un progetto tecnico? Non deve essere un grosso documento formale, bastano quattro o cinque pagine di punti chiave e un paio di diagrammi. E su queste pagine, inizia guardando i meccanismi della proprietà. L'opzione più semplice: viene implementato un proprietario di token, ICO - tutto di seguito. Questo di solito è fatto. Un'opzione più difficile è quando viene utilizzata la multifirma. Puoi prendere come base un contratto di portafoglio affidabile, estrarre una multifirma da lì e utilizzarlo non solo per il portafoglio e l'archiviazione di ether, ma anche per gestire l'ICO stesso e il token. Qui la tua immaginazione non è limitata, puoi facilmente implementare matematicamente una varietà di scenari.

Va bene quando l'ICO è scomposto, cioè non è un contratto che calcola la tariffa, emette token e accetta ether, ma un sistema di contratti intelligenti, quando ogni contratto fa le sue cose. Cioè, accetti ether nella fase ICO, che, a seconda della sua logica, capisce quanti token devi emettere. Dà il comando appropriato al contratto token, il proprietario del token, e allo stesso tempo non tiene l'etere in sé, ma lo trasferisce in un deposito speciale, che è anche un contratto.

Non vedo alcun crimine nel mantenere l'etere nel contratto. Al contrario, è ancora più trasparente in quanto è chiaro cosa sta facendo il contratto. Puoi facilmente vedere che l'etere è memorizzato lì fino alla fine dell'ICO e, se non hai raccolto denaro, è garantito che restituirà tutto agli investitori, e anche i proprietari non possono impedirlo.

D'altra parte, questa complicazione non è mai gratuita. Possiamo dire che questo crea ulteriori problemi in fase di implementazione. E sì, queste connessioni e chiamate sono un'altra opportunità per introdurre vulnerabilità. Guarda i tuoi diritti molto da vicino.

Esiste uno standard per un token, si chiama ERC20 , definisce diversi metodi che devono essere implementati in un contratto. Se il tuo token implementa questo standard, può essere elencato su molti scambi. Inoltre, ERC20 è supportato da altri portafogli oltre a Ethereum Wallet. Quindi, semplicemente implementando le funzioni necessarie, ottieni un'infrastruttura già pronta per lavorare con il tuo token. Inoltre, ci sono librerie che pongono le basi per il token e implementano immediatamente ERC20. Non è necessario implementare lo standard se si dispone di un qualche tipo di token di risorsa puramente interno e se non è previsto che gli utenti lo scambino tra di loro. Se vengono con questo token in un parco di divertimenti e si comprano un biglietto per le attrazioni, allora, probabilmente, non ha bisogno di una quotazione in borsa.

Inoltre, il contratto può essere sospeso in caso di problemi o attività strane. Ad esempio, quando viene versato ether e non vengono emessi token. Quindi devi sospendere l'ICO, capirlo e prendere una decisione. Vale la pena porre questo stato nel progetto tecnico. Puoi anche prevedere l'emissione di un token nel progetto tecnico. È importante pensarci prima dell'ICO, perché devi capire come sarà compatibile con il token, se sarai in grado di effettuare emissioni aggiuntive in seguito.

Assicurati di pensare a un tale schema: questo è il grafico di stato del tuo ICO. È una macchina a stati finiti, ovvero gli stati in cui può trovarsi una ICO. Questo è il grafico, descrive gli stati e dice in quali condizioni avviene il passaggio dall'uno all'altro. Il tuo ICO non dovrebbe solo cambiare stato dalla raccolta di fondi a "Raccolta con successo. Facciamoli uscire il prima possibile". Devi capire quali sono le transizioni tra gli stati in una ICO. Anche gli investitori dovrebbero capirlo, perché vedono che tutto è giusto. E questo deve essere compreso e chiaramente programmato dagli sviluppatori. Per questo, Solidity ha tutti i mezzi, ci sono le cosiddette enumerazioni, con l'aiuto delle quali viene descritto lo stato. Inoltre, consiglio di effettuare transizioni di stato controllate da codice in modo che non vi siano transizioni non valide.

Qualsiasi funzione disponibile al di fuori del contratto può essere impostata allo stato utilizzando i cosiddetti modificatori di solidità. Quindi, puoi investire solo nello stato ICO, ma non durante una pausa. E viceversa, i proprietari possono prelevare denaro solo dopo un ICO completato con successo.

Sviluppo di contratti intelligenti

Quando il progetto tecnico è pronto, il cliente è soddisfatto e lo sviluppatore capisce cosa deve essere fatto, si procede allo sviluppo. Ethereum ha una macchina virtuale (Ethereum Virtual Machine, EVM), esegue proprio questi programmi a contratto e il contratto è il cosiddetto bytecode che viene eseguito dalla macchina virtuale. A questo proposito, diventa possibile sviluppare contratti in più lingue. Il linguaggio Solidity è stato creato appositamente per il compito di sviluppare da zero contratti intelligenti; ha una sintassi simile al C. Oltre ad esso, ci sono altri linguaggi: ci sono simili a JavaScript, c'è un linguaggio simile a Python.

La mia intuizione è che sia meglio scegliere Solidity anche per ragioni neurofisiologiche. Quando uno sviluppatore utilizza un linguaggio simile a Python, scrive comunque uno smart contract Ethereum. Ma allo stesso tempo, la semantica e i modelli tipici di Python iniziano a spuntare nella sua testa e ovviamente non funzionano durante lo sviluppo per Blockchain.

Di Solidità si può parlare a lungo, quindi abbiamo bisogno di alcune linee guida. Innanzitutto, il tartufo rende lo sviluppo molto più semplice. Aiuta a testare il contratto, distribuirlo alle blockchain principali, di prova e locali. E ti consente persino di farlo in modo incrementale, ovvero di integrare il tuo sistema di contratti con nuovi contratti. Allo stesso tempo, il framework ricorderà tutti i vecchi e non li ridistribuirà.

Perché chiedo il riutilizzo delle biblioteche? La community è piuttosto giovane, c'è poco codice, ma tutti i principi ottenuti nello sviluppo del software negli ultimi 30-40 anni rimangono in vigore nel caso della Blockchain. E ci dicono che se c'è un codice sufficientemente ben testato, che di per sé implica il riutilizzo in una vasta gamma di progetti, allora dovremmo prenderlo e non reinventare la ruota.

Prima di tutto, vorrei menzionare la libreria OpenZeppelin / zeppelin-solidity . È sull'orlo di uno standard di fatto quando si sviluppano contratti intelligenti. Non ci sono molti contratti e biblioteche là fuori, sono relativamente piccoli. Ma coprono casi frequenti, forniscono molte cose fuori dagli schemi: proprietà del contratto, alcuni token, token che possono essere creati, masterizzati, diverse ICO tipiche, qualcosa relativo alla sicurezza, ad esempio, protezione contro gli attacchi di rientro.

Un'altra libreria èSafeMath . Consiglio di usarlo anche se non vuoi includere la solidità dello Zeppelin. È piccolo, letteralmente poche battute, puoi copiarlo direttamente nel tuo contratto. Ti assicura contro gli overflow. Questo è un problema molto urgente e serio. Ad esempio, quando hai a che fare con numeri senza segno in Solidità e inavvertitamente sottrai 5 da una tripla, il contratto continua a funzionare, ma di conseguenza ti viene mostrato un numero enorme. Questo è successo a causa dell'overflow. Se utilizzi la libreria SafeMath, si verifica un errore, ovvero la transazione termina con un errore e lo stato non cambia.

Ci sono molte linee guida. Ho citato la macchina a stati, è auspicabile implementarla: registrare gli stati e il modificatore. Inoltre, le transizioni da uno stato all'altro possono essere attuate nel tempo. Allo stesso tempo, viene aggiunto un modificatore a ciascuna funzione, che dice: "Guarderò l'ora e se l'ICO è già iniziato, cambierò lo stato in ICO".

Ci sono pattern, pattern tipici che iniziano a prendere forma nel mondo Solidity, nel mondo smart contract. Ad esempio, hai sentito che ci sono molti modelli nello sviluppo del software, in particolare alcuni sistemi aziendali. Ecco, questi includono, ad esempio, il noto schema di prelievo, quando l'utente preleva i fondi che gli sono dovuti lui stesso, e non quando si tenta di inviarglieli. Ad esempio, se un ICO fallisce, quando devi restituire denaro agli investitori, se provi a farlo da solo, molto probabilmente non avrai successo per una serie di motivi. È anche pieno di problemi di sicurezza. Effettuare un rimborso come prelievo utente con controlli appropriati lo rende molto più semplice.

Ho menzionato la modalità di pausa. Non usato spesso nelle ICO che abbiamo visto ultimamente, ma è un meccanismo molto utile. È chiaro che non assicura contro il 100% delle situazioni problematiche (anche se c'è una pausa, puoi rubare ether), ma riduce notevolmente la possibilità di un attacco.

Riguardo alla sostituzione dei contratti devo dire che non è necessario andare fino in fondo e fare un contratto completamente dinamico, il cui codice può essere arbitrariamente sostituito utilizzando, ad esempio, una chiamatadelegatecall e così via È sufficiente che questo pezzo, lo stadio ICO, che contiene una logica contorta non banale, possa essere sostituito se viene riscontrato un problema. Ciò è possibile grazie al fatto che hai gettoni e denaro separati, il denaro rimane invariato. In linea di massima è possibile sostituire questo pezzo e collegarlo ai due pezzi già esistenti in maniera del tutto trasparente. Ci sono anche alcune particolarità. Se l'ICO esegue l'inizializzazione, ad esempio un token, adottare misure in modo che quando si sostituisce l'inizializzazione non si avvii una seconda volta. Di conseguenza, il tuo ICO avrà un nuovo indirizzo, questo è un nuovo contratto. La possibilità di sostituzione sarà visibile nel codice dei contratti e devi capire che si tratta di una sorta di compromesso. Da un lato vuoi che tutto sia assolutamente immutabile (questo aumenta la tua fiducia in te stesso), dall'altro sarebbe bello andare sul sicuro. Come compromesso, puoi codificare condizioni completamente immutabili. Ad esempio, registra nello storage ether che la soglia minima di raccolta fondi è invariabile in linea di principio. Quindi gli investitori sapranno che non accadrà che hanno raccolto 100mila, ma volevano raccogliere 100 milioni, ma hanno comunque preso quello che avevano.

Quando possibile, dovresti verificare la ragionevolezza dei parametri che le modalità del tuo contratto ricevono come input. Ad esempio, se il tuo token supporta l'emissione e i suoi parametri specificano il numero di token che devono essere generati, puoi controllare questo numero, ad esempio, cercando di vedere se è più di quanto ci siano ora i token in generale. Questa può essere la tua rete di sicurezza quando c'è un errore di battitura in un parametro inserito manualmente. Oppure, ad esempio, se l'emissione è avviata da un'infrastruttura esterna, quando fallisce, può emettere miliardi di miliardi di token per te.

Altri tre link su GitHub:

Ecco una serie di repository con alcune soluzioni. Queste sono cose sperimentali, provale con molta attenzione, e di solito c'è scritto: "Questa è una versione alfa, non memorizzi più di $ 20 su di essa", ma è chiaro che tutte le cose buone nascono dagli esperimenti. Forse è meglio prendere qualcosa di già pronto come base piuttosto che scrivere tutto da zero.

Quale IDE prendere per lo sviluppo della solidità? Sono abituato a lavorare attivamente sulla riga di comando, eseguo Truffle dalla riga di comando, e infatti sono necessari solo tre comandi:test ,compile ,migrate ... In termini di ambiente di sviluppo, ho scelto PyCharm, c'è un plugin gratuito per Solidity, che non è una brutta cosa. L'IDE ti aiuta molto e PyCharm / Idea è un buon IDE, direi anche che è due volte più buono della concorrenza. Ti permetterà di evidenziare la variabile nel contratto, tutto il suo utilizzo, e aiuta molto quando facciamo un audit, quando capisci letteralmente codice non familiare in poche ore usando i suggerimenti dell'ambiente di sviluppo.

Un po 'sul costo dell'esecuzione di contratti intelligenti. Solo i calcoli che cambiano la Blockchain, cioè partecipano alla transazione, avranno un costo. Ci sono funzioni con modificatoriview opure , non modificano lo stato, possono essere utilizzati senza inviare dati alla Blockchain. Se sviluppassimo una funzione chiamata puramente localmente, non costerebbe nulla.

Qualsiasi codice che effettivamente viene eseguito sulla Blockchain e modifica lo stato, salva o invia dati costa gas. È facile impostare un esperimento mentale su questo argomento, posso scrivere codice che, ad esempio, verrà eseguito per molto tempo e risparmierà molto. Se allo stesso tempo i partecipanti alla rete Ethereum devono ripeterlo, il tuo codice funzionerà su milioni di computer in tutto il mondo. Ciò significa che gli sviluppatori di Ethereum si sono presi cura di te pagandolo comunque, e piuttosto costoso ai prezzi attuali. Un'altra cosa è che calcoli e linee diversi hanno costi diversi. Il prezzo dell'aritmetica semplice è di 3-5 unità di gas e la modifica dello stato costerà 20 mila unità di gas. Perché? Poiché la blockchain è cambiata, è cresciuta di 32 byte grazie a te e questi byte sono stati trasferiti a milioni di computer in tutto il mondo.

Test del contratto intelligente

Il testing è un passaggio obbligato, come ci raccontano i 50 anni di storia del software. Ed è strano non vedere i test nei repository del progetto che arrivano all'ICO. Potrebbero essere stati fatti, scritti, ma semplicemente non presentati. Ma comunque, se stai facendo dei test, perché non li metti fuori? È così che mostri agli investitori che tutto è ben testato qui. Questa non è una garanzia che non ci siano errori, ma aiuta ad evitare molti problemi.

I test sono scritti direttamente in Solidity o JavaScript. In ogni caso, con Truffle, puoi eseguire tutti i test contemporaneamente e ottenere un report riassuntivo. In fondo, dovresti dire: tutti i test sono stati superati, nessun fallimento. Mostri a entrambi i clienti ICO, agli utenti e agli investitori che hai testato gli aspetti più importanti del tuo ICO: il token, il crowdsale stesso, l'archiviazione di denaro, persino i bonus. I bonus sono una cosa importante. È molto importante che gli investitori sappiano che riceveranno i loro bonus.

Esistono test unitari: controllano piccoli frammenti di codice isolati ed è conveniente scrivere tali test in Solidity.

function testValidationOfDecrease() {
    Bonuses b = new Bonuses();
    b.add(1000000000, 50);
    b.add(1000000010, 60);
    b.validate(false);
    assertInvalid(b, true);

    b = new Bonuses();
    b.add(1000, 60);
    b.add(1000000000, 50);
    b.add(1000000010, 60);
    b.add(1000000020, 0);
    b.validate(false);
    assertInvalid(b, true);
}

Il codice è Solidity, crea semplicemente un contratto, gli invia i dati e verifica che il contratto funzioni come previsto. Ci sono test scritti in JavaScript. Di solito, qui vengono controllati scenari più complessi quando più contratti sono coinvolti nell'interazione. Diciamo che stiamo creando una serie di contratti che sono stati menzionati in precedenza. Quindi sono coinvolti più contratti, possono esserci anche più utenti. Li chiamiamo anche "investitore tale e tale", "investitore tale e tale". Ci sono anche proprietari, ci sono utenti senza alcun diritto. E qui puoi programmare un'interazione complessa e controllare che i token vengano emessi correttamente durante le interazioni. Oppure verifica che al raggiungimento dell'hard cap l'investitore riceva il resto. Questi test sono chiamati test di integrazione.

Tutte le chiamate alla Blockchain da JavaScript sono asincrone: questo aggiunge codice extra, ogni sorta di promesse, ecc., Quindi suggerisco di usare Babel, una sorta di compilatore JavaScript che nasconderà tutta l'asincronia dietro la costruzioneawait ,async ...

it("test max cap", async function() {
    const role = getRoles();

    const [crowdsale, token, funds] = await instantiate();

    // +5%
    await crowdsale.setTime(1511913601, {from: role.owner1});
    await crowdsale.sendTransaction({from: role.investor1, value: web3.toWei(20, 'finney')});
    await assertBalances(crowdsale, token, funds, web3.toWei(20, 'finney'));

    const investor3initial = await web3.eth.getBalance(role.investor3);
    await crowdsale.sendTransaction({from: role.investor3, value: web3.toWei(1000, 'finney'), gasPrice: 0});

    const investor3spent = investor3initial.sub(await web3.eth.getBalance(role.investor3));
    assertBigNumberEqual(investor3spent, web3.toWei(378, 'finney'), 'change has to be sent');

    assert.equal(await crowdsale.m_state(), 4);
    await assertBalances(crowdsale, token, funds, web3.toWei(398, 'finney'));
    assertBigNumberEqual(await token.balanceOf(role.investor1), STQ(2100));
    assertBigNumberEqual(await token.balanceOf(role.investor3), STQ(39690));

    await checkNoTransfers(crowdsale, token, funds);
    await checkNotInvesting(crowdsale, token, funds);
    await checkNotWithdrawing(crowdsale, token, funds);
    await checkNotSendingEther(crowdsale, token, funds);

    await crowdsale.distributeBonuses(10, {from: role.nobody});

    assertBigNumberEqual(await token.balanceOf(role.investor1), STQ(2600));
    assertBigNumberEqual(await token.balanceOf(role.investor3), STQ(49140));

    await checkNotInvesting(crowdsale, token, funds);
    await checkNotWithdrawing(crowdsale, token, funds);
});

Non dimenticare di testare le eccezioni. Ad esempio, abbiamo verificato che i proprietari ritirino denaro dopo il completamento di un ICO di successo. Dobbiamo anche verificare che questi compagni - investitore 2, investitore 3, anonimo dalla strada - non possono prelevare denaro, cioè quando si presenta una richiesta di prelievo, si verificherà una situazione eccezionale, il contratto non accetterà la richiesta.

Riassumendo: vale la pena provare, ci sono tutti i mezzi per farlo. A proposito, un programmatore non deve essere un tester. Perché? Perché il creatore non vede bene i suoi errori. Aveva già una specie di modello in testa e lo ha trasferito nel codice. Quando un programmatore prova a controllare il suo codice, il suo, inevitabilmente il modello gli compare in testa e il cervello dice: “Sì, qui va tutto bene. Abbiamo creato questo metodo in modo che... E smettila di guardare lì. Andiamo a farci un frullato".

Oltre al test, è necessario anche un audit. Persone appositamente addestrate sono impegnate nell'auditing. Ulteriori test possono essere sviluppati durante l'audit, ma l'auditing è una situazione completamente diversa e abilità molto diverse.

Se stiamo parlando di audit, allora prima di tutto devi capire quali sono le vulnerabilità e quanto pagherai i revisori per loro. Ci sono diversi modi per valutare. Ad esempio, OWASP è una buona metodologia, introduce due dimensioni per la vulnerabilità: importanza e probabilità. L'impatto delle vulnerabilità su un progetto è il prodotto di questi due valori. Questo potrebbe ricordare a qualcuno una matrice di valutazione del rischio.

In pratica, nei rapporti di audit di uno smart contract, spesso si deve vedere che il grado di influenza della vulnerabilità, la sua importanza, è attratto dalle orecchie. Non so perché questo sta accadendo. Tuttavia, le vulnerabilità critiche non sono affatto chiamate critiche. Pertanto, proponiamo una metodologia diversa che collega l'impatto della vulnerabilità nella vita reale al tuo progetto. Nel caso degli smart contract, ci sono risultati abbastanza comprensibili nello sfruttamento della vulnerabilità: puoi prelevare ether o token, il che è molto negativo. In alcune condizioni, il contratto si bloccherà o le sue condizioni si deterioreranno così tanto che il contratto dovrà essere sostituito. Qui, i revisori e il cliente della revisione possono avere un numero minimo di controversie. Un paio di link ai rapporti di audit:

Un report è un documento che parla di quali vulnerabilità sono state rilevate e (idealmente) cosa fare dopo. Qualcuno nei circoli occidentali scrive grandi rapporti: ti dicono che devi nominare questa funzione in modo diverso, ma è meglio spostare questo codice da qualche altra parte. Ma non vedo il punto di farlo se il cliente non si impegna nello sviluppo seriale di contratti intelligenti, se ha bisogno di condurre una ICO una volta e continuare a estrarre la sua sabbia nella cava per la quale ha raccolto l'aria.

Problemi di sicurezza degli smart contract

Passiamo alle questioni che devono essere affrontate. Questo è un argomento per un articolo separato sulla sicurezza dei contratti intelligenti. Ci sono alcune cose da notare. Per iniziare, dai un'occhiata molto attenta alle funzioni e assicurati che siano adeguatamente protette con le restrizioni più restrittive. Ad esempio, una funzione che non cambia nulla nella blockchain può essere dichiarata comeview ... Una funzione che non legge affatto la blockchain - come?pure ... Vale la pena imporre queste restrizioni. Inoltre, per le funzioni amministrative, il titolare deve essere verificato. Sembra ovvio, ma ricorda Parity.

Lo ripeto ancora una volta: tutti i dati nella blockchain sono aperti a tutti, nonostante i modificatori e i diritti di accesso allo stato. Ci potrebbe esserepublic può non essere, ma in realtà tutto si può leggere dal contratto. Non utilizzare un parametro di transazione cometx.origin : questo apre una vulnerabilità. Sceglieremsg.sender ...

Dal non banale. Probabilmente, molti hanno sentito parlare del cosiddetto attacco di rientro, attraverso il quale è stato violato il DAO. Il problema è che, mentre il tuo metodo di contratto è ancora in esecuzione, può effettuare una chiamata esterna. Questo vale solo per le chiamate esterne, che a loro volta possono rientrare lungo la catena e fare riferimento allo stesso metodo o ad un altro metodo del contratto. E questo apre delle vulnerabilità: lo stato del tuo contratto potrebbe non essere ancora coerente, alcune invarianti durante il funzionamento del metodo potrebbero essere temporaneamente violate e non ancora ripristinate.

Esistono diversi metodi per combatterlo. Il metodo più hardcore è il modificatorenonReentrant da contratto di bibliotecaReentrancyGuard - vieta il rientro per i contratti. Perché non usarlo? Costa una certa quantità di gas, scrive uno stato, ma in alcuni casi la sicurezza è più importante del consumo eccessivo di gas.

Prendiamo come esempio l'attacco in corsa frontale. E se criptassi qualcosa e lo metti sulla Blockchain? È impossibile decifrare, perché nessuno ha cancellato la crittografia asimmetrica. Ma non appena si tenta di decifrarlo legittimamente inviando una transazione di password, ecco cosa succede. Innanzitutto, la password è una tantum, perché è arrivata nella blockchain, tutti possono vederla. In secondo luogo, quando la transazione ti ha lasciato, ma non è ancora diventata parte del ramo principale e non ha impegnato i token per te, in questo momento qualcuno può vedere la tua password e inserire la transazione, che sarà precedente alla tua, anche se è successo più tardi nel tempo...

Non molto tempo fa, sono apparse informazioni su un altro attacco: un attacco a indirizzo breve. Alcuni scambi sono stati esposti ad esso. E librerie che inviano transazioni a Ethereum. La libreria API principale di Ethereum web3 non è interessata, ma gli scambi di software sono stati interessati. L'attacco consisteva nel fatto che l'utente utilizzava un indirizzo accorciato di un byte. Quando i parametri sono stati uniti in una transazione, i parametri che seguono questo indirizzo sono stati spostati di un byte. E quando c'era una chiamata dalla macchina virtuale Ethereum a questi parametri, l'EVM aggiungeva implicitamente zero alla fine dei dati della chiamata. Il numero è stato spostato di un byte e tale spostamento è una moltiplicazione per 256. Cioè, l'utente ha rimosso 1 unità di ether quando tutti i controlli di sicurezza sul lato dello scambio erano già stati superati, ma in realtà gli sono state trasferite 256 unità .

Qualcuno dice: "Lo scambio è stato programmato in modo errato". C'è un problema qui nella macchina virtuale Ethereum, perché, a mio avviso, quando si accede a byte al di fuori dei parametri di transazione esistenti, infatti, non dovrebbe esserci una sostituzione implicita di zeri, ma un errore, un'eccezione. Ecco come avviene nella gestione dello spazio degli indirizzi nelle normali applicazioni su un computer.

Ho già parlato di overflow. E dirò ancora che ci sono tipi di dati brevi, ad esempio numeri che occupano 1 byte. Nel caso senza segno, questo è compreso tra 0 e 255 inclusi. È importante evitare di traboccare. A volte si verifica implicitamente, potresti non notarlo. Ad esempio, se si tratta di un parametro di ciclo, sostituisci il tipo con l'utilizzo della parola chiavevar ... Cioè, il tipo verrà selezionato implicitamente come a byte singolo se si inizializza il parametro a zero; quindi, non raggiungerà mai 256; quindi hai potenzialmente un ciclo infinito e un contratto congelato. Non si congelerà, cadrà, ma se il ciclo è da qualche parte in un punto chiave, allora il tuo contratto non andrà da nessuna parte oltre la caduta.

Con aritmetica diversa, possono esserci tipi impliciti di espressioni. Ad esempio, se aumenti qualcosa a una potenza, due numeri di byte e assegni il risultato a un numero grande, senza typecast avrai un risultato in byte e di nuovo si verificherà un overflow.

Bug taglia

Bug bounty - se tradotto letteralmente, questa è l'emissione di ricompense per i bug. La stessa metodologia di valutazione è applicabile qui come la valutazione dell'audit, cioè la valutazione delle vulnerabilità. Individuerei due tipi di programmi di ricompensa dei bug fondamentalmente diversi. Il primo è il cosiddetto bug bounty manuale. Ecco un buon collegamento a come è organizzato questo caso: Aventus Token Sale Bug Bounty . In effetti, questo è un tipo di offerta che offre: "Cerchiamo vulnerabilità in questo e quell'altro codice", vengono stipulate molte condizioni, ad esempio, chi l'ha trovata per primo è un bravo ragazzo. E in generale, vai a vedere, tutto è freddamente descritto lì, quanti soldi sono dovuti per quale vulnerabilità. La meccanica qui è chiara. Esperti di sicurezza, gli hacker ti scrivono che hanno trovato questo e quello. Tu controlli e, in caso affermativo, vengono premiati.

C'è un secondo tipo: bug bounty automatico. È attraente sia per gli hacker che per i clienti. È conveniente qui che non ci siano negoziati, nessuna controversia su che tipo di vulnerabilità sia, quanti soldi ci sono per questo. Nella versione manuale iniziano i dubbi che, si dice, non verrà mai sfruttata in questa forma. Non è qui. Ci sono due scenari qui. Il primo è conveniente per i portafogli, gli archivi di etere, quando l'archivio viene semplicemente distribuito, l'etere viene versato su di esso, quindi dice: "Rompilo, ragazzi". L'unica cosa che può essere aggiunta qui è il commento "Questo è un bug bounty, tutto può e dovrebbe essere rotto e l'aria tolta". Non ne sono sicuro, ma sembrerebbe che così facendo elimini potenziali domande sull'accesso non autorizzato alle informazioni e un articolo criminale di un hacker che hackererà i tuoi interessi. Il secondo scenario di bug bounty automatico è la violazione invariante. I contratti di solito hanno invarianti esplicite o implicite. Ad esempio, i token hanno un numero che indica quanti token ci sono. E questo numero dovrebbe essere uguale alla somma dei saldi dei possessori di token. Oppure, ad esempio, uno storage ether che funziona durante l'ICO, può mantenere la quantità, quanto ether viene raccolto e il saldo del contratto di storage deve essere maggiore o uguale a tale importo. In caso contrario, l'invariante viene violato.

Come è organizzata una tale taglia di bug? C'è un contratto che dà alle parti interessate una nuova copia del contratto con un invariante, e possono in qualche modo giocare con la copia e cercare di violare l'invariante con le loro azioni. Quando viene violato, ricevono automaticamente denaro, sono pagati dal contratto parentale. Questo è conveniente perché tutta questa storia è automatica, e un hacker può ottenere una ricompensa per il suo lavoro in un paio d'ore, e un cliente bug bounty vedrà come è stato violato il suo contratto, lo saprà per certo, perché c'erano 100 etere, ma è diventato 0. Lo vedrà, perché tutto è pubblico in Blockchain. Ed entrambe le parti non hanno bisogno di perdere tempo a discutere.

Distribuisci un contratto

Sviluppato, testato, verificato e bug bounty: ora è il momento di implementare, ovvero mettere contratti sulla blockchain. La distribuzione è automatizzata da Truffle in conformità con i contratti che hai scritto e le connessioni tra di loro, questo è un comando nella console -migrate ... Ci sono punti qui che richiedono attenzione.

Cominciamo con il limite del gas: questo è il limite oltre il quale nessuna transazione può consumare, poiché la transazione deve essere in qualche blocco e il limite non è così grande. Cambia dinamicamente, non accade all'improvviso, e ora il limite è tale che in un contratto non puoi scrivere una matrice di 20 per 20 numeri grandi in una transazione. Non ci sarà abbastanza gas. Anche l'espansione dei contratti, ovvero il lancio di pezzi di codice nella blockchain, costa parecchio gas.

Inoltre, se il tuo contratto crea altri contratti e non li utilizza solo, contiene il loro bytecode e il suo prezzo viene aggiunto al consumo di gas della transazione. Ci siamo imbattuti nel fatto che il sistema dei contratti impone i suoi problemi nella fase di distribuzione, ci sono stati casi in cui non si adattava al blocco e in generale la distribuzione del sistema costava circa 1 etere. Ciò significa che per una distribuzione, prendi e metti 300 dollari. Questo, ovviamente, è risolto: i contratti vengono distribuiti separatamente e quindi collegati. Ma, naturalmente, questo è lavoro extra, problemi extra, vulnerabilità extra. Poiché la distribuzione è costosa, vale la pena distribuirla prima su Testnet: questa è la blockchain di test di Ethereum, per assicurarsi che tutto sia corretto lì. Lì, l'etere non costa quasi nulla, è abbastanza facile ottenerlo, si possono commettere errori ed è meglio prima ripristinare l'intero processo al suo interno.

Abbiamo parlato di gestione di nodi, titolari di contratti, token. I nodi dovrebbero essere preparati in anticipo, avere una blockchain completamente sincronizzata e una certa quantità di ether per i segnali di controllo, cioè per chiamare le transazioni.

Esistono due scenari di distribuzione fondamentalmente diversi. In un caso, gli sviluppatori vengono dal cliente, mostrano: "Ecco, va tutto bene, i test stanno passando. Distribuiamoci". Prendono un nodo, si distribuiscono da esso. C'è un'altra opzione: gli sviluppatori eseguono la distribuzione nel proprio ambiente e trasferiscono i diritti e la proprietà al cliente. Nel primo caso, assicurati in anticipo che il nodo che verrà distribuito abbia abbastanza ether e una blockchain sincronizzata, perché Truffle darà un errore quando si distribuirà su una blockchain non sincronizzata. Nel secondo caso, quando la distribuzione avviene presso gli sviluppatori, ci sono vantaggi per entrambe le parti. Gli sviluppatori usano il loro ambiente, cioè hanno il tartufo corretto, geth e molto altro, e lo fanno in modo rapido e comodo. Per il cliente, il profitto è che gli sviluppatori non hanno accesso fisico ai nodi della rete del cliente. In termini di sicurezza delle informazioni, l'accesso fisico è uno degli scenari peggiori. A sua volta, il trasferimento dei diritti e della proprietà è matematicamente rigorosamente garantito ed è facile per il cliente verificare che tutto sia svolto correttamente.

Durante la distribuzione, in ogni caso, è necessario pensare a come verranno trasferite le informazioni tra i nodi partecipanti alla distribuzione. Ad esempio, indirizzi di contratto o indirizzi multifirma. Gli indirizzi sono tutti grandi, non dovresti nemmeno provare a riscriverli o memorizzarli. Dobbiamo trovare un meccanismo di trasmissione. Ma non c'è niente di sbagliato in questo, sono pubblici. Pubblicalo quanto vuoi. C'è una chiave privata. Nessuno sarà in grado di ottenerlo utilizzando la chiave pubblica nel prossimo futuro.

Come risultato della distribuzione, i proprietari di tutti i contratti dovrebbero essere controllati, che tutto sia corretto, e la connessione dei contratti, che siano collegati nell'ordine giusto, che l'ICO non tenti di lanciare token nel fondo ether, per esempio.

Il cliente dalla sua parte deve imparare questa semplice procedura: aggiungere un contratto incompiuto al suo portafoglio. In fase di aggiunta vengono indicati il ​​suo indirizzo, il nome da ricordare e l'ABI del contratto, che può essere ottenuto previa verifica del contratto, ad esempio su Etherscan. Non è necessario approfondire troppo. È importante copiare, incollare, aggiungere un contratto.

In ogni caso, devi essere in grado di eseguire questa procedura. Non sono esattamente sicuro che il portafoglio conservi informazioni sul contratto o se le perda dopo la chiusura. Ma in ogni caso, devi capire che questa è l'aggiunta di un contratto al portafoglio, non influisce in alcun modo sulla blockchain, accade esclusivamente con te, in locale.

In questo modo potrai leggere comodamente il contratto. L'interfaccia ha la capacità di visualizzare direttamente i campi del contratto, inclusi quelli complessi, ad esempio array, mappature. Inoltre, puoi scrivere su un contratto, cosa di cui devi anche essere in grado, perché questo sta inviando segnali di controllo, questo sta inviando transazioni, ad esempio, a funzioni amministrative.

Supponiamo che tu voglia cambiare il proprietario di un contratto. È piuttosto semplice. Indica da chi e a chi. Indica da quale conto vuoi pagare ether per l'operazione. Ti verrà chiesta la password per questo account, quindi la transazione sarà online.

Se utilizzi la sostituzione di un contratto ICO, non dovresti dimenticare immediatamente di elaborare lo scenario di sostituzione, chi fa cosa, in modo che, ad esempio, i proprietari a cui hai già dato i diritti non abbiano domande in modo che possano aprire e cambiare rapidamente nel loro ufficio. E così nessuno ha cercato freneticamente di capire cosa fare e non ha commesso errori.

Verifica del contratto

Ora parliamo di verifica: che cos'è, perché è necessaria. Abbiamo detto che tutto nella blockchain è pubblico. Anche il bytecode del contratto è pubblico. Tuttavia, ho detto che è gestito da macchine virtuali Ethereum e tu non sei una macchina virtuale Ethereum e, ti dico, questa macchina è di livello piuttosto basso, è stack, di livello inferiore rispetto al set di istruzioni del moderno Intel e processori AMD. Cioè, rispetto al set di istruzioni AMD64, esegue codice molto più complicato, semplicemente perché lì ci sono operazioni piuttosto primitive. Questo è più simile ai processori RISC, il cosiddetto set di istruzioni ridotto. È molto difficile capire dal bytecode del contratto cosa fa. È difficile per me capire cosa fa il contratto, senza il codice sorgente, per un investitore, ancora di più. Questo non significa che puoi scrivere backdoor nei contratti, perché verranno trovati. Non in cinque minuti, ma in cinque giorni, dieci giorni.

Torniamo al problema originale. È necessario chiarire all'investitore cosa fa il contratto. Per questo esiste un meccanismo di verifica: per qualsiasi contratto, chiunque può offrire il suo codice sorgente. Questo meccanismo è disponibile su Etherscan. Prende il codice sorgente, prova a compilarlo, ottiene esattamente la stessa cosa che è nella blockchain. E se è così, allora possiamo presumere che questo sia il vero codice sorgente del contratto. Il tuo codice può essere memorizzato in più file. Devi comporli, inserirli lì sotto forma di un pezzo di codice. Inoltre, è necessario passare gli argomenti del costruttore nella forma boxed man mano che sono stati inviati. Cioè, non è affatto una cosa facile da usare. Ma abilmente si può fare.

Di conseguenza, quando il codice sarà verificato in Etherscan, sarà visibile nella scheda sorgente del contratto. Anticipo la domanda: "Come mai questo Etherscan è l'unico confidente?" posso dire di no. Tutti allo stesso modo possono prendere localmente il codice del contratto, compilarlo, ottenere un binario e confrontarlo con ciò che è nella blockchain, e questo non è molto difficile. Pertanto, la verifica per il contratto è meglio eseguita. Gli investitori vedranno il codice e si assicureranno che esattamente ciò che hai promesso nel white paper stia accadendo sulla blockchain.

Conclusione

Quindi, riassumerò. Prima di lavorare sui contratti, vale la pena considerare la loro struttura e relazione complessive. Nel processo di sviluppo dei contratti, è necessario ricordare non solo le tecniche e i problemi tipici della programmazione, ma anche le specifiche della blockchain. Dovresti assolutamente condurre test automatici approfonditi e audit dei contratti, oltre a controllare il loro codice. Completa tutto questo entro e non oltre 3 giorni prima del lancio. Felice ICO!