Y

TXEDITORを使ってマルチシグトランザクションを作る

今回はマルチシグトランザクション

前回はトランザクション作成ツール「TXEDITOR」を使ってP2PKトランザクションを作成しました。今回はマルチシグトランザクションを作ります。

マルチシグトランザクションのscript

マルチシグトランザクションの場合はlocking scriptが M <Public Key 1> <Public Key 2> .. <Public Key N> N OP_CHECKMULTISIG 、unlocking scriptが OP_0 <Signature 1> ... <Signature M> となります。

今回は 2-of-3マルチシグネチャ条件を設定します。

以下手順の ⭐ マークがあるところが注目ポイントです。

TXEDITORによるトランザクション作成 (P2PKH to マルチシグ)

1.事前準備

  • (1) bitcore-libインストール
  • (2) 新規アドレス作成JS作成
  • (3) 送信元アドレス作成
  • (4) 送信先アドレス作成 (3アドレス)
  • (5) locking script作成
  • (6) 送信元アドレスにBitcoinを送付
  • (7) 送信元アドレスにBitcoinを送付

(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());

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

$ node new_address.js
Private Key : 1b1644ea6ca5941011b880001a19e0fb5e14739feddf96a1003bd946428d2ca7
Private Key (WIF) : cNVMZAvNYWsWnWMpEN7vCwdvfvRn1saC1C3sH2DJW6Zhq2FEWU14
Public Key : 023f3b8d04b9fac2ac10b8b8e7a4d5f033f259d26a74d2b0b77313f41585b3d1b5
Bitcoin Address : mfYRZHwMfvFti3gErrKeBmMmMraFJVRMyJ

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

pub1

$ node new_address.js
Private Key : 3a49e7f41ff22b017d59b3ea686e8627dc6e46b618b00b1c9da3184437cf3a79
Private Key (WIF) : cPY1Ndne8fhqWRhhVLCWXz9k1oyA4txQGjAyYg91m3vtp4CzJtkd
Public Key : 022bda026d6aee8133f0290449a282f8cfbccafdc064b0b47068854457f38af3bc
Bitcoin Address : mwvbYhiFB2AbmGfcLAV6JqUtESw8WESqK2

pub2

$ node new_address.js
Private Key : 5cc229f92f31d87db8cba3d6891b484a96201eda76e1032f81cf205020fc2aa0
Private Key (WIF) : cQh1eTbsgrW9cRovBMb9GGyyVfaAYevpWobYGyX1AfTjreFLwGmC
Public Key : 030a230982d9706247d5997df1aea7144266c33a2e6c64c6a3a44c5cdf9c0ff58a
Bitcoin Address : mzXDxXWB1XoPwJavgtiy59er1jmAxZwwWs

pub3

$ node new_address.js
Private Key : d5871141082ba25e38bb55d50acf257977fb8c712db60fc8793841a08d50d1ab
Private Key (WIF) : cUjmhGCroB5vvNADTBCZfDVkCiYpTpjBWvk4WDuXt2RCzqKrLXK7
Public Key : 0218597441c292cb6d73174c1662ac9d60b76688fd359f90e2d653d1a089c9aba9
Bitcoin Address : mvU1PgtJJAdP5Xz3rSwtDfsTiEMwWn1BgA

(5) locking_script.js作成

locking scriptを作成します。pub1〜3のPublic Keyの値を設定してください。

$ vi locking_script.js
var bitcore = require('bitcore-lib');
var network = 'testnet';
var pub1 = new bitcore.PublicKey("022bda026d6aee8133f0290449a282f8cfbccafdc064b0b47068854457f38af3bc", network);
var pub2 = new bitcore.PublicKey("030a230982d9706247d5997df1aea7144266c33a2e6c64c6a3a44c5cdf9c0ff58a", network);
var pub3 = new bitcore.PublicKey("0218597441c292cb6d73174c1662ac9d60b76688fd359f90e2d653d1a089c9aba9", network);
var array = [pub1, pub2, pub3];
var script = new bitcore.Script.buildMultisigOut(array, 2);
console.log("Locking Script: " + script.toString());
console.log("Locking Script (HEX) : " + script.toHex());

(6) locking_script.js実行

$ node locking_script.js 
Locking Script: OP_2 33 0x0218597441c292cb6d73174c1662ac9d60b76688fd359f90e2d653d1a089c9aba9 33 0x022bda026d6aee8133f0290449a282f8cfbccafdc064b0b47068854457f38af3bc 33 0x030a230982d9706247d5997df1aea7144266c33a2e6c64c6a3a44c5cdf9c0ff58a OP_3 OP_CHECKMULTISIG
Locking Script (HEX) : 52210218597441c292cb6d73174c1662ac9d60b76688fd359f90e2d653d1a089c9aba921022bda026d6aee8133f0290449a282f8cfbccafdc064b0b47068854457f38af3bc21030a230982d9706247d5997df1aea7144266c33a2e6c64c6a3a44c5cdf9c0ff58a53ae

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

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

http://tpfaucet.appspot.com/

2.送信元のUTXO取得

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

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

[
   {
      "scriptPubKey":"76a91400472c7ada0f94b832befcdd883501124305fe7b88ac",
      "vout":0,
      "confirmations":0,
      "txid":"203c395cb3bbdab6a44630d4fad22eff21df5518cc102c56ae16c8cf404e3125",
      "amount":1.6
   }
]

3.TXEDITOR (Transactionタブ)を入力

  • txins[0].outpoint.hash = utxoのtxid
  • txins[0].outpoint.index = utxoのvout
  • txins[0].signature_script = utxoのscriptPubKey
  • txouts[0].value = utxo.amount * 100000000 - 100000 = 159900000
  • txouts[0].pk_script = locking_script.jsを実行した結果 (HEX) ⭐

スクリーンショット 2017-02-14 17.05.09.png

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

  • Private key (WIF/HEX) = 送信元のPrivate Key (WIF)

スクリーンショット 2017-02-14 17.08.00.png

5.TXEDITOR (Script)を入力

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

スクリーンショット 2017-02-14 17.08.36.png

6.TXEDITOR (Transactionタブ)を入力

  • txins[0].signature_script = Script.Hex

スクリーンショット 2017-02-14 17.10.34.png

7.decodeRawTransaction実行

確認のために、decodeRawTransactionを実行

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

レスポンス

{
   "txid":"80020248abc2975a64ae4f1c1298fea530a8acf2f2225cee844569552093ba07",
   "size":271,
   "version":1,
   "locktime":0,
   "vin":[
      {
         "txid":"203c395cb3bbdab6a44630d4fad22eff21df5518cc102c56ae16c8cf404e3125",
         "vout":0,
         "scriptSig":{
            "asm":"304402202d7e54a6ee2a6ea3de611e3c6336e23753cfaf84e520aef0cd1ade3e02b65851022039396fa77522c3d5ad5f044b04909d7d20012cc1d6bcd0bc66718771db98f825[ALL] 023f3b8d04b9fac2ac10b8b8e7a4d5f033f259d26a74d2b0b77313f41585b3d1b5",
            "hex":"47304402202d7e54a6ee2a6ea3de611e3c6336e23753cfaf84e520aef0cd1ade3e02b65851022039396fa77522c3d5ad5f044b04909d7d20012cc1d6bcd0bc66718771db98f8250121023f3b8d04b9fac2ac10b8b8e7a4d5f033f259d26a74d2b0b77313f41585b3d1b5"
         },
         "sequence":4294967295
      }
   ],
   "vout":[
      {
         "value":0.015,
         "n":0,
         "scriptPubKey":{
            "asm":"2 0218597441c292cb6d73174c1662ac9d60b76688fd359f90e2d653d1a089c9aba9 022bda026d6aee8133f0290449a282f8cfbccafdc064b0b47068854457f38af3bc 030a230982d9706247d5997df1aea7144266c33a2e6c64c6a3a44c5cdf9c0ff58a 3 OP_CHECKMULTISIG",
            "hex":"52210218597441c292cb6d73174c1662ac9d60b76688fd359f90e2d653d1a089c9aba921022bda026d6aee8133f0290449a282f8cfbccafdc064b0b47068854457f38af3bc21030a230982d9706247d5997df1aea7144266c33a2e6c64c6a3a44c5cdf9c0ff58a53ae",
            "reqSigs":2,
            "type":"multisig",
            "addresses":[
               "mvU1PgtJJAdP5Xz3rSwtDfsTiEMwWn1BgA",
               "mwvbYhiFB2AbmGfcLAV6JqUtESw8WESqK2",
               "mzXDxXWB1XoPwJavgtiy59er1jmAxZwwWs"
            ]
         }
      }
   ]
}

8.broadcast実行

broadcast実行

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

レスポンス

{
   "code":200001,
   "type":"Error",
   "message":"Broadcast failed",
   "errors":[
      {
         "field":"txid",
         "code":"invalid"
      }
   ]
}

あれ… エラーが出るので https://live.blockcypher.com/btc-testnet/pushtx/ からブロードキャストしました。

9.broadcast実行結果

問題なく送信できました。

http://tbtc.blockr.io/tx/info/c85ab15eddd1faabc86b36b5fb0a963ba4ebb3fd5839404708c5e0eb2dcaa545

それっぽい結果をみることができます。

スクリーンショット 2017-02-14 18.08.59.png

TXEDITORによるトランザクション作成 (マルチシグ to P2PKH)

Escrowされている金額を別のアドレスに送信します。

sign.js作成

sign.js

var bitcore = require('bitcore-lib');
var network = 'testnet';

var key1 = new bitcore.PrivateKey("3a49e7f41ff22b017d59b3ea686e8627dc6e46b618b00b1c9da3184437cf3a79", network);
var key2 = new bitcore.PrivateKey("5cc229f92f31d87db8cba3d6891b484a96201eda76e1032f81cf205020fc2aa0", network);
var keys = [key1, key2];

var pub1 = new bitcore.PublicKey("022bda026d6aee8133f0290449a282f8cfbccafdc064b0b47068854457f38af3bc", network);
var pub2 = new bitcore.PublicKey("030a230982d9706247d5997df1aea7144266c33a2e6c64c6a3a44c5cdf9c0ff58a", network);
var pub3 = new bitcore.PublicKey("0218597441c292cb6d73174c1662ac9d60b76688fd359f90e2d653d1a089c9aba9", network);
var pubkeys = [pub1, pub2, pub3];

var utxo = new bitcore.Transaction.UnspentOutput({
  "txId" : "c85ab15eddd1faabc86b36b5fb0a963ba4ebb3fd5839404708c5e0eb2dcaa545",
  "outputIndex" : 0,
  "script" : "52210218597441c292cb6d73174c1662ac9d60b76688fd359f90e2d653d1a089c9aba921022bda026d6aee8133f0290449a282f8cfbccafdc064b0b47068854457f38af3bc21030a230982d9706247d5997df1aea7144266c33a2e6c64c6a3a44c5cdf9c0ff58a53ae",
  "satoshis" : 159900000
});

var multiSigTx = new bitcore.Transaction()
    .from(utxo, pubkeys, 2)
    .to("mfYRZHwMfvFti3gErrKeBmMmMraFJVRMyJ", 159800000)
    .sign(keys);

var serialized = multiSigTx.toString();
console.log(serialized);

sign.js実行

$ node sign.js 
010000000145a5ca2debe0c50847403958fdb3eba43b960afbb5366bc8abfad1dd5eb15ac800000000920047304402203fa6520a6a8345603a03990ae99e7dd83a482f868f902d8f40298c44e8ea808902205e025a57c47af57892c2b616d3f92c679aefd8ac9cfd3e72f35fce6df96a0ffb01483045022100cebdb64fdc383bdbf88fe2820fe49e2e61642e9e94a3b58baa6efdde42fcf745022024a2a7a54a6c0e25b4e1580be62d336716c771dabd837430c58c392dc4c5afc501ffffffff01c05a8609000000001976a91400472c7ada0f94b832befcdd883501124305fe7b88ac00000000

broadcast実行

https://live.blockcypher.com/btc-testnet/pushtx/ からブロードキャストします。

broadcast実行結果

http://tbtc.blockr.io/tx/info/219a49b6a376e8f4ef86866e93483552679b5157318f0e4085430a3cee24e3d8

後半TXEDITOR関係なくなった感ありますが、Multisig pubkey scripts (いわゆる bare multisig) も無事送受信できました。