NEM2(Catapult)だとネームスペースからモザイクまで一発で作れる話

:warning: **この記事はalpacaの時の記事です。最新バージョンでは動きません** :warning: 

# 現行NEMのモザイク発行

現行のNEMで例えば、`nemket.2018:ticket`というモザイクを発行しようとすると以下の3つのトランザクションを発生させる必要があります。

1. 親ネームスペース: `nemket` を作成するトランザクション
2. 子ネームスペース: `2018` を作成するトランザクション
3. モザイク: `ticket` を作成するトランザクション

そしてこのモザイクを発行するのに、親ネームスペースを作成するトランザクションがブロックに取り込まれるのを待って、子ネームスペースを作成して、それがブロックに取り込まれるのを待って...と、モザイクを作るのに3ブロックは待つ必要があります。

これって、何気に面倒くさくありませんか?

これが、NEM2(Catapult)になると1トランザクションで作成することができます！そう、アグリゲートトランザクションを使ってね

# NEM2(Catapult)のモザイク発行

NEM2(Catapult)で `nemket.2018:ticket` というモザイクを発行する際は`AggregateCompleteTransaction`で以下のトランザクションを1まとめにして送ることができます。

1. 親ネームスペース: `nemket` を作成するトランザクション
2. 子ネームスペース: `2018` を作成するトランザクション
3. モザイク: `ticket` を作成するトランザクション
4. モザイク: `ticket` の供給量を設定するトランザクション

※ NEM2の場合、モザイクの作成時にはモザイクの名前・プロパティを設定するトランザクションと供給量を設定するトランザクションは別になっていて、この時点でアグリゲートトランザクションを使っています。

## ソースコード

※ `TransactionHttp('http://localhost:9000')`は[nem2-camel](https://github.com/nemtech/nem2-camel)を立ち上げてつないでいます

```typescript
import { Account, NetworkType, TransactionHttp, NamespaceId, RegisterNamespaceTransaction, Deadline, UInt64, AggregateTransaction, MosaicDefinitionTransaction, MosaicProperties, MosaicSupplyChangeTransaction, MosaicSupplyType } from 'nem2-sdk';

const privateKey = 'YOUR_PRIVATE_KEY';
const account = Account.createFromPrivateKey(privateKey, NetworkType.MIJIN_TEST);

const syncTransactionHttp = new TransactionHttp('http://localhost:9000');

const rootNamespaceName = 'nemket';
const subNamespaceName = '2018';
const mosaicNamespace = rootNamespaceName + '.' + subNamespaceName
const mosaicName = 'ticket';

const registerNamespaceTransaction = RegisterNamespaceTransaction.createRootNamespace(
  Deadline.create(),
  rootNamespaceName,
  UInt64.fromUint(1000),
  NetworkType.MIJIN_TEST
);

const registerSubNamespaceTransaction = RegisterNamespaceTransaction.createSubNamespace(
  Deadline.create(),
  subNamespaceName,
  rootNamespaceName,
  NetworkType.MIJIN_TEST
);

const mosaicDefinitionTransaction = MosaicDefinitionTransaction.create(
  Deadline.create(),
  mosaicName,
  mosaicNamespace,
  MosaicProperties.create({
    supplyMutable: true,
    transferable: true,
    levyMutable: false,
    divisibility: 0,
    duration: UInt64.fromUint(1000)
  }
  ),
  NetworkType.MIJIN_TEST
);

const mosaicSupplyChangeTransaction = MosaicSupplyChangeTransaction.create(
  Deadline.create(),
  mosaicDefinitionTransaction.mosaicId,
  MosaicSupplyType.Increase,
  UInt64.fromUint(100000),
  NetworkType.MIJIN_TEST
);

const aggregateTransaction = AggregateTransaction.createComplete(
  Deadline.create(),
  [
    registerNamespaceTransaction.toAggregate(account.publicAccount),
    registerSubNamespaceTransaction.toAggregate(account.publicAccount),
    mosaicDefinitionTransaction.toAggregate(account.publicAccount),
    mosaicSupplyChangeTransaction.toAggregate(account.publicAccount)
  ],
  NetworkType.MIJIN_TEST,
  []
);

const signedTransaction = account.sign(aggregateTransaction);

syncTransactionHttp.announceSync(signedTransaction).subscribe(
  x => console.log(x),
  err => console.error(err)
);

```

## レスポンス

```
AggregateTransaction {
  type: 16705,
  networkType: 144,
  version: 2,
  deadline: Deadline { value: LocalDateTime { _date: [Object], _time: [Object] } },
  fee: UInt64 { lower: 0, higher: 0 },
  signature: '981D92E100937EBDD75B3D3EE45AA8BA6F9EA8CEEC74A155EFB0620DB87C955D7C7A10282DDE706401D431E30C0EECC79EAC19FAD00AAA4EEDB5AD38B9B49706',
  signer:
   PublicAccount {
     publicKey: '60ED1F0F598C9429963243BFAB09E87A0836BEAB3F47CBF7F3244C57AD4CEB53',
     address:
      Address {
        address: 'SAYWGBK3ELERVSKTSOX4X35RSHHQXAYPXG2FDHK6',
        networkType: 144 } },
  transactionInfo:
   TransactionInfo {
     height: UInt64 { lower: 0, higher: 0 },
     index: undefined,
     id: undefined,
     hash: 'A2D0ACB12F235F1108F4ACADA8CE58C5A099FBEC1C499741E43FE6076E29644C',
     merkleComponentHash: 'A2D0ACB12F235F1108F4ACADA8CE58C5A099FBEC1C499741E43FE6076E29644C' },
  innerTransactions:
   [ RegisterNamespaceTransaction {
       type: 16718,
       networkType: 144,
       version: 2,
       deadline: [Object],
       fee: [Object],
       signature: '981D92E100937EBDD75B3D3EE45AA8BA6F9EA8CEEC74A155EFB0620DB87C955D7C7A10282DDE706401D431E30C0EECC79EAC19FAD00AAA4EEDB5AD38B9B49706',
       signer: [Object],
       transactionInfo: undefined,
       namespaceType: 0,
       namespaceName: 'nemket',
       namespaceId: [Object],
       duration: [Object],
       parentId: undefined },
     RegisterNamespaceTransaction {
       type: 16718,
       networkType: 144,
       version: 2,
       deadline: [Object],
       fee: [Object],
       signature: '981D92E100937EBDD75B3D3EE45AA8BA6F9EA8CEEC74A155EFB0620DB87C955D7C7A10282DDE706401D431E30C0EECC79EAC19FAD00AAA4EEDB5AD38B9B49706',
       signer: [Object],
       transactionInfo: undefined,
       namespaceType: 1,
       namespaceName: '2018',
       namespaceId: [Object],
       duration: undefined,
       parentId: [Object] },
     MosaicDefinitionTransaction {
       type: 16717,
       networkType: 144,
       version: 2,
       deadline: [Object],
       fee: [Object],
       signature: '981D92E100937EBDD75B3D3EE45AA8BA6F9EA8CEEC74A155EFB0620DB87C955D7C7A10282DDE706401D431E30C0EECC79EAC19FAD00AAA4EEDB5AD38B9B49706',
       signer: [Object],
       transactionInfo: undefined,
       parentId: [Object],
       mosaicId: [Object],
       mosaicName: 'ticket',
       mosaicProperties: [Object] },
     MosaicSupplyChangeTransaction {
       type: 16973,
       networkType: 144,
       version: 2,
       deadline: [Object],
       fee: [Object],
       signature: '981D92E100937EBDD75B3D3EE45AA8BA6F9EA8CEEC74A155EFB0620DB87C955D7C7A10282DDE706401D431E30C0EECC79EAC19FAD00AAA4EEDB5AD38B9B49706',
       signer: [Object],
       transactionInfo: undefined,
       mosaicId: [Object],
       direction: 1,
       delta: [Object] } ],
  cosignatures: [] }
```

## ブロックエクスプローラーで確認

※エクスプローラーに不具合があるのかInnterTransactionが3つしかでない...

<img width="683" alt="スクリーンショット 2018-12-06 19.22.57.png" src="https://qiita-image-store.s3.amazonaws.com/0/9315/b3079c38-28ad-f1b9-a035-5e4ceca6344d.png">

# まとめ

複数の取引をひとまとめにする文脈で語られることが多いアグリゲートトランザクションですが、ネームスペースからモザイクの作成までを1回で行える様に、転送トランザクション以外のトランザクションもまとめることができます。
これによって、現行NEMでトランザクションを送って、取り込まれるのを待ってという面倒なことをしなくてもよくなりUXの改善にもつながります。