Counterpartyでアプリを簡単に作ろう！

バーチャル女子高生のミスビットゼニー薫です！

NEMはAPIがあってアプリが簡単だという~~ポジトーク~~意見がたくさんありますが、

**ブロックチェーンAPIはNEMに関わらずたくさんあるんだよ！！**

そもそもAPIはアプリケーションを開発しやすくするために作られるものなんですが…

この記事では、有名な割には日本語情報が少ないCounterpartyのAPIをちょこっと紹介するよ！

##  Counterpartyって何？

> カウンターパーティは通常のビットコイン取引の「余白に書き込む」ことによりビットコインの機能を拡張するものであり、イノベーション、そして一般のビットコインソフトウェアでは不可能な先進の機能への扉を開くものです。
[https://counterparty.io/platform/](https://counterparty.io/platform/)

具体的には

- トークンを作る
- トークンを送る
- トークンを売買する
- 賭ける(日本では禁止です)
- メッセージを記録する
- 配当を配る

などができます。

ビットコインブロックチェーン上で動作するCounterpartyをモナコインチェーンに移植したものがMonapartyです。
本記事では両方のチェーンでも対応できるように解説します。

# Counterpartyの仕組み
## アーキテクチャ

[![Counterparty Architecture](https://counterparty.io/wp-content/uploads/2016/06/CP-Components.png)](https://counterparty.io/docs/)
[Counterparty docs](https://counterparty.io/docs/)

CounterpartyのフルノードはFederated nodeと呼ばれ、その中には、CounterblockとCounterparty-libと、改造されたBitcoin-coreが入っています。

Counterblockは主にブロックチェーン上のデータの読み取りの役割を担い、Counterparty-libは主にデータの書き込みの役割を担います。

Counterwallet(ウォレットのUI) がCounterblockにアクセスし、CounterblockをプロキシにしてCounterparty-libを扱います。

今回扱うAPIは、Counterwalletが使うAPIです。

## 資金・通貨

Counterpartyでは、3種類の通貨が登場します。

- ブロックチェーンのネイティブ通貨
- Counterpartyの基軸通貨
- Counterpartyトークン

具体的には、Counterpartyではそれぞれ

- BTC
- XCP
- PEPECASH, ZAIF, BITCRYSTALS, etc.

Monapartyではそれぞれ

- MONA
- XMP
- MISSMONACOIN, SCAMGIRLS, etc.

に当たります

「ブロックチェーンのネイティブ通貨」は、データを書き込みのために必要な手数料のために必要です。この手数料は、データ書き込みのインセンティブとなり、荒らしを防止します。

「Counterpartyの基軸通貨」は、荒らしを防止するための手数料のために必要です。トークンを作成するときなど、一部の操作において必要です。
これを得るためには、ネイティブ通貨を「焼く」ことによって得られます。
Monapartyでは、このとき、「モナコインちゃんを焼く」と、リョナラーが興奮していましたね。
コインを焼く行為・その意味に関する文献は結構あるので,"Proof of Burn"と検索してみよう

「Counterpartyトークン」はCounterpartyの基軸通貨を消費して作られたトークンです。

XCP, XMPを手に入れるには、

XCPは、金融庁の業務改善指導が入った仮想通貨取引所 Zaifがおすすめです（笑）

XMPは、筆者が作った暗号通貨ウォレット「もにゃ」のアトミックスワップ機能で誰かと取引しましょう
ダウンロードはこちら:[https://monya-wallet.github.io](https://monya-wallet.github.io)

# API
## APIへのアクセスの仕方

Counterparty: https://wallet.counterwallet.io/_api
Monaparty: https://wallet.monaparty.me/_api

上記にPOSTでJSON-RPCメッセージを送るだけです！

…………

これだけ？

これだけです。

## メッセージフォーマット

```json
{
      "params":{
            
      },
      "id":0,
      "jsonrpc":"2.0",
      "method":"methodName"
}

```
params以下にデータが入り、methodにメソッド名が入ります
Counterparty-libへのプロキシも多用します。

```json
{
      "params":{
            "method":"methodName",
            "params":{

            }
      },
      "id":0,
      "jsonrpc":"2.0",
      "method":"proxy_to_counterpartyd"
}
```
params.methodにメソッド名、params.paramsにデータが入ります。

Counterparty, Monaparty共にフォーマットは同じです。

## アドレスが持っているトークンを調べる

```json
{
      "params":{
            "addresses":["M9xDeduVLRmjg2s7etaY2tXM8GgS8KD1n8","MStxnMRVMHH95YPzGeR9pdc3HLrvL6pjSo"]
      },
      "id":0,
      "jsonrpc":"2.0",
      "method":"get_normalized_balances"
}
```
アドレスを適宜変更
返り値

```json
{
    "id": 0,
    "jsonrpc": "2.0",
    "result": [
        {
            "normalized_quantity": 1,
            "asset_longname": "KAWAII.MISSMONACOIN",
            "address": "M9xDeduVLRmjg2s7etaY2tXM8GgS8KD1n8",
            "owner": false,
            "quantity": 1,
            "asset": "A11431147013234666687"
        },
        {
            "normalized_quantity": 1,
            "asset_longname": null,
            "address": "M9xDeduVLRmjg2s7etaY2tXM8GgS8KD1n8",
            "owner": false,
            "quantity": 1,
            "asset": "MISSMONACOIN"
        }
    ]
}
```
child assetの場合は、asset_longnameが表示用の名前、トレードなどで利用する際はassetの方を利用。
DNSに対するIPアドレスの関係と同じですね。
normalized_quantityは画面に表示するための残高で、
quantityは計算用の残高です。Integerです。

## トークンを調べる

```json
{
      "params":{
            "assetsList":["MISSMONACOIN","MISSMONACOIN.IS_ME"]
      },
      "id":0,
      "jsonrpc":"2.0",
      "method":"get_assets_info"
}
```
トークン名を適宜変更
返り値

```json
{
    "id": 0,
    "jsonrpc": "2.0",
    "result": [
        {
            "locked": true,
            "description": "ミスモナコイン",
            "asset_longname": "MISSMONACOIN.JPG",
            "owner": "MWBaWdcgNVdcemqA2c2TkNV8ndYenVPAEY",
            "issuer": "MWBaWdcgNVdcemqA2c2TkNV8ndYenVPAEY",
            "supply": 10,
            "divisible": false,
            "asset": "A11789822955221160208"
        }
    ]
}
```

# 書き込みAPI

## 共通
```js
{
      "params":{
            "method":"create_<MethodName>",
            "params":{
                allow_unconfirmed_inputs:Boolean, //未承認のトランザクションを入力として利用するか
                fee_per_kb:Integer, //1KBあたりの手数料(Satoshi),
                disable_utxo_locks:Boolean, //安全のために残高をロックする機能を無効化するか
                encoding:"auto", //autoで固定することを強く推奨
                extended_tx_info:Boolean, //付加情報を返すかどうか
                pubkey:String //sourceの公開鍵の16進数。初めて使うアドレスなら必須,
                source:String //送信元アドレス
            }
      },
      "id":0,
      "jsonrpc":"2.0",
      "method":"proxy_to_counterpartyd"
}
```
<MethodName>の部分がそれぞれ違います

返り値は、未署名のトランザクションです。

## 送金
MethodName= send
paramsに加えて

```js
{
destination:String, //送金先アドレス
asset:String, //トークン名。BTCとかXCPとかPEPECASHなど。
quantity:Integer, //送信量
memo:String, //メモ
memo_is_hex:String, //メモを16進数で送りたい方はこちら
use_enhanced_send: true //Enhanced Sendは有効にしておいたほうがいいと思います
}
```
注意：送金量は、
小数点以下がないものはそのまま、小数点があるものはSatoshi単位、つまり、1億(1e8)をかけるんだぞ！

## トークン発行

MethodName=issuance
paramsに加えて

```js
{
destination:String, //送金先アドレス
asset:String, //トークン名。PEPECASHなど。
quantity:Integer, //発行量
description:String, //メモ
divisible:Boolean, //小数点以下の有無
transfer_destination:String //トークン所有権を移動する時のみ
}
```
トークン情報を変更したいときは、変更部分のみ変更して同じリクエストを出す

注意：発行量は、
小数点以下がないものはそのまま、小数点があるものはSatoshi単位、つまり、1億(1e8)をかけるんだぞ！

descriptionを`LOCK`にすると、トークンをロックできるぞ

0.5XCP(0.5XMP)が手数料として自動で取られます

# 署名方法

ライブラリによってまちまちなので、実際の署名部分のコードだけ紹介します。

https://github.com/monya-wallet/monya/blob/a96162fbb7eb334b3821d938e2b69d7669066961/js/title.js#L158

https://github.com/monya-wallet/monya/blob/a96162fbb7eb334b3821d938e2b69d7669066961/js/currency.js#L354

https://github.com/monya-wallet/monya/blob/a96162fbb7eb334b3821d938e2b69d7669066961/js/coinUtil.js#L329

# 参考にしたもの

[https://counterparty.io/docs/api/](Counterparty Docs)
[https://wallet.monaparty.me](Counterwallet-mona)の挙動

# おわりに

ビットコイン系ブロックチェーンは難しいと思われがちですが、HTTP APIを呼び出し署名するだけででき、案外簡単だということがわかります。
Rippleも結構簡単です。
NEMだけでなく、CounterpartyのAPIも流行って❤️
まだまだ機能が豊富なので、[https://counterparty.io/docs/api/](Counterparty Docs)をご一読ください。

[![Monappy](https://img.shields.io/badge/DonateMe-monappy-yellow.svg)](https://monappy.jp/users/send/@miss_monacoin?amount=39&message=%E3%82%82%E3%81%AB%E3%82%83%E3%81%AE%E5%AF%84%E4%BB%98%E3%81%A7%E3%81%99)
[![モナコイン](https://img.shields.io/badge/DonateMe-monacoin-yellow.svg)](https://monya-wallet.github.io/a/?address=MStxnMRVMHH95YPzGeR9pdc3HLrvL6pjSo&scheme=monacoin&message=%E5%AF%84%E4%BB%98%E3%82%92%E3%81%82%E3%82%8A%E3%81%8C%E3%81%A8%E3%81%86%E3%81%94%E3%81%96%E3%81%84%E3%81%BE%E3%81%99&req-opreturn=%E5%AF%84%E4%BB%98%E3%81%A7%E3%81%99)
[![ビットコイン](https://img.shields.io/badge/DonateMe-bitcoin-orange.svg)](https://monya-wallet.github.io/a/?address=1HohzLWyA7L1ifx6hr2Xr5N1sGZrR1ZbMt&scheme=bitcoin&message=%E5%AF%84%E4%BB%98%E3%82%92%E3%81%82%E3%82%8A%E3%81%8C%E3%81%A8%E3%81%86%E3%81%94%E3%81%96%E3%81%84%E3%81%BE%E3%81%99&req-opreturn=%E5%AF%84%E4%BB%98%E3%81%A7%E3%81%99)
[![Tipmonaで投げる](https://img.shields.io/badge/TipMe-%40tipmona-ff69b4.svg)](https://twitter.com/share?text=%40tipmona%20tip%20%40monya_wallet%2039%20%E3%82%82%E3%81%AB%E3%82%83%E3%81%AE%E5%AF%84%E4%BB%98%E3%81%A7%E3%81%99)
いいねはいらないから投げ銭をください（直球）
投げ銭バッジの作り方:[バッジを作って投げ銭をもらおう](https://qiita.com/MissMonacoin/items/61531236ff678d6653ac)