レシート付きネームスペースの背後にあるアセットの識別子を取得

レシートを使用して特定のエイリアスとトランザクションの解決を取得します。

ユースケース

Symbol ではアカウントは AliasTransaction のアナウンスによって、それが登録したネームスペースを他のアカウントまたはモザイクにリンクさせることができます。

Symbol パブリックブロックチェーン上でチケット販売者が彼らの顧客へチケットを送るのを想像してください。会社は 1 0dc67fbe1cad29e3SCVG35-ZSPMYP-L2POZQ-JGSVEG-RYOJ3V-BNIU3U-N2E6 へ送る必要があります。エイリアスを使うと、チケット販売者は同じトランザクションを 1 ticketsales.event1.ticket@alice へ送るというように定義することができます。

../../_images/namespace-tickets.png

認識しやすいモザイクとアドレス

トランザクションが正しいモザイクで正しい場所に送信されていることを確認するには、次のスニペットを実行することで ネームスペースに関連づく現在のモザイク識別子 についてネットワークへ直接問い合わせることができます:

// replace with namespace name
const namespaceId = new NamespaceId('symbol.xym');

// replace with node endpoint
const nodeUrl = 'http://api-01.us-east-1.testnet.symboldev.network:3000';
const repositoryFactory = new RepositoryFactoryHttp(nodeUrl);
const namespaceHttp = repositoryFactory.createNamespaceRepository();

namespaceHttp.getLinkedMosaicId(namespaceId).subscribe(
  (mosaicId) => console.log(mosaicId!.toHex()),
  (err) => console.log(err),
);
// replace with namespace name
const namespaceId = new symbol_sdk_1.NamespaceId('symbol.xym');
// replace with node endpoint
const nodeUrl = 'http://api-01.us-east-1.testnet.symboldev.network:3000';
const repositoryFactory = new symbol_sdk_1.RepositoryFactoryHttp(nodeUrl);
const namespaceHttp = repositoryFactory.createNamespaceRepository();
namespaceHttp.getLinkedMosaicId(namespaceId).subscribe(
  (mosaicId) => console.log(mosaicId.toHex()),
  (err) => console.log(err),
);
        // replace with node endpoint
        try (final RepositoryFactory repositoryFactory = new RepositoryFactoryVertxImpl(
                "http://api-01.us-east-1.testnet.symboldev.network:3000")) {
            final NamespaceRepository namespaceRepository = repositoryFactory.createNamespaceRepository();
            final NamespaceId namespaceId = NamespaceId.createFromName("symbol.xym");
            final MosaicId mosaicId = namespaceRepository.getLinkedMosaicId(namespaceId)
                    .toFuture().get();
            System.out.print(mosaicId.getIdAsHex());
        }

しかし、同じ方法では 過去のトランザクションを検証することができません 。これは以下の事実によるものです:

  • エイリアス済みのモザイクまたはアカウントを使用したトランザクションは実際のアドレスや関連付いたモザイクIDではなく、ネームスペース識別子によってブロックチェーンに格納されます。
  • リンクは編集可能です。ネームスペースの作成者はそのネームスペースを別のアセットにリンクすることができます。
  • 期限の切れたネームスペース。ネームスペースリンクは削除される可能性があります。

この時点であなたは疑問に思うかもしれません: どうすれば過去のトランザクションのネームスペースとその実際の識別子との間の正確な関係を得ることができるのでしょうか?その答えは レシート です。各ブロックに対して Symbol ノードはトランザクションまたはブロックヘッダから直接取得することができない、すべての 見えない状態変化 を含むレシートを保存します。

前提条件

  • 入門セクション を完了している
  • 新しい アカウント を作成します。
  • アカウントに手数料を支払うために十分な symbol.xym を入金します。

それではコードを見ていきましょう

この例ではネイティブ通貨のモザイクIDの代わりに symbol.xym を使って TransferTransaction をアナウンスします。ネットワークがトランザクションを承認したら、トランザクションが記録されたブロック高を取得します。この情報を元にブロックのレシートを調べてネームスペースとモザイクの関連を取得します。

  1. 送信したいモザイクを定義します。モザイク識別子の代わりに リンクされたネームスペース識別子 (例: symbol.xym) を使用してください。
const aliasedMosaic = new Mosaic(
  new NamespaceId('symbol.xym'),
  UInt64.fromUint(1000000),
);
const aliasedMosaic = new symbol_sdk_1.Mosaic(
  new symbol_sdk_1.NamespaceId('symbol.xym'),
  symbol_sdk_1.UInt64.fromUint(1000000),
);
  1. TransferTransaction にモザイクを添付してください。
// replace with network type
const networkType = NetworkType.TEST_NET;
const transferTransaction = TransferTransaction.create(
  Deadline.create(epochAdjustment),
  Address.createFromRawAddress('TCHBDE-NCLKEB-ILBPWP-3JPB2X-NY64OE-7PYHHE-32I'),
  [aliasedMosaic],
  PlainMessage.create('Test aliased mosaic'),
  networkType,
  UInt64.fromUint(2000000),
);

// replace with sender private key
const privateKey =
  '1111111111111111111111111111111111111111111111111111111111111111';
const account = Account.createFromPrivateKey(privateKey, networkType);
// replace with meta.networkGenerationHash (nodeUrl + '/node/info')
const networkGenerationHash =
  '1DFB2FAA9E7F054168B0C5FCB84F4DEB62CC2B4D317D861F3168D161F54EA78B';
const signedTransaction = account.sign(
  transferTransaction,
  networkGenerationHash,
);
console.log(signedTransaction.hash);
// replace with network type
const networkType = symbol_sdk_1.NetworkType.TEST_NET;
const transferTransaction = symbol_sdk_1.TransferTransaction.create(
  symbol_sdk_1.Deadline.create(epochAdjustment),
  symbol_sdk_1.Address.createFromRawAddress(
    'TCHBDE-NCLKEB-ILBPWP-3JPB2X-NY64OE-7PYHHE-32I',
  ),
  [aliasedMosaic],
  symbol_sdk_1.PlainMessage.create('Test aliased mosaic'),
  networkType,
  symbol_sdk_1.UInt64.fromUint(2000000),
);
// replace with sender private key
const privateKey =
  '1111111111111111111111111111111111111111111111111111111111111111';
const account = symbol_sdk_1.Account.createFromPrivateKey(
  privateKey,
  networkType,
);
// replace with meta.networkGenerationHash (nodeUrl + '/node/info')
const networkGenerationHash =
  '1DFB2FAA9E7F054168B0C5FCB84F4DEB62CC2B4D317D861F3168D161F54EA78B';
const signedTransaction = account.sign(
  transferTransaction,
  networkGenerationHash,
);
console.log(signedTransaction.hash);

3. Announce the TransferTransaction. Once the transaction is confirmed, retrieve the receipts attached to the block and find for the namespace resolution.

// replace with node endpoint
const nodeUrl = 'http://api-01.us-east-1.testnet.symboldev.network:3000';
const repositoryFactory = new RepositoryFactoryHttp(nodeUrl);
const receiptHttp = repositoryFactory.createReceiptRepository();
const transactionHttp = repositoryFactory.createTransactionRepository();
const listener = repositoryFactory.createListener();
const transactionService = new TransactionService(transactionHttp, receiptHttp);

listener.open().then(() => {
  transactionService
    .announce(signedTransaction, listener)
    .pipe(
      mergeMap((transaction) =>
        transactionService.resolveAliases([transaction.transactionInfo!.hash!]),
      ),
      map((transactions) => transactions[0] as TransferTransaction),
    )
    .subscribe(
      (transaction) => {
        console.log('Resolved MosaicId: ', transaction.mosaics[0].id.toHex());
        listener.close();
      },
      (err) => console.log(err),
    );
});
// replace with node endpoint
const nodeUrl = 'http://api-01.us-east-1.testnet.symboldev.network:3000';
const repositoryFactory = new symbol_sdk_1.RepositoryFactoryHttp(nodeUrl);
const receiptHttp = repositoryFactory.createReceiptRepository();
const transactionHttp = repositoryFactory.createTransactionRepository();
const listener = repositoryFactory.createListener();
const transactionService = new symbol_sdk_1.TransactionService(
  transactionHttp,
  receiptHttp,
);
listener.open().then(() => {
  transactionService
    .announce(signedTransaction, listener)
    .pipe(
      operators_1.mergeMap((transaction) =>
        transactionService.resolveAliases([transaction.transactionInfo.hash]),
      ),
      operators_1.map((transactions) => transactions[0]),
    )
    .subscribe(
      (transaction) => {
        console.log('Resolved MosaicId: ', transaction.mosaics[0].id.toHex());
        listener.close();
      },
      (err) => console.log(err),
    );
});

次は?

レシートにはエイリアスの解決だけでなく、トランザクションやブロックヘッダからは直接取得できない、すべての不可視の状態変化も格納されます。 レシートドキュメント記録された変更の完全なリスト を確認できます。