IOTA:【随時更新】最速でフルノードを立ち上げる。

**願わくば30分でフルノードを君の手に。**
　技術的な話には興味ない人は[フルノード運用のインセンティブ](https://qiita.com/ABmushi/items/6b8413c1fb510e716d58#%E3%83%95%E3%83%AB%E3%83%8E%E3%83%BC%E3%83%89%E9%81%8B%E7%94%A8%E3%81%AE%E3%82%A4%E3%83%B3%E3%82%BB%E3%83%B3%E3%83%86%E3%82%A3%E3%83%96)までとばしても構わない。
　また、有志による[最新の最速フルノード設置法](https://github.com/iotFab/iota-aws-full-node/tree/master)もあるにはあるが、まだ試してないためこの記事ではあくまで一番オーソドックスな方法にこだわる。

　記事内にあるShell、Terminalのコマンド番号に沿ってコピペしていけばフルノードの完成だ。

```shell:[1]この数字
コマンドライン
```


#環境構築
　フルノードだが時が経つにつれて要求スペックが高くなっている。半年前ならメモリ2GBなら問題ないという風潮が、現在2017年12月においては、4GBでギリギリといった具合だ。

　今回使うサービスは[**Vultr**](https://www.vultr.com/?ref=7288508)（こちらは僕からのrefered linkというやつです）。
なぜこのサービスを選んだかというと
　**①値段** - CPU2コア メモリ4GB SSD 60GBで月$20。値段表は[こちら](https://www.vultr.com/pricing/)。
　**②データセンターが東京にもある**（場所はフルノード運用に関係ないが、日本もサポートしているのは何かと安心である。）
　**③Slackを眺めていてよく目にする** IOTAの公式Slack上でよく出てくる名前だから安心かなという理由。

 もちろん皆様の使い慣れたサービスでも運用はできる。

 ローカル環境はMac OS、Unix系を想定している（SSH接続を使うため）。Windowsの人は[PuTTY](http://www.putty.org/)というものをインストールするとSSH接続ができるらしいが、試したことがないため今回は割愛させていただく。

## SSHキー（下準備）
※フルノードには直接関係がないので分かる人は読み飛ばしてOK。
　SSH接続でサーバーにローカルからリモート接続できるようにしてみよう。
　Vultrによる[SSHキー生成](https://www.vultr.com/docs/how-do-i-generate-ssh-keys/)ガイドから引用した。筆者は今までリモートでサーバーにSSH接続というものをやったことがなかったのでこの手順に少々手間取った。筆者のような初心者のためにもメモ程度に手順を書き留めておく。

Unix系ターミナルから以下のコマンドを実行していく。ちなみに、SSHキー保存ディレクトリーへは、`cd ~/.ssh`で行けるはずだ。

```shell:[ssh-1]ローカルマシンでSSHキーの生成
$ ssh-keygen -t rsa
```
```shell:[ssh-2]下のような質問が来る
Generating public/private rsa key pair.
Enter file in which to save the key (/path/to/.ssh/id_rsa): 
```
この場所`/path/to/.ssh/`、この名前`id_rsa`でいいならそのままEnter。もう名前が使われている場合は適当に名前を付ける。

```shell:[ssh-2*]場所と名前を指定したい場合
Generating public/private rsa key pair.
Enter file in which to save the key (/path/to/.ssh/id_rsa): /your/path/to/.ssh/NAME_OF_KEY
```
コロンの後ろに`/your/path/to/.ssh/NAME_OF_KEY`と指定してEnter。

```shell:[ssh-3]パスフレーズの設定
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
```

```shell:[ssh-4]生成されたSSHキーの概要が返ってくる。
Your identification has been saved in /your/path/to/.ssh/NAME_OF_KEY.
Your public key has been saved in /your/path/to/.ssh/NAME_OF_KEY.pub.
The key fingerprint is:
SHA256:##ABC_FINGER_PRINT_HERE_XYZ## username@MacBook-Air.local
The key's randomart image is:
+---[RSA 2048]----+
|+* =.  + .o+ +*. |
|.oo.E.o +.=O  .  |
|o.+ . ..o..=*E.  |
|.f + o  .  ..    |
|    . * S o      |
| .   o o         |
|    .   .    d   |
|       ABC       |
|       G         |
+----[SHA256]-----+
```
```shell:[ssh-5]SSHの公開鍵をサーバーに保管。
$ cat ~/.ssh/NAME_OF_KEY.pub | ssh root@IP.ADD.RE.SS "mkdir -p ~/.ssh && cat >>  ~/.ssh/authorized_keys"
```

　パスワードが求められるので、使っているサーバーを立ち上げた際に決めた、もしくは決められたものを入力する。また、ユーザー名が`root`でない場合はそこを変える。次にssh接続を受け取った際のサーバーの挙動を`sshd_config`に設定する。

```shell:[ssh-6]サーバー（フルノード）側
$ vim /etc/ssh/sshd_config
```
　サーバー側の`sshd_config`ファイルに以下のような変更を行う。
> `PasswordAuthentication yes`を`PasswordAuthentication no`に変更。必要によってはコメント化されているのでそれも解除（先頭の`#`を消す）。パスワードログインを制限する。
> `AuthorizedKeysFile      .ssh/authorized_keys`のコメント化を解除。
> `PubkeyAuthentication no`を`PubkeyAuthentication yes`にする。

　今回行ったのは公開鍵認証方式の設定だ。詳しいことは下記のようなサイトを見るといい。
> [SSHのセキュリティ対策について](http://www.server-memo.net/server-setting/ssh/ssh-sec.html#i-7)
> [ssh公開鍵認証方式で接続](http://www.server-memo.net/server-setting/ssh/ssh-key.html#i-2)
> [ssh公開鍵認証を実装する](https://qiita.com/HamaTech/items/21bb9761f326c4d4aa65)

```shell:[ssh-7]サーバー（フルノード）側
$ service sshd restart
```
　configファイルの再読み込みを行う。OS環境によっては`service sshd reload`だったりする。

```shell:[ssh-8]ローカル側
$ vim ~/.ssh/config
```
 今度はローカル側のconfigファイルに以下のような内容を書き込む。

```shell:[ssh-9]ローカル側（~/.ssh/config）
Host iota_fullnode
	HostName IP.ADD.RE.SS
 	User root
	IdentityFile ~/.ssh/NAME_OF_KEY_id
```
`iota_fullnode`はどんな名前でもOK。何に関係するかはすぐ次のステップで分かる。
`root`は必要に応じて使用しているユーザー名に変更。


```shell:[ssh-10]SSH接続（もちろんローカルから）
$ ssh iota_fullnode
```


`iota_fullnode`の部分は前のステップで設定したホスト名。ここで`Enter passphrase for key '~/.ssh/NAME_OF_KEY_id':`のようなメッセージが返って来た場合は、上記`[ssh-3]パスフレーズの設定`のステップで設定したパスフレーズを入力。

```shell:SSH接続成功！！
Welcome to Ubuntu 17.10 (GNU/Linux 4.13.0-16-generic x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/advantage


0 packages can be updated.
0 updates are security updates.


Last login: Mon Dec 11 23:02:37 2017 from LOCAL.IP.ADD.RESS
root@server-name:~# <Unixコマンドをここに入力できる>
```

#IRIのインストール
　IRIというのはIOTAのフルノードソフトウェアの名前である。サーバー上でこれを立ち上げて安定させることがフルノード運営者の目的である。以下でIRIのインストール手順を紹介する。
　ここ以降はSSH接続した状態でコマンドを打っていく形になる。

```shell:[1]Javaをインストール。
apt-get -y update
apt-get -y install openjdk-8-jre
```

```shell:[2]IRIをインストール。
mkdir -p /opt/iota && cd /opt/iota
wget -O IRI.jar https://github.com/iotaledger/iri/releases/download/v1.4.1.6/iri-1.4.1.6.jar
```
一行目で`/opt/iota`というディレクトリを作成している。IOTA関係のファイル・フォルダを今後はここに集める。二行目の`1.4.1.6`の部分は最新バージョンに設定しておく。（最新バージョンは[こちら](https://github.com/iotaledger/iri/releases)からチェック。）

#INIファイル追加
IRIを起動するときの初期設定はiniファイルにまとめておくと便利である。デフォルトの**iri.ini**を用意したので、それをダウンロードして先ほどの`/opt/iota/`内に設置する。

```shell:[3]iri.iniをDLする
cd /opt/iota
wget -O iri.ini https://raw.githubusercontent.com/abmushi/iota/master/qiita/fullnode/iri.ini
```

ちなみにこのiri.iniの中身は以下のようになっている。

```shell:iri.ini
[IRI]
PORT = 14265
UDP_RECEIVER_PORT = 14600
TCP_RECEIVER_PORT = 15600
NEIGHBORS = udp://94.156.128.15:14600 udp://88.99.249.250:41041
IXI_DIR = ixi
HEADLESS = true
;API_HOST = 0.0.0.0
;REMOTE_AUTH = user:password
;REMOTE_LIMIT_API="removeNeighbors, addNeighbors, getNeighbors, interruptAttachingToTangle, attachToTangle"
;IRI_OPTIONS = "--remote"
```
　`NEIGHBORS`にすでに二つ追加されているが、これはSwarm Nodeというもので、こちらから接続すると向こうから自動で繋ぎ返してくれるものである。テストとしてはじめのうちは追加しておくことをオススメする。

　コメントアウトされている下半分の行については、フルノードにリモートでAPIアクセスする際必要となる項目である。それについては後ほど説明するので今はそのままにしておこう。
　また、設定項目はこれだけではない。興味がある人は[こちら](https://blog.louie.lu/2017/11/15/iota-iri-configuration-documentation/)のリストも確認しよう。

#サービス定義
IRIをサービスとして登録しておくことで今後の起動、停止、再起動、ステータス確認を容易にする。


```shell:[4]サービス定義をDL
cd /etc/systemd/system
wget -O iota.service https://raw.githubusercontent.com/abmushi/iota/master/qiita/fullnode/iota.service
```

ちなみにサービス定義の中身は以下の通り。今のところは変える必要はない。

```shell:iota.service
[Unit]
Description=IOTA node
After=network.target

[Service]
WorkingDirectory=/opt/iota
ExecStart=/usr/bin/java -XX:+DisableAttachMechanism -jar /opt/iota/IRI.jar -p 14625 -c /opt/iota/iri.ini
ExecReload=/bin/kill -HUP $MAINPID
KillMode=process
Restart=on-failure

[Install]
WantedBy=multi-user.target
Alias=iota.service
```

#起動してみよう
　もうこの時点でフルノード起動の準備は整っている。以下のコマンドを打ち込んでみよう。

```shell:[5]初回起動コマンド
systemctl daemon-reload && systemctl enable iota
systemctl start iota
pgrep java
```
一行目のコマンドの後、`Failed to execute operation: Invalid argument`というエラーが出るが気にしなくて良い。

```shell:[6]ステータス確認
journalctl -u iota -f
```
このコマンドでIRIの現在の状況を見ることができる。

```shell:Logが見れる。
-- Logs begin at Sat 2017-12-16 20:29:06 UTC. --
...java[5618]: 12/16 20:29:07.805 [main] INFO  com.iota.iri.network.Node - -> Adding neighbor : /88.99.249.250:41041
...java[5618]: 12/16 20:29:07.752 [Thread-2] INFO  c.i.i.n.r.ReplicatorSourcePool - TCP replicator is accepting connections on tcp port 15600
...java[5618]: 12/16 20:29:07.823 [pool-2-thread-1] INFO  com.iota.iri.network.Node - Spawning Broadcaster Thread
...java[5618]: 12/16 20:29:07.825 [pool-2-thread-2] INFO  com.iota.iri.network.Node - Spawning Tips Requester Thread
...java[5618]: 12/16 20:29:07.831 [pool-2-thread-3] INFO  com.iota.iri.network.Node - Spawning Neighbor DNS Refresher Thread
...java[5618]: 12/16 20:29:07.832 [pool-2-thread-3] INFO  com.iota.iri.network.Node - Checking Neighbors' Ip...
...java[5618]: 12/16 20:29:07.839 [pool-2-thread-4] INFO  com.iota.iri.network.Node - Spawning Process Received Data Thread
...java[5618]: 12/16 20:29:07.845 [pool-2-thread-2] INFO  com.iota.iri.network.Node - toProcess = 0 , toBroadcast = 0 , toRequest = 0 , toReply = 0 / totalTransactions = 0
...java[5618]: 12/16 20:29:07.853 [pool-2-thread-5] INFO  com.iota.iri.network.Node - Spawning Reply To Request Thread
...java[5618]: 12/16 20:29:08.305 [main] INFO  com.iota.iri.IRI - IOTA Node initialised correctly.
...java[5618]: 12/16 20:29:17.846 [pool-2-thread-2] INFO  com.iota.iri.network.Node - toProcess = 0 , toBroadcast = 0 , toRequest = 0 , toReply = 0 / totalTransactions = 0
```

##停止&再起動
```shell:停止コマンド
systemctl stop iota
```

```shell:再起動コマンド
systemctl daemon-reload && systemctl restart iota
```

#Neighbors
　IOTAのフルノードのP2Pネットワークは現在のところ、手動でピア（Neighbors）を追加しなければならない。そのためにまずピアを探す必要がある。ピアの出会いの場はIOTAの[公式Slack](http://slack.iota.org/)の**#nodesharing**チャンネルに設けられており、ここで流れているメッセージの主にDMを送るか、自分からメッセージを投稿して誰かからの返信を待つ必要がある。基本英語でのやりとりになるが、皆英語ネイティブでない人がほとんど（だと思う）なので何も怖がる必要はない。
（やはり、IOTA財団の所在するドイツ、と周辺のヨーロッパ諸国からの参加者が多い印象だ。）
　一応、**#nodesharing**チャンネルの中でどのようなメッセージがやりとりされているかを例として載せておくので、Slackにまだ入ってない人でもどんなものか分かるための助けになればと思う。

![chat_fullnode.png](https://qiita-image-store.s3.amazonaws.com/0/187795/27aa7cfd-20be-b564-e111-3e1954e4e08c.png)


　また、udpとtcpの好き嫌いがあるので、もしどちらかを指定されたらポート番号を間違えないように。それぞれのポート番号は上記**iri.ini**で指定されている。今回の例なら、udpは`udp://YOUR.IP.ADD.RESS:14600`、tcpは`tcp://YOUR.IP.ADD.RESS:15600`という風に相手に伝えればOK。

**2017年12月現在、合計5人ほどと接続できれば十分である。**

　自動でNeighborsを見つけて繋いでくれるフルノード[Nelson](https://github.com/SemkoDev/nelson.cli)も実験運用されている。興味がある人はこちらも見てみよう。
##Neighbors追加
　運よく双方同意の上でIPアドレスを交換することができた場合は、先方のIPをIRIに登録する必要がある。ここでAPIをlocalhostから呼び出す。

```shell:Neighbors追加のAPIリクエスト。
curl http://localhost:14265 \
  -X POST \
  -H 'Content-Type: application/json' \
  -H 'X-IOTA-API-Version: 1.4.1.6' \
  -d '{"command": "addNeighbors", "uris": ["udp://NEW.IP.ADD.RESS:14600"]}'
```

###注意事項
※IRIが起動してある状態で行う。
※IPとポート番号の部分は相手のものに変えて入力する。
※IPを複数追加する場合はコンマ「,」で区切る。また、ダブルクオート「"」で囲む。
※`X-IOTA-API-Version: 1.4.1.6`の部分はIRIのバージョンに変える。

このAPIリクエストで追加されたNeighborsは次回再起動した時には消えてしまう。それを防ぐために、**iri.ini**の`NEIGHBORS`にもIPアドレスを追加して上書き保存する。

```shell:iri.ini
[IRI]
PORT = 14265
UDP_RECEIVER_PORT = 14600
TCP_RECEIVER_PORT = 15600
NEIGHBORS = udp://94.156.128.15:14600 udp://88.99.249.250:41041 udp://NEW.IP.ADD.RESS:14600
IXI_DIR = ixi
HEADLESS = true
;API_HOST = 0.0.0.0
;REMOTE_AUTH = user:password
;REMOTE_LIMIT_API="removeNeighbors, addNeighbors, getNeighbors, interruptAttachingToTangle, attachToTangle"
;IRI_OPTIONS = "--remote"
```

###本当に繋がっているのかチェック
```shell:ポート番号は自分のを入れること。
tcpdump port 14600
```

```shell:このようなものが表示される。
...
08:12:48.922958 IP 相手1のIP.14600 > 自分のIP.14600: UDP, bad length 1650 > 1472
08:12:48.940135 IP 自分のIP.14600 > 相手1のIP.14600: UDP, length 1650
08:12:48.940678 IP 相手2のIP.12345 > 自分のIP.14600: UDP, length 1650
08:12:48.940813 IP 自分のIP.14600 > 相手2のIP..12345: UDP, length 1650
...
```

これを見て自分と相手で往復するようになっていれば繋がっていると考える。
##Neighbors削除

```shell:Neighbors削除のAPIリクエスト。
curl http://localhost:14265 \
  -X POST \
  -H 'Content-Type: application/json' \
  -H 'X-IOTA-API-Version: 1.4.1.6' \
  -d '{"command": "removeNeighbors", "uris": ["udp://BYE.IP.ADD.RESS:14600"]}'
```
削除する場合も**iri.ini**から該当IPアドレスを消しておく必要があるので忘れずに。


#ノードのメンテナンス
まず、IRIが動作しているかは先ほども紹介したこのコマンドで表示されるLogを見れば分かる。

```shell:ステータス確認
journalctl -u iota -f
```

##自分のノードは正常か？
自分のノード状態を確認するAPIリクエストはこちら。

```shell:getNodeInfoのAPIリクエスト。
curl http://localhost:14265 \
  -X POST \
  -H 'Content-Type: application/json' \
  -H 'X-IOTA-API-Version: 1.4.1.6' \
  -d '{"command": "getNodeInfo"}'
```
以下のようなレスポンスが返ってくる。返ってこない場合はIRIが起動していないので再起動してみること。

```shell:getNodeInfoのAPIレスポンスの例。
{
    "appName": "IRI",
    "appVersion": "1.0.8.nu",
    "duration": 1,
    "jreAvailableProcessors": 4,
    "jreFreeMemory": 91707424,
    "jreMaxMemory": 1908932608,
    "jreTotalMemory": 122683392,
    "latestMilestone": "VBVEUQYE99LFWHDZRFKTGFHYGDFEAMAEBGUBTTJRFKHCFBRTXFAJQ9XIUEZQCJOQTZNOOHKUQIKOY9999",
    "latestMilestoneIndex": 107,
    "latestSolidSubtangleMilestone": "VBVEUQYE99LFWHDZRFKTGFHYGDFEAMAEBGUBTTJRFKHCFBRTXFAJQ9XIUEZQCJOQTZNOOHKUQIKOY9999",
    "latestSolidSubtangleMilestoneIndex": 107,
    "neighbors": 2,
    "packetsQueueSize": 0,
    "time": 1477037811737,
    "tips": 3,
    "transactionsToRequest": 0
}
```
フルノードが正常に同期されている場合は以下の２つの条件が満たされる。
**①`latestMilestoneIndex`と`latestSolidSubtangleMilestoneIndex`のフィールドの数字が同じである。
②この数字がSlackの#botboxチャンネルで更新されるマイルストーン番号と一致している。**

```shell:良い例
...
"latestMilestoneIndex": 107,
...
"latestSolidSubtangleMilestoneIndex": 107,
```

※IRIを起動したての頃は同期に時間がかかる。その場合`latestMilestoneIndex`が243000と表示され変化しないが、時間が経てば（30分ほど）改善されるはずので待ってみよう。

###最新Tangleのダウンロードで高速同期
もし、Neighborとの同期を待てない。もしくは中々上手くいかない場合は最新データをダウンロードする手もある。`systemctl stop iota`で一旦IRIを一時停止してから、以下のコマンドを打ち込んでみよう。

```shell:4つのコマンドを同時実行
cd /tmp/ && curl -LO http://db.iota.partners/IOTA.partners-mainnetdb.tar.gz && sudo -u root tar xzfv /tmp/IOTA.partners-mainnetdb.tar.gz -C /opt/iota/mainnetdb && rm /tmp/IOTA.partners-mainnetdb.tar.gz
```

```shell:分解するとこうなっている
cd /tmp/
curl -LO http://db.iota.partners/IOTA.partners-mainnetdb.tar.gz
sudo -u root tar xzfv /tmp/IOTA.partners-mainnetdb.tar.gz -C /opt/iota/mainnetdb
rm /tmp/IOTA.partners-mainnetdb.tar.gz
```
　1行目、2行目で`/tmp/`に`http://db.iota.partners/IOTA.partners-mainnetdb.tar.gz`というファイルをダウンロードしている。このファイルは15分ごとに最新のTangleデータをアーカイブしたものだ。約8GBほどあるこのダウンロードには10分ほどかかるかもしれない。
　2行目で実際に`/opt/iota/mainnetdb`に上書きする。ここでも5分ほど時間がかかる。3行目はダウンロードしたファイルを削除しているだけだ。

##Neighborsは正常か？
Neighborsにも**良いもの(Good Neighbors)**、**悪いもの(Bad Neighbors)**がある。追加しているNeighborsの状態を確認するAPIリクエストはこちら。

```shell:getNeighborsのAPIリクエスト。
curl http://localhost:14265 \
  -X POST \
  -H 'Content-Type: application/json' \
  -H 'X-IOTA-API-Version: 1.4.1.6' \
  -d '{"command": "getNeighbors"}'
```
レスポンスは以下のようになる。

```shell:getNeighborsのAPIレスポンスの例。
{
    "duration": 37,
    "neighbors": [
        {
            "address": "/8.8.8.8:14265",
            "numberOfAllTransactions": 922,
            "numberOfInvalidTransactions": 0,
            "numberOfNewTransactions": 92
        },
        {
            "address": "/8.8.8.8:5000",
            "numberOfAllTransactions": 925,
            "numberOfInvalidTransactions": 0,
            "numberOfNewTransactions": 20
        }
    ]
}
```

### 良いNeighborsの条件
>1. `numberOfNewTransactions`が常に多く（2017年12月現在だと約1000~10万）送られてきている。
>2. `numberOfInvalidTransactions`がゼロ。

　`numberOfInvalidTransactions`は主にIRIのバージョンが相手と合っていないと発生する。自分のバージョン、相手のバージョンを確認しておこう。また、上記[最新Tangleのダウンロードで高速同期](https://qiita.com/ABmushi/items/6b8413c1fb510e716d58#%E6%9C%80%E6%96%B0tangle%E3%81%AE%E3%83%80%E3%82%A6%E3%83%B3%E3%83%AD%E3%83%BC%E3%83%89%E3%81%A7%E9%AB%98%E9%80%9F%E5%90%8C%E6%9C%9F)をすると改善される場合もある。

　もし、何日も条件が満たされない場合はNeighborさんに連絡してみる。もしくは削除しちゃってもよい。Bad Neighborsはネットワークの遅延に繋がるため、常に良いNeighborsと繋げているようにしよう。

## IRIのアップデート

```shell:アップデート
cd /opt/iota
wget -O IRI.jar https://github.com/iotaledger/iri/releases/download/v1.4.1.7/iri-1.4.1.7.jar
systemctl restart iota
```
ちなみに2018/01/21の最新版（1.4.1.7）のURLは
`https://github.com/iotaledger/iri/releases/download/v1.4.1.7/iri-1.4.1.7.jar`
となっている。上のコマンドの数字を新しいバージョンのと入れ替えれば良い。こまめに[公式リリース](https://github.com/iotaledger/iri/releases)を確認しておこう。
##フルノードに関する質問
　公式Slackの**#fullnodes**チャンネルにてチャット感覚でベテランに質問できる。最近fullnode運営が流行ってきており、その結果コミュニティの規模がでかくなり、質も上がってきているのでどんな質問も遠慮せず聞いてみよう。


#APIリクエスト
上記、`addNeighbors`のようにlocalhostへリクエストできるAPIはたくさんある。
公式APIドキュメントは[こちら](https://iota.readme.io/v1.2.0/reference#getnodeinfo)から。色々試してみよう。

　簡単な例として、今の自ノードの状態とNeighborの状態をいっぺんに受け取るコードを紹介する。

```python:status.py
import urllib2
import json

cmd1 = 'getNodeInfo'
cmd2 = 'getNeighbors'

command1 = {
    'command': cmd1
}

command2 = {
    'command': cmd2
}

stringified1 = json.dumps(command1)
stringified2 = json.dumps(command2)

headers = {
    'content-type': 'application/json',
}
local_url ="http://localhost:14265"

request1 = urllib2.Request(url=local_url, data=stringified1, headers=headers)
request2 = urllib2.Request(url=local_url, data=stringified2, headers=headers)

returnData1 = urllib2.urlopen(request1).read()
jsonData1 = json.loads(returnData1)

returnData2 = urllib2.urlopen(request2).read()
jsonData2 = json.loads(returnData2)

print '\n- IRI - "'+cmd1+'" - - - - - - - - - - - - - - - - - - - - - - - - - -'
for key1,val1 in jsonData1.items():
        print str(key1)+'       : '+str(val1)
print '\n- IRI - "'+cmd2+'" - - - - - - - - - - - - - - - - - - - - - - - - - -'
for key1,val1 in jsonData2.items():
        if key1 == 'neighbors':
                for each in val1:
                        print '- - - - - '+each['address']+' - - - - -'
                        for k,v in each.items():
                                if k != 'address':
                                        print str(k)+' :                '+str(v)
        else:
                print str(key1)+'       : '+str(val1)


```

```shell:上記コードをDLする。
cd /opt/iota
wget -O status.py https://raw.githubusercontent.com/abmushi/iota/master/qiita/fullnode/status.py
```

```shell:実行
python /opt/iota/status.py
```
　もし、Pythonがインストールされていない場合は`apt-get install python`で。

#リモートからAPIリクエスト（Python）
　今まではlocalhostからしかAPIリクエストが出来なかった。しかし、IOTAを本当に使い倒したいなら自分のフルノードに様々なデバイスからAPIリクエストを送りたいはずだ。そのために、まずは**iri.ini**に変更を加える必要がある。
　まず、先ほどのファイルからコメントを外す（;を取る）。

```shell:iri.ini
[IRI]
PORT = 14265
UDP_RECEIVER_PORT = 14600
TCP_RECEIVER_PORT = 15600
NEIGHBORS = udp://94.156.128.15:14600 udp://88.99.249.250:41041 udp://NEIB.IP.ADD.RESS:14600
IXI_DIR = ixi
HEADLESS = true
API_HOST = 0.0.0.0
REMOTE_AUTH = user:password
REMOTE_LIMIT_API="removeNeighbors, addNeighbors, getNeighbors, interruptAttachingToTangle, attachToTangle"
IRI_OPTIONS = "--remote"
```
　次に`REMOTE_AUTH`にユーザー名となるべく安全な長い強固なパスワードを設定する。INIファイルを更新して上書き保存したら、IRIを再起動しよう。
　`REMOTE_LIMIT_API`によって、リモートから受け付けるAPIリクエストを制限できる。上のファイルでも複数が制限されるように設定されているが、これは公式で推奨されているのをコピペしたものだ。必要に応じて変更を各々で加えてほしい。

　次に、フルノードに外からAPIリクエストを送るPythonプログラムを用意しよう。今回用意したのは以下のファイルである。

```py:iota.py
# -*- coding: utf-8 -*-
import urllib2
import json

#今回はgetNodeInfoをリクエストする。
cmd = 'getNodeInfo'

command = {
    'command': cmd
}

stringified = json.dumps(command)

headers = {
    'content-type': 'application/json',
    'X-IOTA-API-Version': '1.4.1.6'
}

#あなたのフルノードのIPアドレス
node_url = "http://YOUR.IP.ADD.RESS:14265"

request = urllib2.Request(url=node_url, data=stringified, headers=headers)

#先ほどiri.iniに加えたユーザー名とパスワード
username = 'user'
password = 'password'

p = urllib2.HTTPPasswordMgrWithDefaultRealm()
p.add_password(None, node_url, username, password)

handler = urllib2.HTTPBasicAuthHandler(p)
opener = urllib2.build_opener(handler)
urllib2.install_opener(opener)

returnData = urllib2.urlopen(request).read()

jsonData = json.loads(returnData)
print jsonData
```
　今回は`getNodeInfo`をリクエストしたが、もちろんウォレットに欠かせないその他リクエストも送信できる。
　また、[Python](https://github.com/iotaledger/iota.lib.py)以外にも[JavaScript](https://github.com/iotaledger/iota.lib.js)、[Java](https://github.com/iotaledger/iota.lib.java)、[Go](https://github.com/iotaledger/iota.lib.go)など多くの言語用にAPIが用意、開発されているので好きな環境で自分用のウォレットを作ることもできる。

#フルノード運用のインセンティブ
　IOTAのフルノードはマイナーではない。お金は儲からずむしろ減っていく一方だ。なので今のところ、フルノード運営者は技術的理解とロマンを求めてやっている人が多い。この記事も日本でそんな人が増えてほしい一心で執筆した。
　
　**そんなフルノードを運用するインセンティブは将来的にはどこで見いだせるのか。**

　IOTAは手数料無料である。しかし、それはあくまでもお客さん（送金者）目線の話である。IOTAプロトコルをインフラとして使ったサービスを提供する人や企業はフルノードを自社で運用するだろう。その場合そのフルノード管理にコストがかかる。
　Bitcoinではまずマイナーと言う完全に独立したインフラ維持装置がありそのコストはマイニングと手数料によってまかなわれている。
　それに対してIOTAは通貨性を土台にした上層のサービスをマネタイズできる参加者のネットワークで成り立っていくことになる。つまり、インフラ維持コストは商売でまかなわれる。
　具体的に「ガソリン支払いをIOTAで自動化する」という[学生プロジェクト](https://www.cryptocoinsnews.com/iota-based-student-project-places-second-porsche-innovation-contest/)で考えてみよう。もし、ガソリンスタンドが無人化して浮く人件費とVISAやGoogle Payなどの電子決済の手数料合計より、フルノード運用費が安ければガソリンスタンド会社はIOTAのネットワークにフルノードとして参加するかもしれない。
　もしかするとバックエンドでは手数料無料でもフロントエンドで手数料を徴収するIOTA銀行もありえるかもしれない。（なんとも本末転倒であるが）

　どんな形であれ、IOTAにまず興味を持ってくれる人が増えることを願っている。

#参考文献
公式フルノードガイド：[Headless node (full node)](http://iotasupport.com/knowledgebase_headless_node.shtml)
とても詳しいガイド：[IOTA Full Node Tutorial Linux](https://github.com/nuriel77/iri-playbook/wiki/IOTA-Full-Node-Tutorial---Linux)
CentOS用：[Configure IOTA (IRI) Full Headless Node on Centos 7](https://x-vps.com/blog/?p=111)
フルノードのコピペガイド：[IOTA FULL NODE COPY-PASTE
INSTALLATION GUIDE](http://iota.partners/index.html)
大まかな流れとサービス定義：[Setting up an IOTA node on Digital Ocean](https://knarz.github.io/notes/iota-node-do/)
リモート運用：[An almost complete guide to setting up a full IOTA node](https://medium.com/@scott.tudd/an-almost-complete-guide-to-setting-up-a-full-iota-node-d9784dfdc80)
自動ピア追加機能付き最新フルノード環境：[IOTA Nelson ready for public preview](https://medium.com/deviota/iota-nelson-ready-for-public-preview-a958c6d0a531)
その他：[Deploy IOTA IRI (IOTA Refernce Implementation) full node on Arch Linux](https://blog.louie.lu/2017/10/22/configure-deploy-iota-iri-full-node-on-archlinux/)





　「このとおりやっても上手くいかなかった。」など記事内の間違いや訂正箇所。「これについて書いて！」といった追記希望があった場合はコメント欄、もしくはTwitter、IOTA公式Slackまで連絡いただけるととても嬉しい。

今後の予定：スナップショット対応、APIガイド、送金トランザクション生成、MAM。について記事を追記もしくはゼロから書きたい。