- Home
- ビットコインのマルチシグアドレスをNode.jsで作成して送信
ビットコインのマルチシグアドレスをNode.jsで作成して送信
Bitcoin マルチシグアドレスの作成から署名、送信までをまとめる。
確認環境:BitcoinCore(0.18.0)、npm(6.9.0)、nvm(v8.12.0)
マルチシグアドレスの作成
1. プライベートキーの作成(PrivateKey)
bitcore-lib を用いてランダムにプライベートキーを作成する。(2つ以上必要数作成する。)
var bitcore = require('bitcore-lib'); var network = 'livenet'; var privateKey = new bitcore.PrivateKey(); console.log(privateKey.toString());
64文字のプライベートキーがランダムに生成される。
2. パブリックキーの作成(privateKey.toPublicKey)
bitcore-lib を用いてプライベートキーをパブリックキーに変換する。
var bitcore = require('bitcore-lib'); var privkey = process.argv[2]; var privateKey = new bitcore.PrivateKey(privkey); var publicKey = privateKey.toPublicKey(); console.log(publicKey.toString());
66文字のパブリックキーが生成される。
3. マルチシグアドレスの作成(createmultisig)
JSON-RPC を用いてマルチシグアドレスを作成する。
createmultisig required/*必要署名数*/ ["public key",...]
$ curl --user root --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "createmultisig" , "params": [2, '[\"03a8795069c5f6233838c9996a00f9e974056a6661bdb29cd6c9e62a47d239cff4\",\"033d9b042212eeab0dc4ffbf4e4c3a525a0cf61a5b4266d5f0721fdbb815b72644\"]'] }' -H 'content-type: text/plain;' http://127.0.0.1:8332/
トランザクションへの署名
bitcore-lib を用いてトランザクションに署名する。
require('dotenv').config(); const BN = require('bignumber.js'); BN.set({ ROUNDING_MODE: BN.ROUND_DOWN, DECIMAL_PLACES: 8}); const bitcore = require('bitcore-lib'); const explorers = require('bitcore-explorers'); const insight = new explorers.Insight(); const Client = require('bitcoin-core'); const client = new Client({ host: process.env.BITCOIN_NODE_HOST, network: process.env.BITCOIN_NODE_NETWORK, username: process.env.BITCOIN_NODE_USER, password: process.env.BITCOIN_NODE_PASS, port: process.env.BITCOIN_NODE_PORT }); const from_address = "3KxY1Uqjw7oLTcd9xFRsHjtoksESSAae8e"; const to_address = "37Aq5Huw6kXEYV4LpT1b3grS3cULt2nBnd"; let amount = 0.0001; let fee = 0.00002; let threshold = 2; const private_keys = [ new bitcore.PrivateKey('cd6a11ee315416c830d18dd31a497cd0f7f218bfe7629a65dc198d9bd2f8a458'), new bitcore.PrivateKey('7d2373****************************************************613fc7') ]; const public_keys = private_keys.map(bitcore.PublicKey); amount = new BN(amount).multipliedBy(1e8).toNumber(); fee = new BN(fee).multipliedBy(1e8).toNumber(); Promise.resolve(1).then(rows =&gt; { return getUtxos(from_address); }).then(rows =&gt; { let unspent_utxos = rows; const utxos = unspent_utxos.map((unspent_utxo) =&gt; {return bitcore.Transaction.UnspentOutput(unspent_utxo)}); const transaction = new bitcore.Transaction(); <em>// make transaction &amp; signature </em> transaction.from(utxos, public_keys, threshold); transaction.to(to_address, amount); transaction.change(from_address); transaction.fee(fee); transaction.sign(private_keys); const signature = transaction.serialize(); console.log(signature); }); if (private_keys == null) { throw Error('no provate key registered.'); } function getUtxos(from_address) { return new Promise((resolve, reject) =&gt; { insight.getUnspentUtxos(from_address, function (err, utxos) { <em>// insightを用いたutxoの取得</em> if (err) { reject(err); } try { const object = utxos.map((utxo) =&gt; { return utxo.toObject(); }); resolve(object); } catch (e) { reject(e); } }); }); };
署名されたトランザクションが作成される。
送信処理
node.js を用いて署名されたトランザクションを送信する。
require('dotenv').config(); const bitcore = require('bitcore-lib'); const explorers = require('bitcore-explorers'); const Client = require('bitcoin-core'); const client = new Client({ host: process.env.BITCOIN_NODE_HOST, network: process.env.BITCOIN_NODE_NETWORK, username: process.env.BITCOIN_NODE_USER, password: process.env.BITCOIN_NODE_PASS, port: process.env.BITCOIN_NODE_PORT }); const signature = process.argv[2]; client.sendRawTransaction(signature).then(tx_hash =&gt; { console.log(tx_hash); });
送信が完了し64文字のトランザクションIDが返される。
その他(bitcore-cliを用いた署名手順)
1. トランザクション生成情報確認
送信に使用するVOUTを確認する
1.1 hexstring の確認(getrawtransaction)
bitcoin-cli getrawtransaction <em>トランザクションID</em>
トランザクションのhexstringが表示される。
1.2 トランザクションの詳細確認(decoderawtransaction)
bitcoin-cli decoderawtransaction [:hexstring]
トランザクションの詳細な情報が表示される。
{ "txid": "52a98*****************************************************74930", "hash": "52a98*****************************************************74930", "version": 1, "size": 224, "vsize": 224, "weight": 896, "locktime": 0, "vin": [ { "txid": "20e0c*****************************************************89339d", "vout": 1, "scriptSig": { "asm": "3045022100d317****************************************ad9ac93914e9de1e577502204ba1265aa379c2c7****************************************c7de36c8[ALL] 03bc87****************************************2dc36cd836370d7c1ec0", "hex": "483045022100d3****************************************57ad9ac93914e9de1e577502204ba1265aa379c2****************************************13c7de36c8012103bc87****************************************2dc36cd836370d7c1ec0" }, "sequence": 42******95 } ], "vout": [ { "value": 0.00010000, "n": 0, "scriptPubKey": { "asm": "OP_HASH160 d51******************************ee0856a OP_EQUAL", "hex": "a914******************************827ee0856a87", "reqSigs": 1, "type": "scripthash", "addresses": [ "3KxY1Uqjw7oLTcd9xFRsHjtoksESSAae8e" ] } }, { "value": 0.01006657, "n": 1, "scriptPubKey": { "asm": "OP_DUP OP_HASH160 2969c0******************************894e OP_EQUALVERIFY OP_CHECKSIG", "hex": "76a9******************************ac634bdb894e88ac", "reqSigs": 1, "type": "pubkeyhash", "addresses": [ "3Kxjw9xFRsH7oY1UqtoLTcdjksEe8SSAae" ] } } ] }
2. 未署名トランザクションの生成(createrawtransaction)
署名が行われる前のトランザクションを生成する。
bitcoin-cli createrawtransaction [{"txid":"txid","vout":n,"scriptPubKey":"scriptPubKey hex","redeemScript":"redeemScript"] [{"address":amount}
未署名のトランザクションが生成される。
3. トランザクションへの署名(signrawtransactionwithkey)
未署名トランザクションに対し署名を行う。
bitcoin-cli signrawtransactionwithkey "hexstring" ["privatekey",...] [{"txid":"hex","vout":n,"scriptPubKey":"hex","redeemScript":"hex","amount":amount}]
※ここではBase58Checkエンコーディングが使用される。以下のnode.jsを用いてプライベートキーをWIF(Wallet imoprt format)形式に変換する。
ご相談・お見積もり
03-5207-2689