Конфиденциальные данные

Что такое конфиденциальные данные?

В случаях, когда группе организаций канала необходимо скрыть часть данных от других организаций канала, они могут создать новый канал только из огранизаций, которым нужен доступ к этим данным. Однако создание отдельного канала создает административные накладные расходы (поддержка актуальных версий чейнкода, политик, MSP и т.д.), и не решает проблемы в случаях, когда вы хотите, чтобы все участники канала увидели транзакцию, но при этом некоторые ее данные были от них скрыты.

Поэтому Fabric предоставляет возможность создавать Коллекции конфиденциальных данных, которые позволяют определенному подмножеству организаций канала иметь возможность подтверждать, сохранять или запрашивать конфиденциальные данные без нужды заводить отдельный канал.

Что такое «коллекция конфиденциальных данных»?

Коллекция - это совокупность двух элементов:

  1. Самих конфиденциальных данных, передаваемых от пира к пиру через gossip-протокол только организациям, авторизованным на доступ к данным. Эти данные хранятся в отдельной конфиденциальной базе данных состояния (state DB) на пирах авторизованных организаций, доступной в чейнкоде авторизованных пиров. Ордеринг-служба не вовлечена в этот механизм и не имеет доступа к данным. Заметьте, что так как gossip-протокол распространяет конфиденциальные данные от пира одной организации к пиру другой, требуется создать anchor-пиры в канале, и настроить CORE_PEER_GOSSIP_EXTERNALENDPOINT на каждом пире для установления меж-организационного сообщения.
  2. Хеш этих данных подтверждается, подвергается ордерингу и записывается в реестр каждого пира канала. Хеш служит доказательством транзакции и используется для проверки state и для проведения аудита.

Следующая диаграмма иллюстрирует содержимое реестра на пире с доступом к конфиденциальным данным (authorized peer) и на пире без доступа к ним (unauthorized peer).

private-data.private-data

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

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

В каких случаях создавать коллекцию внутри канала, а в каких создавать отдельный канал?

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

Сценарий использования коллекций

Представьте группу из 5 организаций канала по торговле продукцией:

  • Фермер (Farmer) продает свои товары за границу
  • Дистрибьютор (Distributer) поставляет товары за границу
  • Грузоотправитель (Shipper) перевозит товары между сторонами
  • Оптовик (Wholesaler) приобретает товары у агентов по сбыту
  • Ритейлер (Retailer) покупает товары от грузоотправителей и оптовиков

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

Дистрибьютор хочет иметь отчасти конфиденциальные отношения с оптовиком, так как выставляет ему более низкие цены, чем ритейлеру.

Оптовик также хочет иметь такие отношения с ритейлером и грузоотправителем.

Вместо того, чтобы создавать по маленькому каналу на каждое такое отношение, можно организовать несколько коллекций конфиденциальных данных (PDC, Private Data Collection):

  1. PDC1: Дистрибьютор, Фермер и Грузоотправитель
  2. PDC2: Дистрибьютор и Оптовик
  3. PDC3: Оптовик, Ритейлер и Грузоотправитель

private-data.private-data

Пиры, принадлежащие дистрибьютору будут иметь несколько приватных баз данных внутри их реестра, включающих коллекции PDC1 и PDC2.

private-data.private-data

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

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

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

  1. Клиентское приложение посылает proposal-запрос к подтверждающим пирам, чтобы вызвать функцию чейнкода (запись или чтение конфиденциальных данных). Подтверждающие пиры должны быть частью организации с доступом к коллекции. Конфиденциальные данные, или данные, использующиеся для их генерации, посылаются в поле transient proposal“а.
  2. Подтверждающие пиры выполняют транзакцию и сохраняют конфиденциальные данные в transient data store (временном хранилище пира). Они распространяют конфиденциальные данные, основываясь на политике коллекции, авторизованным пирам по gossip-протоколу.
  3. Подтверждающие пиры отправляют ответ на proposal обратно клиенту. Ответ включает подтвержденный read/write set, включающий публичный данный вместе с хешем ключей и значений конфиденциальных данных. Никаких конфиденциальных данных клиенту не посылается. Более детальная информация по подтверждению транзакций с конфиденциальными данными.
  4. Клиентское приложение посылает транзакцию (включающую ответ на proposal с хешами конфиденциальных данных) ордеринг-службе. Транзакция с хешами конфиденциальных данных включается в блок как обычная транзакция. Блок с хешами конфиденциальных данных распространяется на все пиры. Таким образом, все пиры канала могут проверить транзакции с хешами конфиденциальных данных согласованно, без знания конфиденциальных данных.
  5. Во время сохранения блока, авторизованные пира применяют политику коллекции, чтобы понять, имеют ли они доступ к конфиденциальным данным. Если да, они проверят свой локальный transient data store, чтобы определить, получили ли они эти данные во время подтверждения чейнкода. Если не получили, то они попытаются получить данные с другого авторизованного пира. Потом они сверят хеш конфиденциальных данных с хешем в публичном блоке и сохранят транзакцию и блок. Во время проверки/сохранения, конфиденциальные данные перемещаются в их копию конфиденциальной state-базе данных и их конфиденциального writeset хранилища. Затем конфиденциальные данные удаляются из transient data store.

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

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

Есть несколько возможностей PDC, позволяющих обмен и проверку конфиденциальных данных:

  • Во-первых, вам не нужно быть участником коллекции, чтобы записать что-либо в нее, при условии, что соблюдена политика подтверждения. Политика подтверждения может быть определена на уровне чейнкода, на уровне ключей (используя основанное на state подтверждение) или на уровне коллекции (начиная с Fabric v2.0).
  • Во-вторых, начиная с v1.4.2 существует API чейнкода GetPrivateDataHash(), позволяющее чейнкоду или пирам без доступа к коллекции получать хеш по ключу. Это важная функция, в чем вы убедитесь позже, так как она позволяет чейнкоду сверять хеши конфиденциальных данных с теми, что лежат в блокчейне.

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

Паттерны распространения конфиденциальных данных

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

  • Контроль доступа (Access Control) с помощью чейнкода - Вы можете реализовать контроль доступа через чейнкод, чтобы указать, какие клиенты могут совершать запросы PDC. Например, храните ACL (Access Control List) для конфиденциальных данных: в чейнкоде получите удостоверение клиента (через GetCreator() API чейнкода или CID (client identity) library API GetID() или GetMSPID()) и проверьте, что он имеет доступ к конфиденциальным данным, и только тогда их возвращайте. Похожим образом вы можете потребовать, чтобы клиент передал в чейнкод пароль, который должен сойтись с паролем из PDC. Такой же подход может использоваться, чтобы ограничить доступ пользователя к данным не из PDC.
  • Распространение конфиденциальных данных out-of-band (за пределами полосы передачи) - Вы можете распространять конфиденциальные данные вне блокчейна другим организациям, а они могут сверить их хеш с тем, что лежит в блокчейне с помощью GetPrivateDataHash() API чейнкода. Например, организация, желающая купить у вас актив, может проверить характеристики актива и ваше право собственности на него, сверив хеш с тем, что лежит в блокчейне - перед тем, как согласиться на покупку.
  • Распространение данных в другие коллекции - Вы можете „распространить“ конфиденциальные данные при помощи чейнкода, который создаст соответствующий ключ/значение в PDC другой организации: передайте конфиденциальные данные в поле transient, затем чейнкод может проверить, что переданные данные совпадают с теми, что в блокчейне (через GetPrivateDataHash()), а затем записать данные в PDC другой организации.
  • Перенос конфиденциальных данных в PDC другой организакции - Вы можете „перенести“ конфиденциальные данные при помощи чейнкода, который удалит ключ в вашей коллекции и создаст его в коллекции другой организакции. Чейнкод такой же, что и в предыдущем паттерне, но с удалением ключа в вашем PDC. Чтобы доказать, что транзакция всегда удаляет ключ и добавляет его в другую коллекцию, вы можете потребовать подтверждения от третьей стороны, такой как аудитор или регулятор.
  • Использование конфиденциальных данных для получения согласия о транзакции Если вы хотите согласии о проведении транзакции второй стороны до того как транзакция совершена (например, запись в блокчейне, что они соглашаются купить актив за определенную цену), тогда чейнкод может потребовать от них заранее согласиться с транзакцией, записав некий конфиденциальный ключ в их PDC или ваш PDC, который потом будет проверен чейнкодом через GetPrivateDataHash(). Фактически, ровно такой же механим использует встроенная система жизненного цикла чейнкода, чтобы убедиться, что организации согласились с определением чейнкода до того, как он сохранен в канал. Начиная с Fabric v2.0, этот паттерн становится еще более эффективным с политиками подтверждения на уровне коллекции, с помощью которых можно убедиться, что чейнкод был выполнен и одобрен на пире владельца коллекции. Как вариант, может использоваться взаимносогласованный ключ с политикой подтверждения на уровне ключа, который обновляется по условиям преждевременного согласия и подтверждается пирами нужных организаций.
  • Хранение сторон транзакции в тайне - Вариации предыдущего паттерна могут использоваться, чтобы предотвратить утечку сторон транзакции. Например, покупатель указывает свое согласие на покупку в своей коллекции, а в последующей транзакции продавец упоминает конфиденциальные данные покупателя в своей PDC. Доказательство транзакции и с хешированными упоминаниями хранится в блокчейне, только покупатель и продавец знают, что они стороны транзакции, но они могут доказать это третьей стороне в другой транзакции, которая может проверить их хеши.

Заметьте, что, используя паттерны выше, конфиденциальные данные можно контролировать также, как и обычные данные состояния канала:

  • Контроль доступа на уровне ключа - Вы можете внести удостоверение вашего права на собственность как часть значения из PDC, так, что последующие транзакции могут проверить, что инициатор имеет право распространять или переносить данные. В этом случае чейнкод получит удостоверения инициатора (через GetCreator() API чейнкода или CID (client identity) library API GetID() или GetMSPID()), объединит его с другими конфиденциальными данными, переданными в чейнкод, и сверит хеш получившихся данных и проверит, что он сходится с тем, что лежит в блокчейне (через GetPrivateDataHash()).
  • Политики подтверждения на уровне ключа - Как и с обычными данными канала, вы можете установить политику подтверждения на уровне ключа, чтобы установить, какие организации должны подтвердить транзакции, распространяющие или переносящие конфиденциальные данные, используя SetPrivateDataValidationParameter() API чейнкода.

Пример сценария: передача актива с использованием PDC

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

  • Актив может быть представлен открытым ключом UUID. Открыто хранится только информация о владельце актива, больше ничего не известно.
  • Чейнкод потребует, чтобы запрос о передаче актива исходил от клиента, владеющего активом, а изменение информации об активе должно быть подтверждено организацией регулятора и организацией владельца, что регулируется через политики подтверждения на уровне ключа.
  • Конфиденциальные детали актива хранятся в PDC владельца по ключу - хеш от UUID. Другие организации и ордеринг-служба будут видеть только хеш деталей актива.
  • Давайте предположим, что регулятор - участник каждой коллекции, и, следовательно, хранит конфиденциальные данные, хотя это не требуется.

Транзакция по заключению сделки будет проходить так:

  1. Вне блокчейна, продавец и потенциальный покупатель заключают сделку по покупке актива за определенную цену.
  2. Продавец предоставляет доказательство владения активом, или передав конфиденциальные детали вне блокчейна, или предоставив покупателю права на чтение данных на узле продавца или регулятора.
  3. Покупатель сверяет хеш конфиденциальных данных с тем, что лежит на блокчейне.
  4. Покупатель вызывает чейнкод, чтобы записать детали торгов в своей PDC. Чейнкод вызывается на пире покупателя и, возможно, на пире регулятора, если того требует политика подтверждения.
  5. Текущий владелец (продавец) вызывает чейнкод для продажи и передачи актива, и передает чейнкоду конфиденциальные детали и информацию о торгах. Чейнкод вызывается на пирах продавца, покупателя и регулятора, для того, чтобы удовлетворить политику подтверждения обновления открытого состояния, и политики подтверждения PDC покупателя и PDC продавца.
  6. Чейнкод проверяет, что инициирующий его клиент - владелец, проверяет конфиденциальные детали по хешу из коллекции продавца, и проверяет детали торгов по хешу из коллекции покупателя. Затем чейнкод обновляет открытые состояния актива - устанавливает покупателя как владельца и политику подтверждения на покупающую организацию и регулятора, записывает конфиденциальные детали в PDC покупателя и, возможно, удаляет конфиденциальные детали из коллекции продавца. Перед финальным подтверждением, подтверждающие пиры проверяют, что конфиденциальные данные распространены на все авторизованные пиры продавца и регулятора.
  7. Продавец подает транзакцию с открытыми данными хешем конфиденциальных на ордеринг, после чего блок с транзакцией распределяется на все пиры канала.
  8. Каждый пир проверит, что политика подтверждения была удовлетворена (имеются подтверждения от продавца, покупателя и регулятора) и что со времени выполнения чейнкода ни открытые, ни конфиденциальные данные не были изменены какой-либо другой транзакцией.
  9. Все пиры сохранят транзакцию как валидную, так как она прошла все проверки. Пиры покупателя и регулятора получат конфиденциальные данные от других авторизованных пиров, так как они не получили их во время подтверждения, и сохранят их в свои private data state database (если хеш конфиденциальных данных сходится с хешем из транзакции).
  10. С завершением транзакции актив был передан, и все другие участники канала, заинтересованные в нем, смогут посмотреть историю открытого состояния актива, чтобы понять его происхождение. Они не смогут получить доступ ни к каким конфиденциальным данным, если только владелец не передаст их им.

Такой сценарий может быть расширен, например, чейнкод передачи может проверить, что банк выписал аккредетив (денежный документ, содержащий распоряжение об оплате суммы), перед передачей актива. Также участники транзакции могут не иметь своих пиров, а проводить транзакцию через доверенные организации.

Чистка конфиденциальных данных

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

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

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

Как определить PDC

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