IOTA:【入門】トランザクション大解剖！ウォレットは裏で何をやっているか。


# はじめに
　来たるIoT時代。そこでは、大量のノードからの大量のリクエストがネット上を駆け巡っていることだろう。その中にはお金をやり取りする**決済**のリクエストもかなりの数が行き来しているはずである。しかし、現存のブロックチェーンでそれらを捌ききることはできるだろうか？未だ世間的に少数の利用者しか使っていないビットコインでも、ご覧の通り決済が滞り、それゆえスケーラビリティが大きな課題として今後も直面し続ける可能性がある以上、もし、分散型システムでそれを実現したいとしたら、ブロックチェーンとはちがったアプローチを模索しなければならない。また、手数料も問題である。IoTが行き届いた社会とは、小さなデバイスの小さな仕事がネットワーク上で無数に実行される社会であるため、おそらくその決済も少額なものがほとんどであると考えられる。

## IOTA
　しかし、ブロックチェーンではシステムの存続作業（=採掘）をするマイナーたちに報酬をあたえることが不可欠であるため、手数料は必ず利用者から徴収しなければならず、１円単位の少額決済には向かない。そこで考案されたのが**タングル（Tangle）**という新しい**分散型台帳**であり、Tangle上で価値を持つ仮想通貨が[**IOTA**](https://iota.org/)である。
　IOTAは上記ブロックチェーンの課題を解決できるよう設計された。具体的には
>1. スケーラビリティの克服（参加者が何人いても大丈夫）
>2. 手数料はゼロ

　では、これを実現したTangleとは一体何なのであろう？

![tangle.png](https://qiita-image-store.s3.amazonaws.com/0/187795/31a8143d-0803-bbee-1689-1e4368da8bd3.png)
　端的にBlockchain（ビットコイン等）とIOTAのTangleの違いを図に表すとこうなる。Blockchainではブロックのサイズにスケーラビリティを依存するが、Tangleでは理論上、サイズの柔軟性がBlockchainに比べて高い。

　先日、コミュニティの中でIOTAのホワイトペーパー勉強会が開催されたようだ。その際使われた[こちらのスライド](https://www.slideshare.net/blockchainexe/exe-whitepaperiota)は深いところまで掘り下げられており、とても分かりやすい。また、リンク集も貼っておく。

>[**IOTA日本語ファンサイト**](https://iotafan.jp/)　実質IOTA日本公式サイト。というのもIOTA公式の情報を日本語訳して掲載しているからである。初心者向けの情報も多く掲載されている。
**ホワイトペーパー**[英語](https://forum.helloiota.com/732/The-Tangle-whitepaper) ・[日本語](https://iotafan.jp/wp/iota-wp-jp/)　Tangleについての概要は序盤までで、それ以降は安全性、想定される攻撃とその耐性について高度な数学で説明している。後半は初心者向きではない。
[**Redditの初心者向けスレッド（英語）**](https://www.reddit.com/r/Iota/comments/61rc0c/for_newcomers_all_information_links_you_probably/)　僕はここから始まった。
[**IOTA Guide（英語）**](https://domschiener.gitbooks.io/iota-guide/content/)　ホワイトペーパーが理学部なら、これは工学部。

# シードと三進数
　IOTAは将来的に3進数チップで動作するプロトコルを目指しているため現段階から3進数で全て設計されている。ちなみに3進数を採用した理由としては2進数より[計算コストが安い](https://medium.com/@comefrombeyond/binary-chips-seem-to-do-58-more-work-than-really-necessary-597b293acf45)かららしい。
　シード(Seed)は決して外に漏らしてはいけない。マイナンバーやクレジット番号と同じである。長さ81トライト以下の文字列で。トライト（Tryte）は**３進数**の単位で、大文字のアルファベットのA-Zと数字の9を使って値を表す。

|十進数|２進数（バイト）|３進数（トライト）|
|----------------:|------------------:|------------------:|
|0|0000 0000 (00)|000 (9)|
|1|0000 0001 (01)|00+ (A)|
|2|0000 0010 (02)|0+- (B)|
|3|0000 0011 (03)|0+0 (C)|
|4|0000 0100 (04)|0++ (D)|
|10|0000 1010 (0A)|+0+ (J)|
|-10|1111 0110 (F6)|-0- (Q)|

上記は簡単な３進数\*の表だ。３進数のtrit（トリットと読む。２進数でいうbit、ビット）は、`0`、`+`、`-`の３種類で表されて、３トリット＝１トライトの情報（3の3乗＝27通り）を**大文字アルファベットA-Zの26通りと数字の9**（26+1=27通り）で表す。変換表は[こちら](https://qiita.com/ABmushi/items/46aa26b9753eea367b0c#%E3%83%88%E3%83%A9%E3%82%A4%E3%83%88%E8%A1%A8)。シードは今のところ**81トライト以下**で設定されるので、`HELLO`でも`TEST`でも`99999999`でも、`AFNE9AOU....WHI9DLW`でも大丈夫である。もちろん、**ランダムな81トライトの文字列がセキュリティ上安全である。**

ちなみに推奨されるシード自動生成コマンドとして、

```:コマンド
$ cat /dev/urandom |LC_ALL=C tr -dc 'A-Z9' | fold -w 81 | head -n 1
```
がある。オンラインのジェネレーターなどは**絶対使ってはいけない**。オフラインと謳っているのも基本危険と認識すべきである。また、上記コマンドで生成したとしても数桁は自分で入れ替えるなどすると尚良い。

試しに下記のシードを生成した。（本当は他人に見せてはダメだが便宜上のサンプルとして）
`9ABCDEFGKLAEUNVMSL9AKRUG9ACBWGQ9NVBAEUOWKHG9AEBVWAIWUEROIKXMZHWYQGW9WYERTBVNIAAEX`
![login.png](https://qiita-image-store.s3.amazonaws.com/0/187795/50f09260-01a6-8ff8-6852-ca4fbb9577cf.png)
　シードを決めたら、ウォレットログイン画面のSeedにそれを入力してログインボタンを押す。
　そうするとアカウントに入ることができる。注意してほしいのは、Googleなどのアカウントと違ってIDとパスワードがあるわけではない。つまり、IOTAのウォレットアカウントに入る際は**シードだけ**が必要なので、81トライトのシード単体がIDとパスワードを兼ねている（＝アカウントそのもの）と考えられる。そのため、繰り返しになるがシードの管理は徹底して行うことを強調する。
　早速、このアカウントにIOTAを送金して決済の準備をしたいが、IOTAのアドレスと受取はどのようになっているのだろうか？

*\*正確には0+-で表される３進数のことを[平衡三進法](https://oeis.org/wiki/Balanced_ternary_numeral_system)というが詳細は省略。*

# アドレス
　さて、IOTAのアドレスはシードから複雑な数理計算（ハッシュ関数）を経て生成される。（アドレスからシードの逆生成はできない。）
![address0.png](https://qiita-image-store.s3.amazonaws.com/0/187795/5aff9586-6925-b50c-c69b-cff9920ee85e.png)
　ここでまず注目してほしいのはPrivate Keyの生成である。（JavaScriptのソースは[こちら](https://github.com/iotaledger/iota.lib.js/blob/master/lib/crypto/signing.js)）IOTAでは１つのアドレスの永久利用をセキュリティの観点から推奨していない。（2017/7/28追記:その理由はIOTAの署名のアルゴリズムにある。それについては[こちら](http://qiita.com/ABmushi/items/422d1bf94be0c919583a#%E3%82%A2%E3%83%89%E3%83%AC%E3%82%B9%E5%86%8D%E5%88%A9%E7%94%A8%E3%81%A8%E8%84%86%E5%BC%B1%E6%80%A7)で詳しく検証した。）アドレスは生成のたびに`index`という内部の変数を1つずつ足していき、毎回異なるものが自動的に生成される様になっている。また、`length`ではセキュリティレベルを設定できる。1〜3のレベルがあり、数字が大きい方がセキュリティが強固なものになる。ちなみにウォレットのレベルは**2**。
##アドレスの運命
　よくIOTAの英語情報を探っていると、**address is deterministic（アドレスは決定論的である。）**という文言を目にすると思う。この文の意味をくだいて説明するならば、アドレス生成の引数（`seed`、`index`、`length`）が同一な場合、生成されるアドレスもまた同一になるということだ。これについては[別の記事](https://iotafan.jp/developer/iota_universe_abmushi_20171213/)で例え話を使って図解したのでよければ一読してほしい。
　また、`seed`と`index`、`length`によってどのようなアドレスが生成されるかを図にすると以下のようになる。
![addresses.png](https://qiita-image-store.s3.amazonaws.com/0/187795/4901af7b-95b2-fcad-5474-eed362780456.png)
　これを見ると、`index=0`、つまり今の（＝初期）状態でのアドレスは`BCEQI...`となっており、ウォレットで見れる（下図）ものと一致している。
![address0.png](https://qiita-image-store.s3.amazonaws.com/0/187795/f0ca9595-7663-f289-35e9-91d3953386ed.png)
次にアドレスを生成したときには、`index=1`のアドレスが生成される。
　また、Private Keyからアドレス生成にもシード->Private Keyとは異なる複雑な演算処理が行われているが、それについては以前の記事で解説したので[そちら](http://qiita.com/ABmushi/items/422d1bf94be0c919583a#%E3%82%A2%E3%83%89%E3%83%AC%E3%82%B9%E7%94%9F%E6%88%90)を参照。


# Transaction大解剖
　Transaction（トランザクション）は仮想通貨のシステムではたいてい最少単位のオブジェクトである。宇宙で言う原子。そのためこのTransactionの構造を解剖してみることは今後の理解の速度をアップするはすだ。
## Transactionの構造
　ビットコインではトランザクションの承認の際、複数のTransactionを一つのハッシュ値（[Merkle root](https://ja.wikipedia.org/wiki/%E3%83%8F%E3%83%83%E3%82%B7%E3%83%A5%E6%9C%A8)）にまとめて、それをブロックに添付してまとめて承認していたがIOTAにはブロックが存在しない。Tangleではトランザクションが生成されるとき、Tips（Tangle上の未承認の別のトランザクション）を２つ承認する必要がある。承認とはつまり採掘なので、IOTAではトランザクション生成者（ユーザー）がトランザクション生成のとき同時に採掘（PoW方式）も行っている。（これが手数料0のカラクリ）なので、Transactionの構造にその２つの承認したトランザクション（`TrunkTransaction`と`BranchTransaction`後述）と`nonce`が含まれている。文章で説明してもなので以下がTransactionの構造である。（[原本](https://domschiener.gitbooks.io/iota-guide/content/chapter1/transactions-and-bundles.html)）

|フィールド | 内容 |
|:--|:----|
|hash|このトランザクションのハッシュ（81トライト）|
|**signatureMessageFragment**| 2187トライトの署名に関連する部位。後述|
|**address**| もしこのトランザクションが出力なら受取人のアドレス。もし入力（UTXOからの受け取り）ならそのUTXOのアドレス。UTXOについて分からない方は[こちら](http://qiita.com/hshimo/items/0494f6855b565ce060fd#%E3%83%88%E3%83%A9%E3%83%B3%E3%82%B6%E3%82%AF%E3%82%B7%E3%83%A7%E3%83%B3%E3%81%AE%E5%87%BA%E5%8A%9B%E5%85%A5%E5%8A%9B)から。|
|value|移動するIOTAの額|
|timestamp|タイムスタンプ。IOTAでは必須ではない。|
|currentIndex|Bundle（後述）内のインデックス|
|lastIndex|Bundle内のトランザクションの数|
|bundle|このトランザクションを内包するbundleのハッシュ（81トライト）|
|**trunkTransaction**|**１番目**にこのトランザクションに承認されたトランザクションのハッシュ（81トライト）|
|**branchTransaction**|**２番目**にこのトランザクションに承認されたトランザクションのハッシュ（81トライト）|
|**nonce**|PoWで生成される値|

# Tangleにアタッチ（Attach to Tangle）
　ウォレットの機能その１である**タングルにアタッチ**だが、これが分かりにくい。あたかも受取に必要のように思わせておいて実は、このボタンを押さなくても送金を受け取ることができる。
　何をやっているかを一言で言えば、**空の（０円送金の）トランザクションを指定アドレス宛へ発行すること**である。上項のアドレスでちらっと出てきた`index`を**+1**することを行い、新しいアドレスをSeedから生成（生成自体はハッシュ計算をオフラインで行えるためローカルでやっている）する。そして、この"タングルにアタッチ"ボタンを押すことで、その新しいアドレス宛の空トランザクションをTangle上に発行する（ここはオンラインの動作）。
　また、最近Discordの日本語チャンネルにおける[アタッチについての議論](https://iotafan.jp/discord/attach-20180126/)が非常に有意義に行われ、IOTA日本ファンサイト様にまとめていただいた。一見の価値あり。
　では、アタッチしてみよう。
![attaching.png](https://qiita-image-store.s3.amazonaws.com/0/187795/1149f4c8-0ffd-5d34-ffde-cb471e3391d1.png)
しばらくの時間（1〜2分）待っていると...
![attached.png](https://qiita-image-store.s3.amazonaws.com/0/187795/a1551687-3719-a755-31e9-21ae38233d80.png)
と表示される。空のトランザクションが生成されたことを確認しよう。IOTAのTangle Explorerは[IOTA Tangle Explorer](https://iotasear.ch/)を利用する。受取のアドレス（今回の場合ならBCEQI...）で検索するとアドレス詳細が出てくる。その下のRelated Transaction（関連するトランザクション）の詳細を見てみると、空のトランザクションが見れる（[ここ](http://www.iota.tips/search/?kind=transaction&hash=BMBT9CVBGMGBVKTBMJWMKXKXJ9YPNWLLDE9BWDNWGLUWHTOSSDBMF9LZHAYLTPAQBNJAOKFVPEKO99999)）。
![pending.png](https://qiita-image-store.s3.amazonaws.com/0/187795/de8c1872-22f8-2216-16f4-165e6ec75d5d.png)

執筆時点ではConfirmed=falseとなっていて未承認となっていた。ウォレットの記録の中に*ペンディング中*と表示されているので"バンドル表示"から"再ブロードキャスト"してみたところ、何度やっても承認済みにならない。どうやら同じようなトラブルが多数報告されているようだが、「ウォレットを最新バージョンにする」「再ブロードキャストを繰り返す」「待つ」と言ったそんなの分かっている的な対処法しか見つからない。私の場合はただの空のトランザクションだからマシだが、大きな金額が動くトランザクションでは大きな問題だと思う。

>予定にはなかったペンディング地獄。そちらについてまとめたので[こちら](http://qiita.com/ABmushi/items/1481e5c2f9485abfcca3)の記事を参照してほしい。

結局一日経っても承認されずに終わってしまったのでこの記事にこのアドレスを使うことはこれ以降では行わない。

(2017/7/28追記)
どうやら、この"タングルにアタッチ"によって生成される空のトランザクションは**承認される必要は[ない](https://matthewwinstonjohnson.gitbooks.io/iota-guide-and-faq/content/getting-started/rece.html)**とのことだ。そのため、今回のペンディング地獄は幻想だった。

## 余談
　Attach to Tangleの日本語訳を**タングルにアタッチ**としてしまったのには、筆者にも後悔が残る。というのもAttachという動詞をカタカナにすると初心者にはなんのことか分かりにくいからだ。
　一応、候補としては**添付**といった面白みのないものから、**登録**など飛躍したものまで考えたが、語学の専門家でもないので仕方なくカタカナにしてしまった次第だ。
　参考のため他の漢字文化圏の訳がどうなっているか調べてみると、韓国語では**연결（連結）**、中国語では**附加**や**添加**というふうに決して統一はできていない様子だ。やはり他の文化圏の言葉を輸入するのは難しいということだろうか。
　結局、Attachという動詞がIOTAに採用されたのも、Tangleという小さなトランザクションの大群に新しくくっ付けるといったニュアンスから来たのかなと想像ができる程度だ。まあ想像の域を越えることはない細かい話は余談程度に留めておくのが最善であろう。

# 送金の仕組みとBundle
　気を取り直してウォレットの記録にあるバンドル（Bundle）とは何か説明したい。
例えば、AさんからBさんへの送金の際、IOTAは１つのトランザクションでそれを行わない。基本４つのトランザクションで１つの送金を行うことになっている。Bundleはその４つのトランザクションをまとめる単位と考えるとよい。（４つ以上、４つ以下の場合もある。詳しくは[こちら](https://qiita.com/ABmushi/items/0c9f73e08fdb6597ab9c)から。）
　では、わざわざ４つのトランザクションで送金をする意味を理解するためにBundle内の４つのトランザクションの役割を見てみよう。上記のTransactionの構造と見比べながらだといい。

|Bundle内のindex|Transactionのフィールド|役割|
|:--|:-----|:-----|
|[0]|送金額は`value>0`で指定。送金相手は`address`で指定。|`address`に`value`を送る。|
|[1]|入力アドレス（どこから[0]の`value`の額を持ってくるか）を`address`で指定。また、その入力アドレスからいくら引くかの額を`value<0`に指定。そして、その入力アドレスの電子署名の半分を`signatureMessageFragment`に指定。(署名の生成方法は[こちら](http://qiita.com/ABmushi/items/422d1bf94be0c919583a#%E7%BD%B2%E5%90%8D%E3%81%AE%E6%96%B9%E6%B3%95))|入力したいUTXOのアドレス・額の指定。署名(1/2)の保持。|
|[2]|もう半分の電子署名を`signatureMessageFragment`に指定。入力アドレス（[1]の`address`と同一だが）を`address`で指定。`value=0`。|署名(2/2)の保持。|
|[3]|[1]の`address`から引き落とした額（[1]の`value`）と送金額（[0]の`value`）の差を`value>0`に指定。また、その額がどこの出力アドレス（UTXO）に送るかを`address`に指定。|入力-支払いのおつりを持たせる新UTXOのアドレス・額を指定。|

AさんがBさんに**24 iota**送金する例で考える。送金前Aさんは**777 iota**の残額がある。その777 iotaはZさんから以前受け取った額であるとする。下の図ではZさんからの受取時に生成されたUTXO(アドレス:AUTXO9...)に777 iotaが存在していることを示している。Aさんの残高はAさんの所有権のあるUTXO全ての残高の合計ということだ。
![figure1-1.png](https://qiita-image-store.s3.amazonaws.com/0/187795/832efe32-b129-4489-537c-2f0288e08552.png)
この状態から送金のためにBundleとその中にTransactionを生成する。
![figure1-2b.png](https://qiita-image-store.s3.amazonaws.com/0/187795/557dc69a-37d1-7cc6-82d7-5ad0b63e28af.png)
Bundle承認後、送金が完了される。AさんはTransaction[3]が指定したアドレス(address=AUTXOA...)に新たなUTXOを作り、その残高は777-24=753 iotaとなる。また、BさんはTransaction[0]のアドレス(address=BADR......)に新たなUTXOを作り、その残高は24 iotaとなる。
![figure1 (9).png](https://qiita-image-store.s3.amazonaws.com/0/187795/97baae00-6019-9217-fc9d-bf8f429aa5f2.png)
ビットコインとよく似ているが、ポイントとしては手数料が引かれないということであろう。

## TrunkTransactionとBranchTransaction
　さて、上記Transactionの構造に**trunkTransaction（幹トランザクション）**、**branchTransaction（枝トランザクション）**という変数がある。先ほども述べたようにIOTAのPoWは新しいトランザクションが別の２つのトランザクションを承認する際になされる。そしてこの二つの変数はその承認された２つのトランザクションの**ハッシュ**を保持するためのものだ。基本的には２つのトランザクションの選定（**Tips Selection**）はランダムに行われるが、実は送金の際は特殊なルールがある。まず、下の図を見てほしい。
![bundle3_eng.png](https://qiita-image-store.s3.amazonaws.com/0/187795/a488bc99-3103-a84e-6d60-b7c5cbe1dd7f.png)


気づいてほしいのは、trunkTransactionの承認はindexが0から3の方向へまるでBundleを幹にする木を作るようになっている。このような特殊な承認をするのは、送金のためにBundle内に複数のトランザクションがある場合である。例えば、**'タングルにアタッチ'**の時生成される空のトランザクションは、Bundle内にそのトランザクション１つしかないためこのルールは適用されず、単純に１番目に承認されたものを`trunkTransaction`、２番目を`branchTransaction`とする。

[チートシートを作成しました](https://qiita.com/ABmushi/items/0c9f73e08fdb6597ab9c#%E3%83%81%E3%83%BC%E3%83%88%E3%82%B7%E3%83%BC%E3%83%88)

## Milestone（マイルストーン）
　Milestone（マイルストーン）というのは現在運用中のCoordinatorと呼ばれるノードが発行する特殊なTransactionのことで、主にTangle上のチェックポイントとして使われる。マイルストーンのTransactionはBundle内から上図のように参照される。また、マイルストーンは下図のような構造になっている。
![milestone2_eng.png](https://qiita-image-store.s3.amazonaws.com/0/187795/1b177bf9-9070-a3a8-fceb-e09bca59415c.png)

　一つのマイルストーンは２つのTransaction（Milestone[0]とMilestone[1]）で構成されている。マイルストーンの生成アナウンスはIOTA公式Slackの#botboxチャンネルで逐次確認できる。

# ネットワークをスパム（Spam the network、スパミング）
　主にSpammer（スパマー）によって行われるスパミングについて説明したい。スパムと言えばネット上の迷惑行為だが、どうやらIOTAにおいてはスパムはちがう。そのため、IOTAにおいてのSpamは**スパミング**とあえて訳した。スパマーは非公式のものなら[ここ](https://github.com/guang384/iota)でそのコードを見ることができる。（バージョンによってはウォレットからもできるようだが。）スパマーの目的はズバリ、**空のトランザクションを無意味に大量生成することである！**そんなF5攻撃みたいなことをしてTangleの処理は滞らないか心配するかもしれないが、どうやら[問題ないらしい](https://www.reddit.com/r/Iota/comments/6i5re7/what_is_preventing_spamming_the_network/)。むしろ、スパムトランザクションの生成にも２つのトランザクション承認義務があるため、ネットワークはスパミングによって**恩恵すら受ける**ということだ。また、そんなことしてたらたちまち膨れ上がっていくだろうストレージサイズも、一定期間で残額が0のアドレスを除去し、スナップショット（その時点のデータだけを保存）を残すことができるので、ビットコインのようにジェネシスブロックから全てのブロック（=ブロックチェーン）を保持する訳ではないそうだ。スナップショットをとるタイミングはフルノードごとにローカルで決めることが[できる](https://www.reddit.com/r/Iota/comments/6jku0a/frequency_of_snapshots/
)らしい。

# スナップショット
　IOTAのTangleのデータのダイエットが不定期に行われる。この際は全てのトランザクションが消去され、残高のあるアドレスを新たなGenesisアドレスとしてTangleを言うなれば"生まれ返らせる"操作を**スナップショット**と呼ぶ。
　こちらもIOTA日本ファンサイト様の[Discordまとめ記事](https://iotafan.jp/discord/snapshot-20180124/)は一読の価値ありだ。

# IOTAの今後（2018年2月時点）
　仮想通貨が大暴落、米国株価や日経平均も急落。と経済的不安要素が高まりそうな2018年だが、皆様はどうお過ごしだろうか。ただ、IOTAや他の仮想通貨でもここで踏ん張って開発しきれたプロジェクトが今後の世の中のためになる技術となっていくに違いはない。仮想通貨は通貨ではなく、暗号とプロトコルで分散管理され、サービスに直結している株のようなものだと筆者は考えているので、サービス自体に価値がないと通貨の価値もなくなってしまうだろう。
　IOTAに関して言えば、まず今年上半期にTrinityウォレットのリリースを控える。
　そして、フラッシュ（IOTA版ライトニングネットワーク）の実用化（ハッカソンの結果も発表された）、データマーケットの整備、そしてIXI（C++版フルノード）運用開始、Coordinator引退が今年中にでも実現できれば及第点ではないかと個人的には思う。３進数プロセッサーJINNは慌てなくてもいいかなというのが私の勝手な意見だが...
　フルノードはアップデートごとに安定してきておりIOTA開発陣の努力を肌で感じられるので、これからもこの調子でコツコツ開発を続け、新たな価値を創造してくれることを期待している。