name: Протокол RGB, от теории к практике goal: Приобретите навыки, необходимые для понимания и использования RGB objectives:


Открытие протокола RGB

Погрузитесь в мир RGB - протокола, предназначенного для реализации и обеспечения соблюдения цифровых прав в форме контрактов и активов на основе правил консенсуса и операций блокчейна Bitcoin. Этот комплексный учебный курс проведет вас через технические и практические основы RGB, от концепций "проверки на стороне клиента" и "одноразовых печатей" до реализации продвинутых смарт-контрактов.

Благодаря структурированной пошаговой программе вы узнаете о механизмах проверки на стороне клиента, детерминированных обязательствах в Bitcoin и схемах взаимодействия между пользователями. Узнайте, как создавать, управлять и передавать токены RGB в Bitcoin или Lightning Network.

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

Курс основан на живом семинаре, организованном Fulgur'Ventures, и проводится тремя известными преподавателями и экспертами в области RGB.

Введение

Презентация курса

Всем привет и добро пожаловать на этот учебный курс, посвященный RGB, системе смарт-контрактов с клиентским подтверждением, работающей на Bitcoin и Lightning Network. Структура курса разработана таким образом, чтобы обеспечить глубокое изучение этой сложной темы. Вот как организован курс:

**Раздел 1: Теория

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

**Раздел 2: Практика

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

**Раздел 3: Приложения

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


Этот учебный курс первоначально вырос из двухнедельного буткемпа по продвинутой разработке в Виареджо, Тоскана, организованного Fulgur'Ventures. Первую неделю, посвященную Rust и SDK, можно найти в этом другом курсе:

https://planb.network/courses/9fbd8b57-f278-4304-8d88-a2d384eaff58

В этом курсе мы сосредоточимся на второй неделе буткемпа, которая посвящена RGB.

Неделя 1 - LNP402:

RGB-Bitcoin

Неделя 2 - Текущее обучение CSV402:

RGB-Bitcoin

Большое спасибо организаторам этих живых курсов и 3 преподавателям, которые приняли в них участие:

Письменная версия этого учебного курса была составлена с использованием двух основных ресурсов:

Готовы погрузиться в сложный и увлекательный мир RGB? Вперёд!

RGB в теории

Введение в концепции распределенных вычислений

RGB - это протокол, предназначенный для применения и обеспечения соблюдения цифровых прав (в форме контрактов и активов) масштабируемым и конфиденциальным способом, основанным на правилах консенсуса и операциях блокчейна Bitcoin. Цель этой первой главы - представить основные понятия и терминологию, связанные с протоколом RGB, подчеркнув, в частности, его тесную связь с основными концепциями распределенных вычислений, такими как проверка на стороне клиента и одноразовые печати.

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

Введение

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

В частности, понятие консенсуса в распределенной системе охватывает два аспекта:

Первая функциональная реализация механизма распределенного консенсуса без права доступа была представлена Сатоши Накамото в биткойне благодаря совместному использованию структуры данных блокчейн и алгоритма Proof-of-Work (PoW). В этой системе достоверность истории блока зависит от вычислительной мощности узлов (майнеров). Таким образом, биткойн является важным и историческим примером распределенной системы консенсуса, открытой для всех (permissionless).

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

В контексте Биткойна вы, несомненно, знакомы с принципами майнинга, децентрализации и окончательности транзакций в блокчейне, а также с тем, как работают платежные каналы. В RGB мы вводим новую парадигму под названием Client-side Validation, которая, в отличие от блокчейна или Lightning, заключается в локальном (на стороне клиента) хранении и проверке переходов состояния смарт-контракта. Она также отличается от других "DeFi" техник (rollups, plasma, ARK и т.д.) тем, что Client-side Validation опирается на блокчейн для предотвращения двойных трат и систему временных меток, сохраняя реестр состояний и переходов вне цепи только у соответствующих участников.

RGB-Bitcoin

Позже мы также введем важный термин: понятие "stash", которое обозначает набор данных на стороне клиента, необходимых для сохранения состояния контракта, поскольку эти данные не реплицируются глобально по всей сети. Наконец, мы рассмотрим обоснование RGB, протокола, использующего преимущества клиентской валидации, и то, почему он дополняет существующие подходы (блокчейн и каналы состояния).

Трилеммы в распределенных вычислениях

Чтобы понять, как Client-side Validation и RGB решают проблемы, не решенные блокчейном и Lightning, давайте откроем для себя 3 основные "трилеммы" в распределенных вычислениях:

1. Масштабируемость, децентрализация и конфиденциальность

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

Государственные каналы (как, например, Lightning Network) более масштабируемы и более приватны, чем блокчейн, поскольку транзакции происходят вне цепи. Однако обязательство публично объявлять о некоторых элементах (транзакции финансирования, топология сети) и мониторинг сетевого трафика могут частично нарушить конфиденциальность. Децентрализация также страдает: маршрутизация требует больших денежных затрат, а крупные узлы могут стать центральными точками. Именно это явление мы начинаем наблюдать на Lightning.

Эта новая парадигма еще более масштабируема и более конфиденциальна, поскольку мы не только можем интегрировать методы доказательства знания с нулевым разглашением, но и не существует глобального графа транзакций, поскольку никто не владеет всем реестром. С другой стороны, это также подразумевает определенный компромисс в отношении децентрализации: эмитент смарт-контракта может играть центральную роль (как "развертыватель контракта" в Ethereum). Однако, в отличие от блокчейна, при Client-side Validation вы храните и проверяете только те контракты, которые вас интересуют, что улучшает масштабируемость за счет отсутствия необходимости загружать и проверять все существующие состояния.

RGB-Bitcoin

2. Теорема CAP (согласованность, доступность, устойчивость к разбиению)

Теорема CAP подчеркивает, что невозможно, чтобы распределенная система одновременно удовлетворяла требованиям согласованности (Consistency), доступности (Availability) и устойчивости к разделам (Partition tolerance).

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

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

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

RGB-Bitcoin

3. Трилемма CIA (конфиденциальность, целостность, доступность)

Эта трилемма напоминает нам о том, что конфиденциальность, целостность и доступность не могут быть оптимизированы одновременно. Блокчейн, Lightning и Client-side Validation по-разному вписываются в этот баланс. Идея заключается в том, что ни одна система не может обеспечить все; необходимо объединить несколько подходов (временную метку блокчейна, синхронный подход Lightning и локальную проверку с помощью RGB), чтобы получить целостный пакет, предлагающий хорошие гарантии в каждом измерении.

RGB-Bitcoin

Роль блокчейна и понятие шардинга

Блокчейн (в данном случае Bitcoin) служит в первую очередь как механизм временной маркировки и защиты от двойных трат. Вместо того чтобы вставлять полные данные смарт-контракта или децентрализованной системы, мы просто включаем криптографические обязательства (commitments) транзакций (в смысле Client-side Validation, которые мы будем называть "переходами состояний"). Таким образом

Шардинг - это концепция, которая зародилась в распределенных базах данных (например, MySQL для социальных сетей, таких как Facebook или Twitter). Чтобы решить проблему объема данных и задержек синхронизации, база данных сегментируется на осколки (США, Европа, Азия и т. д.). Каждый сегмент локально согласован и лишь частично синхронизирован с остальными.

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

Поэтому мы можем представить себе экосистему следующим образом:

RGB-Bitcoin

Эти три элемента образуют треугольное целое, а не линейный стек из "слоя 2", "слоя 3" и так далее. Lightning может напрямую подключаться к Bitcoin или быть связанной с транзакциями Bitcoin, включающими данные RGB. Аналогичным образом, использование "BiFi" (финансы на Bitcoin) может быть связано с блокчейном, Lightning и RGB в соответствии с требованиями к конфиденциальности, масштабируемости или логике контракта.

RGB-Bitcoin

Понятие переходов между состояниями

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

Чтобы понять, как работает эта проверка в контексте Bitcoin и, в целом, понять философию, лежащую в основе Client-side Validation, давайте сначала рассмотрим механизмы блокчейна Bitcoin, а затем увидим, чем Client-side Validation отличается от них и какие оптимизации она дает.

RGB-Bitcoin

В случае с блокчейном Bitcoin проверка транзакций основана на простом правиле:

RGB-Bitcoin

Однако у этой модели есть два существенных недостатка:

RGB-Bitcoin

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

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

RGB-Bitcoin

В то же время, чтобы остальная часть сети (точнее, базовый уровень, такой как Bitcoin) могла зафиксировать конечное состояние, не видя деталей этих данных, Client-side Validation опирается на понятие commitment.

Коммитмент" - это криптографическое обязательство, обычно хэш (например, SHA-256), вставляемый в транзакцию Биткойна, который доказывает, что в нее были включены приватные данные, не раскрывая их.

Благодаря этим обязательствам мы можем доказать:

Однако точное содержание не раскрывается, что позволяет сохранить конфиденциальность.

Если говорить конкретно, то вот как происходит переход в состояние RGB:

RGB-Bitcoin

Удостоверение на стороне клиента дает два основных преимущества:

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

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

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

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

RGB-Bitcoin

Концепция тайника

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

RGB-Bitcoin

Одноразовая печать: возникновение и эксплуатация

При приеме такого актива, как валюта, необходимы две гарантии:

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

Как мы видели ранее, раскрытие отправителем истории переходов состояний позволяет нам гарантировать подлинность токена RGB. Имея доступ ко всем транзакциям, начиная с генезисной транзакции, мы можем подтвердить подлинность токена. Этот принцип похож на принцип биткойна, где история монет может быть прослежена до первоначальной транзакции на coinbase, чтобы проверить их подлинность. Однако, в отличие от Bitcoin, история переходов состояний в RGB является приватной и хранится на стороне клиента.

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

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

RGB-Bitcoin

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

RGB-Bitcoin

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

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

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

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

Следующее сравнение помогает понять этот принцип:

Простое обязательство (дайджест/хеш)Метки времениОдноразовые печати
Публикация обязательства не раскрывает сообщениеДаДаДа
Доказательство даты обязательства / существования сообщения до определённой датыНевозможноВозможноВозможно
Доказательство того, что не может существовать альтернативное обязательствоНевозможноНевозможноВозможно

Одноразовые пломбы работают в три основных этапа:

** Определение уплотнения :**

RGB-Bitcoin

Закрытие :

RGB-Bitcoin

Проверка герметичности :

Вкратце этот процесс можно описать следующим образом:

# Défini par Alice, validé ou accepté par Bob
seal <- Define()
# Fermeture du sceau par Alice avec le message
witness <- Close(seal, message)
# Vérification par Bob
bool <- Verify(seal, witness, message)

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

Именно это и делает система RGB:

Подведем итоги:

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

Многочисленные обязательства и корни

Смарт-контракту RGB может потребоваться потратить несколько одноразовых печатей (несколько UTXO) одновременно. Более того, одна транзакция Биткойна может ссылаться на несколько разных контрактов, каждый из которых запечатывает свой собственный переход состояния. Это требует наличия механизма многокомпонентности для детерминированного и однозначного доказательства того, что ни один из контрактов не существует в двух экземплярах. Именно здесь в RGB вступает в игру понятие якоря: специальная структура, связывающая транзакцию Bitcoin и одно или несколько клиентских обязательств (переходов состояний), каждое из которых потенциально может принадлежать отдельному контракту. Мы подробнее рассмотрим эту концепцию в следующей главе.

RGB-Bitcoin

В двух основных репозиториях проекта на GitHub (под организацией LNPBP) собраны базовые реализации этих концепций, изученных в первой главе:

RGB-Bitcoin

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

RGB-Bitcoin

Вопросы от общественности

На пути к более широкому использованию одноразовых уплотнений

Питер Тодд также создал протокол Open Timestamps, и концепция одноразовых печатей является естественным продолжением этих идей. Помимо RGB, можно предусмотреть и другие варианты использования, например, построение сайдчейнов без использования мерж-майнинга или предложения, связанные с драйвчейнами, такие как BIP300. Любая система, требующая единичного обязательства, в принципе может использовать этот криптографический примитив. Сегодня RGB является первой крупной полномасштабной реализацией.

Проблемы с доступностью данных

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

Шардинг и изоляция контрактов

Каждый контракт представляет собой изолированный осколок: USDT и USDC, например, не обязаны делиться своими историями. Атомарные обмены по-прежнему возможны, но это не предполагает слияния их реестров. Все делается с помощью криптографических обязательств, без раскрытия всего графа истории каждому участнику.

Заключение

Мы уже видели, как концепция Client-side Validation сочетается с блокчейном и государственными каналами, как она отвечает на трилеммы распределенных вычислений и как она уникально использует блокчейн Биткойна для предотвращения двойных трат и для временного клеймения. Идея основана на понятии Пломба одноразового использования, позволяющем создавать уникальные обязательства, которые нельзя повторно расходовать по своему усмотрению. Таким образом, каждый участник загружает только ту историю, которая строго необходима, что повышает масштабируемость и конфиденциальность смарт-контрактов, сохраняя при этом безопасность Биткойна как основы.

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

Прежде чем погрузиться в технические детали второй главы, перечитайте ключевые определения (Client-side Validation, Single-use Seal, anchors и т. д.) и запомните общую логику: мы стремимся совместить сильные стороны блокчейна биткоина (безопасность, децентрализацию, временную маркировку) с сильными сторонами внецепочечных решений (скорость, конфиденциальность, масштабируемость), и именно этого пытаются добиться RGB и Client-side Validation.

Слой обязательств

В этой главе мы рассмотрим реализацию клиентской валидации и одноразовых печатей в блокчейне Биткойна. Мы представим основные принципы работы уровня коммитмента (уровень 1) RGB, уделив особое внимание схеме TxO2, которую RGB использует для определения и закрытия печати в транзакции Bitcoin. Далее мы обсудим два важных момента, которые еще не были подробно рассмотрены:

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

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

Схемы фиксации в Биткойне и их использование в RGB

Как мы видели в первой главе курса, одноразовые печати - это общая концепция: мы даем обещание включить обязательство (commitment) в определенное место транзакции, и это место действует как печать, которую мы закрываем на сообщении. Однако в блокчейне Биткойна есть несколько вариантов выбора места для размещения этого обязательства.

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

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

Это означает, что одноразовая пломба определяется как точная точка выхода (пара TXID + номер выхода). Как только эта выходная точка будет израсходована, пломба будет закрыта.

Работая над RGB, мы выявили как минимум 4 различных способа реализации этих печатей в Bitcoin:

Название схемыОпределение пломбыЗакрытие пломбыДополнительные требованияОсновное применениеВозможные схемы обязательств
PkOЗначение открытого ключаВыход транзакцииP2(W)PKHПока нетKeytweak, taptweak, opret
TxO2Выход транзакцииВыход транзакцииТребует детерминированных обязательств на BitcoinRGBv1 (универсальный)Keytweak, tapret, opret
PkIЗначение открытого ключаВход транзакцииТолько Taproot & несовместимо с устаревшими кошелькамиИдентификация на базе BitcoinSigtweak, witweak
TxO1Выход транзакцииВход транзакцииТолько Taproot & несовместимо с устаревшими кошелькамиПока нетSigtweak, witweak

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

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

Буква "O2" в слове "TxO2" напоминает нам о том, что и определение, и закрытие основаны на расходовании (или создании) транзакционного вывода.

Пример диаграммы TxO2

Напомним, что определение одноразовой печати не обязательно требует публикации транзакции на цепи. Достаточно, чтобы у Алисы, например, уже был неизрасходованный UTXO. Она может решить: "Этот outpoint (уже существующий) теперь будет моей печатью". Она отмечает это локально (со стороны клиента), и до тех пор, пока этот UTXO не будет потрачен, печать считается открытой.

RGB-Bitcoin

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

RGB-Bitcoin

Обратите внимание, что в этом примере :

Чтобы проиллюстрировать эту схему TxO2, мы можем использовать одноразовую печать в качестве механизма отзыва ключа PGP. Вместо того чтобы публиковать сертификат отзыва на серверах, Алиса может сказать: "Этот вывод биткойнов, если он будет потрачен, означает, что мой PGP-ключ отозван".

Таким образом, у Алисы есть конкретный UTXO, с которым локально (на стороне клиента) связано определенное состояние или данные (известные только ей).

Алиса сообщает Бобу, что если эти UTXO будут потрачены, то будет считаться, что произошло определенное событие. Со стороны мы видим лишь транзакцию Bitcoin, но Боб знает, что эта трата имеет скрытый смысл.

RGB-Bitcoin

Когда Алиса тратит этот UTXO, она закрывает печать на сообщении, указывающем на ее новый ключ или просто на отзыв старого. Таким образом, все, кто следит за цепочкой, увидят, что UTXO потрачен, но только те, кто имеет полное доказательство, будут знать, что это именно отзыв ключа PGP.

RGB-Bitcoin

Чтобы Боб или любой другой участник мог проверить скрытое сообщение, Алиса должна предоставить ему информацию вне цепи.

RGB-Bitcoin

Поэтому Алиса должна предоставить Бобу :

RGB-Bitcoin

У третьих лиц нет такой информации. Они видят только, что UTXO был потрачен. Таким образом, обеспечивается конфиденциальность.

Чтобы прояснить структуру, представим процесс в виде двух транзакций:

RGB-Bitcoin RGB-Bitcoin

Поэтому мы называем вторую сделку "сделкой свидетеля".

Чтобы проиллюстрировать это с другой стороны, мы можем представить два слоя:

RGB-Bitcoin

Но при закрытии печати возникает вопрос, куда вставлять обязательство

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

Места обязательств в сделке

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

Транзакция свидетель тратит знаменитый UTXO (или определение печати), и эта трата соответствует закрытию печати. Технически говоря, мы знаем, что каждый аутпоинт может быть потрачен только один раз. Именно на этом основана устойчивость биткойна к двойным тратам. Но транзакция по расходованию средств может иметь несколько входов, несколько выходов или быть составлена сложным образом (coinjoins, Lightning channels и т. д.). Поэтому нам нужно четко определить, куда вставлять обязательство в этой структуре, однозначно и единообразно.

Независимо от метода (PkO, TxO2 и т.д.), обязательство может быть вставлено:

RGB-Bitcoin

Вот подробное описание каждого метода:

RGB-Bitcoin

Сигнализация (подписка к контракту) :

Более ранняя схема предполагала использование случайной части подписи (ECDSA или Schnorr) для встраивания обязательства: эта техника известна как "Подпись к контракту". Вы заменяете случайно сгенерированный nonce на хэш, содержащий данные. Таким образом, подпись неявно раскрывает ваши обязательства, не занимая дополнительного места в транзакции. Этот подход имеет ряд преимуществ:

Однако выявились два основных недостатка:

На практике sig tweak также не очень совместим с существующим оборудованием (аппаратными кошельками) и форматами (Lightning и т. д.). Так что эту замечательную идею трудно реализовать на практике.

Ключевой твик (оплата по контракту) :

В key tweak используется историческая концепция pay-to-contract. Мы берем открытый ключ X и изменяем его, добавляя значение H(message). В частности, если X = x * G и h = H(message), то новый ключ будет X' = X + h * G. Этот модифицированный ключ скрывает приверженность к сообщению. Владелец оригинального закрытого ключа может, добавив h к своему закрытому ключу x, доказать, что у него есть ключ для расходования выходных данных. В теории это элегантно, потому что :

Однако на практике мы сталкиваемся со следующими трудностями:

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

Свидетельский твик :

Другая идея, которую реализовали некоторые протоколы, такие как inscriptions Ordinals, заключается в том, чтобы помещать данные непосредственно в свидетельский раздел транзакции (отсюда выражение "witness tweak"). Однако этот метод :

Кроме того, witness разработан таким образом, что в определенных контекстах его можно обрезать, что может усложнить получение надежных доказательств.

Открытие-возврат (opret) :

Очень простой по своей работе, OP_RETURN позволяет хранить хэш или сообщение в специальном поле транзакции. Но это сразу же обнаруживается: все видят, что в транзакции есть коммитмент, и он может быть отцензурирован или отброшен, а также добавить дополнительный вывод. Поскольку это увеличивает прозрачность и размер, с точки зрения решения для проверки на стороне клиента это считается менее удовлетворительным.

34-byte_Opret_Commitment =
OP_RETURN   OP_PUSHBYTE_32   <mpc::Commitment>
|_________| |______________| |_________________|
1-byte       1-byte         32 bytes

Tapret

Последний вариант - использование Taproot (представленного в BIP341) со схемой Tapret. Tapret - это более сложная форма детерминированного обязательства, которая дает улучшения в плане следа на блокчейне и конфиденциальности операций с контрактами. Основная идея заключается в том, чтобы скрыть обязательство в части Script Path Spend транзакции taproot transaction.

RGB-Bitcoin

Прежде чем описывать, как обязательство вставляется в транзакцию taproot, давайте рассмотрим точную форму обязательства, которое должно императивно соответствовать 64-байтовой строке построенной следующим образом:

64-byte_Tapret_Commitment =
OP_RESERVED ...  ... .. OP_RESERVED   OP_RETURN   OP_PUSHBYTE_33  <mpc::Commitment>  <Nonce>
|___________________________________| |_________| |______________| |_______________|  |______|
OP_RESERVED x 29 times = 29 bytes      1 byte         1 byte          32 bytes        1 byte
|________________________________________________________________| |_________________________|
TAPRET_SCRIPT_COMMITMENT_PREFIX = 31 bytes                    MPC commitment + NONCE = 33 bytes

Таким образом, 64-байтный метод Tapret выглядит как Opret, к которому мы приписали 29 байт OP_RESERVED и добавили дополнительный байт в качестве Nonce.

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

Давайте рассмотрим каждый из этих двух сценариев подробнее.

Регистрация Tapret без существующего Script Path

В этом первом случае мы начинаем с выходного ключа тапроота (Taproot Output Key) Q, который содержит только внутренний открытый ключ P (Internal Key), без связанного с ним пути сценария (Script Path):

RGB-Bitcoin

Чтобы включить обязательство Tapret, добавьте Script Path Spend с уникальным сценарием, как показано ниже:

RGB-Bitcoin

Доказательство включения и уникальности в корневом дереве здесь сводится к единственному внутреннему открытому ключу P.

Интеграция Tapret в уже существующий Script Path

Второй сценарий касается более сложного вывода Q taproot**, который уже содержит несколько скриптов. Например, у нас есть дерево из 3 сценариев:

RGB-Bitcoin

Чтобы добавить обязательство Тапрета, нам нужно вставить нерастрачиваемый скрипт на первый уровень дерева, сместив существующие скрипты на один уровень вниз. Визуально дерево становится :

RGB-Bitcoin

Согласно правилам taproot, каждая ветвь/лист должна быть объединена в соответствии с лексикографическим хэш-порядком. Возможны два случая:

Визуальный пример для первого случая (tHABC < tHT):

RGB-Bitcoin

Пример для второго случая (tHABC > tHT):

RGB-Bitcoin

Оптимизация с помощью ключа

Для повышения конфиденциальности мы можем "добыть" (более точным термином будет "перебор") значение <Nonce> (последний байт 64-байтового Tapret) в попытке получить хэш tHT такой, что tHABC < tHT. В этом случае обязательство возлагается на правую сторону, избавляя пользователя от необходимости разглашать все содержимое существующих скриптов для доказательства уникальности Tapret.

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

Действительные выходы

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

Чтобы удовлетворить этому принципу, независимо от количества выходов в транзакции, мы требуем, чтобы один и только один выход содержал обязательство (commitment). Для каждой из используемых схем (Opret или Tapret) единственными допустимыми выходами, которые могут содержать RGB commitment, являются :

Обратите внимание, что вполне возможно, что транзакция будет содержать одно обязательство Opret и одно обязательство Tapret в двух отдельных выходах. Благодаря детерминированному характеру Seal Definition эти два обязательства соответствуют двум различным частям данных, подтвержденных на стороне клиента.

Анализ и практический выбор в RGB

Когда мы создавали RGB, мы рассмотрели все эти методы, чтобы определить, где и как детерминированно разместить коммитмент в транзакции. Мы определили некоторые критерии:

МетодСлед и размер в блокчейнеРазмер на стороне клиентаИнтеграция кошельковАппаратная совместимостьСовместимость с LightningСовместимость с Taproot
Keytweak (детерминированный P2C)🟢🟡🔴🟠🔴 BOLT, 🔴 Bifrost🟠 Taproot, 🟢 MuSig
Sigtweak (детерминированный S2C)🟢🟢🟠🔴🔴 BOLT, 🔴 Bifrost🟠 Taproot, 🔴 MuSig
Opret (OP_RETURN)🔴🟢🟢🟠🔴 BOLT, 🟠 Bifrost-
Алгоритм Tapret: верхний левый узел🟠🔴🟠🟢🔴 BOLT, 🟢 Bifrost🟢 Taproot, 🟢 MuSig
Алгоритм Tapret # 4: любой узел + доказательство🟢🟠🟠🟢🔴 BOLT, 🟢 Bifrost🟢 Taproot, 🟢 MuSig
Детерминированная схема обязательствСтандартЗатраты в блокчейнеРазмер доказательства на стороне клиента
Keytweak (детерминированный P2C)LNPBP-1, 20 байт33 байта (некорректированный ключ)
Sigtweak (детерминированный S2C)WIP (LNPBP-39)0 байт0 байт
Opret (OP_RETURN)-36 (v)байт (дополнительный TxOut)0 байт
Алгоритм Tapret: верхний левый узелLNPBP-632 байта в свидетельстве (8 vбайт) для любого n-of-m мультиподписи и расходов через путь скрипта0 байт для scriptless scripts taproot ~270 байт в случае одного скрипта, ~128 байт, если несколько скриптов
Алгоритм Tapret #4: любой узел + доказательство уникальностиLNPBP-632 байта в свидетельстве (8 vбайт) для случаев с одним скриптом, 0 байт в свидетельстве в большинстве других случаев0 байт для scriptless scripts taproot, 65 байт, пока Taptree не содержит дюжину скриптов
УровеньЗатраты on-chain (bytes/vbytes)Затраты on-chain (bytes/vbytes)Затраты on-chain (bytes/vbytes)Затраты on-chain (bytes/vbytes)Затраты on-chain (bytes/vbytes)Затраты на клиенте (bytes)Затраты на клиенте (bytes)Затраты на клиенте (bytes)Затраты на клиенте (bytes)Затраты на клиенте (bytes)
ТипTapretTapret #4KeytweakSigtweakOpretTapretTapret #4KeytweakSigtweakOpret
Single-sig00003200320?0
MuSig (n-of-n)0000320032? > 00
Multi-sig 2-of-332/832/8 или 00n/a32~2706532n/a0
Multi-sig 3-of-532/832/8 или 00n/a32~3406532n/a0
Multi-sig 2-of-3 с таймаутами32/800n/a32646532n/a0
УровеньЗатраты on-chain (vbytes)Затраты on-chain (vbytes)Затраты on-chain (vbytes)Клиентские затраты (bytes)Клиентские затраты (bytes)
ТипБазаTapret #2Tapret #4Tapret #2Tapret #4
MuSig (n-of-n)16.50000
FROST (n-of-m)?0000
Multi_a (n-of-m)1+16n+8m8833 * m65
Ветка MuSig / Multi_a (n-of-m)1+16n+8n+8xlog(n)806465
С тайм-аутами (n-of-m)1+16n+8n+8xlog(n)806465
МетодКонфиденциальность и МасштабируемостьИнтероперабельностьСовместимостьПереносимостьСложность
Keytweak (детерминированный P2C)🟢🔴🔴🟡🟡
Sigtweak (детерминированный S2C)🟢🔴🔴🟢🔴
Opret (OP_RETURN)🔴🟠🔴🟢🟢
Algo Tapret: верхний левый узел🟠🟢🟢🔴🟠
Algo Tapret #4: Любой узел + доказательство🟢🟢🟢🟠🔴

В ходе исследования стало ясно, что ни одна из схем обязательств не является полностью совместимой с текущим стандартом Lightning (в котором не используются Taproot, muSig2 или дополнительная поддержка обязательств). В настоящее время ведутся работы по изменению конструкции канала Lightning (BiFrost), чтобы позволить вставлять RGB-обязательства. Это еще одна область, в которой нам необходимо пересмотреть структуру транзакций, ключи и способ подписи обновлений канала.

Анализ показал, что на самом деле другие методы (key tweak, sig tweak, witness tweak и т. д.) дают другие формы осложнений:

Для RGB особенно выделяются два метода: Opret и Tapret, оба классифицируются как "Транзакционный выход" и совместимы с режимом TxO2, используемым в протоколе.

Мультипротокольные обязательства - MPC

В этом разделе мы рассмотрим, как RGB обрабатывает агрегирование нескольких контрактов (или, точнее, их пучков переходов) в рамках одного обязательства (commitment), записанного в транзакции Биткойна по детерминированной схеме (согласно Opret или Tapret). Для этого порядок меркелизации различных контрактов происходит в структуре, называемой MPC Tree (Multi Protocol Commitment Tree). В этом разделе мы рассмотрим, как построить это дерево MPC, как получить его корень и как несколько контрактов могут конфиденциально и однозначно передавать одну и ту же транзакцию.

Multi Protocol Commitment (MPC) предназначен для удовлетворения двух потребностей:

Говоря конкретнее, каждый пучок переходов принадлежит определенному контракту. Вся эта информация вставляется в MPC-дерево, корень которого (mpc::Root) затем снова хэшируется, чтобы получить mpc::Commitment. Именно этот последний хэш помещается в транзакцию Биткойна (свидетельскую транзакцию) в соответствии с выбранным детерминированным методом.

RGB-Bitcoin

Корневой хэш MPC

Значение, фактически записанное на цепочке (в Opret или Tapret), называется mpc::Commitment. Оно вычисляется в форме BIP-341 по формуле :

mpc::Commitment = SHA-256(SHA-256(mpc_tag) || SHA-256(mpc_tag) || depth || cofactor || mpc::Root )

где :

RGB-Bitcoin

MPC Строительство деревьев

Чтобы построить это дерево MPC, нам нужно убедиться, что каждый контракт соответствует уникальной позиции листа. Предположим, что у нас есть :

Затем мы строим дерево шириной w и глубиной d, такое, что 2^d = w, причем w > C, так что каждый контракт может быть помещен в отдельный лист. Позиция pos(c_i) каждого контракта в дереве определяется :

pos(c_i) = c_i mod (w - cofactor)

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

Задача состоит в том, чтобы избегать слишком высоких деревьев и при этом свести риск столкновения к минимуму. Обратите внимание, что явление столкновения подчиняется логике случайного распределения, связанной с Парадоксом Юбилея.

Обитаемые листья

После того как для контрактов i = {0,1,...,C-1} было получено C различных позиций pos(c_i), каждый лист заполняется хэш-функцией (tagged hash):

tH_MPC_LEAF(c_i) = SHA-256(SHA-256(merkle_tag) || SHA-256(merkle_tag) || 0x10 || c_i || BundleId(c_i))

где :

Необитаемые листья

Оставшиеся листья, которым не присвоен контракт (т.е. листья w - C), заполняются "фиктивным" значением (энтропийный лист):

tH_MPC_LEAF(j) = SHA-256(SHA-256(merkle_tag) || SHA-256(merkle_tag) || 0x11 || entropy || j )

где :

Узлы MPC

После генерации листьев w (заселенных или нет) мы переходим к меркелизации. Все внутренние узлы хэшируются следующим образом:

tH_MPC_BRANCH(tH1 || tH2) = SHA-256(SHA-256(merkle_tag) || SHA-256(merkle_tag) || b || d || w || tH1 || tH2)

где :

Продвигаясь таким образом, мы получаем корень mpc::Root. Затем мы можем вычислить mpc::Commitment (как объяснялось выше) и вставить его в цепочку.

Чтобы проиллюстрировать это, давайте представим пример, в котором C=3 (три контракта). Их позиции принимаются равными pos(c_0)=7, pos(c_1)=4, pos(c_2)=2. Остальные листья (позиции 0, 1, 3, 5, 6) - это энтропийные листья. На диаграмме ниже показана последовательность хэшей к корню с :

В итоге получается mpc::Root, затем mpc::Commitment.

RGB-Bitcoin

Проверка вала MPC

Когда верификатор хочет убедиться, что контракт c_i (и его BundleId) включен в конечный mpc::Commitment, он просто получает доказательство Меркла. Это доказательство указывает узлы, необходимые для отслеживания листьев (в данном случае, листа контракта c_i) обратно к корню. Нет необходимости раскрывать все MPC-дерево: это защищает конфиденциальность других контрактов.

В примере верификатору c_2 нужен только промежуточный хэш (tH_MPC_LEAF(D)), два tH_MPC_BRANCH(...), доказательство позиции pos(c_2) и значение cofactor. Затем он может локально восстановить корень, затем пересчитать mpc::Commitment и сравнить его с тем, который был записан в транзакции Bitcoin (в рамках Opret или Tapret).

RGB-Bitcoin

Этот механизм гарантирует, что :

Краткое описание структуры MPC

Multi Protocol Commitment* (MPC) - это принцип, позволяющий RGB объединять несколько контрактов в одну транзакцию Bitcoin, сохраняя уникальность обязательств и конфиденциальность по отношению к другим участникам. Благодаря детерминированному построению дерева, каждому контракту присваивается уникальная позиция, а наличие "фиктивных" листьев (Entropy Leaves) частично маскирует общее количество контрактов, участвующих в транзакции.

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

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

Именно поэтому работа над RGB заняла так много времени. У нас было общее видение с 2019 года: разместить все на стороне клиента, циркулировать токены вне цепи. Но такие детали, как шардинг для нескольких контрактов, структура дерева Меркла, способы обработки коллизий и доказательств слияния... все это требовало итераций.

Якоря: глобальная сборка

После создания наших обязательств (Opret или Tapret) и нашего MPC (Multi Protocol Commitment) нам необходимо рассмотреть понятие Anchor в протоколе RGB. Якорь - это проверяемая структура на стороне клиента, которая объединяет элементы, необходимые для проверки того, что обязательство Биткойна действительно содержит определенную информацию о контракте. Другими словами, якорь суммирует все данные, необходимые для проверки обязательств, описанных выше.

Якорь состоит из трех упорядоченных полей:

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

TxId

Поле Txid соответствует 32-байтовому идентификатору транзакции Bitcoin, содержащей обязательство Opret или Tapret.

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

Доказательство MPC

Второе поле, MPC Proof, относится к доказательству того, что данный конкретный контракт (например, c_i) включен в Multi Protocol Commitment. Оно представляет собой комбинацию из :

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

pos(c_i) = c_i mod (w - cofactor)

Затем используется детерминированная схема меркелизации для объединения всех листьев (контракты + энтропия). В конце концов, MPC Proof позволяет локально восстановить корень и сравнить его с mpc::Commitment, включенным в цепочку.

Дополнительное доказательство транзакции - ETP

Третье поле, ETP, зависит от типа используемого обязательства. Если обязательство имеет тип Opret, то дополнительного доказательства не требуется. Валидатор проверяет первый выход транзакции OP_RETURN и находит там непосредственно mpc::Commitment.

Если обязательство имеет тип Tapret, должно быть предоставлено дополнительное доказательство, называемое Extra Transaction Proof - ETP. Оно содержит :

Это дополнительное доказательство необходимо, поскольку, в отличие от Opret, обязательство Tapret интегрировано в структуру скрипта taproot, что требует раскрытия части дерева taproot, чтобы правильно подтвердить местоположение обязательства.

RGB-Bitcoin

Таким образом, Анкоры содержат всю информацию, необходимую для подтверждения обязательств Биткойна в контексте RGB. Они указывают как соответствующую транзакцию (Txid), так и доказательство позиционирования контракта (MPC Proof), управляя дополнительным доказательством (ETP) в случае Tapret. Таким образом, якорь защищает целостность и уникальность состояния вне цепи, гарантируя, что одна и та же транзакция не может быть переинтерпретирована для других контрактных данных.

Заключение

В этой главе мы рассмотрим :

На практике техническая реализация разделена между несколькими выделенными Rust cratesclient_side_validation, commit-verify, bp_core и т.д.). Основополагающие понятия там есть:

RGB-Bitcoin

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

Введение в смарт-контракты и их состояния

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

Смарт-контракты и цифровые права на предъявителя

Цель RGB - предоставить инфраструктуру для реализации смарт-контрактов на Bitcoin. Под "умным контрактом" мы понимаем соглашение между несколькими сторонами, которое выполняется автоматически и на основе вычислений, без вмешательства человека для обеспечения выполнения его положений. Другими словами, законность договора обеспечивается программным обеспечением, а не доверенной третьей стороной.

Такая автоматизация ставит вопрос о децентрализации: как мы можем освободиться от централизованного реестра (например, центральной платформы или базы данных) для управления правом собственности и исполнения контрактов? Оригинальная идея, подхваченная RGB, заключается в том, чтобы вернуться к способу владения, известному как "инструменты на предъявителя". Исторически сложилось так, что некоторые ценные бумаги (облигации, акции и т. д.) выпускались на предъявителя, что позволяло любому, кто физически владел документом, реализовать свои права.

RGB-Bitcoin

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

Введение в смарт-контракт Состояние RGB

Смарт-контракт в RGB можно рассматривать как машину состояний, определяемую :

RGB-Bitcoin

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

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

Статус и бизнес-логика в RGB

С практической точки зрения, Бизнес-логика контракта принимает форму правил и скриптов, определенных в том, что RGB называет Схемой. Схема кодирует :

В то же время Контрактное государство часто распадается на две составляющие:

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

Договорные операции: создание и эволюция государства

Во вселенной RGB Операция по контракту - это любое событие, которое изменяет контракт из старого состояния в новое состояние. Эти операции следуют следующей логике:

RGB-Bitcoin

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

Цепочка операций: от Бытия до Терминального состояния

Чтобы представить это в перспективе, смарт-контракт RGB начинается с Genesis, самого первого состояния. После этого различные операции контракта следуют одна за другой, образуя DAG (Directed Acyclic Graph) операций:

RGB-Bitcoin

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

Резюме

Смарт-контракты в RGB представляют собой модель цифровых инструментов на предъявителя, децентрализованных, но привязанных к Bitcoin для фиксации времени и гарантирования порядка транзакций. Автоматизированное выполнение этих контрактов основано на :

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

Контрактные операции RGB

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

Переходы состояний и их механика

Общий принцип все тот же - Client-side Validation, когда данные о состоянии хранятся у владельца и проверяются получателем. Однако специфика RGB заключается в том, что Боб, как получатель, просит Алису включить определенную информацию в данные контракта, чтобы иметь реальный контроль над полученным активом, через скрытую ссылку на один из своих UTXO.

Чтобы проиллюстрировать процесс перехода состояния (который является одной из фундаментальных контрактных операций в RGB), давайте рассмотрим пошаговый пример передачи активов между Алисой и Бобом:

*Начальная ситуация:

У Алисы есть тайник RGB с локально подтвержденными данными (клиент-сайд). Этот тайник относится к одному из ее UTXO на Bitcoin. Это означает, что определение печати в этих данных указывает на UTXO, принадлежащий Алисе. Идея заключается в том, чтобы дать ей возможность передать Бобу определенные цифровые права, связанные с активом (например, токены RGB).

RGB-Bitcoin

У Боба тоже есть UTXO :

Боб, с другой стороны, имеет по крайней мере один собственный UTXO, без прямой связи с Алисой. В случае, если у Боба нет UTXO, все равно можно осуществить передачу ему с помощью самой свидетельской транзакции: выход этой транзакции будет включать обязательство (commitment) и неявно связывать право собственности на новый контракт с Бобом.

RGB-Bitcoin

Строительство нового объекта недвижимости (Новое состояние) :

Боб посылает Алисе информацию, закодированную в виде инвойса (мы более подробно рассмотрим построение инвойсов в последующих главах), с просьбой создать новое состояние, соответствующее правилам контракта. Это состояние будет включать новое определение печати, указывающее на один из UTXO Боба. Таким образом, Боб получает право собственности на активы, определенные в этом новом состоянии, например, на определенное количество токенов RGB.

RGB-Bitcoin

Подготовка образца сделки:

Затем Алиса создает транзакцию Bitcoin, расходуя UTXO, на который ссылалась в предыдущей печати (та, которая легитимизировала ее как держателя). На выходе этой транзакции вставляется обязательство (через Opret или Tapret) для закрепления нового состояния RGB. Обязательства Opret или Tapret берутся из MPC-дерева (как было показано в предыдущих главах), которое может объединять несколько переходов из разных контрактов.

Передача Передачи Бобу:

Перед трансляцией транзакции Алиса отправляет Бобу Consignment, содержащее все необходимые данные клиентской стороны (его тайник) и информацию о новом состоянии в пользу Боба. В этот момент Боб применяет правила консенсуса RGB:

Завершение перехода:

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

RGB-Bitcoin

Новое состояние теперь ссылается на UTXO Боба, передавая Бобу право собственности, которое ранее принадлежало Алисе. Вывод Bitcoin, в котором закреплены данные RGB, становится безотзывным доказательством передачи права собственности.

Пример минимального DAG (Directed Acyclic Graph), состоящего из двух контрактных операций (Genesis и State Transition), может проиллюстрировать, как состояние RGB (слой client-side, красный) соединяется с блокчейном Bitcoin (слой Commitment, оранжевый).

RGB-Bitcoin

Он показывает, что Генезис определяет печать (определение печати), а затем переход состояния закрывает эту печать, чтобы создать новую в другом UTXO.

В связи с этим напомним несколько терминов:

Переходы состояний**, описанные в предыдущей главе, являются основной формой работы с контрактами. Они ссылаются на одно или несколько предыдущих состояний (из Genesis или другого перехода состояния) и обновляют их до нового состояния.

RGB-Bitcoin

На этой диаграмме показано, как в State Transition Bundle несколько печатей могут быть закрыты в одной выборочной транзакции, одновременно открывая новые печати. Действительно, интересной особенностью протокола RGB является его способность к масштабированию: несколько переходов могут быть объединены в пакет переходов, причем каждый пакет связан с отдельным листом дерева MPC (уникальный идентификатор пакета). Благодаря механизму Deterministic Bitcoin Commitment (DBC), все сообщение вставляется в выход Tapret или Opret, при этом закрываются предыдущие печати и, возможно, определяются новые. Якорь* служит прямой связью между обязательством, хранящимся в блокчейне, и структурой проверки на стороне клиента (client-side).

В следующих главах мы рассмотрим все компоненты и процессы, связанные с созданием и проверкой перехода состояния. Большинство из этих элементов являются частью консенсуса RGB, реализованного в библиотеке RGB Core Library.

Переходный пакет

В RGB можно объединять различные переходы состояния, принадлежащие одному контракту (т. е. имеющие один и тот же ContractId, полученный из Genesis OpId). В простейшем случае, как между Алисой и Бобом в приведенном выше примере, Переходный пучок содержит только один переход. Однако поддержка операций с несколькими плательщиками (например, объединение монет, открытие канала Lightning и т. д.) означает, что несколько пользователей могут объединить свои переходы состояний в один пакет.

После сбора эти переходы закрепляются (с помощью механизма MPC + DBC) в одной транзакции Bitcoin:

Технически говоря, BundleId, вставляемый в лист MPC, получается из тегированного хэша, применяемого к строгой сериализации поля InputMap пакета:

BundleId = SHA256( SHA256(bundle_tag) || SHA256(bundle_tag) || InputMap )

В котором bundle_tag = urn:lnp-bp:rgb:bundle#2024-02-03, например.

Карта InputMap - это структура данных, в которой для каждого входа i транзакции-образца указана ссылка на OpId соответствующего перехода состояния. Например:

InputMap =
N               input_0    OpId(input_0)    input_1    OpId(input_1)   ...    input_N-1  OpId(input_N-1)
|____________________| |_________||______________| |_________||______________|       |__________||_______________|
16-bit Little Endian   32-bit LE   32-byte hash
|_________________________| |_________________________|  ...  |___________________________|
MapElement1                MapElement2                       MapElementN

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

Генерация состояний и активное состояние

Переход состояния может использоваться для передачи права собственности на актив от одного лица к другому. Однако это не единственные возможные операции в протоколе RGB. В протоколе определены три контрактные операции:

Среди них Genesis и State Extension иногда называют "операциями генерации состояний", поскольку они создают новые состояния, не закрывая сразу ни одного. Это очень важный момент: Genesis и State Extension не предполагают закрытия печати. Скорее, они определяют новую печать, которая затем должна быть потрачена последующим Переходом состояния, чтобы быть действительно подтвержденной в истории блокчейна.

RGB-Bitcoin

Активное состояние** контракта часто определяется как набор последних состояний, полученных в результате истории (DAG) транзакций, начиная с Genesis и следуя всем якорям в блокчейне Биткойна. Любые старые состояния, которые уже устарели (т. е. привязаны к отработанным UTXO), больше не считаются активными, но остаются важными для проверки согласованности истории.

Genesis

Генезис - это отправная точка каждого контракта RGB. Он создается эмитентом контракта и определяет начальные параметры в соответствии с Схемой. В случае с токеном RGB в Genesis может быть указано, например, :

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

Расширение штата

Расширения состояний** предлагают оригинальную функцию для смарт-контрактов. Они позволяют выкупить определенные цифровые права (Валентности), предусмотренные в определении контракта, без немедленного закрытия печати. Чаще всего это касается :

Технически говоря, расширение состояния ссылается на Redeem (определенный тип RGB-входа), который соответствует Valency, определенной ранее (например, в Genesis или другом переходе состояния). Оно определяет новую печать, доступную тому человеку или состоянию, которое ею пользуется. Чтобы печать вступила в силу, она должна быть потрачена последующим Переходом состояния.

RGB-Bitcoin

Например: Бытие создает право выдачи (Valency). Им может воспользоваться уполномоченный актор, который затем строит Расширение государства:

Компоненты контрактной операции

Теперь я хотел бы подробно рассмотреть каждый из составных элементов Операции по договору в RGB. Операция по договору - это действие, которое изменяет состояние договора и которое проверяется на стороне клиента, детерминированным образом, законным получателем. В частности, мы увидим, как операция по договору учитывает, с одной стороны, старое состояние (Old State) договора, а с другой - определение нового состояния (New State).

+---------------------------------------------------------------------------------------------------------------------+
|  Contract Operation                                                                                                 |
|                                                                                                                     |
|  +-----+     +-----------------------+      +--------------------------------+      +---------+     +------------+  |
|  | Ffv |     | ContractId | SchemaId |      | TransitionType | ExtensionType |      | Testnet |     | AltLayers1 |  |
|  +-----+     +-----------------------+      +--------------------------------+      +---------+     +------------+  |
|                                                                                                                     |
|  +-----------------------------------------------+  +------------------------------------------------------------+  |
|  | Metadata                                      |  | Global State                                               |  |
|  |                                               |  | +----------------------------------+                       |  |
|  | +-------------------------------------+       |  | | +-------------------+ +--------+ |                       |  |
|  | |          Structured Data            |       |  | | |  GlobalStateType  | |  Data  | |     ...     ...       |  |
|  | +-------------------------------------+       |  | | +-------------------+ +--------+ |                       |  |
|  |                                               |  | +----------------------------------+                       |  |
|  +-----------------------------------------------+  +------------------------------------------------------------+  |         +------+
|                                                                                                                     +---------> OpId |
|  +-----------------------------------------------+  +------------------------------------------------------------+  |         +------+
|  | Inputs                                        |  | Assignments                                                |  |
|  |                                               |  |                                                            |  |
|  | +-------------------------------------------+ |  | +--------------------------------------------------------+ |  |
|  | | Input #1                                  | |  | | Assignment #1                                          | |  |
+------+       |  | | +----------+ +----------------+ +-------+ | |  | | +----------------+ +-------------+ +-----------------+ | |  |       +--------------+
| OpId +--------------> PrevOpId | | AssignmentType | | Index | | |  | | | AssignmentType | | Owned State | | Seal Definition +--------------> Bitcoin UTXO |
+------+       |  | | +----------+ + ---------------+ +-------+ | |  | | +----------------+ +-------------+ +-----------------+ | |  |       +--------------+
|  | +-------------------------------------------+ |  | +--------------------------------------------------------+ |  |
|  |                                               |  |                                                            |  |
|  | +-------------------------------------------+ |  | +--------------------------------------------------------+ |  |
|  | | Input #2                                  | |  | | Assignment #2                                          | |  |
+------+       |  | | +----------+ +----------------+ +-------+ | |  | | +----------------+ +-------------+ +-----------------+ | |  |       +--------------+
| OpId +--------------> PrevOpId | | AssignmentType | | Index | | |  | | | AssignmentType | | Owned State | | Seal Definition +--------------> Bitcoin UTXO |
+------+       |  | | +----------+ +----------------+ +-------+ | |  | | +----------------+ +-------------+ +-----------------+ | |  |       +--------------+
|  | +-------------------------------------------+ |  | +--------------------------------------------------------+ |  |
|  |                                               |  |                                                            |  |
|  |       ...           ...          ...          |  |     ...          ...             ...                       |  |
|  |                                               |  |                                                            |  |
|  +-----------------------------------------------+  +------------------------------------------------------------+  |
|                                                                                                                     |
|  +-----------------------------------------------+  +------------------------------------------------------------+  |
|  | Redeems                                       |  | Valencies                                                  |  |
|  |                                               |  |                                                            |  |
|  | +------------------------------+              |  |                                                            |  |
+------+       |  | | +----------+ +-------------+ |              |  |  +-------------+  +-------------+                          |  |
| OpId +--------------> PrevOpId | | ValencyType | |  ...   ...   |  |  | ValencyType |  | ValencyType |         ...              |  |
+------+       |  | | +----------+ +-------------+ |              |  |  +-------------+  +-------------+                          |  |
|  | +------------------------------+              |  |                                                            |  |
|  |                                               |  |                                                            |  |
|  +-----------------------------------------------+  +------------------------------------------------------------+  |
|                                                                                                                     |
+---------------------------------------------------------------------------------------------------------------------+

Если мы посмотрим на диаграмму выше, то увидим, что операция Contract Operation включает элементы, относящиеся к Новому состоянию, и элементы, относящиеся к обновленному Старому состоянию.

Элементами Нового государства являются:

Ссылка на Старое государство осуществляется через :

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

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

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

Контракт RGB идентифицируется по ContractId, полученному из Genesis OpId (поскольку до Genesis не существует никакой операции). Говоря конкретнее, мы берем Genesis OpId, меняем порядок байт и применяем кодировку Base58. Такая кодировка делает ContractId более удобным для обработки и распознавания.

Методы и правила обновления статуса

Состояние контракта представляет собой набор информации, которую протокол RGB должен отслеживать для данного контракта. Он состоит из :

RGB-Bitcoin

Глобальное состояние* непосредственно включено в Операцию договора в виде отдельного блока. Состояния Собственности определяются в каждом Назначении, наряду с Определением уплотнения.

Важной особенностью RGB является способ изменения глобального состояния и состояния владения. В целом существует два типа поведения:

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

В таблице ниже показано, как каждый тип операции контракта может манипулировать (или не манипулировать) глобальным состоянием и состоянием владельца:

ГенезисРасширение состоянияПереход состояния
Добавление Global State+-+
Изменение Global Staten/a-+
Добавление Owned State+-+
Изменение Owned Staten/aНет+
Добавление Valencies+++

+ : действие возможно, если схема контракта позволяет это сделать.

-: операция должна быть подтверждена последующим переходом состояния (само по себе продление состояния не закрывает одноразовую пломбу).

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

МетаданныеГлобальное состояниеВладельческое состояние
Область действияОпределено для одной операции контрактаОпределено глобально для контрактаОпределено для каждой печати (Assignment)
Кто может обновлять?Не обновляется (эфемерные данные)Операция, выполняемая участниками (эмитент и др.)Зависит от законного владельца печати (того, кто может потратить её в следующей транзакции)
Временной охватТолько для текущей операцииСостояние устанавливается после операцииСостояние определяется до операции (Seal Definition из предыдущей операции)

Глобальное государство

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

Это глобальное состояние может быть размещено на публичных ресурсах (веб-сайтах, IPFS, Nostr, Torrent и т. д.) и распространено среди сообщества. Кроме того, экономический стимул (необходимость хранить и передавать эти токены и т. д.) естественным образом побуждает контрактных пользователей самостоятельно поддерживать и распространять эти данные.

Задания

Задание Assignment - это базовая структура для определения :

Задание Assignment можно рассматривать как аналог вывода транзакции Bitcoin, но с большей гибкостью. Здесь кроется логика передачи собственности: Assignment связывает определенный тип актива или права (AssignmentType) с печатью. Тот, кто владеет закрытым ключом UTXO, связанным с этой печатью (или тот, кто может потратить этот UTXO), считается владельцем этого Состояния.

Одна из сильных сторон RGB - возможность по своему усмотрению раскрывать (reveal) или скрывать (conceal) поля Seal Definition и Owned State. Это обеспечивает мощное сочетание конфиденциальности и избирательности. Например, вы можете доказать, что переход действителен, не раскрывая всех данных, предоставляя раскрытую версию тому, кто должен ее подтвердить, а третьи лица видят только скрытую версию (хэш). На практике OpId перехода всегда вычисляется из скрытых данных.

RGB-Bitcoin

Определение печати

В раскрытом виде Seal Definition имеет четыре основных поля: txptr, vout, blinding и method :

Скрытая форма определения печати - это SHA256-хэш (метка) конкатенации этих 4 полей, с меткой, специфичной для RGB.

RGB-Bitcoin

Владельческие штаты

Второй компонент Присвоения - это Собственное государство. В отличие от глобального государства, оно может существовать как в публичной, так и в частной форме:

RGB определяет четыре возможных типа состояния (StateTypes) для состояния Owned:

SHA-256(SHA-256(tag_data) || SHA-256(tag_data) || blob)

Например, с :

tag_data = urn:lnp-bp:rgb:state-data#2024-02-12
SHA-256(SHA-256(tag_attachment) || SHA-256(tag_attachment) || file_hash || media_type || salt)

Например, с :

tag_attachment = urn:rgb:state-attach#2024-02-12

Подводя итог, можно сказать, что здесь представлены 4 возможных типа состояния в открытом и скрытом виде:

State                      Concealed form                              Revealed form
+---------------------------------------------------------------------------------------------------------
+--------------------------------------------------------------------------------+
|                                                                                |
Declarative        |                              < void >                                          |
|                                                                                |
+--------------------------------------------------------------------------------+
+---------------------------------------------------------------------------------------------------------
+--------------------------+             +---------------------------------------+
| +----------------------+ |             |         +--------+ +----------+       |
Fungible           | | Pedersen Commitement | | <========== |         | Amount | | Blinding |       |
| +----------------------+ |             |         +--------+ +----------+       |
+--------------------------+             +---------------------------------------+
+---------------------------------------------------------------------------------------------------------
+--------------------------+             +---------------------------------------+
| +----------------------+ |             |         +--------------------+        |
Structured         | |     Tagged Hash      | | <========== |         |     Data Blob      |        |
| +----------------------+ |             |         +--------------------+        |
+--------------------------+             +---------------------------------------+
+---------------------------------------------------------------------------------------------------------
+--------------------------+             +---------------------------------------+
| +----------------------+ |             | +-----------+ +------------+ +------+ |
Attachments        | |     Tagged Hash      | | <========== | | File Hash | | Media Type | | Salt | |
| +----------------------+ |             | +-----------+ +------------+ +------+ |
+--------------------------+             +---------------------------------------+
ЭлементДекларативныйФонгибельныйСтруктурированныйВложения
ДанныеОтсутствуютЗнаковое или беззнаковое 64-битное целое числоЛюбой строгий тип данныхЛюбой файл
Тип информацииОтсутствуетЗнаковый или беззнаковыйСтрогие типыMIME-тип
КонфиденциальностьНе требуетсяPedersen commitmentХеширование с ослеплениемХешированный идентификатор файла
Ограничения по размеруN/A256 байтДо 64 КБДо ~500 ГБ

Входы

Входы контрактной операции относятся к заданиям, которые расходуются в этой новой операции. Вход указывает на :

Входы никогда не появляются в Генезисе, так как не существует предыдущих Назначений. Они также не появляются в Расширениях штата (потому что Расширения штата не закрывают печати; скорее, они переопределяют новые печати на основе Значений).

Когда у нас есть Собственные состояния типа Fungible, логика валидации (через скрипт AluVM, предоставленный в схеме) проверяет согласованность сумм: сумма входящих токенов (Inputs) должна быть равна сумме исходящих токенов (в новых Assignments).

Метаданные

Поле Метаданные может иметь размер до 64 килобайт и используется для включения временных данных, полезных для проверки, но не интегрированных в постоянное состояние контракта. Например, здесь могут храниться промежуточные переменные вычислений для сложных скриптов. Это пространство не предназначено для хранения в глобальной истории, поэтому оно находится вне сферы действия Owned States или Global State.

Валентности

Валентности** - это оригинальный механизм протокола RGB. Они могут быть найдены в Генезисе, Переходах состояния или Расширениях состояния. Они представляют собой числовые права, которые могут быть активированы расширением состояния (через Redeems), а затем завершены последующим переходом. Каждая валентность идентифицируется ValencyType (16 бит). Его семантика (право на перевыпуск, обмен жетонов, право на сжигание и т.д.) определена в схеме.

Если говорить конкретнее, то мы можем представить себе генезис, определяющий валентность "право на перевыпуск". Расширение состояния будет потреблять его (Redeem) при выполнении определенных условий, чтобы ввести новое количество жетонов. Затем Переход состояния, исходящий от держателя созданной таким образом печати, может передать эти новые токены.

Искупает

Redeems - это эквивалент Valency для Inputs для Assignments. Они появляются только в Расширениях штата, поскольку именно там активируется ранее определенная валентность. Повторное использование состоит из двух полей:

Например, Redeem может соответствовать выполнению CoinSwap, в зависимости от того, что было закодировано в Valency.

Характеристики состояния RGB

Сейчас мы рассмотрим несколько основных характеристик состояния в RGB. В частности, мы рассмотрим :

Как всегда, помните, что все, что связано со статусом контракта, подтверждается на стороне клиента в соответствии с правилами консенсуса, изложенными в протоколе, конечная криптографическая ссылка которого закреплена в транзакциях Bitcoin.

Строгая система типов

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

Во многих средах программирования (JSON, YAML...) структура данных может быть гибкой, даже слишком свободной. В RGB, с другой стороны, структура и типы каждого поля определены с явными ограничениями. Например

Благодаря этому строгому протоколу кодирования :

На практике компилируется структура (Schema) и результирующий код (Interface и связанная с ним логика). Для определения контракта (типы, поля, правила) и создания строгого двоичного формата используется описательный язык. В результате компиляции получается :

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

Наконец, при каждой компиляции создается "отпечаток пальца" - криптографический идентификатор, который подтверждает точную версию кода (данные, правила, проверка). Например, идентификатор вида :

BEiLYE-am9WhTW1-oK8cpvw4-FEMtzMrf-mKocuGZn-qWK6YF#ginger-parking-nirvana

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

Чтобы состояние контракта RGB не стало слишком громоздким для проверки на стороне клиента, правило консенсуса устанавливает максимальный размер в 2^16 байт (64 Кио) для любых данных, участвующих в вычислениях для проверки. Это относится к каждой переменной или структуре: не более 65536 байт или эквивалент в числах (32768 16-битных целых чисел и т. д.). Это также относится к коллекциям (спискам, наборам, картам), которые не могут превышать 2^16 элементов.

Это ограничение гарантирует :

Парадигма валидации != владения

Одно из главных новшеств RGB - строгое разделение двух понятий:

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

Владение**, с другой стороны, полностью полагается на безопасность Биткойна. Владение закрытым ключом UTXO означает контроль над возможностью запуска нового перехода (закрытие одноразовой печати). Таким образом, даже если кто-то может увидеть или подтвердить данные, он не сможет изменить состояние, если не владеет UTXO.

RGB-Bitcoin

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

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

Консенсусные разработки в RGB

Помимо семантического версионирования кода, RGB включает в себя систему развития или обновления правил консенсуса контракта с течением времени. Существует две основные формы эволюции:

Ускоренный переход происходит, когда ранее недействительное правило становится действительным. Например, если в контракте появляется новый тип AssignmentType или новое поле :

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

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

Глоссарий RGB

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

AluVM

Аббревиатура AluVM расшифровывается как "Algorithmic logic unit Virtual Machine" - виртуальная машина на основе регистров, предназначенная для проверки смарт-контрактов и распределенных вычислений. Она используется (но не только) для проверки контрактов RGB. Таким образом, скрипты или операции, включенные в контракт RGB, могут быть выполнены в среде AluVM.

Дополнительная информация: Официальный сайт AluVM

Якорь

Якорь представляет собой набор данных на стороне клиента, используемых для доказательства включения уникальной коммисии в транзакцию. В протоколе RGB якорь состоит из следующих элементов:

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

Задание

В логике RGB назначение - это эквивалент транзакционного вывода, который изменяет, обновляет или создает определенные свойства в состоянии контракта. Назначение состоит из двух элементов:

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

Логика бизнеса

Бизнес-логика объединяет все правила и внутренние операции контракта, описанные его схемой (т. е. структурой самого контракта). Она определяет, как и при каких условиях может изменяться состояние контракта.

Удостоверение на стороне клиента

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

Обязательства

Обязательство (в криптографическом смысле) - это математический объект, обозначаемый C, получаемый детерминированно из операции над структурированными данными m (сообщение) и случайной величины r. Мы пишем :

C = \text{commit}(m, r)

Этот механизм состоит из двух основных операций:

Обязательства должны соблюдать два свойства:

m' : \, | \, : m' \neq m \quad \text{and} \quad r' : \, | \, : r' \neq r \quad

Такие как :

\text{verify}(m, r, C) = \text{verify}(m', r', C) \rightarrow \text{True}

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

Консигнация

В консигнации группируются данные, которыми обмениваются стороны и которые подлежат валидации в RGB на стороне клиента. Существует две основные категории консигнации:

Эти партии не записываются публично в блокчейн; они обмениваются напрямую между заинтересованными сторонами по выбранному ими каналу связи.

Контракт

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

Работа по контракту

Операция по договору - это обновление статуса договора, выполняемое в соответствии с правилами схемы. В RGB существуют следующие операции:

Каждая операция изменяет состояние, добавляя или заменяя определенные данные (глобальное состояние, состояние владельца...).

Участник контракта

Участник контракта - это субъект, который принимает участие в операциях, связанных с контрактом. В RGB проводится различие между :

Права по договору

Права по контракту - это различные права, которые могут быть реализованы участниками контракта RGB. Они делятся на несколько категорий:

Состояние контракта

Состояние контракта соответствует текущему состоянию контракта в определенный момент времени. Он может состоять как из публичных, так и из приватных данных, отражающих состояние контракта. RGB различает :

Детерминированное обязательство биткойна - DBC

Детерминированная фиксация Биткойна (DBC) - это набор правил, используемых для доказательной и однозначной регистрации коммитмента в транзакции Биткойна. В протоколе RGB существует две основные формы DBC:

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

Направленный ациклический граф - DAG

DAG (или Acyclic Guided Graph) - это граф без циклов, позволяющий осуществлять топологическое планирование. Блокчейны, как и шарды контрактов RGB, могут быть представлены в виде DAG.

Дополнительная информация: Directed Acyclic Graph

Гравировка

Гравировка - это необязательная строка данных, которую сменяющие друг друга владельцы контракта могут внести в историю контракта. Эта функция существует, например, в интерфейсе RGB21 и позволяет добавлять в историю контрактов памятную или описательную информацию.

Дополнительное доказательство транзакции - ETP

ETP (Extra Transaction Proof) - это часть Anchor, содержащая дополнительные данные, необходимые для подтверждения Tapret commitment (в контексте taproot). Она включает в себя, помимо прочего, внутренний открытый ключ скрипта taproot (internal PubKey) и информацию, специфичную для Script Path Spend.

Genesis

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

Глобальное государство

Глобальное состояние - это набор публичных свойств, содержащихся в состоянии контракта. Оно определяется в Genesis и, в зависимости от правил контракта, может быть обновлено авторизованными переходами. В отличие от собственных состояний, глобальное состояние не принадлежит конкретному субъекту; оно ближе к публичному реестру внутри контракта.

Интерфейс

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

Реализация интерфейса

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

Счет-фактура

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

Сеть молний

Lightning Network - это децентрализованная сеть платежных каналов (или государственных каналов) Биткойна, состоящая из 2/2 кошельков с несколькими подписями. Она обеспечивает быстрые и недорогие нецепочечные транзакции, опираясь при этом на первый уровень Биткойна для арбитража (или закрытия), когда это необходимо.

Для получения более подробной информации о том, как работает Lightning, я рекомендую вам пройти этот другой курс:

https://planb.network/courses/34bd43ef-6683-4a5c-b239-7cb1e40a4aeb

Многопротокольное обязательство - MPC

Мультипротокольное обязательство (MPC) относится к структуре дерева Меркла, используемой в RGB для включения в одну транзакцию Биткойна нескольких Переходных пакетов из разных контрактов. Идея заключается в том, чтобы сгруппировать несколько обязательств (потенциально соответствующих разным контрактам или разным активам) в одной точке привязки, чтобы оптимизировать занятие пространства блока.

Владение государством

Владельческое состояние - это часть контрактного состояния, которая заключена в Назначении и связана с конкретным владельцем (через одноразовую печать, указывающую на UTXO). Она представляет собой, например, цифровой актив или конкретное контрактное право, закрепленное за данным лицом.

Собственность

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

Частично подписанная транзакция биткойна - PSBT

PSBT (Partially Signed Bitcoin Transaction) - это транзакция Bitcoin, которая еще не полностью подписана. Она может быть разделена между несколькими организациями, каждая из которых может добавлять или проверять определенные элементы (подписи, скрипты...), пока транзакция не будет признана готовой для распространения на цепи.

Дополнительная информация: BIP-0174

Обязательства Педерсена

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

Формально, если :

C1=\text{commit}(m1,r1) \quad C2=\text{commit}(m2,r2)

затем

C3=C1⋅C2=\text{commit}(m1+m2, r1+r2)

Это свойство полезно, например, для сокрытия количества обмениваемых токенов, но при этом для проверки итогов.

Дополнительная информация: Pedersen commitment

Выкупить

В расширении штата под Redeem понимается действие по возвращению (или использованию) ранее объявленной Valency. Поскольку валентность - это публичное право, выкуп позволяет уполномоченному участнику претендовать на конкретное расширение штата контракта.

Схема

Схема в RGB - это декларативный фрагмент кода, описывающий набор переменных, правил и бизнес-логики (Business Logic), которые управляют работой контракта. Схема определяет структуру состояний, типы допустимых переходов и условия проверки.

Определение печати

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

Осколок

Осколок представляет собой ветвь в DAG истории переходов состояний контракта RGB. Другими словами, это связное подмножество общей истории контракта, соответствующее, например, последовательности переходов, необходимых для доказательства действительности данного актива с момента генезиса.

Одноразовое уплотнение

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

Тайник

Тайник - это набор данных на стороне клиента, которые пользователь хранит для одного или нескольких контрактов RGB с целью проверки (Client-side Validation). Сюда входит история переходов, отправлений, подтверждений действительности и т. д. Каждый держатель сохраняет только те части истории, которые ему нужны (shards).

Расширение штата

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

Переход состояния

Переход состояния - это операция, которая изменяет состояние RGB-контракта на новое. Она может изменять данные глобального состояния и/или состояния владельца. На практике каждый переход проверяется правилами схемы и закрепляется в блокчейне Биткойна с помощью коммитмента.

Taproot

Относится к формату транзакций биткойна Segwit v1, представленному в BIP341 и BIP342. Taproot улучшает конфиденциальность и гибкость криптовалют, в частности, делая транзакции более компактными и трудноотличимыми друг от друга.

Конечная отправка - конечный пункт отправки

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

Переходный пакет

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

UTXO

Биткойн UTXO (Unspent Transaction Output) определяется хэшем транзакции и выходным индексом (vout). Иногда его также называют outpoint. В протоколе RGB ссылка на UTXO (через Seal Definition) позволяет определить местонахождение Owned State, то есть имущества, хранящегося в блокчейне.

Валентность

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

Сделка со свидетелем

Транзакция свидетеля - это транзакция Биткойна, которая закрывает одноразовую печать вокруг сообщения, содержащего многопротокольное обязательство (MPC). Эта транзакция тратит UTXO или создает его, чтобы запечатать обязательство, связанное с протоколом RGB. Она действует как внутрицепочечное доказательство того, что состояние было установлено в определенный момент времени.

Программирование на RGB

Реализация контрактов RGB

В этой главе мы подробно рассмотрим, как определяется и реализуется контракт RGB. Мы увидим, из каких компонентов состоит RGB-контракт, каковы их роли и как они строятся.

Компоненты договора RGB

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

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

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

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

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

В общем, каждый контракт состоит из :

RGB-Bitcoin

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

Чтобы прояснить эти понятия, приведем сводную таблицу, в которой компоненты контракта RGB сравниваются с концепциями, уже известными в объектно-ориентированном программировании (ООП) или в экосистеме Ethereum:

Компонент контракта RGBЗначениеЭквивалент OOPЭквивалент Ethereum
GenesisНачальное состояние контрактаКонструктор классаКонструктор контракта
SchemaБизнес-логика контрактаКлассКонтракт
InterfaceСемантика контрактаИнтерфейс (Java) / Трейт (Rust) / Протокол (Swift)Стандарт ERC
Interface ImplementationСопоставление семантики и логикиImpl (Rust) / Implements (Java)Application Binary Interface (ABI)

В левой колонке показаны элементы, характерные для протокола RGB. В среднем столбце указана конкретная функция каждого компонента. Затем, в колонке "OOP-эквивалент", мы находим эквивалентный термин в объектно-ориентированном программировании:

В контексте Ethereum Genesis ближе к конструктору контракта, Schema - к определению контракта, Interface - к стандарту, такому как ERC-20 или ERC-721, а Interface Implementation - к ABI (Application Binary Interface), который определяет формат взаимодействия с контрактом.

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

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

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

Схема

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

Схему можно сравнить с "классом" в объектно-ориентированном программировании (ООП). В общем случае она служит моделью, определяющей компоненты контракта, такие как :

RGB-Bitcoin

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

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

На практике Schema не является исполняемым кодом, что можно наблюдать в блокчейнах, хранящих код на цепочке (EVM в Ethereum). Напротив, RGB отделяет бизнес-логику (декларативную) от исполняемого кода на блокчейне (который ограничен криптографическими якорями). Таким образом, схема определяет правила, но применение этих правил происходит вне блокчейна, на сайте каждого участника, в соответствии с принципом Client-side Validation.

Схема должна быть скомпилирована, прежде чем ее можно будет использовать в RGB-приложениях. В результате компиляции создается двоичный файл (например, .rgb) или зашифрованный двоичный файл (.rgba). Когда кошелек импортирует этот файл, он знает, что :

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

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

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

Отличие от программируемых цепных блокчейнов

В отличие от таких систем, как Ethereum, где код смарт-контракта (исполняемый файл) записан в самом блокчейне, RGB хранит контракт (его логику) вне цепочки, в виде скомпилированного декларативного документа. Это означает, что :

Использование эмитентом и пользователями

Когда эмитент создает актив (например, неинфляционный взаимозаменяемый токен), он подготавливает :

Затем он делает скомпилированную схему (файл .rgb) доступной для пользователей, чтобы любой, кто получает передачу этого токена, мог проверить согласованность операции на месте. Без этой схемы пользователь не смог бы интерпретировать данные о статусе или проверить их соответствие правилам контракта.

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

Схема определяет бизнес-логику в RGB. В ней перечислены правила эволюции контракта, структура его данных (Owned States, Global State, Valencies) и связанные с ними скрипты проверки (исполняемые AluVM). Благодаря этому декларативному документу определение контракта (скомпилированный файл) четко отделено от фактического выполнения правил (на стороне клиента). Такое разделение придает RGB большую гибкость, позволяя использовать широкий спектр сценариев (сменные токены, NFT, более сложные контракты), избегая при этом сложности и недостатков, характерных для программируемых блокчейнов на цепочке.

Пример схемы

Давайте рассмотрим конкретный пример схемы для контракта RGB. Это выдержка на языке Rust из файла nia.rs (инициалы для "Неинфляционные активы"), который определяет модель для сменных токенов, которые не могут быть перевыпущены сверх их первоначального запаса (неинфляционный актив). Этот тип токенов можно рассматривать как эквивалент ERC20 во вселенной RGB в Ethereum, т. е. взаимозаменяемые токены, которые соблюдают определенные базовые правила (например, в отношении трансферов, инициализации запасов и т. д.).

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

RGB-Bitcoin

В приведенном ниже коде показано полное определение схемы Rust Schema. Мы будем комментировать его по частям, следуя аннотациям (1) - (9) ниже:

// ===== PART 1: Function Header and SubSchema =====
fn nia_schema() -> SubSchema {
// definitions of libraries and variables
// ===== PART 2: General Properties (ffv, subset_of, type_system) =====
Schema {
ffv: zero!(),
subset_of: None,
type_system: types.type_system(),
// ===== PART 3: Global States =====
global_types: tiny_bmap! {
GS_NOMINAL => GlobalStateSchema::once(types.get("RGBContract.DivisibleAssetSpec")),
GS_DATA => GlobalStateSchema::once(types.get("RGBContract.ContractData")),
GS_TIMESTAMP => GlobalStateSchema::once(types.get("RGBContract.Timestamp")),
GS_ISSUED_SUPPLY => GlobalStateSchema::once(types.get("RGBContract.Amount")),
},
// ===== PART 4: Owned Types =====
owned_types: tiny_bmap! {
OS_ASSET => StateSchema::Fungible(FungibleType::Unsigned64Bit),
},
// ===== PART 5: Valencies =====
valency_types: none!(),
// ===== PART 6: Genesis: Initial Operations =====
genesis: GenesisSchema {
metadata: Ty::<SemId>::UNIT.id(None),
globals: tiny_bmap! {
GS_NOMINAL => Occurrences::Once,
GS_DATA => Occurrences::Once,
GS_TIMESTAMP => Occurrences::Once,
GS_ISSUED_SUPPLY => Occurrences::Once,
},
assignments: tiny_bmap! {
OS_ASSET => Occurrences::OnceOrMore,
},
valencies: none!(),
},
// ===== PART 7: Extensions =====
extensions: none!(),
// ===== PART 8: Transitions: TS_TRANSFER =====
transitions: tiny_bmap! {
TS_TRANSFER => TransitionSchema {
metadata: Ty::<SemId>::UNIT.id(None),
globals: none!(),
inputs: tiny_bmap! {
OS_ASSET => Occurrences::OnceOrMore,
},
assignments: tiny_bmap! {
OS_ASSET => Occurrences::OnceOrMore,
},
valencies: none!(),
}
},
// ===== PART 9: Script AluVM and Entry Points =====
script: Script::AluVM(AluScript {
libs: confined_bmap! { alu_id => alu_lib },
entry_points: confined_bmap! {
EntryPoint::ValidateGenesis => LibSite::with(FN_GENESIS_OFFSET, alu_id),
EntryPoint::ValidateTransition(TS_TRANSFER) => LibSite::with(FN_TRANSFER_OFFSET, alu_id),
},
}),
}
}

Функция nia_schema() возвращает SubSchema, указывая на то, что данная схема может частично наследоваться от более общей схемы. В экосистеме RGB такая гибкость позволяет повторно использовать некоторые стандартные элементы основной схемы, а затем определять правила, специфичные для конкретного контракта. В данном случае мы решили не включать наследование, так как subset_of будет равно None.

Свойство ffv соответствует быстрой версии контракта. Значение zero!() здесь указывает на то, что мы находимся в версии 0 или начальной версии этой схемы. Если впоследствии вы захотите добавить новые функциональные возможности (новый тип операции и т.д.), вы можете увеличить значение этой версии, чтобы указать на изменение консенсуса.

Свойство subset_of: None подтверждает отсутствие наследования. Поле type_system ссылается на строгую систему типов, уже определенную в библиотеке types. Эта строка указывает на то, что все данные, используемые контрактом, используют строгую реализацию сериализации, предоставляемую данной библиотекой.

В блоке global_types мы объявляем четыре элемента. Мы используем ключ, такой как GS_NOMINAL или GS_ISSUED_SUPPLY, чтобы ссылаться на них в дальнейшем:

Ключевое слово once(...) означает, что каждое из этих полей может появиться только один раз.

В owned_types мы объявляем OS_ASSET, который описывает состояние fungible. Мы используем StateSchema::Fungible(FungibleType::Unsigned64Bit), указывая, что количество активов (токенов) хранится в виде 64-битного беззнакового целого. Таким образом, любая транзакция будет отправлять определенное количество единиц этого токена, которое будет проверяться в соответствии с этой строго типизированной числовой структурой.

Мы указываем valency_types: none!(), что означает, что в этой схеме нет валентностей, другими словами, нет специальных или дополнительных прав (таких как перевыпуск, условный ожог и т.д.). Если бы схема включала их, они были бы объявлены в этом разделе.

Здесь мы вступаем в ту часть, которая объявляет об операциях по контракту. Бытие описывается :

Таким образом, мы ограничиваем определение начальной эмиссии токенов: мы должны объявить выпущенную поставку (GS_ISSUED_SUPPLY), а также как минимум одного держателя (Owned State типа OS_ASSET).

Поле extensions: none!() указывает на то, что в данном контракте не предусмотрено расширение состояния. Это означает, что не существует операции выкупа цифрового права (Valency) или расширения состояния перед Переходом. Все делается через Genesis или Переходы состояния.

В переходах мы определяем тип операции TS_TRANSFER. Мы объясняем, что :

Это моделирует поведение базового трансфера, который расходует токены на UTXO, затем создает новые Owned States в пользу получателей, и таким образом сохраняет равенство общей суммы между входами и выходами.

Наконец, мы объявляем скрипт AluVM (Script::AluVM(AluScript { ... })). Этот скрипт содержит :

Этот код проверки отвечает за применение бизнес-логики. Например, он будет проверять :

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

Этот пример схемы "Не надуваемый надувной актив" дает нам лучшее понимание структуры простого контракта с надувными токенами RGB. Мы можем четко видеть разделение между описанием данных (Глобальные и Владельческие состояния), объявлением операций (Генезис, Переходы, Расширения) и реализацией проверки (AluVM-скрипты). Благодаря этой модели токен ведет себя как классический сменный токен, но при этом остается валидированным на стороне клиента и не зависит от внутрицепочечной инфраструктуры для выполнения своего кода. В блокчейне Биткойна закреплены только криптографические обязательства.

Интерфейс

Интерфейс - это слой, предназначенный для того, чтобы сделать контракт читаемым и манипулируемым как для пользователей (чтение человеком), так и для портфелей (чтение программным обеспечением). Таким образом, интерфейс играет роль, сравнимую с ролью интерфейса в объектно-ориентированном языке программирования (Java, Rust trait и т. д.), поскольку он раскрывает и уточняет функциональную структуру контракта, не обязательно раскрывая внутренние детали бизнес-логики.

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

RGB-Bitcoin

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

Общая эксплуатация

Этот метод имеет множество преимуществ:

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

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

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

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

RGB-Bitcoin

На практике, когда кошелек получает RGB-контракт (через файл .rgb или .rgba), он также импортирует связанный с ним интерфейс, который также компилируется. Во время выполнения кошелек может, например, :

Отличие от Ethereum и других систем

В Ethereum интерфейс (описанный через ABI, Application Binary Interface) обычно формируется из хранимого на цепочке кода (смарт-контракта). Изменение конкретной части интерфейса, не затрагивая сам контракт, может быть дорогостоящим или сложным. Однако RGB основан на полностью внецепочечной логике, а данные хранятся в обязательствах на Биткойне. Такая конструкция позволяет изменять интерфейс (или его реализацию), не влияя на фундаментальную безопасность контракта, поскольку проверка бизнес-правил остается в схеме и коде AluVM.

Компиляция интерфейса

Как и в случае со схемой, интерфейс определяется в исходном коде (часто на языке Rust) и компилируется в файл .rgb или .rgba. Этот двоичный файл содержит всю информацию, необходимую кошельку для :

После импорта интерфейса кошелек может корректно отображать контракт и предлагать пользователю взаимодействие.

Интерфейсы, стандартизированные ассоциацией LNP/BP

В экосистеме RGB интерфейс используется для придания читабельного и манипулируемого смысла данным и операциям контракта. Таким образом, интерфейс дополняет схему, которая описывает внутреннюю бизнес-логику (строгие типы, скрипты валидации и т. д.). В этом разделе мы рассмотрим стандартные интерфейсы, разработанные ассоциацией LNP/BP для распространенных типов контрактов (сменные токены, NFT и т. д.).

Напомним, что идея заключается в том, что каждый интерфейс описывает, как отображать и манипулировать контрактом на стороне кошелька, четко называя поля (такие как spec, ticker, issuedSupply...) и определяя возможные операции (такие как Transfer, Burn, Rename...). Несколько интерфейсов уже работают, но в будущем их будет становиться все больше и больше.

Некоторые готовые к использованию интерфейсы

RGB20 - это интерфейс для взаимозаменяемых активов, который можно сравнить со стандартом ERC20 в Ethereum. Однако он идет на шаг дальше, предлагая более широкую функциональность:

Например, интерфейс RGB20 может быть связан со схемой Non-Inflatable Asset (NIA), которая устанавливает ненадуваемый первоначальный объем поставки, или с другими более продвинутыми схемами, если это необходимо.

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

RGB25 - это гибридный стандарт, сочетающий в себе сменные и несменные аспекты. Он предназначен для частично взаимозаменяемых активов, таких как токенизация недвижимости, когда вы хотите разделить объект недвижимости, сохранив при этом связь с единым корневым активом (другими словами, у вас есть взаимозаменяемые части дома, связанные с неперемещаемым домом). Технически этот интерфейс можно связать со схемой *Collectible Fungible Asset (CFA)**, которая учитывает понятие разделения при отслеживании исходного актива.

Разрабатываемые интерфейсы

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

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

Пример интерфейса

В этом фрагменте кода Rust показан интерфейс RGB20 (функциональный актив). Этот код взят из файла rgb20.rs в стандартной библиотеке RGB. Давайте посмотрим на него, чтобы понять структуру интерфейса и то, как он обеспечивает мост между, с одной стороны, бизнес-логикой (определенной в схеме) и, с другой стороны, функциональными возможностями, открытыми для кошельков и пользователей.

// ...
fn rgb20() -> Iface {
let types = StandardTypes::with(rgb20_stl());
Iface {
version: VerNo::V1,
name: tn!("RGB20"),
global_state: tiny_bmap! {
fname!("spec") => GlobalIface::required(types.get("RGBContract.DivisibleAssetSpec")),
fname!("data") => GlobalIface::required(types.get("RGBContract.ContractData")),
fname!("created") => GlobalIface::required(types.get("RGBContract.Timestamp")),
fname!("issuedSupply") => GlobalIface::one_or_many(types.get("RGBContract.Amount")),
fname!("burnedSupply") => GlobalIface::none_or_many(types.get("RGBContract.Amount")),
fname!("replacedSupply") => GlobalIface::none_or_many(types.get("RGBContract.Amount")),
},
assignments: tiny_bmap! {
fname!("inflationAllowance") => AssignIface::public(OwnedIface::Amount, Req::NoneOrMore),
fname!("updateRight") => AssignIface::public(OwnedIface::Rights, Req::Optional),
fname!("burnEpoch") => AssignIface::public(OwnedIface::Rights, Req::Optional),
fname!("burnRight") => AssignIface::public(OwnedIface::Rights, Req::NoneOrMore),
fname!("assetOwner") => AssignIface::private(OwnedIface::Amount, Req::NoneOrMore),
},
valencies: none!(),
genesis: GenesisIface {
metadata: Some(types.get("RGBContract.IssueMeta")),
global: tiny_bmap! {
fname!("spec") => ArgSpec::required(),
fname!("data") => ArgSpec::required(),
fname!("created") => ArgSpec::required(),
fname!("issuedSupply") => ArgSpec::required(),
},
assignments: tiny_bmap! {
fname!("assetOwner") => ArgSpec::many(),
fname!("inflationAllowance") => ArgSpec::many(),
fname!("updateRight") => ArgSpec::optional(),
fname!("burnEpoch") => ArgSpec::optional(),
},
valencies: none!(),
errors: tiny_bset! {
SUPPLY_MISMATCH,
INVALID_PROOF,
INSUFFICIENT_RESERVES
},
},
transitions: tiny_bmap! {
tn!("Transfer") => TransitionIface {
optional: false,
metadata: None,
globals: none!(),
inputs: tiny_bmap! {
fname!("previous") => ArgSpec::from_non_empty("assetOwner"),
},
assignments: tiny_bmap! {
fname!("beneficiary") => ArgSpec::from_non_empty("assetOwner"),
},
valencies: none!(),
errors: tiny_bset! {
NON_EQUAL_AMOUNTS
},
default_assignment: Some(fname!("beneficiary")),
},
tn!("Issue") => TransitionIface {
optional: true,
metadata: Some(types.get("RGBContract.IssueMeta")),
globals: tiny_bmap! {
fname!("issuedSupply") => ArgSpec::required(),
},
inputs: tiny_bmap! {
fname!("used") => ArgSpec::from_non_empty("inflationAllowance"),
},
assignments: tiny_bmap! {
fname!("beneficiary") => ArgSpec::from_many("assetOwner"),
fname!("future") => ArgSpec::from_many("inflationAllowance"),
},
valencies: none!(),
errors: tiny_bset! {
SUPPLY_MISMATCH,
INVALID_PROOF,
ISSUE_EXCEEDS_ALLOWANCE,
INSUFFICIENT_RESERVES
},
default_assignment: Some(fname!("beneficiary")),
},
tn!("OpenEpoch") => TransitionIface {
optional: true,
metadata: None,
globals: none!(),
inputs: tiny_bmap! {
fname!("used") => ArgSpec::from_required("burnEpoch"),
},
assignments: tiny_bmap! {
fname!("next") => ArgSpec::from_optional("burnEpoch"),
fname!("burnRight") => ArgSpec::required()
},
valencies: none!(),
errors: none!(),
default_assignment: Some(fname!("burnRight")),
},
tn!("Burn") => TransitionIface {
optional: true,
metadata: Some(types.get("RGBContract.BurnMeta")),
globals: tiny_bmap! {
fname!("burnedSupply") => ArgSpec::required(),
},
inputs: tiny_bmap! {
fname!("used") => ArgSpec::from_required("burnRight"),
},
assignments: tiny_bmap! {
fname!("future") => ArgSpec::from_optional("burnRight"),
},
valencies: none!(),
errors: tiny_bset! {
SUPPLY_MISMATCH,
INVALID_PROOF,
INSUFFICIENT_COVERAGE
},
default_assignment: None,
},
tn!("Replace") => TransitionIface {
optional: true,
metadata: Some(types.get("RGBContract.BurnMeta")),
globals: tiny_bmap! {
fname!("replacedSupply") => ArgSpec::required(),
},
inputs: tiny_bmap! {
fname!("used") => ArgSpec::from_required("burnRight"),
},
assignments: tiny_bmap! {
fname!("beneficiary") => ArgSpec::from_many("assetOwner"),
fname!("future") => ArgSpec::from_optional("burnRight"),
},
valencies: none!(),
errors: tiny_bset! {
NON_EQUAL_AMOUNTS,
SUPPLY_MISMATCH,
INVALID_PROOF,
INSUFFICIENT_COVERAGE
},
default_assignment: Some(fname!("beneficiary")),
},
tn!("Rename") => TransitionIface {
optional: true,
metadata: None,
globals: tiny_bmap! {
fname!("new") => ArgSpec::from_required("spec"),
},
inputs: tiny_bmap! {
fname!("used") => ArgSpec::from_required("updateRight"),
},
assignments: tiny_bmap! {
fname!("future") => ArgSpec::from_optional("updateRight"),
},
valencies: none!(),
errors: none!(),
default_assignment: Some(fname!("future")),
},
},
extensions: none!(),
error_type: types.get("RGB20.Error"),
default_operation: Some(tn!("Transfer")),
type_system: types.type_system(),
}
}

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

Разница со Schema заключается в природе типов. В Schema используются строгие типы (например, FungibleType::Unsigned64Bit) и более технические идентификаторы. В интерфейсе используются имена полей, макросы (fname!(), tn!()) и ссылки на классы аргументов (ArgSpec, OwnedIface::Rights...). Цель здесь - облегчить функциональное понимание и организацию элементов для кошелька.

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

Глобальное состояние и задания

В разделе global_state находятся такие поля, как spec (описание актива), data, created, issuedSupply, burnedSupply, replacedSupply. Это поля, которые кошелек может прочитать и представить. Например:

В разделе Назначения мы определяем различные роли или права. Например:

Ключевое слово public или private (например, AssignIface::public(...)) указывает, являются ли эти состояния видимыми (public) или конфиденциальными (private). Что касается Req::NoneOrMore, Req::Optional, то они указывают на ожидаемое возникновение.

Генезис и переходы

Часть genesis описывает, как инициализируется актив:

Затем для каждого перехода (Transfer, Issue, Burn...) интерфейс определяет, какие поля операция ожидает получить на вход, какие поля операция выдаст на выход и какие ошибки могут возникнуть. Например:

Переход :

Переход Выпуск :

Переход ожога :

Поэтому каждая операция описывается так, чтобы ее мог прочитать кошелек. Это позволяет отобразить графический интерфейс, в котором пользователь может ясно увидеть: "У вас есть право на сжигание. Хотите ли вы сжечь определенную сумму? Код знает, что нужно заполнить поле burnedSupply и проверить, что burnRight является действительным.

Подводя итог, важно помнить, что интерфейс, каким бы полным он ни был, сам по себе не определяет внутреннюю логику контракта. Основную работу выполняет Схема, которая включает в себя строгие типы, структуру Genesis, переходы и так далее. Интерфейс просто раскрывает эти элементы в более интуитивном и именованном виде для использования в приложении.

Благодаря модульности RGB, интерфейс можно модернизировать (например, добавить переход Rename, исправить отображение поля и т. д.) без необходимости переписывать весь контракт. Пользователи этого интерфейса могут немедленно воспользоваться этими улучшениями, как только они обновят файл .rgb или .rgba.

Но как только вы объявили интерфейс, вам нужно связать его с соответствующей схемой. Это делается с помощью Interface Implementation, которая определяет, как сопоставить каждое именованное поле (например, fname!("assetOwner")) со строгим идентификатором (например, OS_ASSET), определенным в схеме. Это гарантирует, например, что когда кошелек манипулирует полем burnRight, это состояние, которое в схеме описывает возможность сжигать токены.

Реализация интерфейса

В архитектуре RGB мы видели, что каждый компонент (схема, интерфейс и т. д.) может быть разработан и скомпилирован независимо. Однако есть один незаменимый элемент, который связывает эти различные строительные блоки воедино: Реализация интерфейса. Это то, что явно сопоставляет идентификаторы или поля, определенные в схеме (со стороны бизнес-логики), с именами, объявленными в интерфейсе (со стороны представления и взаимодействия с пользователем). Таким образом, когда кошелек загружает контракт, он может точно понять, какое поле чему соответствует, и как операция, названная в интерфейсе, связана с логикой схемы.

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

Вот классический пример реализации интерфейса, в котором мы связываем схему Non-Inflatable Asset (NIA) с интерфейсом RGB20:

fn nia_rgb20() -> IfaceImpl {
let schema = nia_schema();
let iface = Rgb20::iface();
IfaceImpl {
version: VerNo::V1,
schema_id: schema.schema_id(),
iface_id: iface.iface_id(),
script: none!(),
global_state: tiny_bset! {
NamedField::with(GS_NOMINAL, fname!("spec")),
NamedField::with(GS_DATA, fname!("data")),
NamedField::with(GS_TIMESTAMP, fname!("created")),
NamedField::with(GS_ISSUED_SUPPLY, fname!("issuedSupply")),
},
assignments: tiny_bset! {
NamedField::with(OS_ASSET, fname!("assetOwner")),
},
valencies: none!(),
transitions: tiny_bset! {
NamedType::with(TS_TRANSFER, tn!("Transfer")),
},
extensions: none!(),
}
}

В этом интерфейсе реализации :

В результате компиляции получается отдельный файл .rgb или .rgba, который импортируется в кошелек в дополнение к Схеме и Интерфейсу. Таким образом, программное обеспечение знает, как конкретно соединить этот контракт NIA (логика которого описывается его схемой) с интерфейсом "RGB20" (который предоставляет человеческие имена и режим взаимодействия для сменных токенов), применяя эту реализацию интерфейса в качестве шлюза между ними.

Зачем нужна отдельная реализация интерфейса?

Разделение повышает гибкость. Одна схема может иметь несколько различных реализаций интерфейса, каждая из которых отображает свой набор функциональных возможностей. Более того, сама реализация интерфейса может развиваться или переписываться, не требуя изменений ни в схеме, ни в интерфейсе. Это сохраняет принцип модульности RGB: каждый компонент (схема, интерфейс, реализация интерфейса) может быть изменен и обновлен независимо, при условии соблюдения правил совместимости, налагаемых протоколом (одинаковые идентификаторы, согласованность типов и т. д.).

В конкретном случае, когда кошелек загружает контракт, он должен :

Эта модульная архитектура делает возможными такие сценарии использования, как :

В следующей главе мы рассмотрим, как работает передача контракта и как формируются счета-фактуры RGB.

Переводы по контрактам

В этой главе мы проанализируем процесс передачи контракта в экосистеме RGB. Для иллюстрации мы рассмотрим Алису и Боба, наших обычных героев, которые хотят обменяться активами RGB. Мы также покажем некоторые фрагменты команд из командной строки инструмента rgb, чтобы увидеть, как он работает на практике.

Понимание передачи договора RGB

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

1) Установка кошелька RGB

Прежде всего Бобу нужно установить RGB-кошелек, то есть программное обеспечение, совместимое с протоколом. Изначально он не содержит никаких контрактов. Бобу также понадобится :

Напомним, что Обладающие состояния в RGB относятся к биткоин UTXO. Поэтому мы всегда должны быть в состоянии управлять и тратить UTXO в транзакции Bitcoin, которая включает криптографические обязательства (Tapret или Opret), указывающие на данные RGB.

2) Получение информации о контракте

Затем Бобу нужно получить интересующие его данные о контракте. Эти данные могут распространяться по любому каналу: веб-сайт, электронная почта, приложение для обмена сообщениями... На практике они группируются в соглашение, то есть небольшой пакет данных, содержащий :

RGB-Bitcoin

Общий размер часто составляет порядка нескольких килобайт, поскольку каждый компонент обычно весит менее 200 байт. Можно также транслировать эту партию в Base58, по каналам, устойчивым к цензуре (например, через Ностр или Lightning Network), или в виде QR-кода.

3) Импорт и проверка контрактов

Получив груз, Боб импортирует его в свой кошелек RGB. После этого :

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

Процесс обнаружения владельца определенного актива RGB аналогичен поиску плательщика биткойнов. Детали этого соединения зависят от способа использования (маркетплейсы, приватные каналы чата, выставление счетов, продажа товаров и услуг, заработная плата...).

4) Выставление счета-фактуры

Чтобы начать передачу актива RGB, Боб должен сначала выставить счет-фактуру. Этот счет-фактура используется для :

Боб использует инструмент rgb в командной строке. Предположим, ему нужно 100 единиц токена, чей ContractId известен, он хочет полагаться на Tapret и указывает его UTXO (456e3..dfe1:0):

bob$ rgb invoice RGB20 100 <ContractId> tapret1st:456e3..dfe1:0

В конце этой главы мы подробнее рассмотрим структуру RGB-счетов.

5) Передача счетов-фактур

Сформированный счет-фактура (например, в виде URL: rgb:2WBcas9.../RGB20/100+utxob:...) содержит всю информацию, необходимую Алисе для подготовки перевода. Как и накладная, она может быть закодирована в компактном виде (Base58 или другой формат) и отправлена через приложение для обмена сообщениями, электронную почту, Nostr...

RGB-Bitcoin

6) Подготовка транзакций на стороне Алисы

Алиса получает счет от Боба. В ее RGB-кошельке есть тайник, содержащий актив, который нужно перевести. Чтобы потратить UTXO, содержащий актив, она должна сначала сгенерировать PSBT (Partially Signed Bitcoin Transaction), то есть неполную транзакцию Bitcoin, используя имеющийся у нее UTXO:

alice$ wallet construct tx.psbt

Эта базовая транзакция (пока без подписи) будет использована для закрепления криптографического обязательства, связанного с передачей Бобу. Таким образом, UTXO Алисы будет потрачен, а на выходе мы разместим обязательство Tapret или Opret для Боба.

7) Формирование передаточной партии

Затем Алиса создает терминальную партию (иногда называемую "передаточной партией") с помощью команды :

alice$ rgb transfer tx.psbt <invoice> consignment.rgb

Этот новый файл consignment.rgb содержит :

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

8) Боб проверяет и принимает груз

Алиса передает эту терминальную партию Бобу. После этого Боб :

bob$ rgb accept consignment.rgb
sig:DbwzvSu4BZU81jEpE9FVZ3xjcyuTKWWy2gmdnaxtACrS
RGB-Bitcoin

9) Вариант: Боб отправляет Алисе подтверждение (платежную ведомость)

Если Боб захочет, он может отправить эту подпись обратно Алисе. Это означает:

Это не является обязательным, но может дать Алисе уверенность в том, что впоследствии не возникнет споров по поводу передачи.

10) Алиса подписывает и публикует транзакцию

Алиса может :

alice$ rgb check <sig>
alice$ wallet sign —publish tx.psbt
RGB-Bitcoin

После подтверждения эта транзакция знаменует собой завершение передачи. Боб становится новым владельцем актива: теперь у него есть состояние Owned State, указывающее на контролируемый им UTXO, что подтверждается наличием обязательства в транзакции.

Вкратце, вот полный процесс перевода:

RGB-Bitcoin

Преимущества передачи данных в формате RGB

Только Алиса и Боб имеют доступ ко всем данным о переходе состояний. Они обмениваются этой информацией вне блокчейна, через транзакции. Криптографические обязательства в транзакции Bitcoin не раскрывают ни тип актива, ни его количество, что гарантирует гораздо большую конфиденциальность, чем другие системы токенов на цепочке.

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

Сложные обмены (например, атомарный обмен между BTC и активом RGB) могут быть осуществлены в рамках одной транзакции, что избавляет от необходимости использовать скрипты HTLC или PTLC. Если соглашение не транслируется, каждый может повторно использовать свои UTXO другими способами.

Сводная диаграмма переноса

Прежде чем рассматривать счета более подробно, приведем краткую схему общего процесса передачи RGB:

RGB-Bitcoin

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

Счета-фактуры RGB

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

Идентификаторы и кодирование

Для каждого из следующих элементов определяется уникальный идентификатор:

Эта уникальность очень важна, поскольку каждый компонент системы должен быть различим. Например, контракт X нельзя спутать с другим контрактом Y, а два разных интерфейса (например, RGB20 против RGB21) должны иметь разные идентификаторы.

Чтобы сделать эти идентификаторы эффективными (небольшого размера) и читаемыми, мы используем :

Например, ContractId может быть представлен чем-то вроде :

rgb:2WBcas9-yjzEvGufY-9GEgnyMj7-beMNMWA8r-sPHtV1nPU-TMsGMQX

Префикс rgb: подтверждает, что это RGB-идентификатор, а не HTTP-ссылка или другой протокол. Благодаря этому префиксу кошельки могут правильно интерпретировать строку.

Сегментация идентификаторов

Идентификаторы RGB часто бывают довольно длинными, так как для обеспечения безопасности (криптографической) могут потребоваться поля длиной 256 бит и более. Чтобы облегчить чтение и проверку человеком, мы разбиваем эти строки на несколько блоков, разделенных дефисом (-). Таким образом, вместо длинной, непрерывной строки символов мы делим ее на более короткие блоки. Такая практика характерна для номеров кредитных карт или телефонов, и здесь она также применяется для облегчения проверки. Так, например, пользователю или партнеру можно сказать: "Пожалуйста, проверьте, что третий блок - 9GEgnyMj7", вместо того чтобы сравнивать все сразу. Последний блок часто используется в качестве контрольной суммы, чтобы иметь систему обнаружения ошибок или опечаток.

Например, ContractId в кодировке base58 и сегментированный может быть :

2WBcas9-yjzEvGufY-9GEgnyMj7-beMNMWA8r-sPHtV1nPU-TMsGMQX

Каждое из тире разбивает строку на части. Это не влияет на семантику кода, только на его представление.

Использование URL-адресов для счетов-фактур

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

Счет-фактура для взаимозаменяемого токена (например, токена RGB20) может выглядеть следующим образом:

rgb:2WBcas9-yjzEvGufY-9GEgnyMj7-beMNMWA8r-sPHtV1nPU-TMsGMQX/RGB20/100+utxob:egXsFnw-5Eud7WKYn-7DVQvcPbc-rR69YmgmG-veacwmUFo-uMFKFb

Давайте проанализируем этот URL:

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

Можно представить себе систему, в которой вместо ContractId используется простой тикер (например, USDT). Однако в этом случае возникли бы серьезные проблемы с доверием и безопасностью: тикер не является уникальной ссылкой (несколько контрактов могут претендовать на название USDT). В RGB нам нужен уникальный, однозначный криптографический идентификатор. Поэтому была принята 256-битная строка, закодированная в base58 и сегментированная. Пользователь знает, что он манипулирует именно тем контрактом, чей идентификатор 2WBcas9-yjz..., а не каким-либо другим.

Дополнительные параметры URL

Вы также можете добавить дополнительные параметры в URL, как и в HTTP, например :

rgb:2WBcas9-yjzEvGufY-9GEgnyMj7-beMNMWA8r-sPHtV1nPU-TMsGMQX/RGB20/100+utxob:egXsFnw-5Eud7WKYn-7DVQvcPbc-rR69YmgmG-veacwmUFo-uMFKFb?sig=6kzbKKffP6xftkxn9UP8gWqiC41W16wYKE5CYaVhmEve

Рассмотрим случай NFT через интерфейс RGB21. Например, мы можем иметь :

rgb:7BKsac8-beMNMWA8r-3GEprtFh7-bjzEvGufY-aNLuU4nSN-MRsLOIK/RGB21/DbwzvSu-4BZU81jEp-E9FVZ3xj-cyuTKWWy-2gmdnaxt-ACrS+utxob:egXsFnw-5Eud7WKYn-7DVQvcPbc-rR69YmgmG-veacwmUFo-uMFKFb

Здесь мы видим :

Идея та же: передайте уникальную ссылку, которую кошелек может интерпретировать, четко идентифицируя уникальный актив, подлежащий передаче.

Другие операции через URL

URL-адреса RGB используются не только для запроса перевода. Они также могут кодировать более сложные операции, такие как выпуск новых токенов (issuance). Например:

rgb:2WBcas9-yjzEvGufY-9GEgnyMj7-beMNMWA8r-sPHtV1nPU-TMsGMQX/RGB20/issue/100000+utxob:egXsFnw-5Eud7WKYn-7DVQvcPbc-rR69YmgmG-veacwmUFo-uMFKFb

Здесь мы находим :

Например, кошелек может гласить: "Меня попросили выполнить операцию выдачи из интерфейса RGB20, по такому-то и такому-то контракту, на 100 000 единиц, в пользу такой-то и такой-то Одноразовой Печати*"

Теперь, когда мы рассмотрели основные элементы RGB-программирования, я расскажу вам в следующей главе о том, как составлять RGB-контракт.

Составление смарт-контрактов

В этой главе мы рассмотрим пошаговый подход к написанию контракта с помощью инструмента командной строки rgb. Цель - показать, как установить и работать с CLI, скомпилировать схему, импортировать интерфейс и реализацию интерфейса, а затем выпустить (issue) актив. Мы также рассмотрим базовую логику, включая компиляцию и проверку состояния. К концу этой главы вы сможете воспроизвести этот процесс и создать свои собственные RGB-контракты.

Напомним, что внутренняя логика RGB основана на библиотеках Rust, которые вы, как разработчики, можете импортировать в свои проекты для управления частью валидации на стороне клиента. Кроме того, команда LNP/BP Association работает над привязками для других языков, но эта работа еще не завершена. Кроме того, другие организации, такие как Bitfinex, разрабатывают свои собственные интеграционные стеки (мы поговорим о них в последних двух главах курса). Таким образом, на данный момент официальным эталоном является rgb CLI, даже если он остается относительно недоработанным.

Установка и презентация инструмента rgb

Основная команда называется просто rgb. Она напоминает git, с набором подкоманд для работы с контрактами, их вызовом, выпуском активов и так далее. Bitcoin Wallet в настоящее время не интегрирован, но будет интегрирован в ближайшей версии (0.11). Следующая версия позволит пользователям создавать и управлять своими кошельками (через дескрипторы) непосредственно из rgb, включая генерацию PSBT, совместимость с внешним оборудованием (например, аппаратным кошельком) для подписи и взаимодействие с таким программным обеспечением, как Sparrow. Это упростит весь сценарий эмиссии и передачи активов.

Установка через Cargo

Мы устанавливаем инструмент в Rust с :

cargo install rgb-contracts --all-features

(Примечание: крейт называется rgb-contracts, а установленная команда будет называться rgb. Если крейт с именем rgb уже существовал, могло произойти столкновение, отсюда и название)

При установке компилируется большое количество зависимостей (например, парсинг команд, интеграция Electrum, управление доказательствами нулевого знания и т. д.).

По завершении установки в меню :

rgb

Запуск rgb (без аргументов) выводит список доступных подкоманд, таких как interfaces, chema, import, export, issue, invoice, transfer и т.д. Вы можете изменить директорию локального хранилища (тайник, в котором хранятся все журналы, схемы и реализации), выбрать сеть (testnet, mainnet) или настроить свой сервер Electrum.

RGB-Bitcoin

Первый обзор элементов управления

Выполнив следующую команду, вы увидите, что интерфейс RGB20 уже интегрирован по умолчанию:

rgb interfaces

Если этот интерфейс не интегрирован, клонируйте файл :

git clone https://github.com/RGB-WG/rgb-interfaces

Скомпилируйте его:

cargo run

Затем импортируйте выбранный вами интерфейс:

rgb import interfaces/RGB20.rgb
RGB-Bitcoin

С другой стороны, нам говорят, что ни одна схема еще не была импортирована в программное обеспечение. Также нет контракта в тайнике. Чтобы увидеть его, выполните команду :

rgb schemata

Затем вы можете клонировать хранилище, чтобы получить определенные схемы:

git clone https://github.com/RGB-WG/rgb-schemata
RGB-Bitcoin

Этот репозиторий содержит в директории src/ несколько файлов Rust (например, nia.rs), которые определяют схемы (NIA для "Ненадуваемый актив", UDA для "Уникальный цифровой актив" и т.д.). Для компиляции можно выполнить команду :

cd rgb-schemata
cargo run

В результате создается несколько файлов .rgb и .rgba, соответствующих скомпилированным схемам. Например, вы найдете NonInflatableAsset.rgb.

Импорт схемы и реализации интерфейса

Теперь вы можете импортировать схему в rgb :

rgb import schemata/NonInflatableAssets.rgb
RGB-Bitcoin

Это добавляет ее в локальный архив. Если мы выполним следующую команду, то увидим, что схема теперь появилась:

rgb schemata

Создание контракта (выдача)

Существует два подхода к созданию нового актива:

Вы можете найти примеры в Rust в папке examples, которые иллюстрируют, как вы создаете ContractBuilder, заполняете глобальное состояние (имя актива, тикер, поставка, дата и т.д.), определяете Owned State (к какому UTXO он приписан), затем собираете все это в contract consignment, который вы можете экспортировать, подтвердить и импортировать в тайник.

Другой способ - вручную отредактировать YAML-файл, чтобы настроить ticker, name, upply и так далее. Предположим, файл называется RGB20-demo.yaml. Вы можете указать :

Вот пример YAML-файла, который нужно создать:

interface: RGB20Fixed
globals:
spec:
ticker: PBN
name: Plan B Network
details: "Pay attention: the asset has no value"
precision: 2
terms:
text: >
SUBJECT TO, AND WITHOUT IN ANY WAY LIMITING, THE REPRESENTATIONS AND WARRANTIES OF ANY SELLER. PROPERTY IS BEING SOLD “AS IS”...
media: ~
issuedSupply: 100000000
assignments:
assetOwner:
seal: tapret1st:b449f7eaa3f98c145b27ad0eeb7b5679ceb567faef7a52479bc995792b65f804:1
amount: 100000000 # this is 1 million (we have two digits for cents)
RGB-Bitcoin

Затем просто выполните команду :

rgb issue '<SchemaID>' ssi:<Issuer> rgb20-demo.yaml
RGB-Bitcoin

В моем случае уникальный идентификатор схемы (должен быть заключен в одинарные кавычки) - RDYhMTR!9gv8Y2GLv9UNBEK1hcrCmdLDFk9Qd5fnO8k, и я не указал эмитента. Итак, мой заказ: :

rgb issue 'RDYhMTR!9gv8Y2GLv9UNBEK1hcrCmdLDFk9Qd5fnO8k' ssi:anonymous rgb20-demo.yaml

Если вы не знаете идентификатор схемы, выполните команду :

rgb schemata

CLI отвечает, что новый контракт был выпущен и добавлен в тайник. Если мы введем следующую команду, то увидим, что теперь есть дополнительный контракт, соответствующий только что выпущенному:

rgb contracts
RGB-Bitcoin

Затем следующая команда выводит глобальные состояния (имя, тикер, предложение...) и список Owned States, то есть распределений (например, 1 миллион токенов PBN, определенных в UTXO b449f7eaa3f98c145b27ad0eeb7b5679ceb567faef7a52479bc995792b65f804:1).

rgb state '<ContractId>'
RGB-Bitcoin

Экспорт, импорт и проверка

Чтобы поделиться этим контрактом с другими пользователями, его можно экспортировать из тайника в файл :

rgb export '<ContractId>' myContractPBN.rgb
RGB-Bitcoin

Файл myContractPBN.rgb может быть передан другому пользователю, который может добавить его в свой тайник с помощью команды :

rgb import myContractPBN.rgb

При импорте, если это простая контрактная партия, мы получим сообщение "Importing consignment rgb". Если это более крупная переходная партия, команда будет другой (rgb accept).

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

rgb validate myContract.rgb

Использование, проверка и отображение тайников

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

rgb dump
RGB-Bitcoin

В результате будет создана папка с подробной информацией обо всем тайнике.

Трансфер и PSBT

Чтобы осуществить перевод, вам потребуется манипулировать локальным кошельком Bitcoin для управления обязательствами Tapret или Opret.

Создайте счет-фактуру

В большинстве случаев взаимодействие между участниками контракта (например, Алисой и Бобом) происходит через создание счета-фактуры. Если Алиса хочет, чтобы Боб что-то выполнил (передачу токена, перевыпуск, действие в DAO и т. д.), Алиса создает счет-фактуру, в котором подробно описывает свои инструкции Бобу. Таким образом, мы имеем :

В отличие от других экосистем, RGB-счет не ограничивается понятием оплаты. Он может содержать любой запрос, связанный с контрактом: отозвать ключ, проголосовать, создать гравировку (engraving) на NFT и т. д. Соответствующая операция может быть описана в интерфейсе контракта. Соответствующая операция может быть описана в интерфейсе контракта.

Следующая команда генерирует RGB-фактуру:

$ rgb invoice $CONTRACT -i $INTERFACE $ACTION $STATE $SEAL

С :

Например, с помощью следующих команд

alice$ CONTRACT='iZgIN9EL-2H21UgQ-x!A3uJc-WwXhCSm-$9Lwcc1-v!mUkKY'
alice$ MY_UTXO=4960acc21c175c551af84114541eace09c14d3a1bb184809f7b80916f57f9ef8:1
alice$ rgb invoice $CONTRACT -i RGB20 --amount 100 $MY_UTXO

CLI создаст счет-фактуру, как :

rgb:iZgIN9EL-2H21UgQ-x!A3uJc-WwXhCSm-$9Lwcc1-v!mUkKY/RGB20/100+utxob:zlVS28Rb-...

Она может быть передана Бобу по любому каналу (текст, QR-код и т. д.).

Осуществление перевода

Для переноса из этого счета :

bob$ rgb transfer tx.psbt $INVOICE consignment.rgb
alice$ rgb accept consignment.rgb
bob$ rgb check <sig> && wallet sign --publish tx.psbt

В следующей главе мы подробно рассмотрим интеграцию RGB в Lightning Network.

RGB в сети Lightning

В этой главе я предлагаю рассмотреть, как RGB можно использовать в сети Lightning Network для интеграции и перемещения активов RGB (токенов, NFT и т. д.) через внецепочечные платежные каналы.

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

Создание и финансирование каналов

Чтобы создать канал Lightning, передающий RGB-активы, нам понадобятся два элемента:

В терминах Биткойна транзакция финансирования должна существовать для определения эталонного UTXO, даже если она содержит лишь небольшое количество сатов (при этом каждый вывод в будущих транзакциях обязательств должен оставаться выше лимита пыли). Например, Алиса может решить предоставить 10 тыс. сатов и 500 USDT (выпущенных в виде актива RGB). В транзакцию финансирования мы добавляем обязательство (Opret или Tapret), которое закрепляет переход состояния RGB.

RGB-Bitcoin

После того как транзакция финансирования подготовлена (но еще не передана), создаются транзакции обязательств, чтобы любая из сторон могла закрыть канал в одностороннем порядке в любой момент. Эти транзакции похожи на классические транзакции обязательств Lightning, за исключением того, что мы добавляем дополнительный выход, содержащий RGB-якорь (OP_RETURN или Taproot), связанный с новым переходом состояния.

Затем переход в состояние RGB перемещает активы из мультисигмы 2/2 финансирования в выходы транзакции обязательств. Преимущество этого процесса в том, что безопасность состояния RGB в точности соответствует карательной механике Lightning: если Боб передаст старое состояние канала, Алиса может наказать его и потратить выход, чтобы вернуть и саты, и токены RGB. Таким образом, стимул даже сильнее, чем в канале Lightning без RGB-активов, поскольку атакующий может потерять не только sats, но и RGB-активы канала.

Таким образом, транзакция с обязательствами, подписанная Алисой и отправленная Бобу, будет выглядеть следующим образом:

RGB-Bitcoin

А сопровождающая транзакция с обязательствами, подписанная Бобом и отправленная Алисе, будет выглядеть следующим образом:

RGB-Bitcoin

Обновление канала

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

Например, если Алиса переводит 30 USDT Бобу по каналу, новый переход состояния будет отражать баланс в 400 USDT для Алисы и 100 USDT для Боба. Транзакция фиксации добавляется в якорь OP_RETURN/Taproot (или модифицируется им), чтобы включить этот переход. Обратите внимание, что, с точки зрения RGB, входом для перехода остается исходный мультисиг (в котором активы на цепи фактически распределяются до закрытия канала). Меняются только выходы RGB (распределения), в зависимости от принятого решения о перераспределении.

Транзакция с обязательствами, подписанная Алисой, готова к распространению Бобом:

RGB-Bitcoin

Транзакция с обязательствами, подписанная Бобом, готова к распространению Алисой:

RGB-Bitcoin

Управление HTLC

В действительности Lightning Network позволяет направлять платежи по нескольким каналам, используя HTLC (Hashed Time-Locked Contracts). То же самое происходит и с RGB: для каждого платежа, проходящего по каналу, к транзакции, совершающей транзакцию, добавляется выход HTLC, а к этому HTLC привязывается распределение RGB. Таким образом, тот, кто потратит HTLC-вывод (благодаря секрету или по истечении таймлока), получит и саты, и связанные с ними RGB-активы. С другой стороны, вам, очевидно, нужно иметь достаточно денег на дороге в виде как сатов, так и RGB-активов.

RGB-Bitcoin

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

https://planb.network/courses/34bd43ef-6683-4a5c-b239-7cb1e40a4aeb

Карта кодов RGB

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

RGB-Bitcoin

Удостоверение на стороне клиента

Управление валидацией вне цепи и логикой одноразовых печатей.

Детерминированные обязательства биткойна (DBC)

Управление детерминированными привязками в транзакциях Bitcoin (Tapret, OP_RETURN и т. д.).

Многопротокольное обязательство (MPC)

Многочисленные комбинации задействования и интеграция с различными протоколами.

Строгие типы и строгое кодирование

Строгая система типизации и детерминированная сериализация используются для проверки на стороне клиента.

Ядро RGB

Ядро протокола, которое включает в себя основную логику проверки RGB.

Стандартная библиотека и кошелек RGB

Стандартные реализации, управление тайниками и кошельками.

RGB CLI

CLI rgb и crate wallet для работы с контрактами в командной строке.

Схема RGB

Содержит примеры схем (NIA, UDA и т.д.) и их реализаций.

ALuVM

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

Протокол биткойна - BP

Дополнения для поддержки протокола Bitcoin (транзакции, обходы и т. д.).

Повсеместные детерминированные вычисления - UBIDECO

Экосистема, связанная с детерминированными разработками с открытым исходным кодом.

Построение на основе RGB

DIBA и проект Bitmask

Этот заключительный раздел курса основан на презентациях, сделанных различными докладчиками на буткампе RGB. Он включает в себя отзывы и размышления о RGB и его экосистеме, а также презентации инструментов и проектов, основанных на протоколе. Модератором первой главы выступает Хантер Бист, а двух последующих - Фредерико Тенга.

От JavaScript к Rust и в экосистему биткойна

Сначала Хантер Бист работал в основном на JavaScript. Затем он открыл для себя Rust, синтаксис которого поначалу показался ему непривлекательным и разочаровывающим. Однако потом он оценил мощь языка, контроль над памятью (heap и stack), а также безопасность и производительность. Он подчеркивает, что Rust - это отличная тренировочная база для глубокого понимания того, как работает компьютер.

Хантер Бист рассказывает о своем участии в различных проектах экосистемы altcoin, таких как Ethereum (с Solidity, TypeScript и т. д.), а затем Filecoin. Он объясняет, что поначалу некоторые протоколы произвели на него впечатление, но в итоге большинство из них его разочаровали, не в последнюю очередь из-за их токеномики. Он осуждает сомнительные финансовые стимулы, инфляционное создание токенов, которое размывает инвесторов, и потенциально эксплуататорский аспект этих проектов. В итоге он занял позицию Биткойн-максималиста, не в последнюю очередь потому, что некоторые люди открыли ему глаза на более разумные экономические механизмы Биткойна и на надежность этой системы.

Привлекательность RGB и создание слоев

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

В феврале 2022 года он присоединился к DIBA для работы над RGB, и в частности над кошельком Bitmask. В то время Bitmask был еще в версии 0.01, а RGB работал в версии 0.4, только для управления одиночными токенами. Он отмечает, что это было менее ориентировано на самообеспечение, чем сегодня, поскольку логика была частично серверной. С тех пор архитектура развивалась в направлении этой модели, что очень ценится биткойнерами.

Основы протокола RGB

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

Сегодня RGB выделяется своей концептуальной устойчивостью и унифицированными спецификациями через ассоциацию LNP/BP. Принцип основан на валидации на стороне клиента. В блокчейне Bitcoin хранятся только криптографические обязательства (commitments, через Taproot или OP_RETURN), в то время как большая часть данных (определения контрактов, истории переводов и т. д.) хранится у соответствующих пользователей. Таким образом, нагрузка на хранилище распределяется, а конфиденциальность обмена укрепляется, не утяжеляя блокчейн. Такой подход позволяет создавать взаимозаменяемые активы (стандарт RGB20) или уникальные активы (стандарт RGB21) в рамках модульной и масштабируемой структуры.

Функция токена (RGB20) и уникальные активы (RGB21)

С помощью RGB20 мы определяем взаимозаменяемый токен в Биткойне. Эмитент выбирает поставку, точность и создает контракт, по которому он может осуществлять переводы. Каждый перевод ссылается на биткойн UTXO, который действует как пломба одноразового использования. Эта логика гарантирует, что пользователь не сможет потратить один и тот же актив дважды, поскольку только тот, кто способен потратить UTXO, на самом деле владеет ключом для обновления состояния контракта на стороне клиента.

RGB21 нацелены на уникальные активы (или "NFT"). Актив имеет запас 1 и может быть связан с метаданными (файл изображения, аудио и т. д.), описанными через определенное поле. В отличие от NFT на публичных блокчейнах, данные и их MIME-идентификаторы могут оставаться приватными, распространяясь между пирами по усмотрению владельца.

Решение Bitmask: кошелек для RGB

Чтобы использовать возможности RGB на практике, проект DIBA разработал кошелек под названием Bitmask. Идея состоит в том, чтобы предоставить инструмент на базе Taproot, не требующий хранения, доступный в виде веб-приложения или расширения для браузера. Bitmask управляет активами RGB20 и RGB21 и интегрирует различные механизмы безопасности:

Благодаря такой архитектуре все транзакции с активами происходят на стороне клиента. Со стороны транзакция биткоина представляет собой не что иное, как классическую транзакцию по расходованию средств Taproot, о которой никто не заподозрит, что она также несет в себе перевод сменных токенов или NFT. Отсутствие перегрузки на цепочке (отсутствие публично хранимых метаданных) гарантирует определенную степень конфиденциальности и позволяет легче противостоять возможным попыткам цензуры.

Безопасность и распределенная архитектура

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

Использование CRDT (Conflict-free replicated data type) позволяет объединять различные версии тайника, если они расходятся. Каждый волен размещать эти данные там, где ему заблагорассудится, поскольку ни один узел не несет в себе всю информацию, связанную с активом. Это в точности отражает философию Client-side Validation, где каждый владелец отвечает за хранение доказательств достоверности своего RGB-актива.

На пути к расширению экосистемы: рынок, совместимость и новые функции

Компания, стоящая за Bitmask, не ограничивается простой разработкой кошелька. DIBA намерена разработать :

В то же время мы работаем над WebBTC или WebLN (стандарты, позволяющие веб-сайтам просить кошелек подписывать транзакции Bitcoin или Lightning), а также над возможностью "телеобжига" записей Ordinals (если мы хотим перевести Ordinals в более сдержанный и гибкий формат RGB).

Заключение

Весь процесс показывает, как экосистема RGB может быть развернута и доступна для конечных пользователей с помощью надежных технических решений. Переход от перспективы альткоинов к более ориентированному на Биткоин видению, в сочетании с открытием Client-side Validation, иллюстрирует довольно логичный путь: мы понимаем, что можно реализовать различные функциональные возможности (сменные токены, NFT, смарт-контракты...) без форка блокчейна, просто используя преимущества криптографических обязательств в транзакциях Taproot или OP_RETURN.

Кошелек Bitmask является частью этого подхода: со стороны блокчейна все, что вы видите, - это обычная транзакция Bitcoin; со стороны пользователя вы управляете веб-интерфейсом, где создаете, обмениваете и храните все виды внецепочечных активов. Эта модель четко отделяет денежную инфраструктуру (Bitcoin) от логики эмиссии и передачи (RGB), обеспечивая при этом высокий уровень конфиденциальности и лучшую масштабируемость.

Работа Bitfinex над RGB

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

Предпосылки и цели

Начиная примерно с 2022 года, команда Bitfinex RGB сосредоточилась на разработке технологического стека, который позволяет эффективно использовать и тестировать RGB. Было сделано несколько вкладов:

Этот подход призван охватить всю цепочку потребностей: от низкоуровневой библиотеки (RGBlib), позволяющей реализовать кошелек, до производственного аспекта (узел Lightning, кошелек для Android и т.д.).

Библиотека RGBlib: упрощение разработки RGB-приложений

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

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

Книжный магазин предлагает :

Таким образом, RGBlib опирается на сложные понятия, характерные для RGB (проверка на стороне клиента, якоря Tapret/Opret), но инкапсулирует их так, что конечному приложению не нужно перепрограммировать все или принимать рискованные решения. Более того, RGBlib уже привязан к нескольким языкам (Kotlin и Python), что открывает возможности для использования за пределами простой вселенной Rust.

Iris Wallet: пример RGB-кошелька на Android

Чтобы доказать эффективность RGBlib, команда Bitfinex разработала Iris Wallet, на данном этапе исключительно для Android. Это мобильный кошелек, который иллюстрирует пользовательский опыт, схожий с обычным биткойн-кошельком: вы можете выпустить актив, отправить его, получить его, просмотреть его историю, оставаясь при этом в модели самоохраны.

Iris обладает рядом интересных особенностей:

Использование сервера Electrum:

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

Прокси-сервер RGB:

В отличие от Биткойна, RGB требует обмена метаданными вне цепочки (согласованиями) между отправителем и получателем. Чтобы упростить этот процесс, Iris предлагает решение, при котором обмен происходит через прокси-сервер. Получающий кошелек генерирует инвойс, в котором указывается, куда отправитель должен отправить данные клиентской стороны. По умолчанию URL указывает на прокси-сервер, размещенный командой Bitfinex, но вы можете изменить этот прокси-сервер (или разместить свой собственный). Идея заключается в том, чтобы вернуться к привычному пользовательскому опыту, когда получатель показывает QR-код, а отправитель сканирует этот код для проведения транзакции, без каких-либо сложных дополнительных манипуляций.

** Непрерывное резервное копирование:**

В контексте Биткойна обычно достаточно сохранить резервную копию семян (хотя в наши дни мы рекомендуем сохранять семена и дескрипторы). В случае с RGB этого недостаточно: вам также необходимо хранить локальную историю (консигнации), доказывающую, что вы действительно владеете активом RGB. Каждый раз, когда вы получаете чек, устройство сохраняет новые данные, которые необходимы для последующих трат. Iris автоматически управляет зашифрованной резервной копией в Google Drive пользователя. Это не требует особого доверия к Google, поскольку резервная копия зашифрована, а в будущем планируется использовать более надежные опции (например, персональный сервер), чтобы избежать риска цензуры или удаления сторонним оператором.

*Другие особенности:

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

Прокси-сервер и пользовательский опыт

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

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

Интеграция RGB в сеть Lightning

Еще одно ключевое направление работы команды Bitfinex - сделать сеть Lightning Network совместимой с активами RGB. Цель состоит в том, чтобы сделать возможными каналы Lightning в USDT (или любом другом токене) и воспользоваться теми же преимуществами, что и биткоин в Lightning (почти мгновенные транзакции, маршрутизация и т. д.). Если говорить конкретно, то это предполагает создание узла Lightning, модифицированного под :

Это решение, получившее название "RGB Lightning Node", использует LDK (Lightning Dev Kit) в качестве основы и добавляет механизмы, необходимые для внедрения RGB-токенов в каналы. Lightning-коммиты сохраняют классическую структуру (пробиваемые выходы, таймлок...), а также дополнительно закрепляют переход в состояние RGB (через Opret или Tapret). Для пользователя это открывает путь к Lightning-каналам в стабильных монетах или в любом другом активе, эмитированном через RGB.

Потенциал DEX и влияние на биткойн

Когда несколько активов управляются через Lightning, становится возможным представить атомарную биржу на одном маршруте Lightning, используя ту же логику секретов и таймлоков. Например, пользователь A держит биткоин на одном канале Lightning, а пользователь B держит USDT RGB на другом канале Lightning. Они могут построить путь, соединяющий два их канала, и одновременно обменивать BTC на USDT, не нуждаясь в доверии. Это не что иное, как атомарный обмен, происходящий в несколько хопов, благодаря чему внешние участники практически не замечают, что совершают сделку, а не просто маршрутизацию. Этот подход предлагает :

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

Влияние на биткойн может быть положительным: Инфраструктура Lightning (узлы, каналы и сервисы) будет более полно загружена благодаря объемам, генерируемым этими стабильными монетами, деривативами и другими токенами. Торговцы, заинтересованные в платежах USDT на Lightning, механически обнаружат платежи BTC на Lightning (управляемые тем же стеком). Обслуживание и финансирование инфраструктуры Lightning Network также может выиграть от увеличения этих не-BTC потоков, что косвенно принесет пользу пользователям Биткойна.

Заключение и ресурсы

Команда Bitfinex, занимающаяся RGB, своей работой иллюстрирует разнообразие возможностей, которые можно реализовать на базе этого протокола. С одной стороны, есть RGBlib, библиотека, облегчающая разработку кошельков и приложений. С другой - Iris Wallet, практическая демонстрация на Android изящного интерфейса для конечного пользователя. Наконец, интеграция RGB с Lightning показывает, что каналы стабильных монеток возможны, и открывает путь к потенциальному децентрализованному DEX на Lightning.

Этот подход остается в значительной степени экспериментальным и продолжает развиваться: библиотека RGBlib дорабатывается по ходу дела, Iris Wallet получает регулярные улучшения, а выделенная нода Lightning пока не является основным клиентом Lightning.

Для тех, кто хочет узнать больше или внести свой вклад, есть несколько ресурсов, включая :

В следующей главе мы подробно рассмотрим, как запустить узел RGB Lightning.

RLN - RGB Lightning Node

В этой заключительной главе Фредерико Тенга шаг за шагом проведет вас через настройку узла Lightning RGB в среде Regtest и покажет, как создавать на нем токены RGB. Запустив два отдельных узла, вы также узнаете, как открыть между ними канал Lightning и обмениваться активами RGB.

Это видео является учебным пособием, аналогичным тому, что мы рассматривали в предыдущей главе, но в этот раз оно посвящено именно Lightning!

Основным ресурсом для этого видео является репозиторий Github RGB Lightning Node, который позволяет легко запустить эту конфигурацию в Regtest.

Развертывание узла Lightning, совместимого с RGB

В ходе этого процесса на практике реализуются все концепции, рассмотренные в предыдущих главах:

Представляем rgb-lightning-node

Проект rgb-lightning-node представляет собой демон Rust, основанный на форке rust-lightning (LDK), модифицированном для учета наличия RGB-активов в канале. При открытии канала можно указать наличие активов, и при каждом обновлении состояния канала создается RGB-переход, отражающий распределение актива в выходах Lightning. Это позволяет :

Код все еще находится на стадии альфа-версии: мы рекомендуем использовать его только в regtest или в testnet.

Установка узла

Чтобы скомпилировать и установить бинарный файл rgb-lightning-node, мы начнем с клонирования репозитория и его подмодулей, а затем запустим команду :

git clone https://github.com/RGB-Tools/rgb-lightning-node --recurse-submodules --shallow-submodules
RGB-Bitcoin

Из корня проекта выполните следующую команду для компиляции и установки двоичного файла :

cargo install --locked --debug --path .
RGB-Bitcoin

По завершении этой команды в каталоге $CARGO_HOME/bin/ будет доступен исполняемый файл rgb-lightning-node. Убедитесь, что этот путь находится в вашем $PATH, чтобы вы могли вызывать команду из любой директории.

Требования к производительности

Для работы демона rgb-lightning-node требуется наличие и настройка :

Каждый экземпляр RLN должен будет взаимодействовать с bitcoind для трансляции и мониторинга своих транзакций на цепи. Демону необходимо предоставить аутентификацию (логин/пароль) и URL (хост/порт).

Демон должен уметь выводить список и изучать транзакции на цепи, в частности, находить UTXO, на котором был привязан актив. Вам нужно будет указать URL вашего сервера Electrum или Esplora.

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

Идентификаторы и URL вводятся при разблокировке демона через API. Подробнее об этом позже.

Запуск регтеста

Для простого использования есть скрипт regtest.sh, который автоматически запускает через Docker набор сервисов: bitcoind, electrs (индексатор), rgb-proxy-server.

RGB-Bitcoin

Это позволяет запустить локальную, изолированную, предварительно настроенную среду. Она создает и уничтожает контейнеры и каталоги данных при каждой перезагрузке. Мы начнем с запуска файла :

./regtest.sh start

Этот скрипт будет :

RGB-Bitcoin

Далее мы запустим несколько узлов RLN. В отдельных оболочках запустите, например, (для запуска 3 узлов RLN) :

# 1st shell
rgb-lightning-node dataldk0/ --daemon-listening-port 3001 \
--ldk-peer-listening-port 9735 --network regtest
# 2nd shell
rgb-lightning-node dataldk1/ --daemon-listening-port 3002 \
--ldk-peer-listening-port 9736 --network regtest
# 3rd shell
rgb-lightning-node dataldk2/ --daemon-listening-port 3003 \
--ldk-peer-listening-port 9737 --network regtest
RGB-Bitcoin

Вы также можете выполнять команды на узлах RLN из браузера:

https://rgb-tools.github.io/rgb-lightning-node/

Чтобы узел мог открыть канал, он должен сначала иметь биткоины на адресе, сгенерированном с помощью следующей команды (например, для узла n°1):

curl -X POST http://localhost:3001/address

В ответе вы найдете адрес.

RGB-Bitcoin

На bitcoind Regtest мы собираемся добыть несколько биткоинов. Выполнить

./regtest.sh mine 101
RGB-Bitcoin

Отправьте средства на адрес узла, указанный выше:

./regtest.sh sendtoaddress <address> <amount>
RGB-Bitcoin

Затем заминируйте блок, чтобы подтвердить транзакцию:

./regtest.sh mine 1
RGB-Bitcoin

Запуск Testnet (без Docker)

Если вы хотите протестировать более реалистичный сценарий, вы можете запустить 3 узла RLN в Testnet, а не в Regtest, указав на публичные сервисы:

rgb-lightning-node dataldk0/ --daemon-listening-port 3001 \
--ldk-peer-listening-port 9735 --network testnet
rgb-lightning-node dataldk1/ --daemon-listening-port 3002 \
--ldk-peer-listening-port 9736 --network testnet
rgb-lightning-node dataldk2/ --daemon-listening-port 3003 \
--ldk-peer-listening-port 9737 --network testnet

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

С логином :

Вы также можете настроить эти элементы с помощью API init/unlock.

Выпуск токена RGB

Чтобы выпустить токен, мы начнем с создания "цветных" UTXO:

curl -X POST -H "Content-Type: application/json" \
-d '{
"up_to": false,
"num": 4,
"size": 2000000,
"fee_rate": 4.2,
"skip_sync": false
}' \
http://localhost:3001/createutxos
RGB-Bitcoin

Вы, конечно, можете адаптировать заказ. Чтобы подтвердить сделку, мы моем :

./regtest.sh mine 1

Теперь мы можем создать актив RGB. Команда будет зависеть от типа актива, который вы хотите создать, и его параметров. Здесь я создаю токен NIA (Non Inflatable Asset) под названием "PBN" с запасом в 1000 единиц. Параметр precision позволяет определить делимость единиц.

curl -X POST -H "Content-Type: application/json" \
-d '{
"amounts": [
1000
],
"ticker": "PBN",
"name": "Plan B Network",
"precision": 0
}' \
http://localhost:3001/issueassetnia
RGB-Bitcoin

В ответе указывается идентификатор вновь созданного актива. Не забудьте записать этот идентификатор. В моем случае это :

rgb:fc7fMj5S-8yz!vIl-260BEhU-Hj1skvM-ZHcjfyz-RTcWc10
RGB-Bitcoin

Затем вы можете передать его в цепь или распределить в канале Lightning. Именно этим мы и займемся в следующем разделе.

Открытие канала и передача актива RGB

Сначала вы должны подключить свой узел к аналогу в сети Lightning с помощью команды /connectpeer. В моем примере я контролирую оба узла. Поэтому я получу открытый ключ второго узла Lightning с помощью этой команды:

curl -X 'GET' \
'http://localhost:3002/nodeinfo' \
-H 'accept: application/json'

Команда возвращает открытый ключ моего узла n°2:

031e81e4c5c6b6a50cbf5d85b15dad720fec92c62e84bafb34088f0488e00a8e94
RGB-Bitcoin

Далее мы откроем канал, указав соответствующий актив (PBN). Команда /openchannel позволяет задать размер канала в сатоши и выбрать включение актива RGB. Это зависит от того, что вы хотите создать, но в моем случае команда выглядит так: :

curl -X POST -H "Content-Type: application/json" \
-d '{
"peer_pubkey_and_opt_addr": "031e81e4c5c6b6a50cbf5d85b15dad720fec92c62e84bafb34088f0488e00a8e94@localhost:9736",
"capacity_sat": 1000000,
"push_msat": 10000000,
"asset_amount": 500,
"asset_id": "rgb:fc7fMj5S-8yz!vIl-260BEhU-Hj1skvM-ZHcjfyz-RTcWc10",
"public": true,
"with_anchors": true,
"fee_base_msat": 1000,
"fee_proportional_millionths": 0,
"temporary_channel_id": "a8b60c8ce3067b5fc881d4831323e24751daec3b64353c8df3205ec5d838f1c5"
}' \
http://localhost:3001/openchannel

Узнайте больше здесь:

RGB-Bitcoin

Для подтверждения транзакции добывается 6 блоков:

./regtest.sh mine 6
RGB-Bitcoin

Канал Lightning теперь открыт и также содержит 500 токенов PBN на стороне узла n°1. Если узел n°2 хочет получить токены PBN, он должен сгенерировать счет-фактуру. Вот как это сделать:

curl -X POST -H "Content-Type: application/json" \
-d '{
"amt_msat": 3000000,
"expiry_sec": 420,
"asset_id": "rgb:fc7fMj5S-8yz!vIl-260BEhU-Hj1skvM-ZHcjfyz-RTcWc10",
"asset_amount": 100
}' \
http://localhost:3002/lninvoice

С :

В ответ вы получите RGB-фактуру (как описано в предыдущих главах):

lnbcrt30u1pncgd4rdqud3jxktt5w46x7unfv9kz6mn0v3jsnp4qv0grex9c6m22r9ltkzmzhddwg87eykx96zt47e5pz8sfz8qp28fgpp5jksvqtleryhvwr299qdz96qxzm24augy5agkdhltudk463lt9dassp5d6n0sqgl0c4gx52fdmutrdtqamt0y4xuz2rcgel4hpjwne08gmls9qyysgqcqpcxqzdylz5wfnkywnxvvmkvnt2x4fj6wre0gshvjtv95ervvzzg4592t2gdgchx6mkf5k45jrrdfn8j73d2f2xx4mrxycq7qzry4v4jan6uxhhacyqa4gn6plggwpq9j74tu74f2zsamtz6ymt600p8su4c4ap9g9d8ku2x3wdh6fuc8fd8pff2yzpjrf24ys3cltca9fgqut6gzj
RGB-Bitcoin

Теперь мы оплатим этот счет с первого узла, на котором хранится необходимая наличность с токеном PBN:

curl -X POST -H "Content-Type: application/json" \
-d '{
"invoice": "lnbcrt30u1pncgd4rdqud3jxktt5w46x7unfv9kz6mn0v3jsnp4qv0grex9c6m22r9ltkzmzhddwg87eykx96zt47e5pz8sfz8qp28fgpp5jksvqtleryhvwr299qdz96qxzm24augy5agkdhltudk463lt9dassp5d6n0sqgl0c4gx52fdmutrdtqamt0y4xuz2rcgel4hpjwne08gmls9qyysgqcqpcxqzdylz5wfnkywnxvvmkvnt2x4fj6wre0gshvjtv95ervvzzg4592t2gdgchx6mkf5k45jrrdfn8j73d2f2xx4mrxycq7qzry4v4jan6uxhhacyqa4gn6plggwpq9j74tu74f2zsamtz6ymt600p8su4c4ap9g9d8ku2x3wdh6fuc8fd8pff2yzpjrf24ys3cltca9fgqut6gzj"
}' \
http://localhost:3001/sendpayment
RGB-Bitcoin

Оплата была произведена. Это можно проверить, выполнив команду :

curl -X 'GET' \
'http://localhost:3001/listpayments' \
-H 'accept: application/json'
RGB-Bitcoin

Вот как развернуть узел Lightning, модифицированный для переноса RGB-активов. Эта демонстрация основана на :

Благодаря этому процессу:

Проект по-прежнему находится на стадии альфа-версии. Поэтому настоятельно рекомендуется ограничиться тестовыми средами (regtest, testnet).

Возможности, открываемые этой совместимостью LN-RGB, весьма значительны: стабильные монеты на Lightning, DEX layer-2, перевод взаимозаменяемых токенов или NFT по очень низкой цене... В предыдущих главах были описаны концептуальная архитектура и логика проверки. Теперь у вас есть практическое представление о том, как запустить такой узел в работу, для ваших будущих разработок или тестов.

Заключительный раздел

Отзывы и рейтинги

true

Заключение

true