Skip to content

Активы в реальном мире ​

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

RWAs отличаются от количественных балансов активов:

  • Цифровой актив - суммарный баланс, содержащийся на счете
  • NFT - это уникальная запись в цепочке с одним владельцем
  • RWA - партия, которая может содержать бизнес-метаданные, количество, хранение, заморозки, состояние выкупа, происхождение и политику контроллера

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

RWA Лот ​

Лет RWA содержит:

  • id: генерируемый канонический идентификатор RWA, отображающийся как <hash>$<domain>
  • owned_by: счет, который в настоящее время является владельцем партии
  • quantity: невыплаченное количество, представленное партией;
  • spec: спецификация количества, например в десятичной шкале
  • primary_reference: главный расчет, сертификат, счет или регистрационная справка вне цепи
  • status: Необязательный текст о статусе предприятия
  • metadata: компактные поля JSON, используемые для бизнес-контекста и индексации.
  • parents: источниковые партии, используемые для получения этой партии
  • controls: учетные записи контроллера, роли контроллера и разрешенные операции контроллера
  • is_frozen и held_quantity: состояние жизненного цикла, применяемое по времени выполнения;

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

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

RegisterRwa не принимает выбранного вызывающего id, и не принимает owner Поле. орган по сделке становится первоначальным owned_by Расчет, и время выполнения генерирует RwaId в целевой области.

Текстовая форма RWA ID составляет:

text
<generated-hash>$<domain>

Например:

text
0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef$commodities.universal

Заявки должны хранить свой бизнес-идентификатор в primary_reference или metadata, а затем обнаруживать генерируемый RwaId из RwaEvent::Created, FindRwas, /v1/rwas, или маршрут исследователя, установленный после выполнения сделки.

жизненный цикл ​

Общие RWA рабочие процессы включают:

ОперацияРеализованное поведение
RegisterRwaСоздать генерируемый ID лот в домене; уполномоченный орган по сделке становится owned_by.
TransferRwaПеремещение количества на другой счет. Полный перевод может изменить owned_by. Частичный перевод создает отдельную детскую партию с генерируемой ID.
HoldRwaРезервное количество. Требует конфигурированный контроллер и hold_enabled.
ReleaseRwaУдалить задержанное количество. Требует конфигурированный контроллер и hold_enabled.
FreezeRwaБлокировать обычные операции владельца. требует конфигурированного контроллера и freeze_enabled.
UnfreezeRwaВозобновить обычные операции владельца. Требуется конфигурированный контроллер и freeze_enabled.
RedeemRwaПостоянно вычитать количество из обращения. Владелец или контролер может представить его, когда redeem_enabled является верным.
MergeRwasОбъединить количество от родительских партий с одной доменой и спецификации в генерируемый детский лот.
ForceTransferRwaПеремещение количества через поток контроллера требует конфигурированного контроллера и force_transfer_enabled.
SetRwaControlsЗаменить правила контроля партии, требует владельца или контролера.
SetKeyValue<Rwa> / RemoveKeyValue<Rwa>Обновление метаданных лота. Требует владельца или контролера; замороженные лоты требуют контроллера.

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

Метаданные и контроль ​

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

  • ссылка на класс активов, эмитента, хранителя или регистра
  • идентификаторы складов, хранилищ, ISIN, счетов или сертификатов
  • хэши содержимого для удостоверений и юридических документов
  • SoraFS пути или проявленные ссылки на большие объемы доказательств
  • маркировки сроков действия, юрисдикции или соответствия, используемые услугами вне цепочки;

Реализованный RwaControlPolicy имеет следующие поля:

json
{
  "controller_accounts": [],
  "controller_roles": [],
  "freeze_enabled": true,
  "hold_enabled": true,
  "force_transfer_enabled": false,
  "redeem_enabled": true
}

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

Вопросы, события и APIs ​

Используйте FindRwas, чтобы перечислить зарегистрированные лоты RWA. Приложения, которые нуждаются в живых обновлениях, могут подписаться на Rwa события данных для создания, изменения владельца, разделения, слияния, выкупа, заморожения, размораживания, удержания, высвобождения, силового переноса, контроля-измены. и метаданных событий.

Torii раскрывает маршруты цепного состояния, такие как: /v1/rwas и /v1/rwas/query, плюс маршруты исследователей, такие как: /v1/explorer/rwas и /v1/explorer/rwas/{rwa_id} генерируемые клиенты должны предпочитать прямой /openapi документ для точной формы ответа, выявленной узлом.

Попробуй на Taira ​

Проверьте, зарегистрировано ли общественное Taira в настоящее время партию RWA:

bash
curl -fsS 'https://taira.sora.org/v1/rwas?limit=5' \
  | jq '{total, rwa_ids: [.items[].id]}'

Перечислить маршруты RWA, выявленные в документе Taira OpenAPI:

bash
curl -fsS https://taira.sora.org/openapi.json \
  | jq -r '.paths | keys[] | select(startswith("/v1/rwas") or startswith("/v1/explorer/rwas"))'

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

Попробуй . ​

В приведенных ниже примерах используются поверхности Python SDK из Shared Setup. Замените счет IDs, частные ключи и генерируемый лот IDs значениями из вашей собственной сети перед отправкой транзакции.

Открыть маршруты RWA API ​

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

python
from iroha_python import create_torii_client

client = create_torii_client("https://taira.sora.org")
openapi = client.request_json("GET", "/openapi", expected_status=(200,))

rwa_paths = sorted(
    path for path in openapi.get("paths", {}) if path.startswith("/v1/rwas")
)

for path in rwa_paths:
    print(path)

Если список пустой, узел может по-прежнему поддерживать инструкции и запросы RWA через другие Torii APIs, но он не раскрывает факультативную семейство маршрутов JSON.

Запись квитанции на складе ​

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

python
from iroha_python import TransactionConfig, TransactionDraft

config = TransactionConfig(
    chain_id=CHAIN_ID,
    authority=alice,
    metadata={**TX_METADATA, "source": "rwa-docs"},
)

draft = TransactionDraft(config)
draft.register_rwa(
    {
        "domain": "commodities.universal",
        "quantity": "100",
        "spec": {"scale": 0},
        "primary_reference": "warehouse-receipt-001",
        "status": "active",
        "metadata": {
            "asset_class": "commodity",
            "commodity": "copper",
            "warehouse": "DXB-01",
            "inspection_report": "sorafs://reports/copper-001.json",
        },
        "parents": [],
        "controls": {
            "controller_accounts": [alice],
            "controller_roles": [],
            "freeze_enabled": True,
            "hold_enabled": True,
            "force_transfer_enabled": False,
            "redeem_enabled": True,
        },
    }
)

envelope = draft.sign_with_keypair(alice_pair)
client.submit_transaction_envelope_and_wait(envelope)

После выполнения транзакции список генерируется RWA IDs. Маршруты цепочного состояния раскрывают канонический IDs; используйте маршруты событий или исследователей, когда вам нужно сопоставить ID обратно с primary_reference или метаданными:

python
page = client.list_rwas_typed(limit=20, offset=0)

for lot in page.items:
    print(lot.id)

Кнопки с Explorer также могут возвращать более богатые прогнозы:

python
page = client.list_explorer_rwas_typed(domain="commodities.universal")

for lot in page.items:
    print(lot.id, lot.primary_reference, lot.owned_by, lot.quantity)

Перевод с временной задержкой ​

Используйте генерируемые RWA ID Этот пример предполагает, что alice является владельцем и также конфигурирована в качестве контроллера с hold_enabled.

python
warehouse_lot_id = (
    "0123456789abcdef0123456789abcdef"
    "0123456789abcdef0123456789abcdef$commodities.universal"
)

draft = TransactionDraft(
    TransactionConfig(chain_id=CHAIN_ID, authority=alice, metadata=TX_METADATA)
)

draft.transfer_rwa(warehouse_lot_id, quantity="10", destination=bob)
draft.hold_rwa(warehouse_lot_id, quantity="5")

envelope = draft.sign_with_keypair(alice_pair)
client.submit_transaction_envelope_and_wait(envelope)

Подача ReleaseRwa после успешного выполнения процесса вне цепи:

python
draft = TransactionDraft(
    TransactionConfig(chain_id=CHAIN_ID, authority=alice, metadata=TX_METADATA)
)
draft.release_rwa(warehouse_lot_id, quantity="5")

envelope = draft.sign_with_keypair(alice_pair)
client.submit_transaction_envelope_and_wait(envelope)

Добавление контрольных и аудиторских метаданных ​

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

python
draft = TransactionDraft(
    TransactionConfig(chain_id=CHAIN_ID, authority=alice, metadata=TX_METADATA)
)

draft.set_rwa_controls(
    warehouse_lot_id,
    {
        "controller_accounts": [alice],
        "controller_roles": [],
        "freeze_enabled": True,
        "hold_enabled": True,
        "force_transfer_enabled": True,
        "redeem_enabled": True,
    },
)
draft.set_rwa_key_value(warehouse_lot_id, "auditor", "alice")
draft.set_rwa_key_value(
    warehouse_lot_id,
    "proof_hash",
    "sha256:2b1c7a4e...",
)

envelope = draft.sign_with_keypair(alice_pair)
client.submit_transaction_envelope_and_wait(envelope)

Количество выкупа или отчисления на пенсию ​

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

python
draft = TransactionDraft(
    TransactionConfig(chain_id=CHAIN_ID, authority=alice, metadata=TX_METADATA)
)
draft.redeem_rwa(warehouse_lot_id, quantity="1")

envelope = draft.sign_with_keypair(alice_pair)
client.submit_transaction_envelope_and_wait(envelope)

Заморозка во время проверки соответствия ​

Подача FreezeRwa, когда внецепочного обзора должно блокировать обычные операции владельцев. Подписьчик должен быть контролером. В партии должна быть freeze_enabled.

python
draft = TransactionDraft(
    TransactionConfig(chain_id=CHAIN_ID, authority=alice, metadata=TX_METADATA)
)
draft.freeze_rwa(warehouse_lot_id)
draft.set_rwa_key_value(
    warehouse_lot_id,
    "review",
    {
        "status": "frozen",
        "reason": "custodian inventory check",
        "case_id": "OPS-2026-0042",
    },
)

envelope = draft.sign_with_keypair(alice_pair)
client.submit_transaction_envelope_and_wait(envelope)

Сдача UnfreezeRwa после прохождения пересмотра:

python
draft = TransactionDraft(
    TransactionConfig(chain_id=CHAIN_ID, authority=alice, metadata=TX_METADATA)
)
draft.unfreeze_rwa(warehouse_lot_id)
draft.set_rwa_key_value(
    warehouse_lot_id,
    "review",
    {"status": "cleared", "case_id": "OPS-2026-0042"},
)

envelope = draft.sign_with_keypair(alice_pair)
client.submit_transaction_envelope_and_wait(envelope)

Поступление счета ​

Представьте счёт в виде партии RWA путем хранения номера счета в primary_reference и метаданных. После регистрации используйте генерируемый ID для передачи и выкупа.

python
draft = TransactionDraft(
    TransactionConfig(chain_id=CHAIN_ID, authority=alice, metadata=TX_METADATA)
)
draft.register_rwa(
    {
        "domain": "receivables.universal",
        "quantity": "50000",
        "spec": {"scale": 2},
        "primary_reference": "INV-2026-0007",
        "status": "issued",
        "metadata": {
            "asset_class": "invoice",
            "currency": "USD",
            "debtor": "example-buyer",
            "due_date": "2026-06-30",
            "document_hash": "sha256:4df4c8...",
        },
        "parents": [],
        "controls": {
            "controller_accounts": [alice],
            "controller_roles": [],
            "freeze_enabled": True,
            "hold_enabled": False,
            "force_transfer_enabled": False,
            "redeem_enabled": True,
        },
    }
)

envelope = draft.sign_with_keypair(alice_pair)
client.submit_transaction_envelope_and_wait(envelope)

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

python
invoice_lot_id = (
    "fedcba9876543210fedcba9876543210"
    "fedcba9876543210fedcba9876543210$receivables.universal"
)

draft = TransactionDraft(
    TransactionConfig(chain_id=CHAIN_ID, authority=alice, metadata=TX_METADATA)
)
draft.transfer_rwa(invoice_lot_id, quantity="50000", destination=bob)

envelope = draft.sign_with_keypair(alice_pair)
client.submit_transaction_envelope_and_wait(envelope)

Выкупить представленную сумму после расчета вне цепочки:

python
draft = TransactionDraft(
    TransactionConfig(chain_id=CHAIN_ID, authority=bob, metadata=TX_METADATA)
)
draft.redeem_rwa(invoice_lot_id, quantity="50000")

envelope = draft.sign_with_keypair(bob_pair)
client.submit_transaction_envelope_and_wait(envelope)

Углеродный кредит ​

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

python
carbon_lot_id = (
    "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
    "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa$carbon.universal"
)

draft = TransactionDraft(
    TransactionConfig(chain_id=CHAIN_ID, authority=alice, metadata=TX_METADATA)
)
draft.redeem_rwa(carbon_lot_id, quantity="250")
draft.set_rwa_key_value(
    carbon_lot_id,
    "retirement_certificate",
    "sorafs://certificates/carbon-credit-2026-001-retired.json",
)

envelope = draft.sign_with_keypair(alice_pair)
client.submit_transaction_envelope_and_wait(envelope)

Соедините две партии ​

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

python
warehouse_lot_id_2 = (
    "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
    "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb$commodities.universal"
)

draft = TransactionDraft(
    TransactionConfig(chain_id=CHAIN_ID, authority=alice, metadata=TX_METADATA)
)
draft.merge_rwas(
    {
        "parents": [
            {"rwa": warehouse_lot_id, "quantity": "40"},
            {"rwa": warehouse_lot_id_2, "quantity": "60"},
        ],
        "primary_reference": "warehouse-receipt-003",
        "status": "merged",
        "metadata": {
            "asset_class": "commodity",
            "commodity": "copper",
            "warehouse": "DXB-01",
            "merge_reason": "same custodian and quality grade",
        },
    }
)

envelope = draft.sign_with_keypair(alice_pair)
client.submit_transaction_envelope_and_wait(envelope)

Для полного примера сделки Python см. Real-World Assets.