Конфиденциальные смарт-контракты: как мы реализовали важнейшую фичу для блокчейна в финтехе

Моя цель - предложение широкого ассортимента товаров и услуг на постоянно высоком качестве обслуживания по самым выгодным ценам.

В посте про историю развития смарт-контрактов целый раздел мы посвятили такому понятию, как конфиденциальные смарт-контракты. У блокчейна есть целый ряд преимуществ, которые делают его привлекательных для реализации конфиденциальных систем. Но данные смарт-контрактов, формирующих бизнес-логику блокчейна, по умолчанию хранятся в открытом виде и доступны для всех. Этот конфликт решают конфиденциальные смарт-контракты (КСК) — они стали для нас одной из основных фичей платформы, запланированных на 2023 год, и успешно дошли до релиза. Далее мы раскроем подробности реализации КСК и приведем пример контракта, который вы легко сможете развернуть на оpen-source инстансе нашей сети.

Идея реализации конфиденциальных смарт-контрактов стала созревать в ходе нашего проекта с ФНС, Федеральной налоговой службой. Подробней о нем рассказывал наш CTO Денис еще в прошлом году; актуальный кейс можно посмотреть у нас на сайте. Если вкратце, то на наших блокчейн-технологиях работает центральная платформа распределенного реестра ФНС: через нее проходили все заявки на выдачу беспроцентных кредитов от малого и среднего бизнеса по программе беспроцентного кредитования, утвержденной в Постановлениях Правительства во время пандемии.

Информация о заемщике внутри этой системы должна быть сразу доступна для всех организаций — иначе заемщик, пользуясь рассинхронизацией системы, сумеет набрать много беспроцентных кредитов в разных банках. Но сумма кредитов конкретным заемщикам при этом должна быть закрыта, так как по закону эти сведения составляют коммерческую тайну.

Общий кейс

Обобщим описанное выше. Представим, что существует некая центральная организация BaseOrg, которая находится в одной сети с организациями Org1, Org2, Org3… и взаимодействует с ними по одной и той же модели. Но некоторые детали и результаты этих взаимодействий должны быть доступны не всем, а только центральной организации и выбранным другим.

Посмотрим на это в ракурсе смарт-контрактов. Технически все взаимодействия головной организации должны быть реализованы в рамках одного смарт-контракта. Стейт этого смарт-контракта единый, на одном contractId. У каждой пары BaseOrg+Org1, BaseOrg+Org2, BaseOrg+Org3 в стейте контракта записаны ключи, доступные только нодам в паре. Помимо этого, есть, конечно, и ключи, доступные всем участникам.

Если наложить «конфиденциальные смарт-контракты» на описанную конфигурацию, то вот какие требования мы должны реализовать:

  • создание приватных групп, в рамках которых участники сети могут обмениваться конфиденциальной информацией, фиксируемой в транзакциях в закрытом виде;

  • распространение приватных параметров вызова смарт-контракта и приватных результатов исполнения между участниками приватной группы;

  • валидация успешного исполнения смарт-контракта с приватными результатами в рамках группы, а затем в рамках общего консенсуса по результатам исполнения смарт-контракта.

Три способа достижения конфиденциальности

Конфиденциальные смарт-контракты не единственный способ реализовать конфиденциальность в нашем кейсе. Всего здесь можно выделить три подхода.

Конфиденциальные транзакцииданные по транзакции доступны только определенному количеству участников. Так мы переносим задачу с уровня смарт-контрактов на уровень транзакций и решаем задачу более точечно. Но для транзакций у нас уже реализован механизм передачи конфиденциальных данных, в рамках которого мы создаем группы доступа к данным, 

отправляемые в сеть через gRPC или REST API. Если реализовать конфиденциальность на уровне транзакций, придется изменить весь этот подход так, чтобы приватность работала нативно для большей части транзакций. Нас вполне устраивает текущая схема, так что оценим другие варианты.

Конфиденциальные данные в транзакцияхтранзакции публичные, но данные в них скрыты как минимум частично. Это путь наименьших доработок, который минимально меняет текущие механизмы обменов. Но тогда невозможно будет сохранить анонимность или конфиденциальность самих операций. И в целом такой способ решает, скорее, не общий кейс, а частный кейс с ФНС, который мы описали в начале поста. 

Конфиденциальные смарт-контрактыдоступ к вызову контракта и получению результатов есть только у некоторых участников. Этот подход реализуется на сравнительно более высоком уровне и, соответственно, на уровне концепции возникает минимум нюансов. Мы просто вызываем смарт-контракт и получаем валидный конфиденциальный результат. Так можно скрыть не только данные, но и сам смарт-контракт, а также транзакцию с результатом. Реализация также выглядит вполне доступной, так как мы работаем на уровне смарт-контрактов и не затрагиваем более глубокие слои блокчейна.

Третий вариант, как вы уже догадались, и пошел в разработку. Здесь надо отдельно подумать об инфраструктуре смарт-контрактов, ведь если в проектах будет задействовано большое количество P2P-обменов, мы рискуем перегрузить более сложными смарт-контрактами. Может помочь параллельное исполнение смарт-контрактов — мы тоже писали о нем в посте об истории развития этих инструментов. Наконец, стоит продумать, как смарт-контракты будут вызывать друг друга (об этом, кстати, будет следующий пост в нашем блоге). Некоторые из этих вопросов мы будем решать уже в 2024 году, а пока расскажем о том, что у нас получилось к концу года минувшего.

Итоговая реализация

Мы выбрали довольно простой вариант реализации смарт-контрактов. Единственное архитектурное изменение по сравнению с обычными смарт-контрактами — это введение новых групп, которым можно давать входные данные для контракта и получать выходные данные в ответ.

Взаимодействие с конфиденциальными смарт-контрактами, как и с обычными, проходит в три этапа: создание, вызов и обновление. Вот какие новые инструменты мы добавили для этого.

CreateContractTransactionV6 — новая транзакция создания контракта, включающая новые поля:

  • isConfidential — является ли смарт-контракт конфиденциальным или нет;

  • groupParticipants — участники приватной группы;

  • groupOwners — администраторы приватной группы.

UpdateContractTransactionV5 — новая транзакция обновления смарт-контракта, с новыми полями groupOwners и groupParticipants, выполняющими те же функции.

Также для конфиденциальных контрактов мы прописали отдельные вызовы:

  • через REST API — POST confidential-contracts/call

  • через gRPC — ConfidentialCall

Создаем конфиденциальный смарт-контракт

Попробовать конфиденциальные смарт-контракты можно на open-source версии нашей платформы. Развернуть ее несложно, гайд мы публиковали. Вот для примера простой конфиденциальный смарт-контракт:

val image = createContractImage() // cоздание образа контракта
// создание группы, которая имеет доступ к конфиденциальным данным
val participants = nodes.map(node => Address.fromString(node.address).explicitGet()).toSet
// генерация и отправка запроса на создание контракта с поддержкой конфиденциальных данных
val request = createSignedCreateContractRequestV6(txSender,
image,
List.empty,
isConfidential = true,
groupParticipants = participants,
groupOwners = Set(txSender.toAddress))
val createTxId = txSenderNode.signedCreateContractV6(request).id

// конфиденциальные данные
val expectedInput = List(IntegerDataEntry("test", 1))
val request = ConfidentialContractCallRequest(
sender = txSender.toAddress.toString,
contractId = contractId,
contractVersion = 1,
params = expectedInput,
timestamp = System.currentTimeMillis(),
fee = callContractFee,
commitment = None,
commitmentKey = None
)

// вызов контракта
val callResponse = txSenderNode.confidentialCall(request, broadcast = true)

val callTransactionId = (callResponse \ "callContractTransactionV6" \ "id").as[String]

// проверка, что данные не доступны публично
val executedTransactionFromPublic = txSenderNode.executedTxFor(callTransactionId)
executedTransactionFromPublic.results shouldBe List.empty

val confidentialInputAndOutput = txSenderNode.confidentialTxWithInputAndOutput(callTransactionId)

val expectedOutput           = List(IntegerDataEntry("sum", 1))
val actualConfidentialInput  = (confidentialInputAndOutput \ "confidentialInput").as[ConfidentialInput]
val actualConfidentialOutput = (confidentialInputAndOutput \ "confidentialOutput").as[ConfidentialOutput]

// проверка, что для нужных участников данные возвращаются
actualConfidentialInput.entries shouldBe expectedInput
actualConfidentialOutput.entries shouldBe expectedOutput

/* как изменяется контракт для поддержки конфиденциальности определенного ключа - просто ставится проверка на версию транзакции */

private def handleCallTransaction(
tx: ContractTransaction,
authToken: String
): Unit = {
if (tx.version >= 6) {
tx.params.extractStringParam("confidential-parameter")
} else {

// do something else
}
}

Некоторые моменты стоит пояснить дополнительно. Конфиденциальность смарт-контракта прописывается в момент получения транзакции call. В самом контракте необходимо прописать проверку версии транзакции (шестая или более поздняя) и уже после этого проводить манипуляции с ключом. Это предотвращает использование ключей приватных групп неконфиденциальными транзакциями.

А вот как, в общих чертах, отработает приведенный выше смарт-контракт:

  1. Произойдет вызов конфиденциального смарт-контракта.

  2. Участник группы participants, регламентированной через политику валидации, передаст в контракт конфиденциальные данные.

  3. Смарт-контракт отправит конфиденциальные выходные данные в отдельный инстанс RocksDB, где его смогут прочитать только участники группы participants.

В самом смарт-контракте при этом будет доступна только логика и названия ключей

Развитие конфиденциальных смарт-контрактов

В 2024 году мы планируем в рамках конфиденциальных смарт-контрактов внедрить атомарные транзакции. Возможно, как и в обычных смарт-контрактах, добавим поддержку MVCC (управление параллельным доступом посредством многоверсионности). Другие фичи конфиденциальных смарт-контрактов будут появляться в соответствии с потребностями конкретных проектов.

Источник: https://habr.com/ru/companies/web3_tech/articles/787344/


Интересные статьи

Интересные статьи

Вопрос о создании мирового правительства не нов, но он становится все более актуальным в условиях глобализации и технологического прогресса. Исторические попытки создать такие структуры, как Лига Наци...
Звание текста с лучшими мемами получила статья про антисоветы для работы с ML-экспериментами. Привет, Хабр! Это уже четвертый выпуск дайджеста по ML и работе с данными для тех, кто тащит эти напр...
При работе с Kubernetes в облаке через интерфейс платформы видно только кластеры и виртуальные машины, которые под ними крутятся. Это усложняет управление и мониторинг: пользователь просто не види...
Прозрачность блокчейн является преимуществом во многих случаях, но есть также ряд случаев использования смарт-контрактов, которые требуют конфиденциальности по различным деловым или юридическим причин...
В предыдущих сериях: «Джет» перешел на новую сеть на базе небезызвестного вендора. Как происходил процесс аудита систем, сбора «хотелок» и укрощения «заповедника мутантов» читайте в первой ча...