Coluとは
ColuはBitcoinのブロックチェーン上で トークンを発行、送信することができるplatformです。
カラードコイン(Colored Coin)プロトコルを利用しており、Coluが提供するAPIやSDKを使ってチケットやコインなどの所有権の管理をすることがでます。
では実際にtokenを発行、送信していきます。
公式サイト
http://documentation.colu.co/
環境構築
Colu SDKとColu APIを使う2つの方法がありますが、この記事ではColu APIを使う方法で実装していきたいと思います。
testnetとmainnetがありますが、今回はtestnetを使用します。mainnetを使用する際にはAPI keyが必要です。
Colu Serverを立ち上げて、そこにJSON-RPCでAPIアクセスすることでColu APIを使用することができます。
では、Go言語を使ってAPIアクセスします。
まずはColu Serverを立ち上げます。
Install & Run Colu Server
npm i -g colu
defaultではportが80になっているので、localで適宜portを変えましょう
export COLU_SDK_RPC_SERVER_HTTP_PORT=8081
Colu serverを起動します。
colu
PrivateSeedの取得
resp, err := http.Post("http://localhost:8081", "application/json",
bytes.NewBufferString(`{
"jsonrpc": "2.0",
"method": "hdwallet.getPrivateSeed",
"id": "1"
}`))
defer resp.Body.Close()
b, err := ioutil.ReadAll(resp.Body)
fmt.Println(string(b))
response
{
"jsonrpc": "2.0",
"id": "1",
"result": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
}
resultのvalue部分がprivateSeedになります。
privateSeedがわかると色々とできてしまうので、自分でしっかり管理しましょう。
privateSeedの設定
先ほどのprivateSeedをColu Serverに設定します。
export COLU_SDK_PRIVATE_SEED=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Colu APIアクセス
実際にトークンの発行、送信をしていきます。
アドレスの作成
まずは送信用と受信用の二つのaddressを作成します。
resp, err := http.Post("http://localhost:8081", "application/json",
bytes.NewBufferString(`{
"jsonrpc": "2.0",
"method": "hdwallet.getAddress",
"id": "1"
}`))
defer resp.Body.Close()
b, err := ioutil.ReadAll(resp.Body)
fmt.Println(string(b))
response
{
"jsonrpc": "2.0",
"id": "1",
"result": "mh6YCgTLk3b1c7ZJYeYBPsFMUnbAh55wBM"
}
{
"jsonrpc": "2.0",
"id": "1",
"result": "n3wj1zjYExb963krQbLiSrs9dhrxxpqm9A"
}
トークンの発行
次にトークンを発行します。
TakuCoinを100枚発行して、先ほどのmh6YCgTLk3b1c7ZJYeYBPsFMUnbAh55wBMに送ります。
resp, err := http.Post("http://localhost:8081", "application/json",
bytes.NewBufferString(`{
"jsonrpc": "2.0",
"method": "issueAsset",
"id": "1",
"params": {
"amount": 100,
"issueAddress": "mh6YCgTLk3b1c7ZJYeYBPsFMUnbAh55wBM",
"divisibility": 0,
"reissueable": false,
"transfer": [
{
"amount":100,
"address": "mh6YCgTLk3b1c7ZJYeYBPsFMUnbAh55wBM"
}
],
"metadata": {
"assetName": "takuCoin"
}
}
}`))
defer resp.Body.Close()
b, err := ioutil.ReadAll(resp.Body)
fmt.Println(string(b))
response
{
"jsonrpc": "2.0",
"id": "1",
"result": {
"txHex": "0100000001bf4a0c5aad8c52e8bf7c3739d0de747d8306b4307176f074c63164133ff9923b000000001976a9141152282ec857755e1f1b4ab7728b048db90d32a388acffffffff0358020000000000001976a9141152282ec857755e1f1b4ab7728b048db90d32a388ac0000000000000000406a3e43430201cbb17f1b6f4f12e25f89a896eec3cbe933248387ebd3821bcc45c6af5a82657a48aef028431a6178d7bcaa812a5b26d89e2bd9e120120020121058020000000000001976a9141152282ec857755e1f1b4ab7728b048db90d32a388ac00000000",
"assetId": "La6gS5BPnMhcdzh3xpCmbCRZ52AxQvKhiXYo7t",
"coloredOutputIndexes": [
0
],
"financeTxid": "3b92f93f136431c674f0767130b406837d74ded039377cbfe8528cad5a0c4abf",
"txid": "4517c3ed82134b88ab70123226b6faf9f214a0b29bf171ac3fecc2c14353608c",
"receivingAddresses": [
{
"address": "mh6YCgTLk3b1c7ZJYeYBPsFMUnbAh55wBM",
"amount": 100
}
],
"issueAddress": "mh6YCgTLk3b1c7ZJYeYBPsFMUnbAh55wBM"
}
}
これでtakuCoinが100枚発行されました。
この段階では、mh6YCgTLk3b1c7ZJYeYBPsFMUnbAh55wBMが100枚持っています。
トークン情報の確認
先ほど発行されたトークンの情報を確認します。
resp, err := http.Post("http://localhost:8081", "application/json",
bytes.NewBufferString(`{
"jsonrpc": "2.0",
"method": "coloredCoins.getAssetData",
"id": "1",
"params": {
"assetId": "La6gS5BPnMhcdzh3xpCmbCRZ52AxQvKhiXYo7t"
}
}`))
defer resp.Body.Close()
b, err := ioutil.ReadAll(resp.Body)
fmt.Println(string(b))
response
{
"jsonrpc": "2.0",
"id": "1",
"result": {
"assetId": "La6gS5BPnMhcdzh3xpCmbCRZ52AxQvKhiXYo7t",
"assetAmount": 100,
"assetTotalAmount": 100,
"assetData": [
{
"address": "mh6YCgTLk3b1c7ZJYeYBPsFMUnbAh55wBM",
"amount": 100,
"utxo": "4517c3ed82134b88ab70123226b6faf9f214a0b29bf171ac3fecc2c14353608c:0",
"metadata": {
"assetId": "La6gS5BPnMhcdzh3xpCmbCRZ52AxQvKhiXYo7t",
"divisibility": 0,
"lockStatus": true,
"aggregationPolicy": "aggregatable",
"someUtxo": "4517c3ed82134b88ab70123226b6faf9f214a0b29bf171ac3fecc2c14353608c:0",
"numOfHolders": 1,
"totalSupply": 100,
"numOfTransfers": 0,
"numOfIssuance": 1,
"numOfBurns": 0,
"firstBlock": 1085719,
"issuanceTxid": "4517c3ed82134b88ab70123226b6faf9f214a0b29bf171ac3fecc2c14353608c",
"issueAddress": "mh6YCgTLk3b1c7ZJYeYBPsFMUnbAh55wBM",
"metadataOfIssuence": {
"data": {
"assetName": "takuCoin"
}
},
"sha2Issue": "ebd3821bcc45c6af5a82657a48aef028431a6178d7bcaa812a5b26d89e2bd9e1"
}
}
]
}
}
トークンの送信
次に作成したtakuCoinを20個もう一つのアドレス(n3wj1zjYExb963krQbLiSrs9dhrxxpqm9A)に送信します。
resp, err := http.Post("http://localhost:8081", "application/json",
bytes.NewBufferString(`{
"jsonrpc": "2.0",
"method": "sendAsset",
"id": "1",
"params": {
"from": ["mh6YCgTLk3b1c7ZJYeYBPsFMUnbAh55wBM"],
"to": [
{
"address": "n3wj1zjYExb963krQbLiSrs9dhrxxpqm9A",
"amount": 20,
"assetId": "La6gS5BPnMhcdzh3xpCmbCRZ52AxQvKhiXYo7t"
}
]
}
}`))
defer resp.Body.Close()
b, err := ioutil.ReadAll(resp.Body)
fmt.Println(string(b))
response
{
"jsonrpc": "2.0",
"id": "1",
"result": {
"txHex": "0100000002d823af311f1b6ef197aa01a4a2fc378b59af7174a912523b44d1264bc4f4c595000000001976a9141152282ec857755e1f1b4ab7728b048db90d32a388acffffffffc4dacc35b8efe714497af3bf36c75be745b82534b4e7e4f55227ef0c503035bf000000001976a9141152282ec857755e1f1b4ab7728b048db90d32a388acffffffff0358020000000000001976a914f6021554bf49284bcbb0f583a8b95c73bc7f6b2388ac0000000000000000086a0643430215001458020000000000001976a9141152282ec857755e1f1b4ab7728b048db90d32a388ac00000000",
"multisigOutputs": [],
"coloredOutputIndexes": [
0
],
"financeTxid": "bf3530500cef2752f5e4e7b43425b845e75bc736bff37a4914e7efb835ccdac4",
"txid": "149fd978feacfa8751391f7b5310b72dc43c2f17398c4359ac52ae76074732de"
}
}
トークン所有者の確認
次にTakuCoinを誰が所有しているかを確認します。
resp, err := http.Post("http://localhost:8081", "application/json",
bytes.NewBufferString(`{
"jsonrpc": "2.0",
"method": "coloredCoins.getStakeHolders",
"id": "1",
"params": {
"assetId": "La6gS5BPnMhcdzh3xpCmbCRZ52AxQvKhiXYo7t"
}
}`))
defer resp.Body.Close()
b, err := ioutil.ReadAll(resp.Body)
fmt.Println(string(b))
{
"jsonrpc": "2.0",
"id": "1",
"result": {
"assetId": "La6gS5BPnMhcdzh3xpCmbCRZ52AxQvKhiXYo7t",
"holders": [
{
"address": "n3wj1zjYExb963krQbLiSrs9dhrxxpqm9A",
"amount": 20
},
{
"address": "mh6YCgTLk3b1c7ZJYeYBPsFMUnbAh55wBM",
"amount": 80
}
],
"divisibility": 0,
"lockStatus": true,
"aggregationPolicy": "aggregatable",
"someUtxo": "149fd978feacfa8751391f7b5310b72dc43c2f17398c4359ac52ae76074732de:0"
}
}
これでトークンが送信されたことが確認できました。
Colored Coin Explorer
ColuはColoredCoinProtcolを利用しているため、以下のサイトでもアセット情報や、トランザクション情報を確認することができます。
Colored Coin Explorer
http://coloredcoins.org/explorer/testnet