Имена контрактов

Аудитория: Архитекторы, разработчики смарт-контрактов и приложений, администраторы

Чейнкод - это общий контейнер для развертывания кода в блокчейн-сети Hyperledger Fabric. В рамках чейнкода определяется один или несколько связанных смарт-контрактов. У каждого смарт-контракта есть уникальное в рамках чейнкода имя. Приложения обращаются к определенному смарт-контракту в чейнкоде по его имени.

В этой главе мы опишем:

Чейнкод

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

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

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

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

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

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

Имя

Каждый смарт-контракт внутри чейнкода уникальным образом идентифицируется своим именем. Смарт-контракт может явно назначить это имя при создании класса или позволить классу Contract неявно назначить имя по умолчанию.

Изучите чейнкод papercontract.js file:

class CommercialPaperContract extends Contract {

    constructor() {
        // Unique name when multiple contracts per chaincode file
        super('org.papernet.commercialpaper');
    }

Здесь конструктор CommercialPaperContract задает имя контракта как org.papernet.commercialpaper. В результате внутри чейнкода papercontract этот смарт-контракт связан с именем контракта org.papernet.commercialpaper.

Если имя контракта не задано явным образом, тогда ему присваивается имя по умолчанию – имя класса. В нашем примере имя контракта по умолчанию будет – CommercialPaperContract.

Выбирайте имена с осторожностью. Дело даже не в том, что у каждого смарт-контракта имя должно быть уникальным, но еще и в том, что оно должно быть «говорящим» для того, кто его читает. В частности, рекомендуется использовать явный порядок присвоения имен по образцу DNS – для того, чтобы названия были прозрачными и со смыслом. Так, например, имя org.papernet.commercialpaper означает, что этот контракт задан для стандартных коммерческих ценных бумаг на сети PaperNet.

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

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

Приложение

Как только чейнкод будет установлен на узле и развернут в канале, его смарт-контракты станут доступны приложению:

const network = await gateway.getNetwork(`papernet`);

const contract = await network.getContract('papercontract', 'org.papernet.commercialpaper');

const issueResponse = await contract.submitTransaction('issue', 'MagnetoCorp', '00001', '2020-05-31', '2020-11-30', '5000000');

Из приведенного примера видно, как приложение обращается к смарт-контракту через вызов метода network.getContract(). По имени смарт-контракта org.papernet.commercialpaper из чейнкода papercontract получается ссылка на объект contract, который используется для отправки транзакций по выпуску коммерческих ценных бумаг в вызове функции API contract.submitTransaction().

Контракт по умолчанию

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

default.contract Смарт-контракт по умолчанию - это первый контракт, определенный в чейнкоде.

Согласно этой диаграмме, CommercialPaperContract - контракт по-умолчанию. Даже если бы у нас было два смарт-контракта, смарт-контракт по-умолчанию облегчил бы написание нашего предыдущего примера:

const network = await gateway.getNetwork(`papernet`);

const contract = await network.getContract('papercontract');

const issueResponse = await contract.submitTransaction('issue', 'MagnetoCorp', '00001', '2020-05-31', '2020-11-30', '5000000');

Такой способ работает, потому что смарт-контракт по-умолчанию в papercontract - это CommercialPaperContract и в нем имеется транзакция issue. Заметим, что транзакция issue в BondContract может быть вызвана только явным образом. Сходным образом, несмотря на то, что транзакция cancel уникальна, она может быть вызвана только явным образом, потому что принадлежит смарт-контракту BondContract, который не является смарт-контрактом по-умолчанию.

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

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