CosmosSDKとTendermintについて

#はじめに
ERCの規格など様々な規格を用いて、多種のトークンが発行されるようになり、複数のプラットフォームのトークンをいかに流動的に扱うか？というのが次の課題となっています。
KyberNetworkなどを用いたERC相互のexchange手法もその一つですが、KyberNetworkはEthereumを基盤とした環境で、なおかつERC準拠の規格で統一される必要性がありますが、クロスチェーンプロトコルを用いて、複数の基盤をシームレスに接続するという方法があります。

#Cosmos-SDKとは
複数通貨にまたがった、ブロックチェーンを作るためのframeworkで「Internet of Blockchain」を提唱しておりインターネットのように誰もがブロックチェーンの開発に参加することを目標としています。(ブロックチェーンのスケーラビリティ問題や相互運用性を解決する分散型プラットフォームでクロスチェーンプロトコルと呼ばれる)。
Cosmosネットワークでは以下のように2種類のブロックチェーン（ハブ(Hub)とゾーン(Zone)）があります。
下図のようにハブを中心としてさまざまなゾーンが接続することで、それぞれのゾーンの間におけるトークンの移動が簡単に行える仕組みです。

![alt](https://i2.wp.com/zoom-blc.com/wp-content/uploads/2018/01/cosmos2-e1515391545238.png?zoom=2&resize=700%2C505&ssl=1)

#Tendermint
Tendermintとは、ブロックチェーンネットワークなど分散ネットワークにおいて不正を防止するソフトウェアです。
ブロックチェーンネットワークをスケーラブルにし、分散型アプリケーションの開発も容易にすることを目指しています。
Cosmosネットワークは全てTendermintを基盤としており、COSMOSハブと全てのゾーンのブロックチェーンはTendermintを利用します。
ファイナリティのある同じTendermintのコンセンサスアルゴリズムをベースとすることで、異なるブロックチェーン間でのトークン移動を可能にしています。

#TendermintCore & ABCI
Tendermintは、Tendermint CoreとABCI(Application Blockchain Interface)の2つの構成要素で作られています。


Tendermint Core：コンセンサスアルゴリズム(PoS)を提供
ABCI：あらゆるプログラミング言語で処理できるようにするインターフェース

```
+---------------------+
|                     |
|     Application     |
|                     |
+--------+---+--------+
         ^   |
         |   | ABCI
         |   v
+--------+---+--------+
|                     |
|                     |
|     Tendermint      |
|                     |
|                     |
+---------------------+
```

(Tendermintの詳細）
https://tendermint.readthedocs.io/en/master/index.html

#Cosmosのtoken (Atom & Photon)
Cosmosハブには、AtomとPhotonという2種類のネイティブトークンが存在します。
Atom：PoSでの賭け金に利用
Photon：トランザクション手数料を支払う

CosmosハブではPoSでコンセンサスが採用されており、
バリデーターがデポジットするお金はAtomトークンで支払われます。
ユーザーが送金するときなどに発生するトランザクション手数料はPhotonトークンで支払われます。

#Loom(PlasmaChain)など他の環境との相互互換性
PlasmaChainとCosmosハブの連携などが発表されており、今後注目が集まっています。
https://medium.com/loom-network-japanese/loom-cosmos-87193e24819


#チュートリアルやってみる
https://cosmos.network/docs/tutorial/
https://github.com/cosmos/sdk-application-tutorial/blob/master/tutorial/build-run.md

(参考)Building and running the application
https://cosmos.network/docs/tutorial/build-run.html#building-the-nameservice-application

#構成
チュートリアルは下記構成になっています。



```app.go
bam "github.com/cosmos/cosmos-sdk/baseapp"
type nameServiceApp struct {
    *bam.BaseApp
```

```handler.go
func handleMsgSetName(ctx sdk.Context, keeper Keeper, msg MsgSetName) sdk.Result {
    if !msg.Owner.Equals(keeper.GetOwner(ctx, msg.Name)) { // Checks if the the msg sender is the same as the current owner
        return sdk.ErrUnauthorized("Incorrect Owner").Result() // If not, throw an error
    }
    keeper.SetName(ctx, msg.Name, msg.Value) // If so, set the name to the value specified in the msg.
    return sdk.Result{}                        // return
}
```

```keeper.go
 {
    coinKeeper bank.Keeper
    namesStoreKey  sdk.StoreKey // Unexposed key to access name store from sdk.Context
    ownersStoreKey sdk.StoreKey // Unexposed key to access owners store from sdk.Context
    pricesStoreKey sdk.StoreKey // Unexposed key to access prices store from sdk.Context

    cdc *codec.Codec // The wire codec for binary encoding/decoding.
}
```


```msgs.go
type MsgSetName struct {
    Name string
    Value  string
    Owner  sdk.AccAddress
}
```

```querier.go

 NewQuerier(keeper Keeper) sdk.Querier {
    return func(ctx sdk.Context, path []string, req abci.RequestQuery) (res []byte, err sdk.Error) {
        switch path[0] {
        case QueryResolve:
            return queryResolve(ctx, path[1:], req, keeper)
        case QueryWhois:
            return queryWhois(ctx, path[1:], req, keeper)
        default:
            return nil, sdk.ErrUnknownRequest("unknown nameservice query endpoint")
        }
    }
}
```

```codec.go
// RegisterCodec registers concrete types on the Amino codec
func RegisterCodec(cdc *codec.Codec) {
    cdc.RegisterConcrete(MsgSetName{}, "nameservice/SetName", nil)
    cdc.RegisterConcrete(MsgBuyName{}, "nameservice/BuyName", nil)
}
```


#インストール&チュートリアル実行

```

//goのインストール
$ brew install goenv
$ goenv --version

$ vim .bash_profile

export PATH="$HOME/.goenv/bin:$PATH"
eval "$(goenv init -)"

$ source .bash_profile
$ goenv install -l
$ goenv install 1.11.0
$ goenv global 1.11.0
$ go version

//depのインストール
$brew install dep

//cosmosのディレクトリにコードをcloneする
$ mkdir -p $GOPATH/src/github.com
$ mkdir cosmos && cd cosmos
$ git clone https://github.com/cosmos/sdk-application-tutorial.git
$ cd sdk-application-tutorial

//envでGOBINを確認
$go env
$export GOBIN=$(pwd)/bin
$export GOPATH="/Users/<user_name>/go/"
$export GOBIN=/Users/<user_name>/go/bin/

>>フォルダ構成
/Users/<user_name>/go/src/github.com/cosmos/sdk-application-tutorial

//インストール
$ make get_vendor_deps && make install
get_vendor_deps....appの依存関係
make install ....nsdとnscliをinstall
(ここではGOBINにインストールされるので、必ずGOBINにパスを通しておく）
$ /Users/<user_name>/go/bin/nsd help
$ /Users/<user_name>/go/bin/nscli help

//チェーンを初期化する
$ nsd init --chain-id testchain
Initialized nsd configuration and bootstrapping files in /Users/<user_name>/.nsd...

//キー(jack)を作成する
$ nscli keys add jack
Enter a passphrase to encrypt your key to disk:
Repeat the passphrase:

NAME: TYPE: ADDRESS:            PUBKEY:
jack  local cosmos1rs46rzfda2vl9ul2jc6pnlhsfrfmtref7x08yf cosmospub1addwnpepqds5vaas9zue8stcmggl57f6rrggk7047ql0h5yezwhnjthx6vu2yzsxvjr

//キー(alice)を作成する
$ nscli keys add alice
Enter a passphrase to encrypt your key to disk:
Repeat the passphrase:

NAME: TYPE: ADDRESS:            PUBKEY:
alice local cosmos1x46e67smaca802u6yp09qrhzw9rdj7cv7txn6d cosmospub1addwnpepqfnx063jxp27626t0kx56km37q29lrkg4q9ecnmk2w0a3m9kvwsncw6u6zj

//アカウントを作成する
$ nsd add-genesis-account $(nscli keys show jack --address) 1000mycoin,1000jackcoin
$ nsd add-genesis-account $(nscli keys show alice --address) 1000mycoin,1000alicecoin

//開始する
$ nsd start
I[2019-04-02|15:42:01.812] Starting ABCI with Tendermint                module=main 
E[2019-04-02|15:42:01.833] Couldn't connect to any seeds                module=p2p 
I[2019-04-02|15:42:06.845] Executed block                               module=state height=1 validTxs=0 invalidTxs=0
I[2019-04-02|15:42:06.846] Committed state                              module=state height=1 txs=0 appHash=8F8F4EF9A1FD404D0BC5462E03D1D6A6D600143FE9DCFF24A3B1B2A7AD1C0F11

$nscli query account $(nscli keys show jack --address) --indent --chain-id testchain

```



#参考
Getting Started
https://cosmos.network/docs/tutorial/#requirements

Announcing Loom PlasmaChain Interoperability with Cosmos Hub
https://medium.com/loom-network/announcing-loom-plasmachain-interoperability-with-cosmos-hub-24b4e236baf2?__s=aw9irfuurmzxvb1fbgiv
https://medium.com/loom-network/announcing-loom-plasmachain-interoperability-with-cosmos-hub-24b4e236baf2

What is Tendermint Core? The Most Comprehensive Guide Ever
https://blockgeeks.com/guides/tendermint/