Skip to content

Анонимные транзакции

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

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

Строительные блоки

Концепция .Представление в бухгалтерском учете
Защищенная запискаЧастная запись в кошельке содержит актив, сумму, данные о владельце и случайность.
Приверженность32-байтное общественное значение, которое обязуется к ноте без раскрытия ее полей.
ОтменительПубличное значение 32 байта, полученное при расходовании ноты. Iroha отклоняет повторные аннулирующие значения для предотвращения двойного расхода.
Меркельский кореньНедавний корень дерева обязательств актива. Доказательства используют его, чтобы показать, что расходные банкноты существуют.
Доказательная прикреплениеProofAttachment содержит доказательные байты плюс ссылка на проверяющий ключ или встроенный верификационный ключ.
Конфиденциальное мероприятиеСобытие в регистре, такое как ConfidentialEvent::Shielded, Transferred или Unshielded.

Основные инструкции:

  • RegisterZkAsset: регистрирует актив как ZK-способный и связывает ключи для проверки передачи, щита и незащищенного.
  • Shield: дебирует государственный баланс и добавляет обязательство о защищенной банкноте.
  • ZkTransfer: расходует защищенные банкноты на новые обязательства по защищенным банкнотам.
  • Unshield: расходует защищенные банкноты и кредитует баланс государственного счета.
  • ScheduleConfidentialPolicyTransition и CancelConfidentialPolicyTransition: изменение политики конфиденциальности актива посредством управления.

Определение активов также содержит AssetConfidentialPolicy. Контроль режима политики, который действует:

Режим .Значение .
TransparentOnlyПринимаются только обычные публичные балансы и трансферты.
ConvertibleПользователи могут перемещать стоимость между общедоступными балансами и защищенными банкнотами.
ShieldedOnlyВыпуск активов и перечисления должны оставаться в защищенном регистре.

Как их использовать

  1. Включить конфиденциальную поддержку на узлах валидатора. Валидаторы должны согласовать обратный конец верификатора, активные ключи проверки, параметр Poseidon/Pedersen IDs и версию секретных правил. Ноды отклоняют коллег или блоки с несовместимыми дигестами секретных функций.
  2. Публикуйте или регистрируйте проверяющие ключи и наборы параметров, используемые схемами. VerifyingKeyId, к примеру halo2/ipa:vk_transfer.
  3. Зарегистрировать актив как ZK-способный с RegisterZkAsset, или перейти на политический переход от TransparentOnly до Convertible или ShieldedOnly.
  4. Защита государственных средств с помощью Shield. Кошелек создает обязательство о банкноте и зашифрованную полезную нагрузку для получателя перед отправкой сделки.
  5. Передача в частном порядке с помощью ZkTransfer. Кошелек создает доказательство того, что он владеет входящими записями, что значения входа и выхода балансируют и что каждая потраченная запись закреплена в недавнем дереве обязательств.
  6. Unshield раскрывает публичную сумму и счет получателя, расходует аннулирующий частный банкнот и может создавать собственные выходы на изменения.
  7. Аудит путем чтения конфиденциальных событий, записей о доказательствах, статуса аннулирующего и анонимных записей о поручительстве через заданные запросы и конечные точки Torii.

CLI Примеры

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

Зарегистрировать актив с гибридным капиталом ZK:

bash
iroha app zk register-asset \
  --asset <asset-definition-id> \
  --allow-shield true \
  --allow-unshield true \
  --vk-transfer halo2/ipa:vk_transfer \
  --vk-unshield halo2/ipa:vk_unshield \
  --vk-shield halo2/ipa:vk_shield

Создайте версию зашифрованного конверта полезной нагрузки для защищенной ноты:

bash
iroha app zk envelope \
  --ephemeral-pubkey 0101010101010101010101010101010101010101010101010101010101010101 \
  --nonce-hex 020202020202020202020202020202020202020202020202 \
  --ciphertext-b64 AQIDBA== \
  --print-json \
  --output note-envelope.bin

Защита государственных средств в защищенном регистре актива:

bash
iroha app zk shield \
  --asset <asset-definition-id> \
  --from <account-id> \
  --amount 1000 \
  --note-commitment ABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABAB \
  --enc-payload note-envelope.bin

Незащищенный с прозрачным прикреплением JSON:

bash
cat > unshield-proof.json <<'JSON'
{
  "backend": "halo2/ipa",
  "proof_b64": "BASE64_PROOF_BYTES",
  "vk_ref": {
    "backend": "halo2/ipa",
    "name": "vk_unshield"
  }
}
JSON

iroha app zk unshield \
  --asset <asset-definition-id> \
  --to <account-id> \
  --amount 1000 \
  --inputs DEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEF \
  --proof-json unshield-proof.json

SDK Пример

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

rust
use iroha_data_model::{
    isi::zk::{Unshield, ZkTransfer},
    prelude::{AccountId, AssetDefinitionId, InstructionBox},
    proof::{ProofAttachment, ProofBox, VerifyingKeyId},
};

fn transfer_instruction(
    asset: AssetDefinitionId,
    input_nullifier: [u8; 32],
    output_commitment: [u8; 32],
    anchor_root: [u8; 32],
    proof_bytes: Vec<u8>,
) -> InstructionBox {
    let backend = "halo2/ipa".into();
    let proof = ProofBox::new(backend, proof_bytes);
    let vk = VerifyingKeyId::new("halo2/ipa", "vk_transfer");
    let attachment = ProofAttachment::new_ref("halo2/ipa".into(), proof, vk);

    ZkTransfer::new(
        asset,
        vec![input_nullifier],
        vec![output_commitment],
        attachment,
        Some(anchor_root),
    )
    .into()
}

fn unshield_instruction(
    asset: AssetDefinitionId,
    recipient: AccountId,
    amount: u128,
    input_nullifier: [u8; 32],
    anchor_root: [u8; 32],
    proof_bytes: Vec<u8>,
) -> InstructionBox {
    let backend = "halo2/ipa".into();
    let proof = ProofBox::new(backend, proof_bytes);
    let vk = VerifyingKeyId::new("halo2/ipa", "vk_unshield");
    let attachment = ProofAttachment::new_ref("halo2/ipa".into(), proof, vk);

    Unshield::new(
        asset,
        recipient,
        amount,
        vec![input_nullifier],
        attachment,
        Some(anchor_root),
    )
    .into()
}

Аннонимная конфискация активов

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

Для подробной информации о поведении и примерах ISI, см. Native Asset Escrow.

Животный цикл:

  1. OpenAnonymousAssetEscrow расходует защищенные банкноты финансирования и создает одно обязательство по поручительству.
  2. AcceptAnonymousAssetEscrow записывает покупателя.
  3. MarkAnonymousEscrowPaymentSent записывает, что покупатель отправил платеж вне цепочки.
  4. ReleaseAnonymousAssetEscrow расходует обязательства по хранению в качестве гарантии на обязательства по выпуску покупателя.
  5. CancelAnonymousAssetEscrow расходует обязательство по поручению обратно на выпускные обязательства продавца, если оплата не была отмечена.
  6. OpenAnonymousEscrowDispute и ResolveAnonymousEscrowDispute обрабатывают спорные поручительства с хэшами доказательств и урегулируемым разделением.

Используйте анонимные запросы по поручительству, перечисленные в Запросы для проверки отчетов и статусов поручительства.

Математика

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

Защищенная записка может быть описана как:

n=(asset,amount,owner,ρ) n = (\mathsf{asset}, \mathsf{amount}, \mathsf{owner}, \rho)

где owner получается из материала просмотра или расходования получателем, а rho - примечание случайности.

Признаки - это скрытые обязательства:

C=Commit(asset,amount,owner,ρ) C = \mathsf{Commit}(\mathsf{asset}, \mathsf{amount}, \mathsf{owner}, \rho)

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

C=Hc(amount,ρ,owner_tag,asset_tag) C = H_c(\mathsf{amount}, \rho, \mathsf{owner\_tag}, \mathsf{asset\_tag})

При расходовании банкноты кошелек получает аннулирующий код:

N=Hn(spend_key,ρ,asset_tag,chain_tag) N = H_n(\mathsf{spend\_key}, \rho, \mathsf{asset\_tag}, \mathsf{chain\_tag})

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

Дерево обязательств доказывает существование записки. Если кошелек тратит обязательство C_i, доказательство включает в себя частный путь Merkle от C_i до недавнего общественного корня:

MerkleRoot(Ci,path)=R \mathsf{MerkleRoot}(C_i, \mathsf{path}) = R

В случае передачи от защищенного к защищенному доказательству также требуется сохранение стоимости:

inputs=outputs \sum \mathsf{inputs} = \sum \mathsf{outputs}

Для незащищенной суммы общественная сумма включается:

inputs=public_amount+private_change \sum \mathsf{inputs} = \mathsf{public\_amount} + \sum \mathsf{private\_change}

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

Verify(vk,public_inputs,π)=true \mathsf{Verify}(\mathsf{vk}, \mathsf{public\_inputs}, \pi) = \mathsf{true}

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

Что публично

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

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

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