Blockchain sans intermédiaires: comment nous avons envoyé des titres à un registre distribué

Historiquement, toute activité économique repose sur des intermédiaires. Toute transaction, même simple, entre les deux parties s'accompagne de l'implication de différents intermédiaires - banques, bourses, chambres de compensation, etc. L'exclusion des intermédiaires rendrait probablement l'interaction plus efficace. Alors pourquoi ne pas essayer de construire une nouvelle infrastructure décentralisée sur la base de la blockchain, où les participants à la transaction peuvent travailler directement? Dans cet article, nous parlerons de la façon dont nous avons commencé notre voyage vers une telle infrastructure: nous avons développé des transactions blockchain et, par conséquent, effectué des repos - emprunter de l'argent contre des titres.



Obligations à court terme


Notre première transaction financière de gré à gré sur la blockchain a été l'émission d'une obligation à court terme de l'opérateur mobile MTS avec la participation du National Settlement Depository (NSD). Il s'agit d'une sorte de «banque centrale» de tous les dépositaires. Les dépositaires sont des intermédiaires d'infrastructure qui tiennent des registres des propriétaires de titres et les émettent.

Dans cette transaction, MTS, en appelant la fonction du contrat intelligent, a enregistré dans la blockchain une expression de volonté de vendre des titres à Sberbank, et a confirmé dans la blockchain son accord avec les termes de la transaction. Les contre-ordres signés par les deux parties ont été reçus par NSD, qui les a exécutés dans leurs systèmes comptables. De plus, la blockchain affichait les comptes des participants à la transaction en titres et en argent.

Dans ce projet, nous avons sélectionné la plateforme open source Hyperledger Fabric 1.1 , conçue pour créer des solutions de blockchain d'entreprise fermées. Les chaînes de blocs publiques ne conviennent pas ici, car nous devons garantir la confidentialité des données. Nous avons rencontré de telles limitations dans le pilote d'affacturage de Sberbank avec M. Video, qui a été implémenté sur la blockchain Ethereum. En revanche, Hyperledger Fabric vous permet de placer tous les participants à une transaction dans un canal dédié, où ils peuvent échanger toutes les informations nécessaires et les traiter avec des contrats intelligents complets.

Le code source du projet d'émission d'obligations MTS a été téléchargé publiquement sur GitHub. Sans même entrer dans l'algorithme de travail, vous pouvez comprendre que dans le cycle de vie d'une transaction, la blockchain s'est vu confier un rôle plutôt modeste de transport des ordres de compensation. En revanche, sur la base de ces instructions, les soldes des comptes ont changé - du point de vue de la logique métier, cela était plus intéressant qu'un simple service de gestion électronique de documents.

Le principal avantage de la solution était sa polyvalence. Le régime «deux contreparties et un registraire» couvre presque toutes les transactions sur le marché de gré à gré et avec des modifications mineures - la plupart des transactions commerciales en général.

REPO 1.0


Dans un nouveau projet sur la blockchain, nous avons décidé de montrer comment mettre en œuvre un accord de rachat dans un système décentralisé - un prêt d'argent contre des titres. En règle générale, ces transactions et d'autres transactions de gré à gré passent par des intermédiaires - dépositaire, chambres de compensation, courtiers.

Dans ce projet, nous avons conclu un accord de rachat entre Sberbank et un partenaire étranger. Il utilisait déjà Hyperledger Fabric version 1.2. Par rapport aux obligations MTS, nous avions deux différences:

  • Seuls deux participants à la transaction liés à la blockchain, dont les dépositaires - Euroclear et Clearstream - ont reçu toutes les commandes via les canaux de transmission de données traditionnels des back-offices de Sberbank et de sa contrepartie.
  • Dans le contrat intelligent, nous avons mis en œuvre une logique commerciale complexe: des devis quotidiens de la sécurité qui ont servi de garantie pour le prêt ont été téléchargés dans la blockchain, et le contrat intelligent a calculé le besoin et le montant du remboursement anticipé, en tenant compte du coût modifié de la garantie, de l'escompte, du calendrier des échanges de sortie et d'autres paramètres. Une telle synchronisation P2P des algorithmes de calcul entre les participants ne peut pas être obtenue sans un registre distribué. Ceci est beaucoup plus pratique qu'un calcul indépendant des obligations et des montants de chaque côté - pas de rapprochements longs, pas de confirmations.

Entre les contreparties ont organisé un chat et un workflow au sein du canal. Les données les concernant ont été stockées dans la blockchain. Après chaque modification du registre distribué, les membres du canal ont reçu une alerte par e-mail.

«REPO 1.0», nous avons travaillé du côté juridique. Avec l'aide d'un grand cabinet d'avocats, une analyse des affaires de la Haute Cour de Londres a été réalisée. De plus, l'EDS de la banque et de sa contrepartie a utilisé différents algorithmes cryptographiques.

Comment fonctionne REPO 1.0?


Chaque partie à la transaction a son propre nœud de chaîne de blocs. Tous les nœuds sont connectés les uns aux autres dans un réseau P2P. Supposons que vous deviez conclure un accord. Nous déployons un contrat intelligent entre les parties à la transaction, où l'instrument financier est entièrement décrit.



Après la création du contrat de notre côté, il est signé par le commerçant. Le client examine et signe également le contrat. Ensuite, les signatures sont examinées et vérifiées. Dans ce cas, la transaction a été effectuée en vertu du droit anglais, les données sur la signature numérique électronique ont été saisies dans le document GMRA. Pour la signature du client, la vérification est nécessaire qu'une personne autorisée soit présente dans le certificat de signature. Enfin, le client accepte le contrat et accepte toutes les conditions. Vous pouvez joindre n'importe quel nombre de documents à un contrat signé.

Après cela, le contrat reçoit le statut "en activité". Le contrat «en cours» est automatiquement recalculé lors du chargement des nouveaux prix du marché. S'il y a un titre dans le contrat, le prix du marché est pris, le Loan-To-Value (LTV) est recalculé - le rapport entre le montant du prêt et la valeur du titre en titres. LTV est l'un des termes clés d'une opération de mise en pension, sa signification est prescrite dans le contrat. Le cours de l'action a fortement augmenté - et le LTV devient inférieur à celui indiqué dans le GMRA (en ce qui concerne la loi anglaise). En conséquence, la banque rend les titres au client (comme l'une des options), car compte tenu des nouveaux prix, il s'avère que la banque détient une sécurité plus élevée.

Mais si LTV devient plus grand, le programme vous permet d'imprimer un avis de garantie - une notification au client sur la nécessité de faire une sécurité supplémentaire (actions ou argent) afin que la valeur LTV revienne à celle initiale. Auparavant, l'avis de garantie ne pouvait être envoyé que par courrier, des documents distincts étaient créés à cet effet et lors de la création de ces documents, LTV pouvait à nouveau changer. Maintenant, nous voyons les mêmes calculs avec le client en ligne, nous pouvons facilement interagir.

De plus, le programme fixe chaque jour le prix du rachat de titres en tenant compte des intérêts. Si le client est en désaccord lors du chargement du prix du marché, il regarde le journal de recalcul complet - ce qui était, ce qui est devenu, quel prix a été chargé, d'où il vient. Et puis la discussion par chat commence.

REPO 2.0


Nous voulions que notre REPO sur la blockchain puisse initier le mouvement des actifs réels sur la base de notre logique interne. Mais dans REPO 1.0, en raison de difficultés organisationnelles avec la connexion des dépositaires occidentaux, nous n'avons pas encore pu y parvenir. Nous avons donc commencé le nouveau pilote Repo 2.0. Il avait deux buts:

  • La transaction devrait être réalisée avec la participation de deux parties et du dépositaire, afin de tirer le meilleur parti de l'infrastructure du projet obligataire MTS.
  • La blockchain doit être habilitée à réévaluer les garanties et à mettre en place un appel de marge qui pourrait être automatiquement exécuté par un dépositaire connecté à un réseau distribué.

NSD a immédiatement voulu se connecter au projet. Afin de décrocher une transaction initiée dans la blockchain sur le domaine conservateur des lois fédérales régissant le marché financier national, nous avons travaillé avec des avocats pour un accord complémentaire de cinq pages à l'accord de gestion électronique des documents. Il a été signé par toutes les parties à la transaction et NSD.

NSD a agi comme chambre de compensation dans cette transaction. Il a exécuté toutes les instructions sur le mouvement des fonds et des titres. Cette transaction a été conclue en vertu du droit russe.

Le client a accepté le contrat avec une signature électronique. Ensuite, l'accord a été accepté par Sberbank avec sa signature - il a vérifié la conformité de tous les paramètres avec les valeurs nécessaires et l'autorité de la personne qui a accepté du client. Après cela, le contrat est entré en vigueur. NSD a téléchargé les données du marché, le contrat intelligent recalculé.

Comment fonctionne REPO 2.0?


Pour déployer le réseau et interagir avec l'interface client avec le code de chaîne, nous avons utilisé la solution Fabric Starter . Au lieu de l'interface grpc standard pour HLF, il fournit une API REST, qui dans notre cas a considérablement réduit la complexité de l'intégration.



Le réseau a augmenté comme suit. Après la pré-installation sur le serveur Docker, chacun des trois côtés a lancé Fabric Starter, qui a créé des conteneurs avec les composants du nœud. Ces composants comprenaient un homologue externe pour interagir avec d'autres organisations et un service d'API REST via lequel le nœud interagissait avec l'application cliente. Lors du démarrage de Starter, le réseau de la chaîne de blocs a également été configuré et un canal privé a été créé dans lequel le code de chaîne avec la politique d'approbation a été installé. Dans notre cas, chaque transaction doit avoir la signature des trois participants.

Au cours de la phase de test, Docker Swarm a été utilisé pour organiser la connexion des serveurs des participants, mais dans le but de conclure un accord réel, ils sont passés au DNS. La plateforme elle-même est responsable du transport des messages; les données sont transmises sur Internet avec le cryptage TLS.

Le côté technique du problème


Le processus de développement d'une application distribuée sur HLF commence assez traditionnellement - avec des structures de données et un code de chaîne (en fait, un ensemble de procédures stockées), dont l'appel conduit à la conservation, la modification ou la lecture de ces structures depuis le grand livre. La plate-forme permet l'utilisation de divers langages de programmation pour le développement de codes de chaîne et de SGBD pour le stockage local. Nous préférons Go et CouchDB, respectivement.

L'essence centrale des projets de mise en pension dans notre modèle de données est le contrat lui-même et ses obligations subsidiaires. Ils ont été créés pour chacun des deux pilotes, ainsi que pour les appels de marge. Cette architecture était un pas en avant par rapport au modèle obligataire MTS, qui était basé sur l'essence de l '«Ordre». Des objets indépendants ont également été créés pour les titres, qui ont ainsi été partiellement symbolisés. Mais le développement de l'expérience avec la gestion des comptes et la tokenisation virtuelle de l'argent, nous avons décidé de reporter à l'une des prochaines versions de la solution.

Les principales fonctions de notre solution:

  • Créez un contrat.
  • Signez un contrat avec votre EDS confirmant l'acceptation des termes du contrat.
  • Téléchargez les prix du marché et commencez à recalculer la valeur des garanties. Son écart par rapport au seuil fixé a entraîné la création d'une nouvelle obligation d'appel de marge.
  • Refléter le statut de l'obligation.

Sur le plan technique, la procédure de réévaluation est ici la plus intéressante. Analysons-le plus en détail.

Dans le processus opérationnel, la procédure devrait être lancée une fois par jour, après que l'Oracle (dans le pilote de «REPO 2.0» exécuté par NSD) ait téléchargé les cotations mises à jour des titres dans le système.

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

Le cycle principal de la procédure passe par tous les titres pour lesquels les cotations ont été mises à jour.

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

Ensuite, plusieurs contrôles sont effectués. Par exemple, si l'échange avec lequel les données du marché ont été reçues est aujourd'hui un jour de congé, le recomptage ne devrait pas avoir lieu.

 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) } 

Pour calculer le prix de l'obligation mis à jour, le rendement du coupon couru (NDC) est ajouté au prix net chargé. Le pilote a mis en œuvre la prise en charge du schéma 30/360 pour le calcul des 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 

Si la devise de transaction est différente de la devise dans laquelle le titre est coté, une conversion de change est effectuée.

 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 } } } 

Maintenant, nous devons calculer LTV. Conservez l'ancienne valeur du coefficient pour l'histoire.

 oldCurLTV := contract.MarginingTerms.CurrentLTV 

Il est nécessaire de prendre en compte les appels de marge exécutés pendant la durée de la transaction. Les exigences peuvent provenir des deux côtés et sous deux formes:

  • Valeurs mobilières. L'emprunteur apporte une garantie supplémentaire en cas de baisse du prix de marché de la garantie. Le créancier retourne une partie de la garantie en cas d'augmentation de prix.
  • L'argent. L'emprunteur rembourse à l'avance la partie du prêt qui a cessé d'être couverte par des garanties moins chères. Le prêteur augmente le montant du prêt en réponse à une augmentation de la valeur de la garantie.

Dans le premier cas, le montant des titres de la garantie est simplement mis à jour. Et en cas de gagner de l'argent sur eux, il est également nécessaire d'accumuler la rentabilité spécifiée dans les conditions supplémentaires de la transaction.

 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) } 

Nous calculons le montant total du rachat - en fait, c'est le montant du prêt avec intérêt, que nous devons rembourser.

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

Maintenant, nous calculons le coefficient LTV. Pour ce faire, soustrayez le titre en espèces du prix de rachat et divisez la valeur résultante par la valeur totale des titres du titre. Les montants crédités par le créancier sont marqués d'un «-» et seront ajoutés au prix de rachat.

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

Enfin, nous calculons les déclencheurs du contrat. La même procédure crée des objets d'ordre d'appel de marge si la valeur LTV s'écarte du couloir spécifié.

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

Et écrivez des informations dans l'historique pour les afficher sur l'interface utilisateur.

 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) 

Pour résumer


Un tel régime peut fonctionner non seulement avec des titres et des contrats, mais aussi dans d'autres scénarios. Par exemple, avec les approvisionnements en électricité, où il y a différents tarifs, différentes connexions à différents moments. Ou avec l'affacturage - prêt aux fournisseurs par des signaux d'expédition de marchandises. Il existe de nombreux cas d'utilisation en économie, lorsque chacun utilise ses propres sources de données qui doivent être vérifiées.

Notre objectif est de créer un réseau qui relie les banques entre elles et leurs clients à l'échelle nationale, et en utilisant des contrats intelligents pour y décrire des contrats non pas de crypto, mais de l'économie traditionnelle - les instruments financiers. Un tel réseau sera stable, ouvert et, comme il devrait l'être dans un réseau P2P, personne ici n'aura un statut spécial.

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


All Articles