プロローグ
先日、StackExchangeでこんな質問をしました。
P2SH-wrapped P2PKH
というものですが、それが何なのかを含めて質問をしたので、その訳を書いておきます。
...ついでにやってみました。
P2SH-wrapped P2PKHなんてできるのか? (質問の訳)
P2SH-wrapped P2WPKH
のような、アドレスの形式があることはよく知られています。これはSegWitアドレスをP2SHにラップ(包んでしまう)するものですね。
こういったアドレスの形式を考えているうちに、こんな疑問が思い浮かびました。「P2SH-wrapped P2PKH
なんてできるのか?」ってね。
当然、こんなのは無用な長物なんてのは自明だけど、考えるだけ考えてみたいと思います。
Step 1: 変換するアドレスを決める
ここにあった1CciesT23BNionJeXrbxmjc7ywfiyM4oLW
というアドレスを例に取りましょう。
Step 2: アドレスを「出力スクリプト」1に変換し、hash160でハッシュする
OP_DUP OP_HASH160 7f6ab65fa911f558ca2dde3e9d073acb02c0d5c6 OP_EQUALVERIFY OP_CHECKSIG
が得られました。
ハッシュしたらc852ac34a1c76b63a279c97502c9ccc4e3cb9e8b
が出てきました。
Step 3: ハッシュしたスクリプトからP2SHを作る
toBase58Check(c852ac34a1c76b63a279c97502c9ccc4e3cb9e8b, 5) = 3KxE77EHe1ip6WGRifwr9fZ5WBDGsLyWFz
この3KxE77EHe1ip6WGRifwr9fZ5WBDGsLyWFz
が欲しいアドレスです。
ここに再現用のコードを置いておきます。
質問
3KxE77EHe1ip6WGRifwr9fZ5WBDGsLyWFz
(P2SH-wrapped P2PKH address)に送られたコインは、普通にP2PKHから送金するように送金できますか?
じゃあやってみよう
...とは言ってもMainnetのコインではやりたくないので、Testnetでやります。
mqXLdhurwGm7mnciUm43RKejSUm8drqetx
というアドレスを用意したので、これを変換します。
2NBGcEkQnHY5DYZmRQADonnZUMdiPkKKnUy
になりました。(途中計算はここ)
できたP2SHアドレスに送ってみよう
送ってみました。普通のP2SHなので見栄え0ですが。
早速spendしよう
途中計算の通り、出力スクリプト(ここではredeemScript)はOP_DUP OP_HASH160 6dc3e7c54d2a45d79efb8f114213a2dcb893921d OP_EQUALVERIFY OP_CHECKSIG
です。
以下のコードでトランザクションを生成しました。
const bitcoin=require('bitcoinjs-lib@3.3.2');
const testnet=bitcoin.networks.testnet;
const txb=new bitcoin.TransactionBuilder(testnet);
// see https://chain.so/tx/BTCTEST/29ca616a0cc35c2482ccf4c0f9a563ca80504519a0798df95c1d36a7aa089ec9 for what I mean
txb.addInput("29ca616a0cc35c2482ccf4c0f9a563ca80504519a0798df95c1d36a7aa089ec9", 0);
// 214 is fee: hardcode here for shortcut
// tb1qcgf5jv2028y5s0cgelk8qe97mq3upupt3wmfj6 is my address to return coin
txb.addOutput("tb1qcgf5jv2028y5s0cgelk8qe97mq3upupt3wmfj6", 10000-214);
const keyPair=bitcoin.ECPair.fromWIF("cPztn6Pe3LLXeqRwK6ecV46yNRRYRUsT9auATTmFK5GB6eVTySza", testnet);
txb.sign(0, keyPair, bitcoin.script.fromASM("OP_DUP OP_HASH160 6dc3e7c54d2a45d79efb8f114213a2dcb893921d OP_EQUALVERIFY OP_CHECKSIG"));
console.log(txb.build().toHex());
実行結果はここ。
0100000001c99e08aaa7361d5cf98d79a01…483f08cfec7064bed823c0f02b00000000
が今回送るトランザクションになります。
ブロードキャストしたら...
ちゃんと帰ってきました!2
トランザクションがこれ。
すごい! なんとなく。
結論
P2SH-wrapped P2PKHなんて...できる!
なお需要があるはずがないので、参考程度に。3