So erstellen Sie die einfachste Blockchain in Ruby

In diesem Artikel erfahren Sie, wie Sie mit ** Ruby ** eine einfache Blockchain-Demo erstellen.

Stufe 1: Übertragung

In diesem Stadium werden wir den Kontostand überprüfen und die Überweisung vornehmen. Überweisungen sind Additionen oder Subtraktionen, die basierend auf Ihrem Kontostand durchgeführt werden.

Die HTTP-Protokolle GET und POST sind der beste Weg, um diese Funktion zu implementieren. GET ruft die Daten vom Server ab und POST ändert die Daten auf dem Server.

Hier benötigt die UI-Anzeige kein HTML-Protokoll. Sie können Rubys Webframework Sinatra verwenden, um URLs und verwandte Methoden zu organisieren, und UE verwenden, um Übertragungsinformationen in der Befehlszeile anzuzeigen.

Clientseitige Methoden und serverseitige URLs sind sehr einfach.

Client: client.rb

def create_user(name) … end

  def get_balance(user)  … end

  def transfer(from, to, amount) ... end

Server: hasebcoin.rb

get "/balance" ... end

  post "/users" ... end

  post "/transfers" ... end

Erforderliche Kenntnisse für diese Ebene: Ruby, HTTP GET, POST, Sinatra

Stufe 2: Aufbau eines Klatschnetzwerks

Die Blockchain hat eine dezentrale Struktur, die als "Klatschprotokoll" bezeichnet wird. "Klatsch" ist hier kein Gerücht, sondern Informationen, die in einem verteilten Netzwerk verbreitet werden.

Bauen wir ein Klatschnetzwerk auf, in dem Filmnamen ausgetauscht werden.

client.rb sendet eine Nachricht an den angegebenen Port.

def self.gossip(port, state)
  ...  

  Faraday.post("#{URL}:#{port}/gossip", state: state).body
 
  ...

end

gossip.rb empfängt zwei Parameter: Quellport und Zielport. Tauschen Sie Informationen über bestimmte Quellen auf der Quellseite aus, z. B. über die Ports 1111 und 2222.

In einem realen verteilten Netzwerk sind die beiden Ports im Wesentlichen zwei Netzwerkknoten. Der Informationsaustausch zwischen verschiedenen lokalen Ports repräsentiert die Kommunikation zwischen verschiedenen Knoten im simulierten Netzwerk.

An jedem Knoten Sprechen Sie alle 3 Sekunden den Namen Ihres Lieblingsfilms.

every(3.seconds) do

  …

  gossip_response = Client.gossip(port, JSON.dump(STATE))

  update_state(JSON.load(gossip_response))

  ...

end

Ändern Sie alle 8 Sekunden Ihren Lieblingsfilmnamen.

every(8.seconds) do

  …

  update_state(PORT => [@favorite_movie, @version_number])

  ...

end

Der Server empfängt und verarbeitet die Daten.

post '/gossip' do

  …

  update_state(JSON.load(their_state))

  …

end

In einem Netzwerk von 4 Personen

  1. Führen Sie gossip.rb 1111 auf dem ersten Knoten aus. Der erste Knoten spricht den Namen Ihres Lieblingsfilms an Port 1111. 2, führen Sie gossip.rb 2222 1111 aus. Der zweite Knoten spricht Ihren Lieblingsfilmnamen an Port 2222 mit dem ersten Knoten (Port 1111). 3, führen Sie gossip.rb 3333 2222 aus. Der dritte Knoten spricht Ihren Lieblingsfilmnamen von Port 3333 zum zweiten Knoten (Port 2222). 4, führen Sie gossip.rb 4444 3333 aus. Der vierte Knoten spricht Ihren Lieblingsfilmnamen von Port 4444 zum dritten Knoten (Port 3333).

Nach einer Weile erhalten nur vier Knoten die Peer-End-Informationen und die Daten ändern sich ständig. Dies ist ein einfaches Gossip-Netzwerk.

Stufe 3: Datenverschlüsselung und -entschlüsselung

Verschlüsselungsalgorithmen der obersten Ebene bilden die Grundlage der Blockchain. Auf dieser Ebene wird eine asymmetrische Verschlüsselungstechnologie verwendet, um Blockchain-Konten zu implementieren. Der RSA-Algorithmus kann öffentliche und private Schlüssel generieren und eine asymmetrische Verschlüsselung erzwingen.

def generate_key_pair … end
def sign(plaintext, raw_private_key) ... end

Dank des OpenSSL-Moduls der Ruby-Sprache können Sie schnell eine asymmetrische Verschlüsselung und Signaturüberprüfung implementieren. In der Blockchain ist der öffentliche Schlüssel das Konto und der private Schlüssel das Kennwort. Jedes Schlüsselpaar ist ein Blockchain-Konto.

Entschlüsseln Sie den Code.

def plaintext(ciphertext, raw_public_key) … end

Überprüfen Sie, ob die Verschlüsselung eine Nachricht ist.

def valid_signature?(message, ciphertext, public_key) … end

** Für diese Schicht erforderliche Kenntnisse: Asymmetrischer Verschlüsselungsalgorithmus **

Stufe 4: Data Mining

In dieser Phase wird der Arbeitsnachweis implementiert und Blöcke für die Blockchain generiert. Dies ist ein zeitaufwändiger und langwieriger Prozess. Hash-Funktionen sind irreversibel und es gibt keine Konflikte. Der Berechnungsprozess ist einfach. Sie können das Ergebnis erhalten, indem Sie eine Hash-Operation für die Eingabe ausführen.

Die Eingabe enthält Informationen zur Überweisung, z. B. den Überweisungsbetrag, den Namen des Absenders und den Namen des Empfängers. Es gibt verschiedene Algorithmen für Hash-Operationen.

Hier verwenden wir den SHA256-Algorithmus.

def hash(message) … end

Wenn Sie dieselben Informationen hashen, erhalten Sie jedes Mal unterschiedliche Ergebnisse. Die Berechnung wird fortgesetzt, bis das erhaltene Ergebnis das Merkmal "ausgehend von mehreren Ziffern von 0" erfüllt.

Überprüfen Sie, ob das Ergebnis mit einigen Ziffern von 0 beginnt.

def is_valid_nonce?(nonce, message)

  hash(message + nonce).start_with?("0" * NUM_ZEROES)

end

Es ist nicht einfach, Arbeiten auszuführen, um die oben genannten Bedingungen zu erfüllen. Es kostet viel Zeit. Alle diese Arbeiten werden als Bergbau bezeichnet.

def find_nonce(message)

  …  

  until is_valid_nonce?(nonce, message)

  ...

end

Die Eingabe enthält das Ergebnis der vorherigen Hash-Operation. Daher wird jede Hash-Operation von der vorherigen Hash-Operation beeinflusst. Mit anderen Worten ist dies eine Kettenstruktur. Dies ist der Grund, warum es eine Blockchain genannt wird.

Stufe 5: Regel der längsten Kette

In diesem Stadium wird der erste Block initialisiert, die Blockchain-Struktur entsprechend erzeugt und die Blockchain gebildet. Die Blockchain wird in einer Array-Struktur gespeichert. Während des Speicherns muss der Block validiert werden.

Initialisieren Sie den Block.

def initialize(prev_block, msg)

  @msg = msg

  @prev_block_hash = prev_block.own_hash if prev_block
  
  mine_block!
    
end

Die lohnendste Aufgabe beim Bergbau ist es, Nonce zu finden.

def mine_block!

  @nonce = calc_nonce

  @own_hash = hash(full_block(@nonce))

end

Der gesamte Block wird auf diese Weise komprimiert.

def full_block(nonce)

  [@msg, @prev_block_hash, nonce].compact.join

end

Initialisieren Sie die Blockchain: Klasse BlockChain

Speichern Sie einfach mit Array!

def initialize(msg)
  
  @blocks = []

  @blocks << Block.new(nil, msg)

end

Fügen Sie der Kette Blöcke hinzu. Die gesamte Blockchain wächst kontinuierlich.

def add_to_chain(msg)

  @blocks << Block.new(@blocks.last, msg)

  puts @blocks.last

end

Sie müssen genau überprüfen, ob der Block fehlerfrei ist.

def valid?

  @blocks.all? { |block| block.is_a?(Block) } &&

    @blocks.all?(&:valid?) &&
    
    @blocks.each_cons(2).all? { |a, b| a.own_hash == b.prev_block_hash }
    
end

Stufe 6. Stückkombination

Schließlich wirkt Blockchain magisch durch die harmonische Zusammenarbeit mit allen Komponenten im Netzwerk. In der ersten Phase ist die Übertragung eine Transaktionsklasse, und Sie müssen den privaten Schlüssel verwenden, um die Informationen zu signieren.

@signature = PKI.sign(message, priv_key)

Die Belohnung des Bergmanns für den ersten Block beträgt 500.000 Silbermünzen.

def self.create_genesis_block(pub_key, priv_key)

  genesis_txn = Transaction.new(nil, pub_key, 500_000, priv_key)

  Block.new(nil, genesis_txn)

end

Überprüfen Sie, ob die Ihrem Konto belasteten Ausgaben gültig sind.

def all_spends_valid?

  compute_balances do |balances, from, to|

    return false if balances.values_at(from, to).any? { |bal| bal < 0 }

  end

  true

end

Fügen Sie einen unbekannten Knoten $ PEERS hinzu, um das Netzwerk weiter wachsen zu lassen.

if PEER_PORT.nil?

  # You are the progenitor!

  $BLOCKCHAIN = BlockChain.new(PUB_KEY, PRIV_KEY)

  else

  # You're just joining the network.

  $PEERS << PEER_PORT

end

Die Datenverarbeitung zwischen Knoten lädt und aktualisiert die Blockchain und PEER.

# @param blockchain

# @param peers

post '/gossip' do

  their_blockchain = YAML.load(params['blockchain'])

  their_peers = YAML.load(params['peers'])

  update_blockchain(their_blockchain)

  update_peers(their_peers)  

  YAML.dump('peers' => $PEERS, 'blockchain' => $BLOCKCHAIN)

end

Die Verarbeitung des empfangenen Blocks konzentriert sich darauf, ob die Kette lang ist.

def update_blockchain(their_blockchain)  

  return if their_blockchain.nil?

  return if $BLOCKCHAIN && their_blockchain.length <= $BLOCKCHAIN.length
  
  return unless their_blockchain.valid?  $BLOCKCHAIN = their_blockchain
  
  end

Aktualisieren Sie PEER bis neu.

def update_peers(their_peers)

  $PEERS = ($PEERS + their_peers).uniq

end

Wenn Sie Geld senden, holen Sie sich den pub_key des Empfängers und senden Sie ihn über den pub_key des Absenders.

# @param to (port_number)

# @param amount

post '/send_money' do

  to = Client.get_pub_key(params['to'])

  amount = params['amount'].to_i

  $BLOCKCHAIN.add_to_chain(Transaction.new(PUB_KEY, to, amount, PRIV_KEY))

  'OK. Block mined!'


end

Setzen Sie die Blockchain in das Klatschnetzwerk ein und bauen Sie alle Funktionskomponenten zusammen. Dies ist abgeschlossen. Sie haben erfolgreich eine Blockchain erstellt.

Weitere Informationen zu dieser Demo finden Sie auf Github: [https://github.com/Haseeb-Qureshi/lets-build-a-blockchain](https://github.com/Haseeb-Qureshi/lets- Build-a-Blockchain? spm = a2c65.11461447.0.0.30084c44XBVTHc)

Weitere Informationen zu Blockchain und anderen innovativen Technologien finden Sie unter www.alibabacloud.com.

Recommended Posts

So erstellen Sie die einfachste Blockchain in Ruby
Wie man in Ruby auf unbestimmte Zeit iteriert
So installieren Sie Bootstrap in Ruby
So rufen Sie den Hashwert in einem Array in Ruby ab
So erhalten Sie das Datum mit Java
Wie installiere ich die in Ubuntu verwendete Sprache und wie erstelle ich die Umgebung?
So finden Sie die Ursache des Ruby-Fehlers
Wie man android-midi-lib baut
So debuggen Sie die Verarbeitung im Ruby on Rails-Modell nur mit der Konsole
So erstellen Sie ein ausführbares JAR in Maven
So überprüfen Sie Rails-Befehle im Terminal
So implementieren Sie Paginierung in GraphQL (für Ruby)
Ich möchte den Wert in Ruby erhalten
[Ruby-Grundlagen] Verwendung der Slice-Methode
So beheben Sie Fehler, die beim Integrationstest "Ruby on Rails" auftreten
[Ruby] Verwendung der Standardausgabe bei der bedingten Verzweigung
So stellen Sie die Anzeigezeit in Rails auf japanische Zeit ein
[Java] So lassen Sie den privaten Konstruktor in Lombok weg
[Ruby on Rails] So ändern Sie den Spaltennamen
Organisierte schrittweise Interaktion mit dem JDK
[Ruby On Rails] So setzen Sie die Datenbank in Heroku zurück
So starten Sie einen anderen Befehl in einem Ruby-Programm
So geben Sie den Ressourcenpfad beim HTML-Import an
[Schienen] So zeigen Sie Bilder in der Ansicht an
So beheben Sie den SSL_connect-Fehler im PayPal Ruby SDK
Verwendung von Ruby return
[Ruby] Wie man auskommentiert
Ruby: Wie man Cookies benutzt
Offline-Echtzeit-Schreibweise Implementierungsbeispiel für das Problem in E05 (Ruby, C11)
So erhalten Sie den Namen einer Klasse / Methode, die in Java ausgeführt wird
Verwendung der Getter / Setter-Methode (in Objektorientierung)
So stellen Sie die Chronik ein, wenn sich die Zeit in CentOS7 verschiebt
So verbinden Sie die Zeichenfolgen in der Liste durch Kommas getrennt
So ändern Sie eine Zeichenfolge in einem Array in eine Zahl in Ruby
So erstellen Sie ein Platzhalterteil zur Verwendung in der IN-Klausel
[Mit Backtricks] So stellen Sie React to the simple Rails vor
So zeigen Sie Diagramme in Ruby on Rails an (LazyHighChart)
[Ruby] So rufen Sie den Inhalt des Doppel-Hash ab
So fügen Sie dieselben Indizes in ein verschachteltes Array ein
So leiten Sie den letzten Tag des Monats in Java ab
So wechseln Sie Java in der OpenJDK-Ära auf dem Mac
[Schienen] Anzeigen von Informationen, die in der Datenbank gespeichert sind
Wie man Lombok im Frühling benutzt
So finden Sie May'n in XPath
So blenden Sie die Bildlaufleiste in WebView aus
Verwendung der Methode form_with
So führen Sie JUnit in Eclipse aus
Übergeben Sie das Gebietsschema i18n an JavaScript
Versuchen Sie, Yuma in Ruby zu implementieren