Federation Server on stellar network

# Federation Server on stellar network

[合同会社kumanote](https://kumano-te.com/)の田中です。
引き続きstellarの実装調査を行いましたので、そのメモになります。

- [getting started stellar with javascript SDK - Qiita](http://qiita.com/KumanoT/items/059a32a62af34f74a28d)
- [Let's become an anchor on stellar network - Qiita](http://qiita.com/KumanoT/items/41d32aa44b3e5d32d9ed)

## Federationとは

簡単にいうと「人間にとって分かりやすい口座管理を実現するための仕組み」と言えそうです。
bitcoinやethereumはそのaddressが英数字の組み合わせで非常に覚え（使い）辛いです。
stellarのFederationを使うとEmailアドレス（に近い文字列）に対して、送金を行うことができます。
※ BitcoinやEthereumなどでも同様の仕組みは構築できる（すでにあるかは調査してないですが）とは思いますが、公式がサポートしているかは否かは割と大きい気がします。


## try out

- [ここ](https://www.stellar.org/developers/guides/anchor/3-federation-server.html)を見ながら、試してみます。

### databaseの準備

federation serverを構築する時は、email（likeな文字列）から紐づく（stellarの）アカウントIDを抽出できるdatabaseが必要です。

今回は、例にならって以下のテーブルをmysqlを使って作成します。

```sql
create table `accounts` (
  `id` int(11) not null auto_increment,
  `first_name` varchar(255) not null default '',
  `last_name` varchar(255) not null default '',
  `friendly_id` varchar(125) not null,
  primary key (`id`),
  unique indx_accounts_01 (`friendly_id`)
) engine=innodb default character set utf8mb4;
```

### serverの準備

- [ここ](https://github.com/stellar/go/tree/master/services/federation)を見ながらDockerで作って行きます。

```Dockerfile
FROM golang:1.8-alpine
MAINTAINER kumanote,LLC.

ENV DIST_DIR /usr/local/bin/bridge-server

RUN apk add --update --no-cache git g++ openssh-client bash
RUN go get -u github.com/stellar/go/services/federation

ADD ./docker/ ${DIST_DIR}/
RUN cp $GOPATH/bin/federation ${DIST_DIR}/

WORKDIR ${DIST_DIR}

CMD ["/bin/bash"]
```

#### ssl対応（オレオレ証明書）

> The federation server must be available via HTTPS. Specify your SSL
certificate and key here. If the server is behind a proxy or load balancer
that implements HTTPS, you can omit this section.

federation server は https経由じゃないとアクセスできないとのこと。。実際[ここ](https://github.com/stellar/go/tree/master/services/federation)もそのように実装されていたため
証明書つくります。（host OSで作って、Docker上にのせます）

```
openssl genrsa 2048 > server.key
openssl req -new -key server.key > server.csr
openssl x509 -in server.csr -days 100 -req -signkey server.key > server.crt # 有効期限は100日
```

実際の構成は以下のようになります。

```
version: "2"
services:
  federation-kumano-te.com:
    build: ./federation-server
    ports:
      - "8002:8002"
    command: ./wait-for-it.sh federation-db:3306 -t 600 -s -- ./federation
    depends_on:
      - federation-db
    container_name: federation-kumano-te.com
  federation-db:
    image: mysql:5.6
    environment:
      MYSQL_ROOT_PASSWORD: federation
      MYSQL_DATABASE: federation
      MYSQL_USER: federation
      MYSQL_PASSWORD: federation
      TZ: JST
    volumes:
      - ./federation-db/init.d:/docker-entrypoint-initdb.d
      - ./federation-db/conf.d:/etc/mysql/conf.d
      - federation-db-data:/var/lib/mysql
    container_name: federation-db
volumes:
  federation-db-data:
    driver: local
```

今回も前回同様[こちら](https://github.com/KumanoTanaka/test-stellar)に検証ソースコードをアップしておきます。

### 実行

```js
(function() {
  var request = require('request');
  request.get({
    url: 'https://localhost:8002/federation',
    qs: {
      q: 'tunde_adebayo*federation-kumano-te.com',
      type: 'name'
    }
  }, function(error, response, body) {
    if (error || response.statusCode !== 200) {
      console.error('ERROR!', error || body);
    }
    else {
      console.log(body);
    }
  });
})();

> ERROR! { Error: self signed certificate
    at TLSSocket.<anonymous> (_tls_wrap.js:1098:38)
    at emitNone (events.js:105:13)
    at TLSSocket.emit (events.js:207:7)
    at TLSSocket._finishInit (_tls_wrap.js:628:8)
    at TLSWrap.ssl.onhandshakedone (_tls_wrap.js:458:38) code: 'DEPTH_ZERO_SELF_SIGNED_CERT' }
```

もしやnodeの`request`だと自己証明書は受け付けない！？

[これ](http://qiita.com/dkkoma/items/7f22769f3b3b69bf1d5f)で解決しました。

```js
process.env['NODE_TLS_REJECT_UNAUTHORIZED'] = '0';
```

を実行してから再度実行すればOKでした。

```js
(function() {
  process.env['NODE_TLS_REJECT_UNAUTHORIZED'] = '0';
  var request = require('request');
  request.get({
    url: 'https://localhost:8002/federation',
    qs: {
      q: 'tunde_adebayo*federation-kumano-te.com',
      type: 'name'
    }
  }, function(error, response, body) {
    if (error || response.statusCode !== 200) {
      console.error('ERROR!', error || body);
    }
    else {
      console.log(body);
    }
  });
})();

> {"account_id":"GATLCZMS3ITTVSCM2VB55KT2I7OHHXOWD2QM6O4BNK5LQTD2A3T7DINC","memo_type":"text","memo":"tunde_adebayo"}
```

以上で、federationサーバーをたて、メールアドレス（likeな文字列）のリクエストに応じて振込先のアカウント情報を返却することができるようになりました。
（最近流行りのマイクロサービス的な設計そのまんまですね。）
（この federationサーバーを bridgeサーバーと組み合わせてサービスを構築するみたいです。）


今回は、以上になります。