4
1

symbol-sdk@3.0.7で作るモザイクとネームスペースのトランザクション

Last updated at Posted at 2023-07-05

はじめに

こんにちは。

symbol-sdkの3.0.7、トランザクションシリーズ第二弾です。

今回はモザイクとネームスペースをやっていきます。

シリーズ

注意事項

書いてあるコードについて、正確性や完全性を保証するものではありません。あくまで参考程度として頂き、最新情報は公式ドキュメンテーションをご確認ください。

共通

まずはモザイクのトランザクションとネームスペースのトランザクションで共通となる個所について。
デッドラインと鍵ペアです。

import symbolSdk from 'symbol-sdk';

const network = symbolSdk.symbol.Network.TESTNET;
const deadline = network.fromDatetime(new Date(Date.now() + 7200000)).timestamp;

const facade = new symbolSdk.facade.SymbolFacade(network.name);

const privateKey = new symbolSdk.PrivateKey(PRIVATE_KEY);
const keyPair = new facade.constructor.KeyPair(privateKey);

参考: symbol-sdk@3.0.7を試してみる

モザイク発行のトランザクション

モザイクフラグ

MosaicFlagsというものが用意されています。とりあえず全部つけておきます。

const { MosaicFlags } = symbolSdk.symbol;

const mosaicFlags = MosaicFlags.SUPPLY_MUTABLE.value |
  MosaicFlags.TRANSFERABLE.value |
  MosaicFlags.RESTRICTABLE.value |
  MosaicFlags.REVOKABLE.value;

もしくは単純に数値でも大丈夫です。

const mosaicFlags = 3;
const mosaicFlags = 1 | 2 | 4 | 8;    // 15

モザイクナンス

モザイクIDは(確か)アドレスと乱数から生成されるので、その乱数がモザイクナンスです。

const mosaicNonceValue = 123;

モザイクナンスは4バイト。なので4バイトの乱数でも良い。

function getRandomInt(max) {
  return Math.floor(Math.random() * max);
}

const mosaicNonceValue = getRandomInt(0xffffffff);

モザイクID

モザイクIDを生成するには、 generateMosaicId というヘルパーが用意されています。そして、トランザクションに渡す用に UnresolvedMosaicId にします。

const ownerAddress = network.publicKeyToAddress(keyPair.publicKey);
const mosaicIdRaw = symbolSdk.symbol.generateMosaicId(ownerAddress, mosaicNonceValue);
const mosaicId = new symbolSdk.symbol.UnresolvedMosaicId(mosaicIdRaw);
console.log("mosaicId:", mosaicId.toString());

トランザクション

モザイク定義と発行量変更。

以下はテスト用モザイクなので、モザイクの期間が有限です。 durationBlockDuration にしてますが、たぶん numberBigInt でも大丈夫だと思います。

const definitionTransaction = facade.transactionFactory.createEmbedded({
  type: 'mosaic_definition_transaction_v1',
  signerPublicKey: keyPair.publicKey.toString(),
  duration: new symbolSdk.symbol.BlockDuration(86400n),
  divisibility: 1,
  nonce: new symbolSdk.symbol.MosaicNonce(mosaicNonceValue),
  flags: new symbolSdk.symbol.MosaicFlags(mosaicFlags),
});

const supplyTransaction = facade.transactionFactory.createEmbedded({
  type: 'mosaic_supply_change_transaction_v1',
  signerPublicKey: keyPair.publicKey.toString(),
  mosaicId,
  delta: new symbolSdk.symbol.Amount(1000000000n),
  action: symbolSdk.symbol.MosaicSupplyChangeAction.INCREASE,
});

アグリゲートトランザクションにします。

const innerTransactions = [ definitionTransaction, supplyTransaction ];
const transactionsHash = symbolSdk.facade.SymbolFacade.hashEmbeddedTransactions(innerTransactions)

const transaction = facade.transactionFactory.create({
  type: 'aggregate_complete_transaction_v2',
  signerPublicKey: keyPair.publicKey.toString(),
  fee: 1000000n,
  deadline,
  transactions: innerTransactions,
  transactionsHash,
});

リボークトランザクション

他の人からモザイクを回収するトランザクションです。あまり凝った点はありません。

const mosaicId = 0x13A98C75D38B2D59n;

const transaction = facade.transactionFactory.create({
  type: 'mosaic_supply_revocation_transaction_v1',
  signerPublicKey: keyPair.publicKey.toString(),
  fee: 1000000n,
  deadline,
  sourceAddress: ADDRESS_RECEIVER_1,
  mosaic: { mosaicId, amount: 100n },
});

mosaicIdBigInt で渡したり、 UnresolvedMosaicId で渡したり、どっちがいいんだろう。

ネームスペースを作成するトランザクション

ネームスペース名は、 string もしくは uint8array で。

const namespaceName = 'name1';
const namespaceName = new TextEncoder().encode('name1');

トランザクション。

const transaction = facade.transactionFactory.create({
  type: 'namespace_registration_transaction_v1',
  signerPublicKey: keyPair.publicKey.toString(),
  fee: 1000000n,
  deadline,
  duration: new symbolSdk.symbol.BlockDuration(86400n),
  registrationType: symbolSdk.symbol.NamespaceRegistrationType.ROOT,
  name: namespaceName,
});

チャイルドネームスペースを作成する

ネームスペース名は、 string もしくは uint8array で。

const namespaceName = 'child1';
const namespaceName = new TextEncoder().encode('child1');

親のネームスペースはIDで指定します。

const namespaceId = symbolSdk.symbol.generateNamespaceId('name1');
const namespaceId = new symbolSdk.symbol.NamespaceId(0xFBE54EC2AAA8EFDFn);

トランザクション。

const transaction = facade.transactionFactory.create({
  type: 'namespace_registration_transaction_v1',
  signerPublicKey: keyPair.publicKey.toString(),
  fee: 1000000n,
  deadline,
  registrationType: symbolSdk.symbol.NamespaceRegistrationType.CHILD,
  parentId: namespaceId,
  name: namespaceName,
});

さらにチャイルドネームスペースを作成する

ネームスペース名

const namespaceName = 'grandchild1';
const namespaceName = new TextEncoder().encode('grandchild1');

親のネームスペースIDです。 generateNamespaceId では、ネームスペース名にparent.childのように.を入れられないので、代わりに generateMosaicAliasId を使います。

const namespaceId = symbolSdk.symbol.generateMosaicAliasId('name1.child1');
const namespaceId = new symbolSdk.symbol.NamespaceId(0x83BCCBAA250528DFn);

あとは同様です。

署名と送信

const signature = facade.signTransaction(keyPair, transaction);
const jsonPayload = facade.transactionFactory.constructor.attachSignature(transaction, signature);
const hash = facade.hashTransaction(transaction).toString();

console.log(jsonPayload);
console.log(hash);

const sendRes = await axios.put(`${NODE_URL}/transactions`, jsonPayload).then((res) => res.data);
console.log(sendRes);

await axios
  .get(`${NODE_URL}/transactionStatus/${hash}`).then((res) => res.data)
  .then((statusRes) => {
    console.log(statusRes)
  })
  .catch((e) => {
    console.log(e.message, e.response.data)
  });

おわりに

今回はモザイクとネームスペースに関連するトランザクションについて書いていきました。

4
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
1