LoginSignup
3
1

More than 1 year has passed since last update.

TransferTransactionのスキーマを読み解こうその3

Last updated at Posted at 2022-06-22

トランザクションのスキーマ

スクリーンショット 2022-06-24 1.55.29.png

該当ソースコードはこちら

これがトランザクションのスキーマの全体像。

import "entity.cats"
import "transaction_type.cats"

# binary layout for a transaction
@size(size)
@initializes(version, TRANSACTION_VERSION)
@initializes(type, TRANSACTION_TYPE)
@discriminator(type)
@is_aligned
abstract struct Transaction
	inline SizePrefixedEntity
	inline VerifiableEntity
	inline EntityBody

	# transaction type
	type = TransactionType

	# transaction fee
	fee = Amount

	# transaction deadline
	deadline = Timestamp

トランザクションの属性について

@size(size)
@initializes(version, TRANSACTION_VERSION)
@initializes(type, TRANSACTION_TYPE)
@discriminator(type)
@is_aligned

ここの@で始まるところは「属性」(アトリビュート)と言いまして、
トランザクションのスキーマに対して属性を付与することができます。

たとえば魔法使いの属性に水属性を付与すると水の魔法使いとなってリムル・テンペストが
種族が龍の個体に風属性を付与するとヴェルドラ・テンペスト
となるように属性を付与することができる認識でいます。

まず、ここでは「トランザクション」に対するバイナリのレイアウトを設定してますので、
トランザクションの属性を示唆しているわけです。
その属性をそれぞれ見ていきましょう。

@size(size)

size(x): x フィールドが(可変長の)構造体のフルサイズを含むことを示す。

これはトランザクションの構造体の長さ(バイト数)と思っていいと思います

スクリーンショット 2022-06-24 1.58.50.png

@initializes(version, TRANSACTION_VERSION)
@initializes(type, TRANSACTION_TYPE)

initializes(x, Y): xフィールドがY定数で初期化されるべきであることを示す。

ここではトランザクションのバージョンとトランザクションのタイプが初期化されます。
symbolではトランザクションのバージョンは1しかなく、ここは固定値になります。

またトランザクションのタイプはいろいろありますが、
転送トランザクションの場合は0x4154が入ります

こっちでトランザクションのタイプを確認できます。

スクリーンショット 2022-06-24 2.00.03.png

@discriminator(type)

discriminator(x [, y ]+): (x, ...y)プロパティがファクトリー生成時に識別器として使用されるべきであることを示す
(抽象構造に対してのみ意味を持つ)。

ここではトランザクションのタイプの16進数からどう言ったタイプなのか識別子ます。
なので流れはトランザクションのタイプを16進数で定義してから
識別器を使ってトランザクションの種類を判別する

@initializes(type, 0x4154) # この状態ではまだ転送トランザクションと認識されない
@discriminator(type) # この引数のtypeは上で初期化したtypeです。@discriminatorで初めて転送トランザクションということがわかります。

スクリーンショット 2022-06-24 2.00.48.png

@is_aligned

is_aligned: すべての構造体フィールドがアライメントされた境界上に配置されることを示す。

これはパフォーマンスの最適化(計算効率の向上)のために属性が指定されます。

image.png

たとえばこれが
Heightが7バイト
Timestampが3バイト
Difficultyが4バイト
とそれぞれバラバラだったとすると
Heightのポインター(Heightの最初のアドレス)
Timestampのポインター(Timestampの最初のアドレス)
Difficultyのポインター(Difficultyの最初のアドレス)
を探すのが難しくなります。

そこでHeightを7バイトの後ろに意味のない1バイトを入れることによって8バイトとすることで
コンピュータはポインタを探すのが早くなります。
そのようなデータ構造を持たせることでどこになにがあるかを調べる必要がなくできるので
計算効率が上がるということです。

この@is_alignedの属性にはそのような意味があります(スキーマによってサイズ数は異なることもありますが8バイト単位に揃えることでデータを扱いやすくなります。)

ある時

スクリーンショット 2022-06-11 1.20.54.png

ない時

スクリーンショット 2022-06-11 1.21.01.png

とりあえずこれでトランザクションの属性はわかりました。

3
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
3
1