Toda atividade econômica é construída historicamente sobre intermediários. Qualquer transação simples, mesmo entre as duas partes, é acompanhada pelo envolvimento de vários intermediários - bancos, trocas, câmaras de compensação, etc. A exclusão de intermediários provavelmente tornaria a interação mais eficiente. Então, por que não tentar criar uma nova infraestrutura descentralizada com base no blockchain, onde os participantes da transação possam trabalhar diretamente? Neste post, falaremos sobre como iniciamos nossa jornada para essa infraestrutura: desenvolvemos transações de blockchain e, eventualmente, realizamos operações compromissadas - um empréstimo de dinheiro garantido por valores mobiliários.

Obrigações de curto prazo
Nossa primeira transação financeira de balcão na blockchain foi a emissão de um título de curto prazo da operadora móvel MTS com a participação do National Settlement Depository (NSD). Este é um tipo de "banco central" de todos os depositários. Os depositários são intermediários de infraestrutura que mantêm registros dos proprietários de títulos e os emitem.
Nessa transação, a MTS, ao chamar a função do contrato inteligente, registrou na blockchain uma expressão de vontade de vender títulos para o Sberbank, e confirmou na blockchain seu acordo com os termos da transação. As contra-ordens assinadas por ambas as partes foram recebidas pela NSD, que as executou em seus sistemas contábeis. Além disso, o blockchain exibia as contas dos participantes da transação em valores mobiliários e dinheiro.
Nesse projeto, selecionamos a plataforma
Hyperledger Fabric 1.1 de código aberto, projetada para criar soluções de blockchain corporativas fechadas. Bloqueios públicos não são adequados aqui, porque precisamos garantir a privacidade dos dados. Enfrentamos essas limitações no piloto de factoring do Sberbank com o M. Video, que foi implementado no blockchain Ethereum. Por outro lado, o Hyperledger Fabric permite colocar todos os participantes de uma transação em um canal dedicado, onde eles podem trocar todas as informações necessárias e processá-las com contratos inteligentes com todos os recursos.
O código-fonte do projeto de emissão de títulos do MTS foi carregado publicamente no GitHub. Mesmo sem entrar no algoritmo do trabalho, você pode entender que, no ciclo de vida de uma transação, o blockchain recebeu um papel bastante modesto como transporte de ordens de compensação. Por outro lado, com base nessas instruções, os saldos das contas foram alterados - portanto, do ponto de vista da lógica de negócios, isso era mais interessante do que um simples serviço de gerenciamento de documentos eletrônicos.
A principal vantagem da solução foi a versatilidade. O esquema “duas contrapartes e um registrador” abrange quase todas as transações no mercado de balcão, e com pequenas alterações - a maioria das transações comerciais em geral.
REPO 1.0
Em um novo projeto na blockchain, decidimos mostrar como implementar um acordo de recompra em um sistema descentralizado - um empréstimo de dinheiro contra valores mobiliários. Normalmente, essas e outras transações de balcão passam por intermediários - depositário, câmaras de compensação, corretores.
Nesse projeto, celebramos um acordo de recompra entre o Sberbank e um parceiro estrangeiro. Ele já usava o Hyperledger Fabric versão 1.2. Comparado aos títulos do MTS, tivemos duas diferenças:
- Apenas duas partes da transação conectaram-se à blockchain, cujos depositários - Euroclear e Clearstream - receberam todos os pedidos por meio dos canais tradicionais de transmissão de dados do back office do Sberbank e de sua contraparte.
- No contrato inteligente, implementamos uma lógica de negócios complexa: as cotações diárias da segurança que serviram de garantia para o empréstimo foram baixadas para o blockchain e o contrato inteligente calculou a necessidade e o valor do reembolso antecipado, levando em consideração o custo alterado das garantias, descontos, calendário de trocas de saída e outros parâmetros. Essa sincronização P2P de algoritmos de cálculo entre participantes não pode ser obtida sem um registro distribuído. Isso é muito mais conveniente do que um cálculo independente de obrigações e valores de cada lado - sem reconciliações demoradas, sem confirmações.
Entre as contrapartes organizou um bate-papo e um fluxo de trabalho dentro do canal. Os dados neles foram armazenados no blockchain. Após cada alteração no registro distribuído, os membros do canal receberam um alerta por email.
"REPO 1.0", trabalhamos do lado jurídico. Com a ajuda de um grande escritório de advocacia, foi realizada uma análise dos casos da High Court of London. Além disso, o SDE do banco e de sua contraparte usava algoritmos criptográficos diferentes.
Como o REPO 1.0 funciona?
Cada parte da transação possui seu próprio nó blockchain. Todos os nós estão conectados um ao outro em uma rede P2P. Suponha que você precise fazer um acordo. Implementamos um contrato inteligente entre as partes da transação, onde o instrumento financeiro é totalmente descrito.

Após a criação do contrato do nosso lado, ele é assinado pelo trader. O cliente também revisa e assina o contrato. Em seguida, as assinaturas são revisadas e verificadas. Nesse caso, a transação foi conduzida de acordo com a lei inglesa, os dados da assinatura digital eletrônica foram inseridos no documento GMRA. Para assinar pelo cliente, é necessária a verificação de que uma pessoa autorizada esteja presente no certificado de assinatura. Finalmente, o cliente aceita o contrato e concorda com todas as condições. Você pode anexar qualquer número de documentos a um contrato assinado.
Depois disso, o contrato recebe o status de "em trabalho". O contrato "em andamento" é recalculado automaticamente ao carregar novos preços de mercado. Se houver um título no contrato, o preço de mercado é calculado, o Loan-To-Value (LTV) é recalculado - a razão entre o valor do empréstimo e o valor do título em títulos. LTV é um dos termos principais de uma transação compromissada, cujo significado é prescrito no contrato. O preço das ações subiu bastante - e o LTV está se tornando menor do que o indicado na GMRA (quando se trata da lei inglesa). Dessa forma, o banco devolve títulos ao cliente (como uma das opções), uma vez que, considerando novos preços, verifica-se que o banco possui maior segurança.
Porém, se o LTV aumentar, o programa permite que você imprima um aviso colateral - uma notificação ao cliente sobre a necessidade de garantir segurança adicional (ações ou dinheiro) para que o valor do LTV retorne ao valor inicial. Anteriormente, o aviso colateral só podia ser enviado por correio, documentos separados eram criados para isso e, durante a criação desses documentos, o LTV podia mudar novamente. Agora que vemos os mesmos cálculos com o cliente online, podemos interagir facilmente.
Além disso, o programa diariamente fixa o preço da recompra de valores mobiliários, levando em consideração os juros. Se o cliente discorda dele ao carregar o preço de mercado, ele analisa o registro completo do recálculo - o que foi, o que se tornou, qual o preço carregado, de onde veio. E então a discussão no bate-papo começa.
REPO 2.0
Queríamos que nosso REPO no blockchain fosse capaz de iniciar o movimento de ativos reais com base em nossa lógica interna. Mas no REPO 1.0, devido a dificuldades organizacionais na conexão de depositários ocidentais, ainda não conseguimos isso. Então começamos o novo piloto Repo 2.0. Ele tinha dois objetivos:
- A transação deve ser realizada com a participação de duas partes e do depositário, para aproveitar ao máximo a infraestrutura do projeto de títulos do MTS.
- O blockchain precisa ter o poder de reavaliar as garantias e configurar uma chamada de margem que pode ser executada automaticamente por um depositário conectado a uma rede distribuída.
O NSD imediatamente quis se conectar ao projeto. Para conseguir uma transação iniciada no blockchain no campo conservador das leis federais que regem o mercado financeiro doméstico, trabalhamos com advogados para um contrato suplementar de cinco páginas ao contrato de gerenciamento de documentos eletrônicos. Foi assinado por todas as partes da transação e pelo NSD.
A NSD atuou como uma câmara de compensação nessa transação. Ele executou todas as instruções sobre movimentação de fundos e valores mobiliários. Esta transação foi concluída sob a lei russa.
O cliente aceitou o contrato com uma assinatura eletrônica. Em seguida, o contrato foi aceito pelo Sberbank com sua assinatura - ele verificou a conformidade de todos os parâmetros com os valores necessários e a autoridade da pessoa que aceitou do cliente. Depois disso, o contrato entrou em funcionamento. A NSD carregou dados de mercado, contrato inteligente recalculado.
Como o REPO 2.0 funciona?
Para implantar a rede e interagir com a interface do cliente com o código da cadeia, usamos a solução
Fabric Starter . Em vez da interface grpc padrão para HLF, ela fornece uma API REST, que no nosso caso reduziu significativamente a complexidade da integração.

A rede subiu da seguinte maneira. Cada um dos três lados após a pré-instalação no servidor Docker lançou o Fabric Starter, que criou contêineres com os componentes do nó. Esses componentes incluíam um ponto externo para interagir com outras organizações e um serviço de API REST por meio do qual o nó interagia com o aplicativo cliente. Ao iniciar o Starter, a rede blockchain também foi configurada e um canal privado foi criado no qual o código da cadeia com política de endosso foi instalado. No nosso caso, cada transação deve ter as assinaturas dos três participantes.
Durante a fase de teste, o Docker Swarm foi usado para organizar a conexão dos servidores dos participantes; no entanto, com o objetivo de fazer um acordo real, eles mudaram para o DNS. A própria plataforma é responsável pelo transporte de mensagens; os dados são transmitidos pela Internet com criptografia TLS.
O lado técnico da questão
O processo de desenvolvimento de um aplicativo distribuído no HLF começa tradicionalmente - com estruturas de dados e um código de cadeia (de fato, um conjunto de procedimentos armazenados), cuja chamada leva à preservação, modificação ou leitura dessas estruturas do razão. A plataforma permite o uso de várias linguagens de programação para o desenvolvimento de códigos de cadeia e DBMSs para armazenamento local. Preferimos Go e CouchDB, respectivamente.
A essência central dos projetos de recompra em nosso modelo de dados é o próprio contrato e suas obrigações subsidiárias. Eles foram criados para cada um dos dois pilotos, bem como para chamadas de margem. Essa arquitetura foi um passo à frente em comparação com o modelo de títulos MTS, baseado na essência da “Ordem”. Objetos independentes também foram criados para títulos, que foram, portanto, parcialmente tokenizados. Mas, com o desenvolvimento do experimento com gerenciamento de contas e tokenização virtual de dinheiro, decidimos adiar para uma das próximas versões da solução.
As principais funções da nossa solução:
- Crie um contrato.
- Assine um contrato com sua EDS confirmando a aceitação dos termos do contrato.
- Faça o download dos preços de mercado e comece a recalcular o valor da garantia. Seu desvio do limite definido causou a criação de uma nova obrigação de chamada de margem.
- Reflita o status da obrigação.
No lado técnico, o procedimento de reavaliação é mais interessante aqui. Vamos analisá-lo em mais detalhes.
No processo comercial, o procedimento deve ser iniciado uma vez por dia, após o Oracle (no piloto do "REPO 2.0" realizado pela NSD) fazer o upload das cotações atualizadas dos títulos no sistema.
func (t *CIBContract) recalculationData(stub shim.ChaincodeStubInterface, loadData *loadDataType, curDay string) pb.Response {...}
O ciclo principal do procedimento passa por todos os títulos cujas cotações foram atualizadas.
for _, securities := range loadData.Securities {...}
Em seguida, várias verificações são realizadas. Por exemplo, se a troca com a qual os dados de mercado foram recebidos é hoje um dia de folga, a recontagem não deve ocorrer.
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) }
Para calcular o preço atualizado do título, o rendimento acumulado do cupom (NDC) é adicionado ao preço líquido carregado. O piloto implementou o suporte ao esquema 30/360 para o cálculo de 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
Se a moeda da transação for diferente da moeda na qual o título é cotado, uma conversão de câmbio é realizada.
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 } } }
Agora precisamos calcular o LTV. Mantenha o antigo valor do coeficiente para a história.
oldCurLTV := contract.MarginingTerms.CurrentLTV
É necessário levar em consideração as chamadas de margem executadas durante a vida útil da transação. Os requisitos podem vir de ambos os lados e de duas formas:
- Títulos. O mutuário faz uma segurança adicional no caso de uma queda no preço de mercado da garantia. O credor retorna parte da garantia em caso de aumento de preço.
- Dinheiro O mutuário antecipa o pagamento da parcela do empréstimo que deixou de ser coberta por garantias mais baratas. O credor aumenta o montante do empréstimo em resposta a um aumento no valor das garantias.
No primeiro caso, a quantidade de títulos em garantia é simplesmente atualizada. E, no caso de ganhar dinheiro com eles, também é necessário acumular a lucratividade especificada nos termos adicionais da transação.
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) }
Calculamos o valor total da recompra - na verdade, esse é o valor do empréstimo com juros, que precisamos reembolsar.
rePurchasePriceCur := contract.GeneralTerms.PurchasePrice.Sum + (contract.GeneralTerms.PurchasePrice.Sum*contract.GeneralTerms.RepoRate*float64(deltaSigningDate)/float64(contract.MarginingTerms.Basis))/100
Agora calculamos o coeficiente LTV. Para fazer isso, subtraia o título em dinheiro do preço de recompra e divida o valor resultante pelo valor total dos títulos no título. Os valores creditados pelo credor são marcados com um "-" e serão adicionados ao preço da recompra.
contract.MarginingTerms.CurrentLTV = (rePurchasePriceCur - allSumCollateral) * float64(100) / (float64(contract.GeneralTerms.PurchasedSecurities.Quantity) * curCurrVal)
Por fim, calculamos os gatilhos do contrato. O mesmo procedimento criará objetos de ordem de chamada de margem se o valor LTV se desviar do corredor especificado.
contract = t.checkTriggerEvents(stub, "LoadData", contract, curDay, securities)
E escreva informações no histórico para exibição na interface do usuário.
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)
Resumir
Esse esquema pode funcionar não apenas com valores mobiliários e contratos, mas também em outros cenários. Por exemplo, com suprimentos de eletricidade, onde existem tarifas diferentes, conexões diferentes em momentos diferentes. Ou com factoring - empréstimos a fornecedores por sinais de remessa de mercadorias. Existem muitos casos de usuários em economia, quando todos usam suas próprias fontes de dados que precisam ser verificadas.
Nosso objetivo é criar uma rede que conecte os bancos entre si e com seus clientes em todo o país e usando contratos inteligentes para descrever nele contratos não de criptografia, mas da economia tradicional - instrumentos financeiros. Essa rede será estável, aberta e, como deveria estar em uma rede P2P, ninguém aqui terá um status especial.