Last active
November 15, 2020 09:51
-
-
Save pierrenoizat/6880a12a599fa03a2099e3b38e8664e0 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'bitcoin' | |
require 'money-tree' | |
require 'bip44' | |
require 'bech32' | |
include Bitcoin | |
include Bitcoin::Builder | |
include Bitcoin::Protocol | |
include Bitcoin::Util | |
include Bitcoin::Secp256k1 | |
include Bech32 | |
base_factor = 100000000 | |
mnemonic = "beyond .. satoshi" # enter your own passphrase here | |
seed = BipMnemonic.to_seed(mnemonic: mnemonic) | |
@btc_wallet = Bip44::Wallet.from_seed(seed, "m/44'/0") | |
@btc_node = @btc_wallet.sub_wallet "m/0/1" | |
alice_public_key = Key.new(nil,@btc_node.public_key).pub | |
@btc_node = @btc_wallet.sub_wallet "m/0/2" | |
bob_public_key = Key.new(nil,@btc_node.public_key).pub_compressed | |
@btc_node = @btc_wallet.sub_wallet "m/0/3" | |
escrow_public_key = Key.new(nil,@btc_node.public_key).pub_compressed | |
# Creation of Witness Script: here a 2-of-2 multisig as an example | |
witness_script_string = "2 #{bob_public_key} #{escrow_public_key} 2 OP_CHECKMULTISIG" | |
witness_script = Script.from_string(witness_script_string).to_payload | |
# Calculation of Native P2WSH Address: | |
script_pubkey = Script.to_witness_p2sh_script(sha256(witness_script.bth)) | |
native_p2wsh_address = SegwitAddr.new | |
native_p2wsh_address.hrp = 'bc' # hrp = human-readable part | |
native_p2wsh_address.script_pubkey = script_pubkey.bth | |
puts "\n Native P2WSH Address: #{native_p2wsh_address.addr} \n\n" | |
# Native P2WSH Address: bc1qxfet744v05jfc3ks7gf4pguyjjfqcfvtsjvxkwa7emgvv4990arq3rwz2v | |
# Transaction funding Native P2WSH Address: | |
@btc_node = @btc_wallet.sub_wallet "m/0/1" | |
puts Key.new(nil,@btc_node.public_key).addr # standard (legacy) uncompressed address | |
destination_address = "bc1qxfet744v05jfc3ks7gf4pguyjjfqcfvtsjvxkwa7emgvv4990arq3rwz2v" | |
utxo_txid = "2a0b545e58fa1d799fedf90488663f8b7cd74ef827fd65b202f37a394f28fb7e" | |
utxo_index = 1 | |
amount = 0.00072387 * base_factor | |
fee = 0.0001 * base_factor | |
sent_amount = amount - fee | |
script_pubkey = Script.to_hash160_script(hash160(alice_public_key)) # to spend a standard utxo | |
tx = build_tx do |t| | |
t.input do |i| | |
i.prev_out utxo_txid | |
i.prev_out_index utxo_index | |
end | |
t.output do |o| | |
o.value sent_amount | |
o.script {|s| s.recipient destination_address } | |
end | |
end | |
tx.to_payload.bth # unsigned tx | |
sig_hash = tx.signature_hash_for_input(0, script_pubkey) | |
sig = Secp256k1.sign(sig_hash, @btc_node.private_key.htb) | |
tx.in[0].script_sig = Script.to_signature_pubkey_script(sig, alice_public_key.htb) | |
puts tx.to_payload.unpack('H*')[0] # signed tx (in hex) | |
puts tx.hash | |
# Transaction spending from P2WSH | |
utxo_txid = "cc432fa044a0ceeb48905be54bcd813ab5ac2e4b41c4a50493fedc8053831c0b" | |
utxo_index = 1 | |
amount = 0.00074434 * base_factor | |
fee = 0.0001 * base_factor | |
sent_amount = amount - fee | |
destination_address = "12qeTKzrK7wm1V8rCjYEysAdtD5D3PxfPV" | |
script_pubkey = Script.to_witness_p2sh_script(sha256(witness_script.bth)) | |
spend_tx = build_tx do |t| | |
t.lock_time 0 | |
t.input do |i| | |
i.prev_out utxo_txid, utxo_index, script_pubkey, amount | |
i.sequence "ffffffff".htb | |
end | |
t.output do |o| | |
o.value sent_amount | |
o.script {|s| s.recipient destination_address } | |
end | |
end | |
tx = Tx.new(spend_tx.to_payload) # initial (unsigned) transaction | |
sig_hash = tx.signature_hash_for_witness_input(0, script_pubkey, amount, witness_script, Tx::SIGHASH_TYPE[:all]) | |
@btc_node = @btc_wallet.sub_wallet "m/0/2" | |
bob_sig = Secp256k1.sign(sig_hash, @btc_node.private_key.htb) + [Tx::SIGHASH_TYPE[:all]].pack("C") | |
@btc_node = @btc_wallet.sub_wallet "m/0/3" | |
escrow_sig = Secp256k1.sign(sig_hash, @btc_node.private_key.htb) + [Tx::SIGHASH_TYPE[:all]].pack("C") | |
tx.in[0].script_witness.stack << '' # init stack | |
tx.in[0].script_witness.stack << bob_sig | |
tx.in[0].script_witness.stack << escrow_sig | |
tx.in[0].script_witness.stack << witness_script | |
tx.to_witness_payload.bth | |
# sample tx id = "e097a3bad35d7e27adc9e770ea178bfb44e4a83d86421d3a69fb671844d878e9" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment