TXEDITORを使ってCounterparty送信トランザクションを作る

今回はCounterparty送信トランザクション

前回はトランザクション作成ツール「TXEDITOR」を使ってP2SHトランザクションを作成しました。今回はCounterpartyの送信トランザクションを作ります。

blog.yzono.com

Counterparty送信トランザクション

Counterpartyトークンを送信する方法は以下3つありますが、今回はOP_RETURNを利用します。

  • OP_RETURN
  • OP_CHECKSIG
  • OP_CHECKMULTISIG

OP_RETURNのデータの例は以下になります。詳しくは後で説明します。

434e545250525459|00000000|000000000004fadf000000174876e800000000000000000000000000
       |             |          |
       |             |          └── All of this is the operation data (maximum 28 bytes)
       |             └──────────────── This is the transaction type identifier (4 bytes)
       └───────────────────────────────── The string CNTRPRTY in hexadecimal (8 bytes)

Counterparty Spec : Encoding a transaction

送信トランザクションの場合のoperation data部は以下になります。

000000000004fadf|000000174876e800
       |               |
       |               └───── quantity (8 bytes)
       └────────────────── asset name (8 bytes)

counterparty-spec

Counterparty Spec : Send Transactions

Counterparty Spec : Asset Names

TXEDITORによるトランザクション作成

1.事前準備

(1) bitcore-libインストール

$ mkdir /tmp/txeditor
$ cd /tmp/txeditor
$ npm install bitcore-lib
$ vi new_address.js

(2) 新規アドレス作成JS作成 (new_address.js)

var bitcore = require('bitcore-lib');
var network = 'testnet';
var privateKey = new bitcore.PrivateKey(network);
console.log("Private Key : " + privateKey.toString());
console.log("Private Key (WIF) : " +privateKey.toWIF());
console.log("Public Key : " + privateKey.toPublicKey().toString());
console.log("Bitcoin Address : " + privateKey.toPublicKey().toAddress().toString());

var script = new bitcore.Script.buildPublicKeyHashOut(privateKey.toPublicKey());
console.log("Locking Script : " + script.toString());
console.log("Locking Script (HEX) : " + script.toHex());                                          

(3) 送信元アドレス作成

$ node new_address.js 
Private Key : 3457c3b9843716e6195a835a2a3f9e3b6869e90e15fe4ee95ff5641d6507790b
Private Key (WIF) : cPLT1aBU1EuiaTUS8GNLZoJ2XpZ2FFZW2AekJ9DPAW89gaJp93Ts
Public Key : 03dd39d15bba279bff1bda974b0eea1f1d7eec3b9cfc36fd3b47620545b1b825f7
Bitcoin Address : myyTr8P4GYZnWJ7Uj12dKDUyd1umDDYkiU
Locking Script : OP_DUP OP_HASH160 20 0xca75bfabeda7cd51307f2ced429dcd0656ac0735 OP_EQUALVERIFY OP_CHECKSIG
Locking Script (HEX) : 76a914ca75bfabeda7cd51307f2ced429dcd0656ac073588ac

(4) 送信先アドレス作成

$ node new_address.js 
Private Key : 486b6e4cb70e765e6e1ce14262774f0db2ba74e7d6cc2014c50df2ef1c983de5
Private Key (WIF) : cQ1UZT61zivtnGkyuDJySJ1fbtDtgTdqf84JvQc6UCBBzRXXwjYD
Public Key : 02937574d4f830cfa93a9b5982e12fd8c693ea62a0e58f62818a02eb642658df41
Bitcoin Address : n2HAAsUB9933V75VvH1Rr6zY4tAwHhYk76
Locking Script : OP_DUP OP_HASH160 20 0xe3bebb5140450dce9e434275c68467ce1b1a1667 OP_EQUALVERIFY OP_CHECKSIG
Locking Script (HEX) : 76a914e3bebb5140450dce9e434275c68467ce1b1a166788ac

(5) 送信元アドレスにBitcoinを送付

以下サイトから送信元アドレスを入力するとTestnetで使えるBitcoinがもらえます

http://tpfaucet.appspot.com/

(6) 送信元のUTXO取得 ⭐

UTXOはIndieSquare APIを利用して取得します。

$ curl https://apitestnet.indiesquare.me/v2/addresses/myyTr8P4GYZnWJ7Uj12dKDUyd1umDDYkiU/utxos

[  
   {  
      "scriptPubKey":"76a914ca75bfabeda7cd51307f2ced429dcd0656ac073588ac",
      "vout":0,
      "confirmations":0,
      "txid":"2eda1b80859112c4235680302982c00477ced7cfc5a4f92db975ae185ff1873d",
      "amount":0.18
   }
]

(7) 送信元アドレスにXCPを送付 ⭐

XCPを入手するにはBTCをBURN(燃やす!)する必要があります。

  • source = 送信元アドレス
  • quantity = utxo.amoutの一部(適当でよいですが全部はダメです)

(7)-1 BURNトランザクションを作成

curl -X POST https://public.coindaddy.io:14001/api/ --user rpc:1234 -H 'Content-Type: application/json; charset=UTF-8' -H 'Accept: application/json, text/javascript' --data-binary '{"jsonrpc":"2.0", "id":0, "method":"create_burn", "params":{"source":"myyTr8P4GYZnWJ7Uj12dKDUyd1umDDYkiU", "quantity":10000000}}'

{
   "result":"01000000013d87f15f18ae75b92df9a4c5cfd7ce7704c0822930805623c4129185801bda2e000000001976a914ca75bfabeda7cd51307f2ced429dcd0656ac073588acffffffff0280969800000000001976a914a11b66a67b3ff69671c8f82254099faf374b800e88ac07fc7900000000001976a914ca75bfabeda7cd51307f2ced429dcd0656ac073588ac00000000",
   "id":0,
   "jsonrpc":"2.0"
}

(7)-2 BURNトランザクションデコード

$ curl -H "Content-Type: application/json" -X POST -d '{"tx": "01000000013d87f15f18ae75b92df9a4c5cfd7ce7704c0822930805623c4129185801bda2e000000001976a914ca75bfabeda7cd51307f2ced429dcd0656ac073588acffffffff0280969800000000001976a914a11b66a67b3ff69671c8f82254099faf374b800e88ac07fc7900000000001976a914ca75bfabeda7cd51307f2ced429dcd0656ac073588ac00000000"}' https://apitestnet.indiesquare.me/v2/transactions/decode

{
   "txid":"a12fa0dbced9e03109d1581579328e8bc31f4694e072eddedd034818b0a063c7",
   "size":144,
   "version":1,
   "locktime":0,
   "vin":[
      {
         "txid":"2eda1b80859112c4235680302982c00477ced7cfc5a4f92db975ae185ff1873d",
         "vout":0,
         "scriptSig":{
            "asm":"OP_DUP OP_HASH160 ca75bfabeda7cd51307f2ced429dcd0656ac0735 OP_EQUALVERIFY OP_CHECKSIG",
            "hex":"76a914ca75bfabeda7cd51307f2ced429dcd0656ac073588ac"
         },
         "sequence":4294967295
      }
   ],
   "vout":[
      {
         "value":0.1,
         "n":0,
         "scriptPubKey":{
            "asm":"OP_DUP OP_HASH160 a11b66a67b3ff69671c8f82254099faf374b800e OP_EQUALVERIFY OP_CHECKSIG",
            "hex":"76a914a11b66a67b3ff69671c8f82254099faf374b800e88ac",
            "reqSigs":1,
            "type":"pubkeyhash",
            "addresses":[
               "mvCounterpartyXXXXXXXXXXXXXXW24Hef"
            ]
         }
      },
      {
         "value":0.07994375,
         "n":1,
         "scriptPubKey":{
            "asm":"OP_DUP OP_HASH160 ca75bfabeda7cd51307f2ced429dcd0656ac0735 OP_EQUALVERIFY OP_CHECKSIG",
            "hex":"76a914ca75bfabeda7cd51307f2ced429dcd0656ac073588ac",
            "reqSigs":1,
            "type":"pubkeyhash",
            "addresses":[
               "myyTr8P4GYZnWJ7Uj12dKDUyd1umDDYkiU"
            ]
         }
      }
   ]
}

(7)-3 BURNトランザクションサイン

  • デコードした内容を入力

スクリーンショット 2017-02-18 00.34.54.png

  • 送信元アドレスのPrivate Key (WIF) を入力してサインボタンクリック

スクリーンショット 2017-02-18 00.34.18.png

  • Script = Signature + Hash Type<改行>送信元のPublic Key

スクリーンショット 2017-02-18 00.34.36.png

  • txins[0].signature_script = Script.Hex

スクリーンショット 2017-02-18 00.34.03.png

(7)-4 BURNトランザクションBroadcast実行

$ curl -H "Content-Type: application/json" -X POST -d '{"tx": "01000000013d87f15f18ae75b92df9a4c5cfd7ce7704c0822930805623c4129185801bda2e000000006a47304402202f77a12084eb191157bbb1e40bb8ccaef1363aa27de7737ad03771bdf0345a6402203cd4c56443cb654207fbf6452a9baa55d8d7ce9a6cd601ffdb426e18f1e03b8c012103dd39d15bba279bff1bda974b0eea1f1d7eec3b9cfc36fd3b47620545b1b825f7ffffffff0280969800000000001976a914a11b66a67b3ff69671c8f82254099faf374b800e88ac07fc7900000000001976a914ca75bfabeda7cd51307f2ced429dcd0656ac073588ac00000000"}' https://apitestnet.indiesquare.me/v2/transactions/broadcast

{
   "txid":"c8bc0c660fbfc57bc6f72a5941c420b110924da2aa4703cd473182c51387e46d"
}

(7)-5 Counterparty残高確認

curl https://apitestnet.indiesquare.me/v2/addresses/myyTr8P4GYZnWJ7Uj12dKDUyd1umDDYkiU/balances

[
   {
      "token":"BTC",
      "balance":0.07994375,
      "unconfirmed_balance":0
   },
   {
      "token":"XCP",
      "balance":139.49001647,
      "unconfirmed_balance":0
   }
]

XCPがあれば成功です! これで事前準備完了です。

2.送信元のUTXO取得

UTXOはIndieSquare APIを利用して取得します。

$ curl https://apitestnet.indiesquare.me/v2/addresses/myyTr8P4GYZnWJ7Uj12dKDUyd1umDDYkiU/utxos

[
   {
      "scriptPubKey":"76a914ca75bfabeda7cd51307f2ced429dcd0656ac073588ac",
      "vout":0,
      "confirmations":0,
      "txid":"77774b1a63393c85ed676b527a5565d46c6db002fdaf851276a56dea918c6be1",
      "amount":0.14
   }
]

#一回ミスったのでUTXO作り直してます.. (気にしないでください)

3.データアウトプットScript作成

1XCPを送信するScriptを作ります。

データ仕様を再度記載します。

434e545250525459|00000000|000000000004fadf000000174876e800000000000000000000000000
       |             |          |
       |             |          └── All of this is the operation data (maximum 28 bytes)
       |             └──────────────── This is the transaction type identifier (4 bytes)
       └───────────────────────────────── The string CNTRPRTY in hexadecimal (8 bytes)
000000000004fadf|000000174876e800
       |               |
       |               └───── quantity (8 bytes)
       └────────────────── asset name (8 bytes)

(1)データ作成

  • CNTRPRTY = 434e545250525459 (固定)
  • Transaction Type = 00000000
  • Asset Name = XCP (0000000000000001)
  • Quantity = 1XCP(100000000 satoshi) (0000000005f5e100)

434e5452505254590000000000000000000000010000000005f5e100

(2)データをARC4暗号化

434e5452505254590000000000000000000000010000000005f5e100をARC4暗号化します。秘密鍵はUTXOのindex=0のtxidです。(77774b1a63393c85ed676b527a5565d46c6db002fdaf851276a56dea918c6be1)

以下のサイトを利用できます。 http://rc4.online-domain-tools.com/

結果は761da27c8722993ed07d6b2020333248a7964907b65a1884b6374be6になります。

スクリーンショット 2017-02-18 04.02.35.png

(3)Script作成

各データを連携します。

OP_RETURN(6a) + データのバイト数(16,1c) + 暗号化したデータ
6a1c761da27c8722993ed07d6b2020333248a7964907b65a1884b6374be6

4.TXEDITOR (Transactionタブ)を入力

スクリーンショット 2017-02-18 03.49.19.png

5.TXEDITOR (Signature(HASHTYPE_ALL))を入力

スクリーンショット 2017-02-18 03.48.51.png

6.TXEDITOR (Script)を入力

スクリーンショット 2017-02-18 03.48.58.png

7.TXEDITOR (Transactionタブ)を入力

スクリーンショット 2017-02-18 03.48.43.png

8.decodeRawTransaction実行

確認のために、decodeRawTransactionを実行

curl -H "Content-Type: application/json" -X POST -d '{"tx": "0100000001e16b8c91ea6da5761285affd02b06d6cd465557a526b67ed853c39631a4b7777000000006a47304402202cf13fcee4c4d40706556b5653c78063284557acf138bf1ab4e0dc3bc83f18b002203c3449a83dd03cc2eff8a34d74e5e4d869adf0e9880ee4eea37745c70ae0c6d3012103dd39d15bba279bff1bda974b0eea1f1d7eec3b9cfc36fd3b47620545b1b825f7ffffffff02e018d400000000001976a914e3bebb5140450dce9e434275c68467ce1b1a166788ac00000000000000001e6a1c761da27c8722993ed07d6b2020333248a7964907b65a1884b6374be600000000"}' https://apitestnet.indiesquare.me/v2/transactions/decode


{
   "txid":"b6093ea814127808a4fd2e2176d4dc0a44d7babc171e75362afe7b81153e6853",
   "size":230,
   "version":1,
   "locktime":0,
   "vin":[
      {
         "txid":"77774b1a63393c85ed676b527a5565d46c6db002fdaf851276a56dea918c6be1",
         "vout":0,
         "scriptSig":{
            "asm":"304402202cf13fcee4c4d40706556b5653c78063284557acf138bf1ab4e0dc3bc83f18b002203c3449a83dd03cc2eff8a34d74e5e4d869adf0e9880ee4eea37745c70ae0c6d3[ALL] 03dd39d15bba279bff1bda974b0eea1f1d7eec3b9cfc36fd3b47620545b1b825f7",
            "hex":"47304402202cf13fcee4c4d40706556b5653c78063284557acf138bf1ab4e0dc3bc83f18b002203c3449a83dd03cc2eff8a34d74e5e4d869adf0e9880ee4eea37745c70ae0c6d3012103dd39d15bba279bff1bda974b0eea1f1d7eec3b9cfc36fd3b47620545b1b825f7"
         },
         "sequence":4294967295
      }
   ],
   "vout":[
      {
         "value":0.139,
         "n":0,
         "scriptPubKey":{
            "asm":"OP_DUP OP_HASH160 e3bebb5140450dce9e434275c68467ce1b1a1667 OP_EQUALVERIFY OP_CHECKSIG",
            "hex":"76a914e3bebb5140450dce9e434275c68467ce1b1a166788ac",
            "reqSigs":1,
            "type":"pubkeyhash",
            "addresses":[
               "n2HAAsUB9933V75VvH1Rr6zY4tAwHhYk76"
            ]
         }
      },
      {
         "value":0,
         "n":1,
         "scriptPubKey":{
            "asm":"OP_RETURN 761da27c8722993ed07d6b2020333248a7964907b65a1884b6374be6",
            "hex":"6a1c761da27c8722993ed07d6b2020333248a7964907b65a1884b6374be6",
            "type":"nulldata"
         }
      }
   ]
}

9.broadcast実行

$ curl -H "Content-Type: application/json" -X POST -d '{"tx": "0100000001e16b8c91ea6da5761285affd02b06d6cd465557a526b67ed853c39631a4b7777000000006a47304402202cf13fcee4c4d40706556b5653c78063284557acf138bf1ab4e0dc3bc83f18b002203c3449a83dd03cc2eff8a34d74e5e4d869adf0e9880ee4eea37745c70ae0c6d3012103dd39d15bba279bff1bda974b0eea1f1d7eec3b9cfc36fd3b47620545b1b825f7ffffffff02e018d400000000001976a914e3bebb5140450dce9e434275c68467ce1b1a166788ac00000000000000001e6a1c761da27c8722993ed07d6b2020333248a7964907b65a1884b6374be600000000"}' https://apitestnet.indiesquare.me/v2/transactions/broadcast

{
   "txid":"b6093ea814127808a4fd2e2176d4dc0a44d7babc171e75362afe7b81153e6853"
}

10.Counterparty残高確認

送信先のアドレスの残高をみてみましょう。

curl https://apitestnet.indiesquare.me/v2/addresses/n2HAAsUB9933V75VvH1Rr6zY4tAwHhYk76/balances

[
   {
      "token":"BTC",
      "balance":0.07894375,
      "unconfirmed_balance":0.139
   },
   {
      "token":"XCP",
      "balance":0,
      "unconfirmed_balance":1
   }
]

unconfirmed_balance = 1 になっていますね。1XCP送信できました。

参考

http://www.binaryhexconverter.com/decimal-to-hex-converter http://www.binaryhexconverter.com/hex-to-decimal-converter