bitcoinjsでテストネットでP2PKのUnspentを作る

# 動機
今どきこんな事やる人はいないからか、説明が見つけられなかった。

# 手順
## 環境構築
```bash
$ yarn init -y && yarn add bitcoinjs-lib
```

## 鍵を作る
```javascript
// genkey.js
const bit = require('bitcoinjs-lib')
const TESTNET = bit.networks.testnet

const p = bit.ECPair.makeRandom()
console.log("Public key:", p.publicKey.toString("hex"))
console.log("Private key:", p.privateKey.toString("hex"))
```

### 実行結果
```bash

$ node genkey.js 
Public key: 025bb45b88a6cc18fafe1befac52e6907e07b2f5e6887bddaabb3f45385accf788
Private key: e12f42cca4de231e5ac282ba75d937a4bfe62047aebcc4f9e5557c5beeac9239
```

### 公開鍵から、P2PKに出力する資金を入金するためのアドレスを作る
```javascript
// genaddr.js
const bit = require('bitcoinjs-lib')
const TESTNET = bit.networks.testnet

// 作った秘密鍵からECPairを復元
const privKey = Buffer.from("e12f42cca4de231e5ac282ba75d937a4bfe62047aebcc4f9e5557c5beeac9239", "hex")
const p = bit.ECPair.fromPrivateKey(privKey)

// 公開鍵からP2PKHのアドレスを作る
const addr = bit.payments.p2pkh({ pubkey: p.publicKey, network: TESTNET }).address
console.log("Address:", addr)
```

### 実行結果
```bash
$ node genaddr.js 
Address: mupGpwcxCJkWXqkqWuojy4Dcrrn8ngC1rT
```

## 作られたアドレスに原資を送る
フォーセット https://testnet-faucet.mempool.co から、`mupGpwcxCJkWXqkqWuojy4Dcrrn8ngC1rT`に、デフォルトの0.001BTCを送る

## Explorerでアドレスを検索して、原資のトランザクションの詳細を得る
https://www.blockchain.com/btc-testnet/address/mupGpwcxCJkWXqkqWuojy4Dcrrn8ngC1rT

ここで、Transaction hashをクリックして
https://www.blockchain.com/btc-testnet/tx/116f3df5d1fb04dff4574fb161e83c80c17fa619e9f98d9966a1a0616079c4bc

トランザクションハッシュ`116f3df5d1fb04dff4574fb161e83c80c17fa619e9f98d9966a1a0616079c4bc`
と、
`mupGpwcxCJkWXqkqWuojy4Dcrrn8ngC1rT`宛の`index 0`を取得する、

## 原資からP2PKで出力するトランザクションを作る
### Explorerから原資のトランザクションのHexを取得する
https://testnet.blockchain.info/rawtx/116f3df5d1fb04dff4574fb161e83c80c17fa619e9f98d9966a1a0616079c4bc?format=hex

#### 取得したHex
```bash
020000000001017721a764f484e73ba1a08ee21d635074e9e34c82b7080bc57baba4e87733455f0000000017160014a9c7cf1ca31f07e8a567433deded7ab46d38afdefeffffff02a0860100000000001976a9149cd84d72559d1d7712e0d9aba5c54af95243e9ee88ac58117a000000000017a914ff06444c89175bc769fe8e17517ac4c0192e63288702473044022034da55fee449b588e9f2f710bda13605db3b597ed4d5588e0fec4232e1bf52a8022069283e3abbc611de3da6b3e9b94e0da36656f1df769519e0504035711bbef578012103b070475b0296dc03c9fee2f6a31f34d340db75dfb2df2e993793d11b9f5b14eef60d1c00
```

### 生トランザクションの作成
```javascript
// gentx.js
const bit = require('bitcoinjs-lib')
const TESTNET = bit.networks.testnet

// 上で作った秘密鍵からECPairを復元
const privKey = Buffer.from("e12f42cca4de231e5ac282ba75d937a4bfe62047aebcc4f9e5557c5beeac9239", "hex")
const p = bit.ECPair.fromPrivateKey(privKey)

const psbt = new bit.Psbt({ network: TESTNET })
psbt.addInput({
	hash: '116f3df5d1fb04dff4574fb161e83c80c17fa619e9f98d9966a1a0616079c4bc', // 原資の出力が含まれているトランザクションのハッシュ
	index: 0,   // 原資の出力のindex
	nonWitnessUtxo: Buffer.from( // 原資の出力が含まれているトランザクション全体のBuffer
		'020000000001017721a764f484e73ba1a08ee21d635074e9e34c82b7080bc57baba4e87733455f0000000017160014a9c7cf1ca31f07e8a567433deded7ab46d38afdefeffffff02a0860100000000001976a9149cd84d72559d1d7712e0d9aba5c54af95243e9ee88ac58117a000000000017a914ff06444c89175bc769fe8e17517ac4c0192e63288702473044022034da55fee449b588e9f2f710bda13605db3b597ed4d5588e0fec4232e1bf52a8022069283e3abbc611de3da6b3e9b94e0da36656f1df769519e0504035711bbef578012103b070475b0296dc03c9fee2f6a31f34d340db75dfb2df2e993793d11b9f5b14eef60d1c00',
		'hex',
	),
})

const p2pk = bit.payments.p2pk({ pubkey: p.publicKey, network: TESTNET })
psbt.addOutput({
	script: p2pk.output,  // P2PKのスクリプトを公開鍵から出力して設定
	value: 10000,  // 0.0001 BTC
});
psbt.addOutput({
	address: 'mupGpwcxCJkWXqkqWuojy4Dcrrn8ngC1rT', // おつりは自分に戻す
	value: 8500,  // 500 Satoshi for the fee
});

psbt.signInput(0, p);
psbt.validateSignaturesOfInput(0);
psbt.finalizeAllInputs();
const txHex = psbt.extractTransaction().toHex()

console.log(txHex)
```

#### 実行結果
```bash
$ node gentx.js 
0200000001bcc4796061a0a166998df9e919a67fc1803ce861b14f57f4df04fbd1f53d6f11000000006b483045022100a911ffa91fda36f21834dbebcb9531a4293d0f4400f7b6750c9aa95840fb1387022045fac1520428bdf9a0a10169cbf14ed23d9f4d2b655d80248c186952bad584ce0121025bb45b88a6cc18fafe1befac52e6907e07b2f5e6887bddaabb3f45385accf788ffffffff0210270000000000002321025bb45b88a6cc18fafe1befac52e6907e07b2f5e6887bddaabb3f45385accf788ac34210000000000001976a9149cd84d72559d1d7712e0d9aba5c54af95243e9ee88ac00000000
```

## トランザクションをブロードキャスト
例えばここから https://blockstream.info/testnet/tx/push 送ると、
https://blockstream.info/testnet/tx/23e339961725176af3390ccfe1c82d82b97e9629a25fc4a832704f99ab196e0b

送られたトランザクションの詳細画面に切り替わる。ここで、下の方にある`DETAIL +`をクリックして見ると、右上にP2PKの出力が出来ていて、上で作った公開鍵 `025bb45b88a6cc18fafe1befac52e6907e07b2f5e6887bddaabb3f45385accf788` が`SCRIPTPUBKEY (ASM)`に含まれていることが確認できる。

![Kazam_screenshot_00004.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/499443/4cd81ae0-bc83-6e0a-2fe8-3f25ff882deb.png)

# お礼
bitcoinjsは本当に便利ですね。メンテしている方々、どうもありがとうございます。