Что такое chaincode

Chaincode - это программа, написанная на Go, node.js или Java, которая реализует какие-либо действия в сети chaincode. Chaincode работает в защищенном контейнере Docker, изолированном от других нод в сети. Chaincode инициализирует и управляет данными в сети blockchain посредством транзакций, отправляемых приложениями.

Chaincode обычно обрабатывает бизнес-логику, согласованную членами сети (организациями), поэтому его можно называть smart contract.

Типы chaincode

В новых версиях hyperledger существует 2 типа:

  1. Lifecycle chaincode - системный chaincode, отвечающий за операции над chaincode. Используется для развертывания chaincode приложения в сети blockchain, чтобы пользователи могли вызывать функции, прописанные в chaincode. Нам не нужно устанавливать lifecycle chaincode, поскольку он является неотъемлемой частью программного обеспечения Hyperledger Fabric. Вызов осуществляется командой peer lifecycle chaincode.

  2. Application chaincode - это и есть простой chaincode (smart contract), который всегда используется в проектах Hyperledger Fabric.

Мы используем функции lifecycle chaincode чтобы сделать application chaincode пригодным для использования. Типичный процесс развертывания chaincode приложения включает следующие шаги:

  1. Упаковку chaincode приложения в пакет chaincode (архив tar)

  2. Установку chaincode на выбранных узлах (peer)

  3. Подтверждение chaincode со стороны каждой организации

  4. Фиксация (commit) chaincode в канале, когда выполнено требование подтверждения жизненного цикла (endorsement requirement). Не выполнившие commit организации не могут использовать chaincode

Политика одобрения (Endorsement policy)

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

Политика одобрения на уровне chaincode согласовываются с участниками канала, когда они утверждают chaincode для своей организации. Достаточное количество участников канала должно утвердить chaincode, чтобы соответствовать политике Channel / Application / LifecycleEndorsement, которая по умолчанию установлена ​​для большинства участников канала (пункт 3 предыдущего параграфа).

Политика одобрения по умолчанию задаётся в configtx.yaml и по умолчанию MAJORITY Endorsement, что значит одобрить должно большинство участников канала (например 2 организации из 3). Помимо стандартного значения может принимать OR или AND.

enter  image  description  here

Из скриншота следует что есть 2 политики одобрения:

  • LifecycleEndorsement - как нетрудно догадаться политика одобрения для lifecycle chaincode (пункт 4).

  • Endorsement - это политика одобрения для транзакций application chaincode.

Ниже рассмотрим политику одобрения в примерах.

Также политику одобрения можно установить через cli, используя –signature-policy .


peer lifecycle chaincode approveformyorg --channelID mychannel --signature-policy "OR('Org1.member', 'Org2.member')" --name mycc --version 1.0 --package-id mycc_1:3a8c5 --sequence 1 --tls --cafile tlsca.example.com-cert.pem

peer lifecycle chaincode commit -o orderer.example.com:7050 --channelID mychannel --signature-policy "OR('Org1.member', 'Org2.member')" --name mycc --version 1.0 --sequence 1 --init-required --tls --cafile tlsca.example.com-cert.pem

Теперь рассмотрим каждый пункт развертывания chaincode (lifecycle chaincode) по пунктам на примерах.

  1. Упаковку chaincode

Для примера я буду использовать официальный пример chaincode для Hyperledger Fabric sacc.

  1. Переходим в директорию с chaincode

cd  sacc

  1. Собственно упаковываем chaincode ( lang= node/golang )

export FABRIC_CFG_PATH=/PATH_TO_CORE_FILE

peer lifecycle chaincode package sacc.tar.gz --path sacc/ --lang golang --label sacc_1.0

ll sacc.tar.gz

  1. Установка chaincode
  1. Устанавливаем chaincode на пирах двух организаций Org1 и Org2.

export FABRIC_CFG_PATH=/PATH_TO_CORE_FILE

export CORE_PEER_TLS_ENABLED=true

export CORE_PEER_LOCALMSPID="org1MSP"

export CORE_PEER_TLS_ROOTCERT_FILE=/org1-ca-cert.pem

export CORE_PEER_MSPCONFIGPATH=/admin-org1/msp

export CORE_PEER_ADDRESS=peer1.org1.test.blockchain.lan:7051

peer lifecycle chaincode install sacc.tar.gz

export FABRIC_CFG_PATH=/PATH_TO_CORE_FILE

export CORE_PEER_TLS_ENABLED=true

export CORE_PEER_LOCALMSPID="org2MSP"

export CORE_PEER_TLS_ROOTCERT_FILE=/org2-ca-cert.pem

export CORE_PEER_MSPCONFIGPATH=/admin-org2/msp

export CORE_PEER_ADDRESS=peer1.org2.test.blockchain.lan:7051

peer lifecycle chaincode install sacc.tar.gz

  1. Подтверждение chaincode
  1. Для подтверждения нам понадобится ID установленного chaincode

peer lifecycle chaincode queryinstalled

enter image description here

  1. Подтверждаем для Org1

export CC_PACKAGE_ID=sacc_1.0:764f4ed27ad886f7c54f2cbd8f5bbc7e87769945d247021744da8fe39aca8c89

peer lifecycle chaincode approveformyorg -o orderer0.org1.test.blockchain.lan:7050 --channelID mychannel --name sacc --version 1.0 --package-id $CC_PACKAGE_ID --sequence 1 --tls --cafile /tls-orderer-ca.pem

enter image description here

  1. Проверяем кто подтвердил установку chaincode

peer lifecycle chaincode checkcommitreadiness --channelID mychannel --name sacc --version 1.0 --sequence 1 --tls --cafile /tls-orderer-ca.pem --output json

enter image description here

  1. Подтверждаем для Org2

export CC_PACKAGE_ID=sacc_1.0:764f4ed27ad886f7c54f2cbd8f5bbc7e87769945d247021744da8fe39aca8c89

peer lifecycle chaincode approveformyorg -o orderer0.org1.test.blockchain.lan:7050 --channelID mychannel --name sacc --version 1.0 --package-id $CC_PACKAGE_ID --sequence 1 --tls --cafile /tls-orderer-ca.pem

enter image description here

  1. Проверяем кто подтвердил установку chaincode

peer lifecycle chaincode checkcommitreadiness --channelID mychannel --name sacc --version 1.0 --sequence 1 --tls --cafile /tls-orderer-ca.pem --output json

enter image description here

Фиксация ( commit ) chaincode

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

  1. Для демонстрации работы политики одобрения сделаем commit который приведёт к неодобренной транзакции. Произойдёт это потому что сделала commit только Org1, в следствии чего не была достигнута политика одобрения.

peer lifecycle chaincode commit -o orderer0.org1.test.blockchain.lan:7050 --channelID mychannel --name sacc --version 1.0 --sequence 1 --tls --cafile /tls-orderer-ca.pem --peerAddresses peer1.org1.test.blockchain.lan:7051 --tlsRootCertFiles /org1-ca-cert.pem

enter image description here

enter image description here

  1. Теперь сделаем правильный commit от двух организаций

peer lifecycle chaincode commit -o orderer0.org1.test.blockchain.lan:7050 --channelID mychannel --name sacc --version 1.0 --sequence 1 --tls --cafile /tls-orderer-ca.pem --peerAddresses peer1.org1.test.blockchain.lan:7051 --tlsRootCertFiles /org1-ca-cert.pem --peerAddresses peer1.org2.test.blockchain.lan:7051 --tlsRootCertFiles /org2-ca-cert.pem

enter image description here

enter image description here

Commit для application chaincode

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

Так как я использую политику одобрения по умолчанию (endorsement) то транзакцию опять-таки должно одобрить большинство.

  1. Выполняем метод, который одобрит только одна организация

peer chaincode invoke -o orderer0.org1.test.blockchain.lan:7050 --tls --cafile /tls-orderer-ca.pem -C mychannel -n sacc -c '{"Args":["set","name","kc"]}'

enter image description here

enter image description here

  1. Выполняем метод, который одобрят обе организация

peer  chaincode  invoke -o  orderer0.org1.test.blockchain.lan:7050 --tls --cafile /tls-orderer-ca.pem -C  mychannel -n  sacc -c '{"Args":["set","name","kc"]}' --peerAddresses  peer1.org1.test.blockchain.lan:7051 --tlsRootCertFiles /org1-ca-cert.pem --peerAddresses  peer1.org2.test.blockchain.lan:7051 --tlsRootCertFiles /org2-ca-cert.pem

peer chaincode query -C mychannel -n sacc -c '{"Args":["get","name"]}'

enter image description here

enter image description here

Еще раз выполняем метод, который одобрит только одна организация, заменяя значение на новое


peer chaincode invoke -o orderer0.org1.test.blockchain.lan:7050 --tls --cafile /tls-orderer-ca.pem -C mychannel -n sacc -c '{"Args":["set","name","myname"]}'

peer chaincode query -C mychannel -n sacc -c '{"Args":["get","name"]}'

В итоге видим, что значение сталось старым, хотя статус был 200.

enter image description here

enter image description here

Выполняем метод, который одобрят обе организация


peer chaincode invoke -o orderer0.org1.test.blockchain.lan:7050 --tls --cafile /tls-orderer-ca.pem -C mychannel -n sacc -c '{"Args":["set","name","myname"]}'  --peerAddresses peer1.org1.test.blockchain.lan:7051 --tlsRootCertFiles /org1-ca-cert.pem --peerAddresses peer1.org2.test.blockchain.lan:7051 --tlsRootCertFiles /org2-ca-cert.pem

peer chaincode query -C mychannel -n sacc -c '{"Args":["get","name"]}'

Вот теперь значение изменилось, потому что одобрило большинство.

enter image description here

enter image description here