Политики подтверждения

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

Примечание

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

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

Несколько способов указать требующиеся подтверждения

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

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

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

Чтобы проиллюстрировать ситуацию, в которой необходимы различные типы политик подтверждения, рассмотрим канал, в котором происходит обмен машинами. «Создание» — также известное как «выпус» — машины как актива, которым можно торговать (другими словами, создание пары ключ-значение для этой машины в world state), потребует удовлетворения политики подтверждения на уровне чейнкода. О том, как установить политику подтверждения на уровне чейнкода речь пойдет в следующей секции).

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

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

Установка политик подтверждения на уровне чейнкода

Участники канала соглашаются с такими политиками, когда соглашаются с определением чейнкода для их организаций. Достаточное число участников канала должно одобрить определение чейнкода, чтобы удовлетворить политику Channel/Application/LifecycleEndorsement, которая, по умолчанию, установлена на большинство участников канала, прежде чем определение может быть сохранено в канале. Когда определение сохранено, чейнкод готов к использованию. Любой вызов чейнкода, пишущего в реестр, должен быть одобрен нужным числом участников канала для удовлетворения политики подтверждения.

Вы можете указать политику подтверждения для чейнкода через Fabric SDKs. Пример как это сделать показан тут: Как установить и запустить чейнкод в документации SDK Node.js. Вы также можете создать политику подтверждения из CLI, когда вы сохраняете определение чейнкода, с использованием флага --signature-policy.

Примечание

Не волнуйтесь про синтаксис политик ('Org1.member' и др.) на данный момент. Мы обсудим синтаксис позже.

Пример:

peer lifecycle chaincode approveformyorg --channelID mychannel --signature-policy "AND('Org1.member', 'Org2.member')" --name mycc --version 1.0 --package-id mycc_1:3a8c52d70c36313cfebbaf09d8616e7a6318ababa01c7cbe40603c373bcfe173 --sequence 1 --tls --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem --waitForEvent

Команда выше одобряет определение чейнкода mycc с политикой AND('Org1.member', 'Org2.member'), которая требует, чтобы транзакцию подписали 1 участник Org1 И 1 участник Org2. После одобрения определения чейнкода mycc нужным числом участников, определение и политика могут быть сохранены в канал следующей командой:

peer lifecycle chaincode commit -o orderer.example.com:7050 --channelID mychannel --signature-policy "AND('Org1.member', 'Org2.member')" --name mycc --version 1.0 --sequence 1 --init-required --tls --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem --waitForEvent --peerAddresses peer0.org1.example.com:7051 --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt --peerAddresses peer0.org2.example.com:9051 --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt

Заметьте, что если включена классификация identity (подробнее: Membership Service Providers (MSP)), можно использовать роль PEER для того, чтобы разрешить подтверждать только пирам.

Пример:

peer lifecycle chaincode approveformyorg --channelID mychannel --signature-policy "AND('Org1.peer', 'Org2.peer')" --name mycc --version 1.0 --package-id mycc_1:3a8c52d70c36313cfebbaf09d8616e7a6318ababa01c7cbe40603c373bcfe173 --sequence 1 --tls --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem --waitForEvent

Кроме возможностей указать политику подтверждения через CLI или SDK, чейнкод может использовать также политики, указанные в конфигурации канала. Вы можете указать флаг --channel-config-policy, чтобы выбрать политику канала, используемую для конфигурации канала или в ACL.

Пример:

peer lifecycle chaincode approveformyorg --channelID mychannel --channel-config-policy Channel/Application/Admins --name mycc --version 1.0 --package-id mycc_1:3a8c52d70c36313cfebbaf09d8616e7a6318ababa01c7cbe40603c373bcfe173 --sequence 1 --tls --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem --waitForEvent

Если вы не укажите политику, определение чейнкода будет использовать политику Channel/Application/Endorsement, которая требует, чтобы транзакция была одобрена большинством участников канала. Эта политика зависит от состава участников, она будет автоматически обновлена при добавлении или удалении организации. Преимущество в использовании политик канала заключается в том, что они обновляются автоматически при изменении состава участников канала.

Если вы укажите политику подтверждения через флак --signature-policy или через SDK, вам потребуется обновлять политику, когда организации покидают канал или присоединяются к нему. Новая организация, добавленная к каналу после определения чейнкода, имеет возможность помотреть (query, или же запросить) этот чейнкод (при наличии доступа, определенного политиками канала или любыми проверками в чейнкоде), но не сможет исполнять (execute) или подтверждать чейнкод. Только организации, указанные в политике подтверждения, могут подписывать транзакции.

Синтаксис политики подтверждения

Как вы могли заметить, политики выражаются через principals («principals» — это identities, подходящие под определенную роль). Principals указываются через 'MSP.ROLE', где MSP — необходимый идентификатор MSP и ROLE — одна из четырех ролей: member, admin, client и peer.

Несколько примеров корректных principals:

  • 'Org0.admin': любой администратор из Org0 MSP
  • 'Org1.member': любой участник Org1 MSP
  • 'Org1.client': любой клиент Org1 MSP
  • 'Org1.peer': любой пир Org1 MSP

Синтаксис языка политик такой:

EXPR(E[, E...])

Где EXPR — это AND, OR или OutOf, а E — это либо principal, либо другой вызов EXPR.

Примеры:
  • AND('Org1.member', 'Org2.member', 'Org3.member') требует одну подпись от каждого из трех principal.
  • OR('Org1.member', 'Org2.member') требует одну подпись от любого из двух principals.
  • OR('Org1.member', AND('Org2.member', 'Org3.member')) требует либо одну подпись от участника из Org1 MSP или же набор из двух подписей — одна от участника Org2 MSP и одна от участника Org3 MSP.
  • OutOf(1, 'Org1.member', 'Org2.member') — то же самое, что OR('Org1.member', 'Org2.member').
  • аналогично, OutOf(2, 'Org1.member', 'Org2.member') эквивалентно AND('Org1.member', 'Org2.member'), а OutOf(2, 'Org1.member', 'Org2.member', 'Org3.member') эквивалентно OR(AND('Org1.member', 'Org2.member'), AND('Org1.member', 'Org3.member'), AND('Org2.member', 'Org3.member')).

Установка политик подтверждения на уровне коллекции

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

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

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

Синтаксис таких политик такой же, как и у политик чейнкод-уровня — в конфигурации коллекции вы можете указать endorsementPolicy с signaturePolicy или channelConfigPolicy. За большими подробностями обратитесь к Private Data.

Установка политик подтверждения на уровне ключа

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

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

Shim-API предоставляет следующие функции для установки и получения политики подтверждения обычного ключа:

Примечание

ep ниже означает «endorsement policy» (политика подтверждения), которая может быть определена с использованиям вышеуказанного синтаксиса или при помощи последующих функций. Любой подход сгенерирует бинарную версию политик подтверждения, которая может быть использована базовым shim API.

SetStateValidationParameter(key string, ep []byte) error
GetStateValidationParameter(key string) ([]byte, error)

Для ключей, составляющих Конфиденциальные данные в коллекции применяются следующие функции:

SetPrivateDataValidationParameter(collection, key string, ep []byte) error
GetPrivateDataValidationParameter(collection, key string) ([]byte, error)

Чтобы помочь при создании политик и их сериализации в байтовые массивы, Go shim предоставляет расширение с вспомогательными функциям, позволяющими разработчику чейнкода работать с политиками подтверждения через MSP индентификаторы организаций, подробней тут — KeyEndorsementPolicy:

type KeyEndorsementPolicy interface {
    // Policy возвращает политику в виде массива байт
    Policy() ([]byte, error)

    // AddOrgs добавляет указанные организации в список организаций, от которых требуется подтверждение
    AddOrgs(roleType RoleType, organizations ...string) error

    // DelOrgs удаляет указанные организации из существующей политики, действующей на уровне данного KVS-ключа.
    DelOrgs(organizations ...string) error

    // ListOrgs возвращает массив организаций канала, от которых требуется подтверждение
    ListOrgs() ([]string)
}

Например, чтобы указать политику подтверждения для ключа, в которой для изменения этого ключа требуется подтверждение от двух конкретных организациий, Передайте MSPID обоих организаций функции AddOrgs(), А потом вызовите Policy(), чтобы создать сериализованную в байтовый массив политику, которую можно будет передать в SetStateValidationParameter().

Чтобы добавить это расширение shim к вашему чейнкоду в качестве зависимости, смотрите Управление внешними зависимостями для чейнкода, написанного на Go.

Проверка

Во время сохранения (commit), установка значения ключа не отличается от установки политики одобрения ключа — и то, и другое обновляет состояние ключа и проверяется по тем же правилам.

Проверка не указан параметр проверки указан параметр проверки
изменение значения проверка политики чейнкода или коллекции проверка политики ключа
изменения политик ключа проверка политики чейнкода или коллекции проверка политики ключа

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

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

Если политика ключа удалена (установлена значением nil), то политики чейнкода или коллекции вновь отвечают за ключ.

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