가이드

가이드 · 전체 6부 중 3부

레코드 검증하기

검증은 Label 309에서 누구의 허락도 필요로 하지 않는 절반입니다. Cardano 트랜잭션 참조만 있으면, 직접 선택한 익스플로러를 통해 공개 체인에 대해 레코드를 스스로 확인할 수 있습니다. 로그인이 필요 없으며, 결과는 누가 그것을 게시했는지에 전혀 좌우되지 않습니다.

CLI로

cardanowall 바이너리를 설치한 다음, 트랜잭션을 지정합니다.

cardanowall verify 3b9f…c1a2

공개 Cardano 익스플로러를 통해 트랜잭션을 조회하고, 레코드를 구조적으로 검증하며, 저작자 서명이 있으면 이를 확인하고, 레코드가 확정되었음을 검증한 뒤 판정을 출력합니다. 판정은 네 가지 상태 중 하나이며, 종료 코드가 이를 그대로 담아내므로 CI에 곧바로 통합할 수 있습니다.

종료 코드판정의미
0valid필수 검사가 모두 통과
1failed레코드에 기인한 검사가 실패(무결성, 구조, 또는 서명)
2unverifiable레코드에 결함은 없으나 필수 검사를 실행할 수 없음(네트워크 또는 정책)
3pending아직 확인 횟수가 부족함 — 보류 중인 레코드에서 나온 결과는 확정이 아님
4CLI 입력 오류(잘못된 인자 또는 필수 입력 누락)

failedunverifiable을 구분하는 것은 의도적입니다. failed 판정은 언제나 레코드 자체에 기인하므로, 잘못 동작하는 익스플로러가 이를 날조할 수 없습니다. unverifiable은 레코드 외부의 사유 — 도달할 수 없는 게이트웨이, 거부 목록에 오른 호스트, 또는 가져오기 상한 — 로 인해 검증자가 검사를 완료할 수 없었음을 의미합니다.

--json을 추가하면 기계 판독이 가능한 보고서를 얻을 수 있으며, 자체 인프라를 지정하면 네트워크 통신의 모든 단계를 직접 통제할 수 있습니다.

cardanowall verify 3b9f…c1a2 \
  --cardano-gateway https://your-koios-instance/api/v1 \
  --threshold 20 \
  --json

레코드가 자신에게 봉인되어 있다면, 키를 검증자에게 넘기면 페이로드를 복호화하고 평문 해시를 다시 계산합니다.

cardanowall verify 3b9f…c1a2 --secret-key-stdin

키가 셸 기록에 남지 않도록, --secret-key 플래그를 그대로 쓰는 대신 --secret-key-stdin, --secret-key-file, 또는 CARDANOWALL_RECIPIENT_KEY 환경 변수를 사용하십시오.

TypeScript SDK로

CLI가 사용하는 검증자는 SDK에도 포함되어 있습니다. 클라이언트도, 베이스 URL도, 키도 필요 없으며, 검증은 게이트웨이에 비의존적입니다.

import { verifyTx } from '@cardanowall/sdk-ts/verifier';

const report = await verifyTx({ txHash: '3b9f…c1a2' });

console.log(report.verdict); // 'valid' | 'pending' | 'unverifiable' | 'failed'

if (report.verdict !== 'valid') {
  console.error(report.issues, report.signatures);
}

verifyTx는 완전한 VerifyReport를 반환합니다. 판정과 exitCode, 해석된 block_timeconfirmationDepth, 구조 검사와 검증자가 합친 issues 목록, 항목별 itemsmerkle 검사 결과, 선택적 signatures, 그리고 발신한 모든 외부 요청을 기록한 auditTrail 로그가 포함됩니다. 이를 통해 검증자가 게시자에게 결코 접속하지 않았음을 스스로 증명할 수 있습니다.

자신에게 봉인된 레코드를 검증하려면, 개인 키를 검증자에게 넘기십시오. 키링은 실행 전체에서 전역적입니다. 전달한 모든 키가 봉인된 모든 항목에 대해 시도되므로, 항목별 인덱스는 존재하지 않습니다.

const report = await verifyTx({
  txHash: '3b9f…c1a2',
  decryption: [{ recipientSecretKey: mySecretKey }],
});

Python SDK로

cardanowall-sdk는 TypeScript 검증자를 바이트 단위로 그대로 옮긴 쌍둥이입니다. 동일한 검사를 수행하고, 동일한 판정을 반환합니다.

import asyncio
import cardanowall

report = asyncio.run(cardanowall.verify_tx(cardanowall.VerifyTxInput(tx_hash="3b9f…c1a2")))
print(report.verdict)

Rust SDK로

cardanowall 크레이트에도 동일한 검증자가 들어 있습니다. verify_tx는 동기식이며 — 블로킹 전송을 내부에 보유합니다 — 동일한 VerifyReport를 반환합니다.

use cardanowall::verifier::{verify_tx, Verdict, VerifyTxInput};

let report = verify_tx(&VerifyTxInput::new("3b9f…c1a2"));

println!("{}", report.verdict.as_str()); // "valid" | "pending" | "unverifiable" | "failed"

if report.verdict != Verdict::Valid {
    eprintln!("{:?}", report.issues);
    eprintln!("{:?}", report.record_signatures);
}

자신에게 봉인된 레코드를 검증하려면, 개인 키를 첨부하십시오. 키링은 실행 전체에서 전역적입니다. 모든 키가 봉인된 모든 항목에 대해 시도되므로, 자격 증명이 항목 인덱스를 지니지 않습니다. 입력 필드는 공개되어 있으므로, VerifyTxInput::new를 기점으로 구성하면 됩니다.

use cardanowall::verifier::{verify_tx, Decryption, VerifyTxInput};

let mut input = VerifyTxInput::new("3b9f…c1a2");
input.decryption = Some(vec![Decryption::Recipient {
    recipient_secret_key: my_secret_key, // Vec<u8>
}]);

let report = verify_tx(&input);

이 작업에 신뢰가 필요 없는 이유

모든 검사는 공개 데이터와 직접 선택한 익스플로러만으로 실행됩니다. 레코드를 게시한 사람은 결과에 영향을 줄 수 없으며, 설령 그들이 내일 사라진다 해도 검증은 정확히 똑같이 작동합니다.