Cosa ci vuole per costruire una blockchain?

La storia dell'umanità è una continua liberazione dalle catene e la creazione di nuove catene, ancora più forti. (Autore anonimo)

Analizzando numerosi progetti blockchain (Bitshares, Hyperledger, Exonum, Ethereum, Bitcoin e altri), capisco che dal punto di vista tecnico sono tutti costruiti secondo principi simili. I blockchain somigliano a case che, nonostante la varietà di strutture, decorazioni e destinazioni, hanno fondamenta, muri, tetti, finestre e porte, che sono collegate tra loro in modi specifici. E se si comprendono i principi fondamentali della progettazione degli edifici e si conoscono le proprietà dei materiali utilizzati, si può determinare lo scopo specifico di una casa. Attualmente, la situazione con il blockchain è che tutti ne hanno sentito parlare, ma pochi capiscono l'architettura e i principi di funzionamento. Pertanto, sorgono incomprensioni su perché e come abbia senso utilizzare le tecnologie blockchain.

In questo articolo esamineremo le proprietà e i principi comuni a tutti i blockchain. Vedremo poi i problemi che possono essere risolti con l'aiuto del blockchain e, per fissare il materiale, costruiremo un piccolo, ma vero blockchain sul nostro sito virtuale!

Dunque, ricordiamo quali problemi ha risolto inizialmente il blockchain.

Sono sicuro che molti parleranno del database distribuito, decentralizzato, pubblico e immutabile. Ma a cosa serviva tutto ciò?

Preferisco iniziare a studiare qualsiasi tecnologia leggendo gli standard, poiché su di essi si basano tutti gli articoli e i libri sull'argomento. Ma attualmente non esistono standard per il blockchain, sono stati creati solo comitati per il loro sviluppo. Attualmente, in ogni progetto blockchain pubblico esiste il proprio documento White paper, che di fatto è un capitolato tecnico. Il primo progetto blockchain di notorietà pubblica è la rete Bitcoin. Andiamo sul sito ufficiale della rete e vediamo da dove è iniziato tutto.

Compito del blockchain

Dunque, il compito che ha risolto il blockchain nella rete pioniera Bitcoin è stata la trasmissione fiduciosa della proprietà degli asset digitali in un ambiente non fidato senza intermediari. Ad esempio, nella rete Bitcoin l'asset digitale è rappresentato dalle monete bitcoin. Tutte le soluzioni tecniche di Bitcoin e degli altri blockchain si riducono a risolvere questo problema.

Problemi che risolve la blockchain

Immaginate che un'organizzazione finanziaria affermi di aver costruito una rete in tutto il mondo, tramite la quale è possibile trasferire denaro a chiunque. Ci credereste? Se l'organizzazione fosse Visa o MasterCard, probabilmente ci credereste; ma se, per esempio, fosse AnonymousWorldMoney, probabilmente no. Perché? Perché sappiamo perfettamente come vengono realizzati i sistemi distribuiti da aziende private, con quali obiettivi e a cosa possono portare. Esaminiamo più nel dettaglio i problemi di tali sistemi e come possono essere risolti mediante tecnologie blockchain.

Supponiamo che nei server di AnonymousWorldMoney siano presenti database e sarebbe meglio se ce ne fossero diversi in vari data center. Quando un mittente trasferisce denaro, la transazione viene registrata e replicata su tutti i server, e i soldi arrivano al destinatario.

Cosa ci vuole per costruire una blockchain?

In un mondo ideale, questo schema funziona perfettamente; nel nostro sorgono invece i seguenti problemi:

  1. Il problema dell'identificazione dei partecipanti da un lato e la necessità di anonimato delle transazioni dall'altro. Cioè, bisogna trasferire denaro a un destinatario specifico in modo che nessuno sappia di questa transazione, eccetto i partecipanti all'affare. Le banche hanno numeri di conto e carte bancarie legati a una persona fisica o giuridica specifica, e il segreto bancario protegge le informazioni sulle transazioni. Ma chi garantisce che l'ipotetica AnonymousWorldMoney non utilizzi i dati personali e le informazioni sulle transazioni per i propri scopi?
  2. Come essere certi che il destinatario abbia ricevuto esattamente l'importo che gli è stato trasferito? Ipoteticamente, il mittente ha trasferito $100, mentre il destinatario ha ricevuto $10. Il mittente si presenta all'ufficio di AnonymousWorldMoney con la propria ricevuta, ma l'impiegato mostra la propria versione, dove è riportato che il mittente ha trasferito solo $10.
  3. Il problema di un ambiente non fidato, ad esempio, la frode nota come double-spending. Un partecipante disonesto potrebbe spendere il proprio saldo più volte, finché il pagamento non viene replicato su tutti i server. Teorema CAP, naturalmente, non è stato annullato, e la coerenza verrà raggiunta alla fine, ma qualcuno non riceverà i soldi per i servizi o i beni forniti. Pertanto, se non c'è fiducia totale nell'organizzazione di pagamento o nei partecipanti all'affare, è necessario costruire una rete basata non sulla fiducia, ma sulla crittografia.
  4. La condizione di AnonymousWorldMoney ha un numero finito di server, che possono diventare non disponibili accidentalmente o per cattive intenzioni.
  5. AnonymousWorldMoney addebiterà una commissione tangibile.
  6. La possibilità di gestione. Durante l’utilizzo di Bitcoin è emerso che le persone desiderano non solo trasferire monete tra di loro, ma anche controllare diverse condizioni per l’elaborazione delle transazioni, programmare scenari di lavoro, eseguire automaticamente azioni in base alle condizioni, ecc.

Come la blockchain risolve questi problemi

  1. L'identificazione dei partecipanti avviene tramite una coppia di chiavi: privata e pubblica, e l'algoritmo della firma digitale identifica in modo univoco il mittente e il destinatario, mantenendo anonime le loro identità.
  2. Le transazioni vengono raccolte in blocchi, si calcola l'hash del blocco, che viene registrato nel blocco successivo. Questa sequenza di registrazione degli hash nei blocchi ha dato il nome alla tecnologia blockchain e rende impossibile la modifica o la cancellazione invisibile di blocchi o singole transazioni dai blocchi. Pertanto, se una transazione entra nella blockchain, si può essere certi che i suoi dati rimarranno immutabili.
  3. La frode del double spending è prevenuta attraverso il raggiungimento di un consenso nella rete su quali dati considerare validi e quali scartare. Nella rete Bitcoin, il consenso viene raggiunto tramite la prova del lavoro PoW (Proof-of-Work).
  4. L'affidabilità del funzionamento della rete è garantita dal fatto che la blockchain è pubblica, dove ogni partecipante può avviare il proprio nodo, ottenere una copia completa della blockchain e, inoltre, iniziare a verificare autonomamente la correttezza delle transazioni. È importante notare che le blockchain moderne consentono di costruire non solo blockchain pubbliche (aperte), ma anche private (chiuse), oltre a utilizzare schemi combinati.
  5. Non si può eliminare completamente la commissione nella blockchain, poiché è necessario pagare le persone che supportano la rete, ma nella blockchain la necessità di una commissione è dimostrata in modo così convincente che non ci sono dubbi sulla sua indispensabilità.
  6. Le blockchain moderne hanno la possibilità di implementare logiche di business, che nella blockchain sono chiamate Smart Contracts. La logica dei contratti intelligenti viene implementata in vari linguaggi di alto livello.

Esaminiamo queste soluzioni più nel dettaglio.

Architettura della blockchain

Componenti della blockchain

Ogni partecipante può avviare il proprio nodo con una copia completa della blockchain (full node). I nodi completi, che possono registrare transazioni nella blockchain, vengono chiamati nodi di consenso (witness) o miner (miner). I nodi completi, che verificano solo la correttezza delle transazioni, vengono chiamati nodi di audit (audit). I client leggeri (light clients) non memorizzano copie complete della blockchain, ma interagiscono con la rete utilizzando nodi completi.
La maggior parte degli utenti per effettuare transazioni utilizza proprio client leggeri o wallet web. Tutti i nodi sono collegati tra loro. Con questo insieme di elementi, l'architettura della rete diventa più resistente:

Cosa ci vuole per costruire una blockchain?

Ciclo di vita delle transazioni

Esaminiamo il ciclo di vita delle transazioni e scomponiamolo in parti:

Cosa ci vuole per costruire una blockchain?

Tecnologie Blockchain

Fermiamoci più in dettaglio sulle soluzioni tecniche e sulle loro interconnessioni.

Identificazione

Ogni transazione blockchain deve essere firmata con una firma digitale. Pertanto, per effettuare una transazione, ogni partecipante deve avere una coppia di chiavi: private / public. A volte la coppia di chiavi è chiamata wallet, poiché le chiavi sono strettamente collegate a un indirizzo digitale unico e al saldo del partecipante. In realtà, le chiavi e gli indirizzi sono semplicemente stringhe di numeri in diversi sistemi di numerazione. Esempi di chiavi e indirizzo del wallet:

Chiave privata: 0a78194a8a893b8baac7c09b6a4a4b4b161b2f80a126cbb79bde231a4567420f
Chiave pubblica: 0579b478952214d7cddac32ac9dc522c821a4489bc10aac3a81b9d1cd7a92e57ba
Indirizzo: 0x3814JnJpGnt5tB2GD1qfKP709W3KbRdfb27V

Per creare una firma digitale nelle blockchain viene utilizzato un algoritmo basato su curve ellittiche: Elliptic Curve Digital Signature Algorithm (ECDSA). Per il suo funzionamento, la chiave privata (un numero a 256 bit) viene solitamente generata casualmente. Il numero di possibili chiavi è pari a 2 elevato alla 256, quindi si può parlare di impossibilità pratica di coincidenza dei valori delle chiavi private.

Successivamente, la chiave pubblica viene ottenuta dalla chiave privata moltiplicando il suo valore per le coordinate di un punto situato sulla curva ellittica, il che produce le coordinate di un nuovo punto sulla stessa curva. Questa operazione garantisce l'ottenimento di una coppia di chiavi adatta per le firme digitali delle transazioni. Infine, l'indirizzo del wallet viene calcolato in modo univoco dalla chiave pubblica.

Ci sono molteplici articoli con dettagli sulla crittografia utilizzata nelle blockchain, ad esempio: Bitcoin in a nutshell — Crittografia

La chiave privata deve rimanere rigorosamente segreta e deve essere conservata in sicurezza. La chiave pubblica è conosciuta da tutti. Se si perde la chiave privata, l'accesso all'asset (monete) non può essere recuperato e i fondi andranno persi per sempre. Pertanto, la questione della conservazione sicura delle chiavi private è estremamente attuale, dato che non è una banca, dove è sempre possibile andare con un documento d'identità e ripristinare il conto. Esiste un'intera industria dedicata alla produzione, dei cosiddetti, portafogli crittografici a freddo, simili a chiavette USB:

Cosa ci vuole per costruire una blockchain?

oppure è possibile utilizzare modi più sicuri, come ad esempio, incidere il valore della chiave privata su gettoni:

Cosa ci vuole per costruire una blockchain?

Transazioni

Maggiori informazioni sulla struttura della transazione possono essere trovate nell'articolo Bitcoin in sintesi — Transazione. È importante capire che ogni transazione contiene almeno i seguenti dati:

Da: 0x48C89c341C5960Ca2Bf3732D6D8a0F4f89Cc4368 - indirizzo digitale del mittente
A: 0x367adb7894334678b90аfe7882a5b06f7fbc783a - indirizzo digitale del destinatario
Valore: 0.0001 - importo della transazione
Hash della transazione: 0x617ede331e8a99f46a363b32b239542bb4006e4fa9a2727a6636ffe3eb095cef - hash della transazione

Successivamente, la transazione viene firmata con la chiave privata e inviata (vedi dettagli sul funzionamento del protocollo Bitcoin in sintesi - Protocollo) a tutti i nodi nella blockchain, che verificano la validità delle transazioni. L'algoritmo di verifica delle transazioni non è banale e comprende una ventina di passaggi.

Blocchi di transazioni

Verificata la validità delle transazioni, i nodi le aggregano in blocchi. Oltre alle transazioni, nel blocco viene registrato l'hash del blocco precedente, un numero (contatore Nonce) e viene calcolato l'hash dell'attuale blocco secondo l'algoritmo SHA-256. L'hash deve soddisfare determinati requisiti di difficoltà. Ad esempio, nella rete Bitcoin la difficoltà dell'hash cambia automaticamente ogni 2 settimane, a seconda della potenza della rete, in modo che un blocco venga generato circa ogni 10 minuti. La difficoltà è definita dalla seguente condizione: l'hash trovato deve essere inferiore a un numero predefinito. Se questa condizione non è soddisfatta, si aggiunge 1 al Nonce e il lavoro di calcolo dell'hash viene ripetuto. Per la ricerca dell'hash viene utilizzato il campo Nonce, poiché sono i soli dati nel blocco che possono essere modificati, mentre gli altri devono rimanere invariati. L'hash corretto deve avere un certo numero di zeri all'inizio, ad esempio, uno degli hash reali:

000000000000000000000bf03212e7dd1176f52f816fa395fc9b93c44bc11f91

La scoperta del hash è una prova del lavoro svolto (Proof-of-Work, PoW) per le reti Bitcoin o Ethereum. Il processo di scoperta degli hash è chiamato mining, in analogia con l'estrazione dell'oro. Il nome descrive accuratamente il processo, poiché comporta semplicemente una ricerca esaustiva di opzioni e, se qualcuno trova l'hash giusto, è davvero una fortuna. È come trovare un vero nugget d'oro tra tonnellate di roccia sterile. La ricompensa per blocco attualmente è di 12.5 BTC e, se moltiplicata per il tasso attuale del bitcoin di $3900, si ottiene più di un chilo d'oro puro. C'è molto per cui lottare!

Dopo il successo nella scoperta dell'hash, il blocco e l'hash trovato vengono registrati nella blockchain come il blocco successivo. Maggiori dettagli sulla struttura dei blocchi possono essere trovati nell'articolo Bitcoin in poche parole - Blockchain, e qui sotto riporterò uno schema semplificato:

Cosa ci vuole per costruire una blockchain?

La blockchain inizia con un blocco che non ha ancora l'hash del blocco precedente. Questo blocco nella blockchain è unico e ha un nome proprio: Genesis block. Gli altri blocchi hanno la stessa struttura e differiscono solo nel numero di transazioni. Le transazioni reali e i blocchi creati attualmente in Bitcoin o Ethereum possono essere visualizzati in Block Explorer.

La dimensione dei blocchi in Bitcoin è limitata a 1 MB e, considerando che il volume minimo di informazioni in una transazione è di circa 200 byte, in un blocco possono esserci circa 6000 transazioni. Da qui, per inciso, deriva la prestazione di Bitcoin, che tutti deridono: un blocco viene generato circa ogni 10 minuti * 60 secondi = 600 secondi, il che dà una prestazione formale di circa 10 TPS. Anche se in realtà non è prestazione, ma un algoritmo di lavoro deliberatamente implementato. In Ethereum, per competere, hanno semplicemente fissato il tempo di generazione del blocco a 15 secondi, e la prestazione è formalmente aumentata. Pertanto, nei blockchain che utilizzano PoW come consenso, è assolutamente senza senso confrontare la prestazione, poiché essa dipende direttamente dalla difficoltà del calcolo dell'hash, che può essere impostata a piacere.

Forks

E cosa succede se, ad esempio, diversi nodi trovano hash che soddisfano i requisiti di complessità, ma sono diversi nel valore (in altre parole, raggiungono diversi consensi) e registrano blocchi nella blockchain? Vediamo come la blockchain si protegge da questa situazione. In questo caso, si verifica un cosiddetto fork ('forchetta'), e la blockchain ha due versioni della catena:

Cosa ci vuole per costruire una blockchain?

Cosa succede dopo? Dopo, una parte della rete inizia a lavorare sul blocco N+2 di una catena, mentre l'altra parte su un'altra:

Cosa ci vuole per costruire una blockchain?

Uno di questi blocchi sarà trovato prima e inviato alla blockchain e allora, secondo le regole, la blockchain dovrà switchare sulla catena più lunga e annullare tutte le transazioni dal blocco alternativo:

Cosa ci vuole per costruire una blockchain?

In questo caso, può verificarsi una situazione in cui la transazione di un partecipante si trovava solo in uno dei blocchi del fork, che è stato annullato. Quindi, per essere certi che la transazione desiderata sia stata registrata nella blockchain, c'è una raccomandazione generale: prima di fidarsi di una transazione, bisogna aspettare che i successivi blocchi vengano aggiunti alla blockchain. Le raccomandazioni su quanti blocchi aspettare variano a seconda delle diverse blockchain. Ad esempio, per la rete Bitcoin, il minimo è 2 blocchi, il massimo 6.

La stessa situazione con il fork dei blocchi si osserverà anche durante la cosiddetta attacco del 51% — quando un gruppo di miner cercherà di creare una catena alternativa di blocchi, cercando di annullare la catena con le proprie transazioni fraudolente. Anche se attualmente, invece di frode, è più vantaggioso spendere le proprie risorse per un mining onesto.

Consensus

Per registrare un blocco nella blockchain, la rete deve arrivare a un consenso. Ricordiamo il compito di raggiungere consenso nelle reti di comunicazione. Il problema è formulato come il problema dei generali bizantini BFT (Byzantine fault tolerance). Tralasciando la descrizione pittoresca dei problemi dell'esercito bizantino, il compito può essere formulato così: come possono i nodi della rete arrivare a un risultato comune, se parte dei nodi della rete possono consapevolmente distorcerlo. Gli algoritmi esistenti per risolvere il problema BFT dimostrano che la rete può funzionare correttamente se i trasgressori sono meno di 1/3. Perché nella rete Bitcoin non è stato applicato il consenso BFT? Perché era necessario utilizzare PoW? Ci sono diverse ragioni:

  • BFT funziona bene con un piccolo set fisso di nodi, mentre nel blockchain pubblico il numero di nodi è imprevedibile e, inoltre, i nodi possono accendersi e spegnersi a piacimento.
  • È necessario motivare le persone a far partire i nodi blockchain. Per questo motivo, le persone devono ricevere una ricompensa. In BFT non c'è formalmente nulla per cui ricevere una ricompensa, mentre in PoW è chiaro a livello intuitivo per cosa viene data la ricompensa: per l'elettricità consumata dalla CPU durante la ricerca dell'hash del blocco.

Oltre a PoW, ci sono diversi altri protocolli di consenso utilizzati nei blockchain moderni, ad esempio:

  • PoS (Proof-of-Stake) — nel blockchain Hyperledger
  • DPoS (Delegated Proof-of-Stake) — nel blockchain BitShares
  • Modifiche di BFT: SBFT (Simplified BFT) e PBFT (Practical BFT), ad esempio, nel blockchain Exonum

Fermiamoci un attimo sul consenso PoS, poiché PoS e le sue varianti hanno avuto la maggiore diffusione nei blockchain privati. Perché proprio nei privati? Da un lato, le caratteristiche di PoS sono migliori rispetto a PoW, poiché per raggiungere il consenso sono necessarie minori risorse di calcolo, il che aumenta la velocità di registrazione dei dati nel blockchain. Ma dall'altro lato, in PoS ci sono più opportunità per frodi, quindi per neutralizzare questo, tutti i partecipanti al blockchain devono essere noti.

Il consenso PoS si basa sulla selezione di un nodo che può registrare un blocco con transazioni nel blockchain in base alla quantità di fondi sul conto, per essere più precisi, non sul conto, ma in garanzia. Cioè, più fondi hai in garanzia, maggiore è la probabilità che la rete selezioni il tuo nodo per registrare il blocco. La garanzia non verrà restituita se il blocco risulta non valido. In questo modo si realizza una protezione contro le frodi. Ci sono le seguenti variazioni di PoS:

  • Il consenso Delegated PoS (DPoS) divide i partecipanti in "votanti" e "validatori". I detentori di monete (partecipanti votanti) delegano il loro diritto di controllare e registrare transazioni nel blockchain ad altri partecipanti. In questo modo, i validatori svolgono tutto il lavoro di calcolo e ricevono una ricompensa per questo, mentre la presenza di partecipanti votanti garantisce l'onestà dei validatori, poiché possono essere sostituiti in qualsiasi momento.
  • Il consenso LPoS (Leased Proof-of-Stake) consente di affittare i propri fondi ad altri nodi, aumentando così le probabilità di verifica dei blocchi. In questo modo, è possibile guadagnare commissioni sulle transazioni senza partecipare direttamente alla verifica delle transazioni e al mining dei blocchi.

Esistono altri consensi che non hanno ancora acquisito ampia diffusione; qui li elenco semplicemente a scopo informativo, mentre una panoramica degli algoritmi di consenso stessi può essere consultata, ad esempio, nell'articolo: Algoritmi di Consenso nel Blockchain.

  • PoET (Proof-of-Elapsed Time)
  • PoC (Proof-of-Capacity)
  • PoB (Proof-of-Burn)
  • PoWeight (Proof-of-Weight)
  • PoA (Proof-of-Activity) — PoW + PoS
  • PoI (Proof-of-Importance)

Affidabilità e modelli di distribuzione dei blockchain

Blockchain pubblica

Resilienza Pubblico o altro nome Blockchain senza permesso si ottiene consentendo a chiunque di connettersi e visualizzare informazioni o persino connettere il proprio nodo, mentre la fiducia si basa sul consenso PoW.

Blockchain privata

Privato o Blockchain privata autorizzata. In queste blockchain solo un gruppo specifico di partecipanti (organizzazioni o persone) ha accesso alle informazioni. Tali blockchain vengono costruite da organizzazioni per aumentare il beneficio o l'efficienza complessivi. La loro affidabilità è garantita da obiettivi comuni dei partecipanti e dagli algoritmi di consenso PoS e BFT.

Consorzio blockchain

Esistono Consortium o Blockchain pubblica autorizzata. Queste sono blockchain a cui chiunque può collegarsi per visualizzarle, ma aggiungere informazioni o connettere il proprio nodo può avvenire solo con il permesso di altri partecipanti. Tali blockchain vengono costruite da organizzazioni per aumentare la fiducia da parte di clienti o consumatori di prodotti o della società in generale. Qui l'affidabilità è raggiunta anche dalla presenza della fiducia tra i partecipanti e dagli stessi algoritmi di consenso PoS e BFT.

Smart Contracts

Nelle blockchain realizzate dopo Bitcoin, è stata aggiunta la possibilità di eseguire smart contracts. In sostanza, uno smart contract è una transazione che contiene codice sorgente per l'esecuzione. Gli smart contract sulla rete Ethereum vengono eseguiti nell'EVM (Ethereum Virtual Machine). Per iniziare l'esecuzione di uno smart contract, è necessario avviarlo esplicitamente con un'altra transazione, oppure devono essere soddisfatte le condizioni preliminari per l'esecuzione. I risultati dell'esecuzione degli smart contract verranno anch'essi registrati nella blockchain. È possibile ottenere dati dall'esterno della blockchain, ma è estremamente limitato.

Quale logica di business può essere implementata utilizzando un contratto intelligente? In realtà non è così tanto, ad esempio la verifica delle condizioni basate su dati della blockchain, la modifica dei proprietari di beni digitali in base a queste condizioni, la registrazione dei dati in uno storage permanente all'interno della blockchain. La logica è implementata in un linguaggio di alto livello speciale, Solidity.

Un classico esempio di funzionalità che viene implementata utilizzando contratti intelligenti è l'emissione di token per condurre un ICO. Ad esempio, ho implementato un contratto intelligente per l'emissione di un modesto 500.000.000 AlexToken. A il link su Etherscan si trova

il codice sorgente del contratto intelligente in linguaggio Solidity

pragma solidity ^0.4.23;

library SafeMath {
    /**
     * @dev Multiplies two numbers, throws on overflow.
     **/
    function mul(uint256 a, uint256 b) internal pure returns (uint256 c) {
        if (a == 0) {
            return 0;
        }
        c = a * b;
        assert(c / a == b);
        return c;
    }
    
    /**
     * @dev Integer division of two numbers, truncating the quotient.
     **/
    function div(uint256 a, uint256 b) internal pure returns (uint256) {
        // assert(b > 0); // Solidity automatically throws when dividing by 0
/**
 * @title SafeMath
 * @dev Math operations with safety checks that throw on error
 */
        // uint256 c = a / b;
        // assert(a == b * c + a % b); // There is no case in which this doesn't hold
        return a / b;
    }
    
    /**
     * @dev Subtracts two numbers, throws on overflow (i.e. if subtrahend is greater than minuend).
     **/
    function sub(uint256 a, uint256 b) internal pure returns (uint256) {
        assert(b <= a);
        return a - b;
    }
    
    /**
     * @dev Adds two numbers, throws on overflow.
     **/
    function add(uint256 a, uint256 b) internal pure returns (uint256 c) {
        c = a + b;
        assert(c >= a);
        return c;
    }
}

/**
 * @title Ownable
 * @dev The Ownable contract has an owner address, and provides basic authorization control
 * functions, this simplifies the implementation of "user permissions".
 **/
 
contract Ownable {
    address public owner;
    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

    /**
     * @dev The Ownable constructor sets the original `owner` of the contract to the sender account.
     **/
   constructor() public {
      owner = msg.sender;
    }
    
    /**
     * @dev Throws if called by any account other than the owner.
     **/
    modifier onlyOwner() {
      require(msg.sender == owner);
      _;
    }
    
    /**
     * @dev Allows the current owner to transfer control of the contract to a newOwner.
     * @param newOwner The address to transfer ownership to.
     **/
    function transferOwnership(address newOwner) public onlyOwner {
      require(newOwner != address(0));
      emit OwnershipTransferred(owner, newOwner);
      owner = newOwner;
    }
}

/**
 * @title ERC20Basic interface
 * @dev Basic ERC20 interface
 **/
contract ERC20Basic {
    function totalSupply() public view returns (uint256);
    function balanceOf(address who) public view returns (uint256);
    function transfer(address to, uint256 value) public returns (bool);
    event Transfer(address indexed from, address indexed to, uint256 value);
}

/**
 * @title ERC20 interface
 * @dev see https://github.com/ethereum/EIPs/issues/20
 **/
contract ERC20 is ERC20Basic {
    function allowance(address owner, address spender) public view returns (uint256);
    function transferFrom(address from, address to, uint256 value) public returns (bool);
    function approve(address spender, uint256 value) public returns (bool);
    event Approval(address indexed owner, address indexed spender, uint256 value);
}

/**
 * @title Basic token
 * @dev Basic version of StandardToken, with no allowances.
 **/
contract BasicToken is ERC20Basic {
    using SafeMath for uint256;
    mapping(address => uint256) balances;
    uint256 totalSupply_;
    
    /**
     * @dev total number of tokens in existence
     **/
    function totalSupply() public view returns (uint256) {
        return totalSupply_;
    }
    
    /**
     * @dev transfer token for a specified address
     * @param _to The address to transfer to.
     * @param _value The amount to be transferred.
     **/
    function transfer(address _to, uint256 _value) public returns (bool) {
        require(_to != address(0));
        require(_value <= balances[msg.sender]);
        
        balances[msg.sender] = balances[msg.sender].sub(_value);
        balances[_to] = balances[_to].add(_value);
        emit Transfer(msg.sender, _to, _value);
        return true;
    }
    
    /**
     * @dev Gets the balance of the specified address.
     * @param _owner The address to query the the balance of.
     * @return An uint256 representing the amount owned by the passed address.
     **/
    function balanceOf(address _owner) public view returns (uint256) {
        return balances[_owner];
    }
}

contract StandardToken is ERC20, BasicToken {
    mapping (address => mapping (address => uint256)) internal allowed;
    /**
     * @dev Transfer tokens from one address to another
     * @param _from address The address which you want to send tokens from
     * @param _to address The address which you want to transfer to
     * @param _value uint256 the amount of tokens to be transferred
     **/
    function transferFrom(address _from, address _to, uint256 _value) public returns (bool) {
        require(_to != address(0));
        require(_value <= balances[_from]);
        require(_value <= allowed[_from][msg.sender]);
    
        balances[_from] = balances[_from].sub(_value);
        balances[_to] = balances[_to].add(_value);
        allowed[_from][msg.sender] = allowed[_from][msg.sender].sub(_value);
        
        emit Transfer(_from, _to, _value);
        return true;
    }
    
    /**
     * @dev Approve the passed address to spend the specified amount of tokens on behalf of msg.sender.
     *
     * Beware that changing an allowance with this method brings the risk that someone may use both the old
     * and the new allowance by unfortunate transaction ordering. One possible solution to mitigate this
     * race condition is to first reduce the spender's allowance to 0 and set the desired value afterwards:
     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
     * @param _spender The address which will spend the funds.
     * @param _value The amount of tokens to be spent.
     **/
    function approve(address _spender, uint256 _value) public returns (bool) {
        allowed[msg.sender][_spender] = _value;
        emit Approval(msg.sender, _spender, _value);
        return true;
    }
    
    /**
     * @dev Function to check the amount of tokens that an owner allowed to a spender.
     * @param _owner address The address which owns the funds.
     * @param _spender address The address which will spend the funds.
     * @return A uint256 specifying the amount of tokens still available for the spender.
     **/
    function allowance(address _owner, address _spender) public view returns (uint256) {
        return allowed[_owner][_spender];
    }
    
    /**
     * @dev Increase the amount of tokens that an owner allowed to a spender.
     *
     * approve should be called when allowed[_spender] == 0. To increment
     * allowed value is better to use this function to avoid 2 calls (and wait until
     * the first transaction is mined)
     * From MonolithDAO Token.sol
     * @param _spender The address which will spend the funds.
     * @param _addedValue The amount of tokens to increase the allowance by.
     **/
    function increaseApproval(address _spender, uint _addedValue) public returns (bool) {
        allowed[msg.sender][_spender] = allowed[msg.sender][_spender].add(_addedValue);
        emit Approval(msg.sender, _spender, allowed[msg.sender][_spender]);
        return true;
    }
    
    /**
     * @dev Decrease the amount of tokens that an owner allowed to a spender.
     *
     * approve should be called when allowed[_spender] == 0. To decrement
     * allowed value is better to use this function to avoid 2 calls (and wait until
     * the first transaction is mined)
     * From MonolithDAO Token.sol
     * @param _spender The address which will spend the funds.
     * @param _subtractedValue The amount of tokens to decrease the allowance by.
     **/
    function decreaseApproval(address _spender, uint _subtractedValue) public returns (bool) {
        uint oldValue = allowed[msg.sender][_spender];
        if (_subtractedValue > oldValue) {
            allowed[msg.sender][_spender] = 0;
        } else {
            allowed[msg.sender][_spender] = oldValue.sub(_subtractedValue);
        }
        emit Approval(msg.sender, _spender, allowed[msg.sender][_spender]);
        return true;
    }
}

/**
 * @title Configurable
 * @dev Configurable varriables of the contract
 **/
contract Configurable {
    uint256 public constant cap = 1000000000*10**18;
    uint256 public constant basePrice = 100*10**18; // tokens per 1 ether
    uint256 public tokensSold = 0;
    
    uint256 public constant tokenReserve = 500000000*10**18;
    uint256 public remainingTokens = 0;
}

/**
 * @title CrowdsaleToken 
 * @dev Contract to preform crowd sale with token
 **/
contract CrowdsaleToken is StandardToken, Configurable, Ownable {
    /**
     * @dev enum of current crowd sale state
     **/
     enum Stages {
        none,
        icoStart, 
        icoEnd
    }
    
    Stages currentStage;
    /**
     * @dev constructor of CrowdsaleToken
     **/
    constructor() public {
        currentStage = Stages.none;
        balances[owner] = balances[owner].add(tokenReserve);
        totalSupply_ = totalSupply_.add(tokenReserve);
        remainingTokens = cap;
        emit Transfer(address(this), owner, tokenReserve);
    }
    
    /**
     * @dev fallback function to send ether to for Crowd sale
     **/
    function () public payable {
        require(currentStage == Stages.icoStart);
        require(msg.value > 0);
        require(remainingTokens > 0);
        
        uint256 weiAmount = msg.value; // Calculate tokens to sell
        uint256 tokens = weiAmount.mul(basePrice).div(1 ether);
        uint256 returnWei = 0;
        
        if(tokensSold.add(tokens) > cap){
            uint256 newTokens = cap.sub(tokensSold);
            uint256 newWei = newTokens.div(basePrice).mul(1 ether);
            returnWei = weiAmount.sub(newWei);
            weiAmount = newWei;
            tokens = newTokens;
        }
        
        tokensSold = tokensSold.add(tokens); // Increment raised amount
        remainingTokens = cap.sub(tokensSold);
        if(returnWei > 0){
            msg.sender.transfer(returnWei);
            emit Transfer(address(this), msg.sender, returnWei);
        }
        
        balances[msg.sender] = balances[msg.sender].add(tokens);
        emit Transfer(address(this), msg.sender, tokens);
        totalSupply_ = totalSupply_.add(tokens);
        owner.transfer(weiAmount);// Send money to owner
    }
    

    /**
     * @dev startIco starts the public ICO
     **/
    function startIco() public onlyOwner {
        require(currentStage != Stages.icoEnd);
        currentStage = Stages.icoStart;
    }
    

    /**
     * @dev endIco closes down the ICO 
     **/
    function endIco() internal {
        currentStage = Stages.icoEnd;
        // Transfer any remaining tokens
        if(remainingTokens > 0)
            balances[owner] = balances[owner].add(remainingTokens);
        // transfer any remaining ETH balance in the contract to the owner
        owner.transfer(address(this).balance); 
    }

    /**
     * @dev finalizeIco closes down the ICO and sets needed varriables
     **/
    function finalizeIco() public onlyOwner {
        require(currentStage != Stages.icoEnd);
        endIco();
    }
    
}
 
/**
 * @title LavevelToken 
 * @dev Contract to create the Lavevel Token
 **/
contract AlexToken is CrowdsaleToken {
    string public constant name = "AlexToken";
    string public constant symbol = "ALT";
    uint32 public constant decimals = 18;
}

e la rappresentazione binaria, come la vede la rete

60806040526000600355600060045533600560006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000600560146101000a81548160ff021916908360028111156200006f57fe5b0217905550620001036b019d971e4fe8401e74000000600080600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546200024a6401000000000262000b1d179091906401000000009004565b600080600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef6b019d971e4fe8401e740000006040518082815260200191505060405180910390a362000267565b600081830190508281101515156200025e57fe5b80905092915050565b611cb880620002776000396000f300608060405260043610610112576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806306fdde03146104c7578063095ea7b31461055757806318160ddd146105bc57806323b872dd146105e7578063313ce5671461066c578063355274ea146106a3578063518ab2a8146106ce57806366188463146106f957806370a082311461075e57806389311e6f146107b55780638da5cb5b146107cc578063903a3ef61461082357806395d89b411461083a578063a9059cbb146108ca578063bf5839031461092f578063c7876ea41461095a578063cbcb317114610985578063d73dd623146109b0578063dd62ed3e14610a15578063f2fde38b14610a8c575b60008060008060006001600281111561012757fe5b600560149054906101000a900460ff16600281111561014257fe5b14151561014e57600080fd5b60003411151561015d57600080fd5b600060045411151561016e57600080fd5b3494506101a7670de0b6b3a764000061019968056bc75e2d6310000088610acf90919063ffffffff16565b610b0790919063ffffffff16565b9350600092506b033b2e3c9fd0803ce80000006101cf85600354610b1d90919063ffffffff16565b111561024c576101f66003546b033b2e3c9fd0803ce8000000610b3990919063ffffffff16565b915061022e670de0b6b3a764000061022068056bc75e2d6310000085610b0790919063ffffffff16565b610acf90919063ffffffff16565b90506102438186610b3990919063ffffffff16565b92508094508193505b61026184600354610b1d90919063ffffffff16565b6003819055506102886003546b033b2e3c9fd0803ce8000000610b3990919063ffffffff16565b6004819055506000831115610344573373ffffffffffffffffffffffffffffffffffffffff166108fc849081150290604051600060405180830381858888f193505050501580156102dd573d6000803e3d6000fd5b503373ffffffffffffffffffffffffffffffffffffffff163073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef856040518082815260200191505060405180910390a35b610395846000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054610b1d90919063ffffffff16565b6000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055503373ffffffffffffffffffffffffffffffffffffffff163073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef866040518082815260200191505060405180910390a361045184600154610b1d90919063ffffffff16565b600181905550600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166108fc869081150290604051600060405180830381858888f193505050501580156104bf573d6000803e3d6000fd5b505050505050005b3480156104d357600080fd5b506104dc610b52565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561051c578082015181840152602081019050610501565b50505050905090810190601f1680156105495780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561056357600080fd5b506105a2600480360381019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610b8b565b604051808215151515815260200191505060405180910390f35b3480156105c857600080fd5b506105d1610c7d565b6040518082815260200191505060405180910390f35b3480156105f357600080fd5b50610652600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610c87565b604051808215151515815260200191505060405180910390f35b34801561067857600080fd5b50610681611041565b604051808263ffffffff1663ffffffff16815260200191505060405180910390f35b3480156106af57600080fd5b506106b8611046565b6040518082815260200191505060405180910390f35b3480156106da57600080fd5b506106e3611056565b6040518082815260200191505060405180910390f35b34801561070557600080fd5b50610744600480360381019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919050505061105c565b604051808215151515815260200191505060405180910390f35b34801561076a57600080fd5b5061079f600480360381019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506112ed565b6040518082815260200191505060405180910390f35b3480156107c157600080fd5b506107ca611335565b005b3480156107d857600080fd5b506107e16113eb565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561082f57600080fd5b50610838611411565b005b34801561084657600080fd5b5061084f6114ab565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561088f578082015181840152602081019050610874565b50505050905090810190601f1680156108bc5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156108d657600080fd5b50610915600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506114e4565b604051808215151515815260200191505060405180910390f35b34801561093b57600080fd5b50610944611703565b6040518082815260200191505060405180910390f35b34801561096657600080fd5b5061096f611709565b6040518082815260200191505060405180910390f35b34801561099157600080fd5b5061099a611716565b6040518082815260200191505060405180910390f35b3480156109bc57600080fd5b506109fb600480360381019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050611726565b604051808215151515815260200191505060405180910390f35b348015610a2157600080fd5b50610a76600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611922565b6040518082815260200191505060405180910390f35b348015610a9857600080fd5b50610acd600480360381019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506119a9565b005b600080831415610ae25760009050610b01565b8183029050818382811515610af357fe5b04141515610afd57fe5b8090505b92915050565b60008183811515610b1457fe5b04905092915050565b60008183019050828110151515610b3057fe5b80905092915050565b6000828211151515610b4757fe5b818303905092915050565b6040805190810160405280600981526020017f416c6578546f6b656e000000000000000000000000000000000000000000000081525081565b600081600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925846040518082815260200191505060405180910390a36001905092915050565b6000600154905090565b60008073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614151515610cc457600080fd5b6000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020548211151515610d1157600080fd5b600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020548211151515610d9c57600080fd5b610ded826000808773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054610b3990919063ffffffff16565b6000808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550610e80826000808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054610b1d90919063ffffffff16565b6000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550610f5182600260008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054610b3990919063ffffffff16565b600260008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a3600190509392505050565b601281565b6b033b2e3c9fd0803ce800000081565b60035481565b600080600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205490508083111561116d576000600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550611201565b6111808382610b3990919063ffffffff16565b600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055505b8373ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546040518082815260200191505060405180910390a36001905092915050565b6000600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515611a0557600080fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614151515611a4157600080fd5b8073ffffffffffffffffffffffffffffffffffffffff16600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a380600560006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6002600560146101000a81548160ff02191690836002811115611b2057fe5b021790555060006004541115611c0a57611ba5600454600080600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054610b1d90919063ffffffff16565b600080600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055505b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166108fc3073ffffffffffffffffffffffffffffffffffffffff16319081150290604051600060405180830381858888f19350505050158015611c89573d6000803e3d6000fd5b505600a165627a7a723058205bbef016cc7699572f944871cb6f05e69915ada3a92a1d9f03a3fb434aac0c2b0029

Maggiori dettagli sui contratti intelligenti possono essere trovati nell'articolo: Cosa sono i contratti intelligenti su Ethereum.

Conclusione

Abbiamo elencato le tecnologie su cui sono basate le moderne blockchain e come sono collegate tra loro. Ora formuliamo quali problemi possono essere risolti con la blockchain e quali soluzioni, nella migliore delle ipotesi, saranno inefficaci. Quindi, l'uso della blockchain non è necessario se:

  • Le transazioni avvengono in un ambiente fidato;
  • La presenza di commissioni di intermediari non peggiora la vita dei partecipanti;
  • I partecipanti non hanno proprietà che possono essere rappresentate come attivi digitali;
  • Non c'è distribuzione negli attivi digitali, cioè solo un partecipante possiede o fornisce valore.

Quale futuro attende la blockchain? Al momento possiamo solo ipotizzare i possibili sviluppi delle tecnologie blockchain:

  • La blockchain diventerà una tecnologia di database comune, come SQL o NoSQL, per risolvere un certo insieme di problemi;
  • La blockchain diventerà un protocollo ampiamente utilizzato, come HTTP per Internet;
  • La blockchain diventerà la base per un nuovo sistema finanziario e politico del pianeta!

Nella prossima parte vedremo quali blockchain esistono attualmente e per quali scopi vengono utilizzate in diverse industrie.

Questo è solo l'inizio!

Fonte: habr.com

Acquista hosting affidabile per siti web con protezione DDoS, VPS VDS server 🔥 Acquista hosting affidabile per siti web con protezione DDoS, VPS VDS server | ProHoster