トランザクション

一般的にトランザクションとはデータベースシステム内での作業単位を表します。ブロックチェーンにおいては、 アカウント によって署名されたアクションが、それ自身の状態を変えるときを指します。

トランザクションはネットワークに受理され、 ブロック に恒久的に保存されます。

トランザクションタイプ

異なる種類のトランザクションがあります。例えば、 モザイク をアカウント間で転送できたり、アカウントの所有権を転送または構築( マルチシグ ルールも含めて)などたくさんあります。

Id タイプ 説明
リモートハーベスティング    
0x414C Account Link アカウントのインポータンスをプロキシアカウントへ移譲する。
Aggregate    
0x4141 Aggregate Complete 異なるアカウントにトランザクションをバッチ送信します。
0x4241 Aggregate Bonded 異なるアカウント間のトランザクションの手配を提案します。
Cosignature アグリゲートボンドトランザクションへ連署します。
モザイク    
0x414D Mosaic Definition 新しいモザイクの取得
0x424D Mosaic Supply Change 既存モザイク供給量の変更をします。
ネームスペース    
0x414E Register Namespace ネームスペースを登録してアセットを整理します。
0x424E Address Alias アカウントにネームスペースをアタッチする。
0x434E Mosaic Alias ネームスペースをモザイクにアタッチする。
Metadata    
0x4144 Account Metadata Transaction アカウントに Key-Value 状態を関連付けます。
0x4144 Mosaic Metadata Transaction モザイクに Key-Value 状態を関連付けます。
0x4144 Namespace Metadata Transaction ネームスペースに Key-Value 状態を関連付けます。
Multisignature    
0x4155 Modify Multisig Account マルチシグコントラクトの作成と変更
Hash Lock    
0x4148 Hash Lock アグリゲートボンドトランザクションのアナウンスに必要なデポジットをロック
Secret Lock    
0x4152 Secret Lock 異なるチェーン間でのトークンスワップの開始。
0x4252 Secret Proof 異なるチェーン間でのトークンスワップの完結。
Account restriction    
0x4150 Account Restriction Address 与えられたアドレスを含む送受信トランザクションの許可/ブロックします。
0x4250 Account Restriction Mosaic 与えられたモザイクを含む受信トランザクションの許可/ブロックします。
0x4350 Account Restriction Entity Type トランザクションタイプによる送信トランザクションの許可/ブロックします。
モザイク制限    
0x4151 Mosaic Restriction Global モザイクにグローバル制限の設定
0x4251 Mosaic Restriction Address 特定のアドレスにモザイク制限を設定
Transfer    
0x4154 Transfer モザイクとメッセージを2つのアカウント間で送信します。

トランザクションの定義

トランザクションは シリアライズ済み 形式で定義されます。各トランザクションは トランザクション定義スキーマ を継承し、型の特定のプロパティが組み合わされます。追加プロパティの説明は 「スキーマ」 セクション の下、それぞれの組み込み機能の説明の最後にあります。

トランザクションを NEM2-SDK を使用して定義する ことを推奨しています。

import {
    Address,
    Deadline,
    NetworkCurrencyMosaic,
    NetworkType,
    PlainMessage,
    TransferTransaction
} from "nem2-sdk";

const recipientAddress = Address
    .createFromRawAddress('SD5DT3-CH4BLA-BL5HIM-EKP2TA-PUKF4N-Y3L5HR-IR54');

const transferTransaction = TransferTransaction.create(
    Deadline.create(),
    recipientAddress,
    [NetworkCurrencyMosaic.createRelative(10)],
    PlainMessage.create('Welcome To NEM'),
    NetworkType.MIJIN_TEST);

console.log(transferTransaction.serialize());

/* Outputs:
B3000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000
000000000000039054410000000000000000B986E63F170
0000090FA39EC47E05600AFA74308A7EA607D145E371B5F
4F1447BC0F00010057656C636F6D6520546F204E454D44B
262C46CEABB858096980000000000
*/

手数料

トランザクションには関連コストがあります。コストはネットワークを安全に保ち、インフラを運用している ハーベスタ へのインセンティブの提供として必須です。

トランザクションに関連する手数料は、主としてトランザクションのサイズにより異なります。実効手数料は、トランザクションのサイズと、ハーベスタによって設定された手数料の乗数の積です。ノードの所有者はこの後者の値を、ゼロを含む正の値に設定できます。

effective_fee = transaction::size * block::fee_multiplier

トランザクションの送信者は、トランザクションの定義中に max_fee を指定しなければならず、これはアカウントがこのトランザクションに費やすことのできる最大手数料を意味します。

effective_feemax_fee 以下の場合、ハーベスタはトランザクションをブロックに含めることを選択できます。 fee_multiplierブロックヘッダ に格納され、含まれているすべてのトランザクションに対して支払われた実効手数料がどれであるかを解決することができます。

ハーベスティングノードはトランザクション包含ストラテジーを決定することができます。

  • Prefer-oldest:高いトランザクションスループットが要求されるネットワークに適しています。最も古いトランザクションを最初に含めます。
  • Minimize-fees: 慈善事業なノード。他のノードが含めたくない最初のトランザクションを含めます。
  • Maximize-fees: パブリックネットワークで最も一般的です。より高い手数料の最初のトランザクションを含みます。

デフォルトでは、手数料はNEMネットワークの基軸通貨である cat.currency で支払われます。プライベートチェーンでは、手数料を無くすためにネットワークの設定を編集したり、ニーズに合った別の モザイク定義 を使用したりできます。

トランザクションへの署名

アカウントはトランザクションをネットワークにアナウンスする前に、トランザクションに署名する必要があります。 トランザクションに署名 することは、定義されたとおりにネットワークの状態を変更することにアカウントが同意したと示されます。

例えば、転送トランザクションには受信者が誰であるかと、転送するモザイクの量が記述されます。この場合、トランザクションに署名することは、それらのモザイクをあるアカウントの残高から他方のアカウントに移動することに同意することを意味します。

アカウントは トランザクションへ署名 をするために次のステップに従う必要があります:

  1. サイズ、署名、および署名者以外のトランザクションのすべてのバイトである 署名バイト を取得します。
  2. ネメシスブロックのジェネレーションハッシュを取得してください。http://localhost:3000/block/1 にアクセスして meta.generationHash の値をコピーします。
  3. 署名バイトにネメシスブロックのジェネレーションハッシュを接頭します。
  4. 署名者の秘密鍵で結果文字列に署名します。これはトランザクションに 署名 を与えます。
  5. 署名者の署名と公開鍵をトランザクションに追加して ペイロード を取得します。
  6. 署名の最初の 32 バイト、署名者公開鍵、ネメシスブロックジェネレーションハッシュ、残りのトランザクションペイロードにハッシュアルゴリズムを適用して トランザクションのハッシュ を計算します。
import {Account} from "nem2-sdk";

const privateKey = process.env.PRIVATE_KEY as string;
const generationHash = process.env.GENERATION_HASH as string;
const account = Account.createFromPrivateKey(privateKey,NetworkType.MIJIN_TEST);

const signedTransaction = account.sign(transferTransaction, generationHash);

console.log(signedTransaction.payload);

/* Outputs:
B3000000F77A8DCFCB57B81F9BE5B46738F7132998F5512
3BFF4D89DC8E5CAE1F071A040E5571F4D8DA125B243C785
DA5261F878E3DE898815F6E8F12A2C0A5F0A9C3504FA624
9E8334E3F83E972461125504AFFD3E7750AFBB3371E7B2D
22A599A3D0E3039054410000000000000000265DEE3F170
0000090FA39EC47E05600AFA74308A7EA607D145E371B5F
4F1447BC0F00010057656C636F6D6520546F204E454D44B
262C46CEABB858096980000000000
 */

console.log(signedTransaction.hash);

/* Outputs:
21C4D9583CE1887BE7187D4B65B67567B45D5E6114AEE155C0CD266B6AA6A302
 */

トランザクションのアナウンス

署名されたトランザクションはネットワークにアナウンスする準備ができています。SDK TransactionHttp サービスを使用するか、ペイロードを transaction endpoint のリクエストに追加することができます。

import {TransactionHttp} from "nem2-sdk";

const transactionHttp = new TransactionHttp('http://localhost:3000');

transactionHttp
    .announce(signedTransaction)
    .subscribe(x => console.log(x), err => console.error(err));
curl -X PUT -H "Content-type: application/json" -d '{"payload":"B3000000F77A8DCFCB57B81F9BE5B46738F7132998F55123BFF4D89DC8E5CAE1F071A040E5571F4D8DA125B243C785DA5261F878E3DE898815F6E8F12A2C0A5F0A9C3504FA6249E8334E3F83E972461125504AFFD3E7750AFBB3371E7B2D22A599A3D0E3039054410000000000000000265DEE3F1700000090FA39EC47E05600AFA74308A7EA607D145E371B5F4F1447BC0F00010057656C636F6D6520546F204E454D44B262C46CEABB858096980000000000"}' http://localhost:3000/transaction

トランザクションのアナウンスをすると、REST API は常にOKをすぐに返します。この時点ではトランザクションが正当かどうかは不明です。

../_images/transaction-cycle.png

トランザクションサイクル

バリデーションの初回ステージは API ノードで行われます。トランザクションが何らかのエラーを含んでいる場合、WebSocket はステータスチャンネルへ通知を投げます。良いケースの場合、トランザクションは P2P ネットワークへ 未承認 ステータスとして到達します。未承認状態のトランザクションを信頼してはいけません。2つ目のバリデーションを通過しないといけないので、これがブロックに取り込まれるかどうかは不明です。

トランザクションがハーベストされたブロックに追加される前に、2つ目のバリデーションは完了します。妥当な場合、ハーベスターはブロックにトランザクションを保存し、それは 承認済み のステータスとなります。

前述した事例の続きとして、そのトランザクションが処理され、設定された総量が署名者のアカウントから受信者のアカウントへ振り込まれた状態になります。さらに、トランザクション手数料は署名者のアカウントから差し引かれます。

この時点でトランザクションの 承認数はゼロ です。ブロックチェーンに別のブロックが追加されると、トランザクションは1つ目の承認を得ます。チェーンに追加された次のブロックが2つ目の承認を与え、続いていきます。

ロールバック

ブロックチェーンは特定の状況下において、最近のブロックをロールバックする必要があるように設計されています。これらはブロックチェーンのフォークを解決するために不可欠なものです。

書き換え制限 とはロールバック可能なブロックの最大数です。したがって、フォークは特定の深さまでしか解決できません。

NEMの書き換え限界は 40 ブロックです。トランザクションが 40 ブロック以上の承認を得ると、それを元に戻すことはできません。

ガイド

スキーマ

トランザクション

トランザクションのシリアル化

インライン

プロパティ タイプ 説明
max_fee Amount トランザクションに最大の手数料を支払うことが許可されています。
deadline Timestamp ネメシスブロックが作成されてから経過した秒数。期限までにトランザクションがブロックに含まれなかった場合は削除されます。デッドラインは 24 時間先までが許容されています。

EmbeddedTransaction

アグリゲート インナートランザクションのシリアル化

インライン

SizePrefixedEntity

サイズをプレフィックスしたエンティティのシリアル化

プロパティ タイプ 説明
size unit32 トランザクションのサイズ