事前準備
事前に知っておいたほうが良い知識はここを読んで理解しておく。
https://www.daiki0321.com/post/block-chain%E3%81%A8%E3%81%AF%E4%BD%95%E3%81%8B
BitCoin のビルド
こちらを参考にインストールしていく。
Mac用の手順はこちら
https://github.com/bitcoin/bitcoin/blob/master/doc/build-osx.md
$ brew install automake berkeley-db4 libtool boost miniupnpc pkg-config python qt libevent qrencode sqlite
$ git clone https://github.com/bitcoin/bitcoin.git
$ cd bitcoin/
$ ./contrib/install_db4.sh .
$ ./autogen.sh
$ ./configure && make && make check
$ sudo make install
bitcoinrb のインストール
rubyのversionが2.4.4より高くないと、以下のエラーが出てbitcoinrbがインストールできない。
ERROR: Error installing bitcoinrb:
zeitwerk requires Ruby version >= 2.4.4.
ruby のVersionの確認の仕方
$ ruby --version
ruby 2.3.7p456 (2018-03-28 revision 63024) [universal.x86_64-darwin18]
私の環境では、rubyのVersionが低かったので、updateした。
$ brew install ruby
$ echo 'export PATH="/usr/local/opt/ruby/bin:$PATH"' >> /Users/<Username>/.bash_profile
$ export PATH="/usr/local/opt/ruby/bin:$PATH"
$ ruby --version
$ sudo gem install bitcoinrb
irb上で、bitcoinが使えればOK
$ irb
irb(main):001:0> require 'bitcoin'
=> true
testnet を使って、walletの作成
こちらのサイトを参考に作成した。
https://armedia.com/blog/bitcoin-testnet-beginners-guide/
bitcoin-qtに-testnetを付けて起動する。
$ bitcoin-qt -testnet
これまでのBlock Chainの取引履歴のブロックがsyncされる、数時間かかるので待つ。
完了したらwalletの作成を行う。
wallet名をtestwalletとして作成する。
testnet用のbitcoinを受け取る。
"受取"のタブを選択後に、新しい受取用アドレスを作成をクリックすると、支払い情報のページが表示されるので、アドレスをコピーする。
ここからtestnet用のbitcoinが入手できる。リンクが無効であれば自分で探してください。
https://testnet-faucet.mempool.co/
Transcationを作成するためにコンソールから以下のコマンドを実行し、UTXOの情報を取得しておく。
次のStepで①〜④が必要になる
>listunspent
[
{
"txid": "709b8d597eb9a1a570f335b9b251f076108a2aed215b593dda663fe351ad1248", ・・・①
"vout": 0,
"address": "tb1qhpfmywf0vh095lh224pv*********",
"label": "",
"scriptPubKey": "0014b853b2392f65de5a7eea5542cfcfe48107c02e51", ・・・④
"amount": 0.00090000,
"confirmations": 286,
"spendable": true,
"solvable": true,
"desc": "wpkh([938552b2/0'/0'/2']03652f8d2d808df552cbea54ccb5f7b0771397b74e2df4531a88b6f73790c77ec5)#0ayly45q",
"safe": true
}
]
>getnewaddress ・・・②
>dumpprivkey <listunspentの結果の"address"を指定> ・・・③
Transaction の作成
ここでは、例として自分自身に対して、送金するトランザクションを作成してみる。
Pay to Public Key Hash(P2PKH)という、公開鍵のハッシュ値を使って送金する最も代表的なトランザクション形式を使う。
$ irb
irb(main):001:0> require 'bitcoin'
irb(main):002:0> Bitcoin.chain_params = :testnet
# 新規のトランザクションを作成
irb(main):003:0> tx = Bitcoin::Tx.new
# Txのinputに対して、UTXOを指定する。自分のwalletに入っている、UXTOをBitcoinCore側で"listunspen"を実行して、txidを取得する。
irb(main):004:0> out_point = Bitcoin::OutPoint.from_txid("①の結果を入れる", 0)
irb(main):005:0> tx_in = Bitcoin::TxIn.new(out_point: out_point)
irb(main):006:0> tx.in << tx_in
# txの中身を確認。
irb(main):007:0> tx
# amountは送金したい金額(value)と手数料(1000)の合計になるようにする。単位はSatoshi
irb(main):008:0> amount = 100000
irb(main):009:0> value = amount - 10000
# トランザクションのoutputを設定する。outputは送金したいbitcoinアドレスとなるため、Wallet側で②を実行して、取得したアドレスを入れる。
irb(main):010:0> script_pubkey = Bitcoin::Script.parse_from_addr("②の結果")
irb(main):011:0> tx_out = Bitcoin::TxOut.new(value: value, script_pubkey: script_pubkey)
irb(main):012:0> tx.out << tx_out
# UTXOを使うために、秘密鍵から鍵情報を取得する。③のコマンドで圧縮された鍵情報が取得できる。
irb(main):014:0> key = Bitcoin::Key.from_wif("③の結果")
# 公開鍵と秘密鍵が以下のコマンドでわかる。
irb(main):015:0> key.pub_key
irb(main):016:0> key.priv_key
# UTXOを解除するために、UTXOのScript Public key を取得する。
irb(main):018:0> prev_script_pubkey = Bitcoin::Script.parse_from_payload('④の結果'.htb)
# 取得したPublic keyを使ってUTXOをunlockするために署名を作成する。
irb(main):019:0> sighash = tx.sighash_for_input(0,prev_script_pubkey, sig_version: :witness_v0, amount: amount)
irb(main):020:0> sig = key.sign(sighash) + [Bitcoin::SIGHASH_TYPE[:all]].pack('C')
# 署名とpublic keyを付けてstackに積むことでunlock scriptが出来上がる。
irb(main):021:0> tx.in[0].script_witness.stack << sig
irb(main):022:0> tx.in[0].script_witness.stack << key.pubkey.htb
# 作成したunlock scriptを使ってUTXOをunlockして、送金する。
irb(main):023:0> tx.verify_input_sig(0, prev_script_pubkey, amount: amount)
irb(main):024:0> tx.to_payload.bth
送金が完了すると、bitcoincore側のwalletで取引履歴が見れるようになる。
参考にしたサイト