Unabhängige Implementierung (Existenznachweis) in 2 Schritten

Hallo allerseits! Mein Name ist Ararat und ich arbeite für QuantNet, das Wettbewerbe für algorithmische Strategien veranstaltet. Vor kurzem hat sich vor mir eine wichtige Aufgabe gestellt - Garantien für die Unverletzlichkeit der Benutzerdaten zu geben (dies ist äußerst wichtig, da zur korrekten Überprüfung der Wirksamkeit von Strategien Daten von den globalen Finanzmärkten in Echtzeit verwendet werden müssen).

Dort bin ich auf das Konzept von PoE (Proof of Existence) gestoßen. Im Internet wurde genug darüber geschrieben, aber die Besonderheiten der Plattform haben mich dazu gebracht, meine Meinung ein wenig zu brechen. Aus diesem Grund habe ich beschlossen, diesen Artikel zu schreiben und meine Erfahrungen mit der Architektur und Implementierung von PoE zu teilen. Ich denke, es wird besonders für Fintech-Leute relevant sein.

Ich habe meinen Artikel in 3 Hauptblöcke unterteilt:

  • Was ist PoE und wann kann es benötigt werden?
  • Implementierungsalgorithmus
  • Die Lösung für meinen speziellen Fall

Was ist also ein Existenznachweis?


Der Existenznachweis (wörtlich: Existenznachweis) hilft zu beweisen, dass ein Dokument, eine Datei oder Daten zu einem bestimmten Datum und einer bestimmten Uhrzeit erstellt wurden. Die größte Anmeldung ist die Patentanmeldung. Aber nach dem, was ich gesehen habe, wird es meistens in Bereichen an der Schnittstelle von Finanzen und IT angewendet.

Ein Beispiel aus meinem Bereich des algorithmischen Handels: Sie haben einen Algorithmus, der ungefähr 70% der korrekten Prognosen für Aktien für die nächsten 2 Wochen liefert. Sie beschließen, Ihre Prognosen an andere Marktteilnehmer zu verkaufen. Der Punkt ist klein - um den Käufer davon zu überzeugen, dass Ihre Prognosen korrekt sind und vor den Gebotsergebnissen erstellt wurden, d. H. garantieren ihre Umsetzung zu einem bestimmten Zeitpunkt.

Wie kann dies garantiert werden? Richtig, implementieren Sie PoE.

PoE-Implementierungsalgorithmus


Zuerst brauchen Sie:

  1. Bereiten Sie die Datei vor, die Sie patentieren möchten. (Ich habe das PDF gemacht, aber Sie können jeden anderen Container verwenden).
  2. Holen Sie sich den Hash der angegebenen Datei (ich habe das sha256-Format verwendet).

Nur für den Fall, dass ein Hash ein einzelner „Fingerabdruck“ einer Datei ist, der (fast vollständig) garantiert, dass keine Übereinstimmung mit dem Hash einer anderen Datei besteht. Wenn Sie den Hash aus der Datei erhalten, müssen Sie nur eine Transaktion im Blockchain-Netzwerk generieren, die den Hash des Dokuments im Hauptteil der Transaktion angibt.

Das ist alles. Mit dem Prolog fertig. Nun kommen wir zu den interessantesten.

(Zur besseren Übersicht habe ich einen speziellen Code erstellt (nur zur Demonstration). Das Demo-Beispiel des Dienstes finden Sie hier .)

Schauen wir uns die Funktionsweise der Demo genauer an.

Ich schlage vor, die Implementierung in zwei Teile zu unterteilen:

  1. Vorbereitung eines intelligenten Vertrags und einer Ätherbrieftasche.
  2. Transaktionsgenerierung in Node.js Code und privatem Schlüssel.

Lass uns in der richtigen Reihenfolge gehen:

Teil 1: Vorbereiten eines intelligenten Vertrags und einer Brieftasche von Ethereum

PoE selbst wurde zuerst mit der Bitcoin-Blockchain assoziiert. Aber ich habe die Ether Blockchain und Smart Contracts für die Implementierung ausgewählt. Intelligente Verträge bieten uns in Zukunft Flexibilität, Modularität und Skalierbarkeit und dienen als Speicher für Hashes in der Blockchain.

Ich habe einen einfachen Smart-Vertrag gewählt, der einen Hash mit einem geeigneten Datum, dem Format Hash => Datum, akzeptieren kann. Es wäre auch super, eine Methode zu haben, die das Hash-Datum beim Aufruf zurückgibt. Außerdem wäre es schön, darauf zu achten, dass nur der Vertragsinhaber neue Hashes hinzufügen konnte.

Smart Contract Code:

``` pragma solidity 0.5.9; /** * @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 private _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 () internal { _owner = msg.sender; emit OwnershipTransferred(address(0), _owner); } /** * @return the address of the owner. */ function owner() public view returns (address) { return _owner; } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { require(isOwner()); _; } /** * @return true if `msg.sender` is the owner of the contract. */ function isOwner() public view returns (bool) { return 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 { _transferOwnership(newOwner); } /** * @dev Transfers control of the contract to a newOwner. * @param newOwner The address to transfer ownership to. */ function _transferOwnership(address newOwner) internal { require(newOwner != address(0)); emit OwnershipTransferred(_owner, newOwner); _owner = newOwner; } } /** * @title HashStore * @dev The contract store the hashes and returns date by hash * Only the owner can add new hashes */ contract HashStore is Ownable { mapping(bytes32 => uint256) private _hashes; event HashAdded(bytes32 hash); function addHash(bytes32 rootHash) external onlyOwner { require(_hashes[rootHash] == 0, "addHash: this hash was already deployed"); _hashes[rootHash] = block.timestamp; emit HashAdded(rootHash); } function getHashTimestamp(bytes32 rootHash) external view returns (uint256) { return _hashes[rootHash]; } } ``` 

Wie Sie bereits bemerkt haben, haben wir zwei separate Verträge verwendet: Ownable und HashStore.
Der HashStore-Vertrag ist für die Speicherung von Hashes und die Ausgabe des Hash-Datums auf Anfrage verantwortlich. Der Ownable-Vertrag ist dafür verantwortlich, zu überprüfen, ob der neue Hash ausschließlich vom Vertragseigentümer hinzugefügt wurde.

Um einen Hash hinzuzufügen, müssen Sie die addHash-Methode aufrufen und den Wert sha256 als Argument an unsere Datei übergeben. Wenn die Hashes im Vertrag übereinstimmen, wird die Transaktion abgelehnt. Dies filtert unerwünschte Duplikate von Werten mit unterschiedlichen Daten. Es wird hier überprüft:

 require(_hashes[rootHash] == 0, "addHash: this hash was already deployed"); 

Wir können das Hash-Transaktionsdatum mit der Methode getHashTimestamp abrufen und den Hash mit dem gewünschten Transaktionsdatum als Argument übergeben. Die Methode getHashTimestamp gibt die Zeit im UNIX-Format zurück. Sie können in ein besser lesbares Format übersetzen.

Also haben wir den Vertrag herausgefunden, jetzt müssen Sie ihn im Netzwerk bereitstellen. Dazu brauchen wir zwei Dinge:

  1. Ätheradresse für die Interaktion mit der Blockchain
  2. etwas Äther zum Aufrufen von Methoden und zum Bereitstellen von Verträgen.

Um bei Tests keinen Äther zu verschwenden, können wir das Ropsten-Testnetzwerk verwenden. Erfahren Sie hier mehr. Diese Adresse ist der Eigentümer des Vertrags, da sie der Initiator der Bereitstellung war und möglicherweise in Zukunft neue Hashes hinzufügt. Danach müssen Sie diese Adresse sowie den privaten Schlüssel Ihrer Brieftasche und die Adresse des Vertrags an einem sicheren Ort aufbewahren. Das werden wir alle in Zukunft brauchen.

Teil 2: Transaktionsgenerierung in Node.js und Private Key

Zu diesem Zeitpunkt haben wir also bereits eine Ether-Brieftasche, ihren geheimen Schlüssel, einen Vertrag im Testnetzwerk und einen Daten-Hash. Die Interaktion mit der Blockchain muss noch konfiguriert werden.

Dazu verwenden wir die Bibliothek web3.js und erstellen ein Token für unseren Knoten. Ich habe meine mit dem Dienst infura.io erstellt und es sieht ungefähr so ​​aus:

 ropsten.infura.io/v3/YOUR_TOKEN_HERE 

Verwenden Sie zum Hashing das Paket sha256. Das Datenformat kann beliebig sein, aber im Beispiel verwenden wir die Daten in JSON.

Wie habe ich meinen Fall mit PoE gelöst?


Zusätzlich zu PoE war es mir wichtig, Benutzer nicht mit Blockchain- und Transaktionsgebühren zu überlasten. Beispielsweise kostet das Aufrufen der addHash-Methode (bytes32 rootHash) 0,2 finney (0,0002 ETH oder 0,06 USD im Juni 2019).



Pro Tag wurden ungefähr 30 Schlussfolgerungen aus der Strategieposition gezogen, das heißt, es kostet uns 2,1 USD. Wenn sich die Anzahl der Benutzer um das 100-fache erhöht und die Etherrate steigt, steigen natürlich die Kosten.

Ich beschloss, einen Tag lang einen Hash in der Blockchain zu behalten. Dieser Hash wird aus Hashes der täglichen Strategieergebnisse und ihrer internen Kennungen generiert.



Wir erhalten eine Lösung, die in ihrer Funktionalität nicht minderwertig ist, jedoch viel billiger. Wir sehen keine Probleme mit der Skalierbarkeit. Sie können jedoch die Ausgabe einer Strategieposition immer in mehrere Blöcke aufteilen und mehrere Hashes im Blockchain-Netzwerk speichern. Ein Teilnehmer kann einen separaten Hash leicht mit anderen benachbarten Hashes überprüfen.

Zusammenfassend


Zur Überprüfung haben wir eine spezielle Vorlage erstellt, die als Jupyter-Notizbuch verfügbar ist. Der Benutzer kann jederzeit die Vorlage herunterladen, alles neu generieren und überprüfen, ob alle Positionen wirklich diejenigen sind, die in der Vergangenheit erstellt und gespeichert wurden.

 ```   : 1.    API       1.     2.    API  ,         3.          ,              .          . ``` 

Source: https://habr.com/ru/post/de459046/


All Articles