Blockchain ohne Zwischenhändler: Wie wir Wertpapiere an eine verteilte Registrierung gesendet haben

Alle wirtschaftlichen Aktivitäten basieren historisch auf Vermittlern. Jede einfache Transaktion zwischen den beiden Parteien wird von der Beteiligung verschiedener Vermittler begleitet - Banken, Börsen, Clearingstellen usw. Der Ausschluss von Vermittlern würde die Interaktion wahrscheinlich effizienter machen. Warum also nicht versuchen, eine neue, dezentrale Infrastruktur auf der Basis der Blockchain aufzubauen, in der die Teilnehmer an der Transaktion direkt arbeiten können? In diesem Beitrag werden wir darüber sprechen, wie wir unsere Reise zu einer solchen Infrastruktur begonnen haben: Wir haben Blockchain-Transaktionen entwickelt und schließlich Repos durchgeführt - ein durch Wertpapiere gesichertes Gelddarlehen.



Kurzfristige Anleihen


Unsere erste außerbörsliche Finanztransaktion in der Blockchain war die Emission einer kurzfristigen Anleihe des MTS-Mobilfunkbetreibers unter Beteiligung des National Settlement Depository (NSD). Dies ist eine Art "Zentralbank" aller Verwahrstellen. Verwahrstellen sind Infrastrukturvermittler, die Aufzeichnungen über Wertpapierinhaber führen und diese ausgeben.

Bei dieser Transaktion zeichnete MTS in der Blockchain einen Ausdruck des Willens zum Verkauf von Wertpapieren an die Sberbank auf und bestätigte in der Blockchain seine Zustimmung zu den Bedingungen der Transaktion, indem sie die Funktion eines intelligenten Vertrags aufrief. Die von beiden Parteien unterzeichneten Gegenaufträge gingen bei NSD ein, die sie in ihren Buchhaltungssystemen ausführte. Darüber hinaus wurden in der Blockchain die Konten der Transaktionsteilnehmer in Wertpapieren und Geld angezeigt.

In diesem Projekt haben wir die Open-Source-Plattform Hyperledger Fabric 1.1 ausgewählt, mit der geschlossene Blockchain-Lösungen für Unternehmen erstellt werden können. Öffentliche Blockchains sind hier nicht geeignet, da wir den Datenschutz gewährleisten müssen. Wir waren mit solchen Einschränkungen im Factoring-Pilotprojekt der Sberbank mit M. Video konfrontiert, das in der Ethereum-Blockchain implementiert wurde. Im Gegensatz dazu können Sie mit Hyperledger Fabric alle Teilnehmer einer Transaktion in einem dedizierten Kanal platzieren, in dem sie alle erforderlichen Informationen austauschen und mit intelligenten Verträgen mit vollem Funktionsumfang verarbeiten können.

Der Quellcode des MTS-Anleiheprojekts wurde öffentlich auf GitHub hochgeladen. Ohne auf den Arbeitsalgorithmus einzugehen, können Sie verstehen, dass die Blockchain im Lebenszyklus einer Transaktion eine eher bescheidene Rolle als Transport von Clearing-Aufträgen erhielt. Auf der anderen Seite haben sich aufgrund dieser Anweisungen die Kontensalden geändert. Aus Sicht der Geschäftslogik war dies also interessanter als ein einfacher elektronischer Dokumentenverwaltungsdienst.

Der Hauptvorteil der Lösung war die Vielseitigkeit. Das System „zwei Gegenparteien und ein Registrar“ deckt nahezu alle Transaktionen auf dem OTC-Markt ab und mit geringfügigen Änderungen - die meisten kommerziellen Transaktionen im Allgemeinen.

REPO 1.0


In einem neuen Projekt zur Blockchain haben wir beschlossen, zu zeigen, wie ein Pensionsgeschäft in einem dezentralen System implementiert werden kann - ein Darlehen von Geld gegen Wertpapiere. In der Regel werden diese und andere OTC-Transaktionen über Vermittler abgewickelt - Verwahrstellen, Clearingstellen und Makler.

In diesem Projekt haben wir einen Pensionsvertrag zwischen der Sberbank und einem ausländischen Partner abgeschlossen. Es wurde bereits Hyperledger Fabric Version 1.2 verwendet. Im Vergleich zu MTS-Anleihen hatten wir zwei Unterschiede:

  • Nur zwei an der Blockchain verbundene Parteien der Transaktion, deren Verwahrstellen - Euroclear und Clearstream - alle Bestellungen über herkömmliche Datenübertragungskanäle von den Backoffices der Sberbank und ihrer Gegenpartei erhalten haben.
  • Im Smart-Vertrag haben wir eine komplexe Geschäftslogik implementiert: Tägliche Angebote der Sicherheiten, die als Sicherheit für das Darlehen dienten, wurden in die Blockchain heruntergeladen, und der Smart-Vertrag berechnete den Bedarf und die Höhe der vorzeitigen Rückzahlung unter Berücksichtigung der geänderten Kosten für Sicherheiten, Rabatt, Kalender der Ausstiegsbörsen und anderer Parameter. Eine solche P2P-Synchronisation von Berechnungsalgorithmen zwischen Teilnehmern kann ohne eine verteilte Registrierung nicht erreicht werden. Dies ist viel bequemer als eine unabhängige Berechnung von Verpflichtungen und Beträgen durch jede Seite - keine zeitaufwändigen Abstimmungen, keine Bestätigungen.

Zwischen den Gegenparteien organisierten sie einen Chat und einen Workflow innerhalb des Kanals. Daten darüber wurden in der Blockchain gespeichert. Nach jeder Änderung in der verteilten Registrierung erhielten die Channel-Mitglieder eine E-Mail-Benachrichtigung.

"REPO 1.0" haben wir von der rechtlichen Seite ausgearbeitet. Mit Hilfe einer großen Anwaltskanzlei wurde eine Analyse der Fälle des High Court of London durchgeführt. Darüber hinaus verwendeten das EDS der Bank und ihrer Gegenpartei unterschiedliche kryptografische Algorithmen.

Wie funktioniert REPO 1.0?


Jede Partei der Transaktion hat einen eigenen Blockchain-Knoten. Alle Knoten sind in einem P2P-Netzwerk miteinander verbunden. Angenommen, Sie müssen einen Deal machen. Wir setzen einen intelligenten Vertrag zwischen den Parteien der Transaktion ein, in dem das Finanzinstrument vollständig beschrieben wird.



Nach Vertragsabschluss unsererseits unterschreibt der Händler den Vertrag. Der Kunde überprüft und unterschreibt auch den Vertrag. Anschließend werden die Signaturen überprüft und verifiziert. In diesem Fall wurde die Transaktion nach englischem Recht durchgeführt, die Daten auf der elektronischen digitalen Signatur wurden in das GMRA-Dokument eingegeben. Für die Unterzeichnung durch den Kunden muss überprüft werden, ob eine autorisierte Person im Unterschriftenzertifikat vorhanden ist. Schließlich akzeptiert der Kunde den Vertrag und stimmt allen Bedingungen zu. Sie können einem unterzeichneten Vertrag beliebig viele Dokumente hinzufügen.

Danach erhält der Vertrag den Status "in Arbeit". Der "in Bearbeitung" -Vertrag wird beim Laden neuer Marktpreise automatisch neu berechnet. Wenn der Vertrag ein Wertpapier enthält, wird der Marktpreis genommen, der Loan-to-Value (LTV) neu berechnet - das Verhältnis des Kreditbetrags zum Wert des Wertpapiers in Wertpapieren. LTV ist einer der Schlüsselbegriffe in einer Repo-Transaktion, dessen Bedeutung im Vertrag festgelegt ist. Der Aktienkurs ist stark gestiegen - und der LTV wird niedriger als der in GMRA angegebene (wenn es um englisches Recht geht). Dementsprechend gibt die Bank Wertpapiere an den Kunden zurück (als eine der Optionen), da sich unter Berücksichtigung neuer Preise herausstellt, dass die Bank über eine höhere Sicherheit verfügt.

Wenn der LTV jedoch größer wird, können Sie mit dem Programm eine Sicherheitenmitteilung ausdrucken - eine Benachrichtigung an den Kunden über die Notwendigkeit, zusätzliche Sicherheiten (Aktien oder Geld) zu leisten, damit der LTV-Wert zum ursprünglichen Wert zurückkehrt. Bisher konnte die Benachrichtigung über Sicherheiten nur per Post gesendet werden, es wurden separate Dokumente dafür erstellt, und während der Erstellung dieser Dokumente konnte sich der LTV erneut ändern. Jetzt sehen wir die gleichen Berechnungen mit dem Kunden online, wir können leicht interagieren.

Darüber hinaus legt das Programm jeden Tag den Preis für den Rückkauf von Wertpapieren unter Berücksichtigung der Zinsen fest. Wenn der Kunde beim Laden des Marktpreises damit nicht einverstanden ist, sieht er sich das vollständige Neuberechnungsprotokoll an - was war, was wurde, welcher Preis wurde geladen, woher er kam. Und dann beginnt die Chat-Diskussion.

REPO 2.0


Wir wollten, dass unser REPO in der Blockchain in der Lage ist, die Bewegung von Real Assets basierend auf unserer internen Logik zu initiieren. In REPO 1.0 konnten wir dies jedoch aufgrund organisatorischer Schwierigkeiten beim Anschluss westlicher Verwahrstellen noch nicht erreichen. Also haben wir den neuen Repo 2.0-Piloten gestartet. Er hatte zwei Ziele:

  • Die Transaktion sollte unter Beteiligung von zwei Parteien und der Verwahrstelle durchgeführt werden, um die Infrastruktur des MTS-Anleihenprojekts optimal zu nutzen.
  • Die Blockchain muss befugt sein, Sicherheiten neu zu bewerten und einen Margin Call einzurichten, der automatisch von einem mit einem verteilten Netzwerk verbundenen Depot ausgeführt werden kann.

NSD wollte sich sofort mit dem Projekt verbinden. Um eine in der Blockchain initiierte Transaktion auf dem konservativen Gebiet der Bundesgesetze für den heimischen Finanzmarkt zu landen, haben wir mit Anwälten eine fünfseitige Zusatzvereinbarung zur Vereinbarung über die Verwaltung elektronischer Dokumente geschlossen. Es wurde von allen Parteien der Transaktion und NSD unterzeichnet.

NSD fungierte bei dieser Transaktion als Clearingstelle. Er führte alle Anweisungen zum Transport von Geldern und Wertpapieren aus. Diese Transaktion wurde nach russischem Recht abgeschlossen.

Der Kunde nahm den Vertrag mit einer elektronischen Unterschrift an. Dann wurde die Vereinbarung von der Sberbank mit ihrer Unterschrift akzeptiert - sie überprüfte die Übereinstimmung aller Parameter mit den erforderlichen Werten und der Autorität der Person, die vom Kunden akzeptiert hatte. Danach ging der Vertrag in Arbeit. NSD hat Marktdaten hochgeladen, Smart Contract neu berechnet.

Wie funktioniert REPO 2.0?


Um das Netzwerk bereitzustellen und mit der Client-Schnittstelle mit dem Kettencode zu interagieren, haben wir die Fabric Starter- Lösung verwendet. Anstelle der Standard-GRPC-Schnittstelle für HLF wird eine REST-API bereitgestellt, die in unserem Fall die Komplexität der Integration erheblich reduziert.



Das Netzwerk wurde wie folgt aufgebaut. Jede der drei Seiten startete nach der Vorinstallation auf dem Docker-Server Fabric Starter, der Container mit den Komponenten des Knotens erstellte. Zu diesen Komponenten gehörten ein externer Peer für die Interaktion mit anderen Organisationen und ein REST-API-Service, über den der Knoten mit der Clientanwendung interagierte. Beim Start von Starter wurde auch das Blockchain-Netzwerk konfiguriert und ein privater Kanal erstellt, in dem der Kettencode mit Endorsement-Richtlinie installiert wurde. In unserem Fall muss jede Transaktion die Signaturen aller drei Teilnehmer haben.

Während der Testphase wurde Docker Swarm verwendet, um die Verbindung der Server der Teilnehmer zu organisieren. Um jedoch ein echtes Geschäft abzuschließen, wechselten sie zu DNS. Die Plattform selbst ist für den Nachrichtentransport verantwortlich, Daten werden mit TLS-Verschlüsselung über das Internet übertragen.

Die technische Seite des Problems


Der Prozess der Entwicklung einer verteilten Anwendung auf HLF beginnt ganz traditionell - mit Datenstrukturen und einem Kettencode (in der Tat einer Reihe gespeicherter Prozeduren), dessen Aufruf zum Erhalt, Ändern oder Lesen dieser Strukturen aus dem Hauptbuch führt. Die Plattform ermöglicht die Verwendung verschiedener Programmiersprachen für die Entwicklung von Kettencodes und DBMS für die lokale Speicherung. Wir bevorzugen Go bzw. CouchDB.

Das zentrale Wesen für Repo-Projekte in unserem Datenmodell ist der Vertrag selbst und seine Nebenverpflichtungen. Sie wurden für jeden der beiden Piloten sowie für Margin Calls erstellt. Diese Architektur war ein Fortschritt im Vergleich zum MTS-Bindungsmodell, das auf dem Wesen der „Ordnung“ basierte. Es wurden auch unabhängige Objekte für Wertpapiere erstellt, die somit teilweise mit einem Token versehen wurden. Bei der Entwicklung des Experiments mit Kontoverwaltung und virtueller Tokenisierung von Geld haben wir uns entschlossen, eine der nächsten Versionen der Lösung zu verschieben.

Die Hauptfunktionen unserer Lösung:

  • Erstellen Sie einen Vertrag.
  • Unterzeichnen Sie mit Ihrem EDS einen Vertrag, in dem die Annahme der Vertragsbedingungen bestätigt wird.
  • Laden Sie die Marktpreise herunter und berechnen Sie den Wert der Sicherheiten neu. Die Abweichung von der festgelegten Schwelle führte zur Schaffung einer neuen Margin-Call-Verpflichtung.
  • Den Status der Verpflichtung widerspiegeln.

Auf der technischen Seite ist das Neubewertungsverfahren hier am interessantesten. Lassen Sie es uns genauer analysieren.

Im Geschäftsprozess sollte das Verfahren einmal täglich gestartet werden, nachdem Oracle (im Pilotprojekt von „REPO 2.0“ von NSD) die aktualisierten Wertpapierkurse in das System hochgeladen hat.

func (t *CIBContract) recalculationData(stub shim.ChaincodeStubInterface, loadData *loadDataType, curDay string) pb.Response {...} 

Der Hauptzyklus des Verfahrens durchläuft alle Wertpapiere, für die die Quotes aktualisiert wurden.

 for _, securities := range loadData.Securities {...} 

Als nächstes werden mehrere Überprüfungen durchgeführt. Wenn beispielsweise der Austausch, bei dem die Marktdaten eingegangen sind, heute einen freien Tag hat, sollte keine Nachzählung erfolgen.

 if t.checkHoliday(stub, contract.Settings.Calendars) == "yes" { hisYes := historyType{curDay, "LoadData. Calendar", "System", "LoadData. Today is holiday ! No load market data to contract !"} ... contract.History = append(contract.History, hisYes) … err = stub.PutState(contrID, contractJSONasBytes) } 

Zur Berechnung des aktualisierten Anleihepreises wird die aufgelaufene Kuponrendite (NDC) zum geladenen Nettopreis addiert. Das Pilotprojekt unterstützte das 30/360-Schema zur Berechnung der NKD.

 priceIzm = float64(securities.Price + float64(securities.CouponRate)*float64((int(settlementDate.Year()) - int(dateStart.Year()))*360 + (int(settlementDate.Month()) - int(dateStart.Month()))*30 + (int(settlementDate.Day()) - int(dateStart.Day())))*100/360/100) curCurrVal = priceIzm 

Wenn sich die Transaktionswährung von der Währung unterscheidet, in der das Wertpapier notiert ist, wird eine Umtauschumrechnung durchgeführt.

 if contract.GeneralTerms.PurchasePrice.Currency != securities.Currency { curCurrName = securities.Currency + "-" + contract.GeneralTerms.PurchasePrice.Currency               for _, currency := range loadData.Currencies {              if currency.Name == curCurrName {                           curCurrVal = priceIzm * currency.Value } } } 

Jetzt müssen wir den LTV berechnen. Behalten Sie den alten Koeffizientenwert für die Geschichte bei.

 oldCurLTV := contract.MarginingTerms.CurrentLTV 

Margin Calls, die während der Laufzeit der Transaktion ausgeführt werden, müssen berücksichtigt werden. Anforderungen können von beiden Seiten kommen und in zwei Formen:

  • Wertpapiere. Der Kreditnehmer macht zusätzliche Sicherheiten im Falle eines Rückgangs des Marktpreises des Wertpapiers. Der Gläubiger gibt im Falle einer Preiserhöhung einen Teil der Sicherheit zurück.
  • Geld. Der Kreditnehmer zahlt vorzeitig den Teil des Kredits zurück, der nicht mehr durch billigere Sicherheiten gedeckt ist. Der Kreditgeber erhöht den Kreditbetrag als Reaktion auf eine Wertsteigerung der Sicherheiten.

Im ersten Fall wird die Höhe der Wertpapiere in den Sicherheiten einfach aktualisiert. Und um damit Geld zu verdienen, ist es auch notwendig, die in den zusätzlichen Bedingungen der Transaktion angegebene Rentabilität zu erzielen.

 for _, addCollateral := range contract.MarginingTerms.AddCollateral { currSumCollateral := addCollateral.Sum + (addCollateral.Sum*contract.MarginingTerms.RateOnCashMargin*float64(deltaColDate) / float64(contract.MarginingTerms.Basis))/100 ... allSumCollateral = allSumCollateral + currSumCollateral ... ht := historyType{curDay, System", "LoadData. Recalculation data(addCollateral) Contract " + contrID + " - currSumCollateral: " + strconv.FormatFloat(float64(currSumCollateral), 'f', 2, 64) ... }        ... contract.History = append(contract.History, ht) } 

Wir berechnen den Gesamtbetrag des Rückkaufs - tatsächlich ist dies der Betrag des Darlehens mit Zinsen, den wir zurückzahlen müssen.

 rePurchasePriceCur := contract.GeneralTerms.PurchasePrice.Sum + (contract.GeneralTerms.PurchasePrice.Sum*contract.GeneralTerms.RepoRate*float64(deltaSigningDate)/float64(contract.MarginingTerms.Basis))/100 

Nun berechnen wir den LTV-Koeffizienten. Subtrahieren Sie dazu das Wertpapier in bar vom Rückkaufpreis und dividieren Sie den resultierenden Wert durch den Gesamtwert der Wertpapiere im Wertpapier. Vom Gläubiger gutgeschriebene Beträge sind mit einem „-“ gekennzeichnet und werden zum Rückkaufpreis hinzugerechnet.

 contract.MarginingTerms.CurrentLTV = (rePurchasePriceCur - allSumCollateral) * float64(100) / (float64(contract.GeneralTerms.PurchasedSecurities.Quantity) * curCurrVal) 

Schließlich berechnen wir die Auslöser im Vertrag. Mit derselben Prozedur werden Margin Call Order-Objekte erstellt, wenn der LTV-Wert vom angegebenen Korridor abweicht.

 contract = t.checkTriggerEvents(stub, "LoadData", contract, curDay, securities) 

Schreiben Sie Informationen in den Verlauf, um sie auf der Benutzeroberfläche anzuzeigen.

 ht := historyType{curDay, "System", "LoadData. Recalculation data(change curLTV, ADTV) Contract " + contrID + " - oldCurLTV: " + strconv.FormatFloat(float64(oldCurLTV), 'f', 2, 64) + ", newCurLTV: " + strconv.FormatFloat(float64(contract.MarginingTerms.CurrentLTV), 'f', 2, 64)...} contract.History = append(contract.History, ht) 

Zusammenfassend


Ein solches System kann nicht nur mit Wertpapieren und Verträgen funktionieren, sondern auch in anderen Szenarien. Zum Beispiel bei Stromversorgungen, bei denen es unterschiedliche Tarife gibt, unterschiedliche Verbindungen zu unterschiedlichen Zeiten. Oder mit Factoring - Kreditvergabe an Lieferanten durch Signale des Warenversands. In der Wirtschaft gibt es viele Anwenderfälle, in denen jeder seine eigenen Datenquellen verwendet, die überprüft werden müssen.

Unser Ziel ist es, ein Netzwerk zu schaffen, das Banken bundesweit miteinander und mit ihren Kunden verbindet und mithilfe intelligenter Verträge Verträge beschreibt, die nicht Krypto, sondern die traditionelle Wirtschaft - Finanzinstrumente - betreffen. Ein solches Netzwerk wird stabil und offen sein, und wie es in einem P2P-Netzwerk sein sollte, wird hier niemand einen besonderen Status haben.

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


All Articles