Жизненный цикл чейнкода: пять шагов до первого вызова
- Зачем это нужно
- Пять шагов целиком
- Шаг 1: упаковать
- Шаг 2: установить на каждый пир
- Шаг 3: одобрить от своей организации
- Шаг 4: посмотреть, кто согласился
- Шаг 5: зафиксировать на канале
- Обновление: версия и номер правки
- Типичные ошибки
- Шпаргалка по главе
- Словарь главы
- Что должен уметь после главы
- Проверка по главе
- Куда дальше: проверенные ресурсы
Зачем это нужно
В Ethereum установка контракта — одна транзакция. Отправил байт-код, получил адрес, работай.
В Fabric это пять шагов, и такая громоздкость не случайна. Контракт здесь исполняют несколько независимых организаций. Прежде чем код начнёт менять общий реестр, каждая из них должна посмотреть на него и письменно согласиться. Пять шагов — это и есть процедура такого согласования.
В прошлой главе учебный скрипт network.sh deployCC делал всё сам. Эта глава — про то, что он делал, потому что на чемпионате скрипта не будет, а будут отказы вида «chaincode definition not agreed to by this org».
Пять шагов целиком
Первые два шага никто, кроме вас, не видит: собрать архив и положить его на пиры. Последние три — настоящие транзакции: они попадают в цепочку, и по ним потом можно посмотреть, кто и когда согласился.
Шаг 1: упаковать
peer lifecycle chaincode package zachetka.tar.gz \
--path ./zachetka --lang node --label zachetka_1.0
Что внутри архива:
metadata.json
code.tar.gz
Шаг 2: установить на каждый пир
. ./env.sh 1
peer lifecycle chaincode install zachetka.tar.gz
. ./env.sh 2
peer lifecycle chaincode install zachetka.tar.gz
INFO [cli.lifecycle.chaincode] submitInstallProposal -> Chaincode code package identifier:
zachetka_1.0:8853d6701bcad0b97bbb6ef75778304e38684d8f23c4dc4dff06006d54f4148b
Обратите внимание: идентификатор одинаковый на обоих пирах.
Это ключевая проверка всей процедуры. Организации одобряют не «чейнкод по имени», а конкретный отпечаток кода. Если бы вторая организация установила чуть изменённый архив, идентификатор бы отличался — и согласия не сложились бы.
Пересобрали проект и упаковали заново — идентификатор сменился, даже если код не менялся ни на строчку (метки времени в архиве). Одобрение со старым идентификатором станет недействительным. Поэтому упаковывают один раз, и один и тот же файл раздают всем организациям.
Посмотреть, что установлено:
peer lifecycle chaincode queryinstalled
Installed chaincodes on peer:
Package ID: basic_1.0:42c5880fedf163ab14f7328cb9c10a7b341cc1008926620749512c3fc5dd48db, Label: basic_1.0
Package ID: zachetka_1.0:8853d6701bcad0b97bbb6ef75778304e38684d8f23c4dc4dff06006d54f4148b, Label: zachetka_1.0
Шаг 3: одобрить от своей организации
peer lifecycle chaincode approveformyorg \
-o localhost:7050 --ordererTLSHostnameOverride orderer.example.com \
--tls --cafile "$ORDERER_CA" \
-C pgk -n zachetka --version 1.0 \
--package-id zachetka_1.0:8853d6701bcad0b97bbb6ef757783... \
--sequence 1
INFO [chaincodeCmd] ClientWait -> txid [efb833de4e2e…] committed with status (VALID) at localhost:7051
approveformyorg — это согласие организации, а не пира. Даже если у организации десять пиров, одобрение делается один раз и от её имени. А вот install нужен на каждом пире, который будет исполнять код.
Шаг 4: посмотреть, кто согласился
peer lifecycle chaincode checkcommitreadiness -C pgk -n zachetka \
--version 1.0 --sequence 1 --output json
После одобрения только первой организации:
{
"approvals": {
"Org1MSP": true,
"Org2MSP": false
}
}
Попробуем зафиксировать, не дожидаясь второй:
Error: failed to create signed transaction: proposal response was not successful,
error code 500, msg failed to invoke backing implementation of 'CommitChaincodeDefinition':
chaincode definition not agreed to by this org (Org2MSP)
Сообщение прямо называет виновника: not agreed to by this org (Org2MSP). Одобряем вторую и смотрим снова:
{
"approvals": {
"Org1MSP": true,
"Org2MSP": true
}
}
checkcommitreadiness — первое, что нужно запускать при любом отказе на этом шаге. Он не меняет ничего и сразу показывает, чьего согласия не хватает.
Шаг 5: зафиксировать на канале
peer lifecycle chaincode commit \
-o localhost:7050 --ordererTLSHostnameOverride orderer.example.com \
--tls --cafile "$ORDERER_CA" -C pgk -n zachetka \
--version 1.0 --sequence 1 \
--peerAddresses localhost:7051 --tlsRootCertFiles "$PEER0_ORG1_CA" \
--peerAddresses localhost:9051 --tlsRootCertFiles "$PEER0_ORG2_CA"
INFO [chaincodeCmd] ClientWait -> txid [a0e1992a8cc5…] committed with status (VALID) at localhost:9051
INFO [chaincodeCmd] ClientWait -> txid [a0e1992a8cc5…] committed with status (VALID) at localhost:7051
Проверяем, что вступило в силу:
peer lifecycle chaincode querycommitted -C pgk -n zachetka
Committed chaincode definition for chaincode 'zachetka' on channel 'pgk':
Version: 1.0, Sequence: 1, Endorsement Plugin: escc, Validation Plugin: vscc,
Approvals: [Org1MSP: true, Org2MSP: true]
Теперь контракт можно вызывать. Первый вызов идёт заметно дольше остальных: пир поднимает для него контейнер.
Обновление: версия и номер правки
Допустим, в контракт добавили функции. Обновление — это те же пять шагов, но с номером правки на единицу больше.
peer lifecycle chaincode package zachetka2.tar.gz --path ./zachetka --lang node --label zachetka_2.0
peer lifecycle chaincode install zachetka2.tar.gz # на обоих пирах
peer lifecycle chaincode approveformyorg ... --version 2.0 --package-id <новый> --sequence 2
peer lifecycle chaincode commit ... --version 2.0 --sequence 2
Committed chaincode definition for chaincode 'zachetka' on channel 'pgk':
Version: 2.0, Sequence: 2, Endorsement Plugin: escc, Validation Plugin: vscc,
Approvals: [Org1MSP: true, Org2MSP: true]
Разница между двумя числами важна:
--version— произвольная строка для людей. Сеть её не проверяет и никаких решений по ней не принимает. Можно написать2.0, можнопосле-аудита.--sequence— целое число, по которому сеть отличает одно определение от другого. Растёт строго на единицу, повторить прежнее нельзя.
Состояние при обновлении не трогается. Ключи, записанные старой версией, остаются как были, и новый код работает поверх них. Отсюда обычная забота при обновлении: если формат хранения поменялся, старые записи придётся уметь читать — или переписать их отдельной функцией.
Через номер правки меняют не только код. Тем же способом меняют политику подтверждения конкретного контракта — например, «эту сделку должны подписывать все три организации, а не большинство».
Типичные ошибки
Ошибка 1. Повторили прежний номер правки.
Error: ... requested sequence is 1, but new definition must be sequence 2
Номер растёт строго на единицу. Если предыдущая попытка зафиксировалась, следующая должна быть на единицу больше — даже если она исправляет ошибку.
Ошибка 2. Одобрили с чужим идентификатором пакета.
Опечатка в длинной шестнадцатеричной строке не вызовет ошибки на шаге одобрения. Она проявится на checkcommitreadiness: организация будет числиться не согласившейся, хотя команду вы выполняли.
Ошибка 3. Забыли установить пакет на второй пир.
Одобрение пройдёт, фиксация пройдёт. Упадёт первый вызов, потому что один из пиров не сможет исполнить код.
Ошибка 4. Собрали архив из несобранного проекта.
Error: endorsement failure during invoke. response: status:500
message:"error in simulation: failed to execute transaction: could not launch chaincode"
Для TypeScript упаковывают папку, где уже есть dist.
Ошибка 5. Перепутали имя на канале и имя папки.
-n zachetka — это имя, под которым контракт вызывают. С названием папки и меткой пакета оно никак не связано, и их расхождение — нормальная ситуация, а не ошибка.
Шпаргалка по главе
| Шаг | Команда |
|---|---|
| Упаковать | peer lifecycle chaincode package cc.tar.gz --path ./cc --lang node --label cc_1.0 |
| Установить | peer lifecycle chaincode install cc.tar.gz |
| Узнать идентификатор | peer lifecycle chaincode queryinstalled |
| Одобрить | peer lifecycle chaincode approveformyorg -C pgk -n cc --version 1.0 --package-id … --sequence 1 |
| Кто согласился | peer lifecycle chaincode checkcommitreadiness -C pgk -n cc --version 1.0 --sequence 1 --output json |
| Зафиксировать | peer lifecycle chaincode commit -C pgk -n cc --version 1.0 --sequence 1 --peerAddresses … |
| Что на канале | peer lifecycle chaincode querycommitted -C pgk -n cc |
| Обновить | те же шаги с --sequence на единицу больше |
Словарь главы
| Термин | Что это |
|---|---|
| Пакет чейнкода | Архив .tar.gz с исходниками и меткой |
| Идентификатор пакета | Метка плюс хеш содержимого; одинаковый код — одинаковый идентификатор |
| Определение чейнкода | Что зафиксировано на канале: имя, версия, номер правки, политика |
approveformyorg | Согласие организации на конкретное определение |
checkcommitreadiness | Проверка «кто уже согласился»; ничего не меняет |
commit | Фиксация определения на канале; выполняется один раз |
--sequence | Номер правки определения: целое, растёт на единицу |
--version | Строка версии для людей; сеть её не проверяет |
Цель: скорость ≥ 90 зн/мин, точность ≥ 88%
peer lifecycle chaincode package cc.tar.gz --path ./cc --lang node --label cc_1.0
Что должен уметь после главы
- назвать пять шагов и сказать, какие из них локальные, а какие попадают в цепочку;
- упаковать чейнкод и установить его на оба пира;
- объяснить, зачем нужен идентификатор пакета и почему он одинаков у всех;
- одобрить определение от каждой организации и проверить готовность;
- зафиксировать определение и посмотреть, что вступило в силу;
- обновить контракт с правильным номером правки;
- по тексту отказа понять, чьего согласия не хватает.
Проверка по главе
Сводная проверка по всей главе: 10 вопросов, 5:00 на всё, без подсказок по ходу. Вопросы показываются по одному, ответ изменить нельзя. Если время выйдет — экзамен завершится с тем, что успел ответить. Пересдавать можно сколько угодно раз.
Куда дальше: проверенные ресурсы
- Жизненный цикл чейнкода — все пять шагов и их настройки.
- Развёртывание чейнкода в учебной сети — те же команды пошагово.
- Справочник команд peer — все флаги
peer lifecycle chaincode. - Политика подтверждения на уровне контракта — как поменять её через номер правки.
Комментарии
Обсуждение живёт в GitHub Discussions и грузится с чужого домена — поэтому только по нажатию.