Create a gist now

Instantly share code, notes, and snippets.

Embed
require 'btcruby'
require 'bitcoin'
require 'bech32'
require './segwit_addr'
require 'active_support'
require 'active_support/core_ext'
require 'ffi'
BTC::Network.default= BTC::Network.mainnet
# Creation of Witness Script: here a 2-of-2 multisig as an example
@public_key = "02530c548d402670b13ad8887ff99c294e67fc18097d236d57880c69261b42def7"
@user_key = BTC::Key.new(public_key:BTC.from_hex(@public_key))
@escrow_key = BTC::Key.new(public_key:BTC.from_hex("024fffe85607b555cf7697e4be0d3d34dc1868baa57c235d926e447e926c08d287"))
witness_script = BTC::Script.new << BTC::Script::OP_2 << @user_key.compressed_public_key << @escrow_key.compressed_public_key << BTC::Script::OP_2
witness_script << BTC::Script::OP_CHECKMULTISIG
# Calculation of Native P2WSH Address:
script_pub_key = BTC::Script.new
script_pub_key<< BTC::Script::OP_0
script_pub_key<< BTC.sha256(witness_script.data)
native_p2wsh_address = SegwitAddr.new
native_p2wsh_address.hrp = 'bc' # hrp = human-readable part
native_p2wsh_address.scriptpubkey = script_pub_key.to_hex
puts "\n Native P2WSH Address: #{native_p2wsh_address.addr} \n\n"
# Native P2WSH Address: bc1qhe8n322l05p35lu2p6g9vgerh93xlsatghmat9mxuctgpzcudqssd2xcyt
# Transaction funding Native P2WSH Address:
@wif = "KxUk...vHQUFC" # address = 16xgoSrGkG3z6eddGr3m4iqoBDTFWuV6J4
@user_key = BTC::Key.new(wif:@wif)
prev_out = "e4f0b0133ac10bd5502ecebeebc398d896a30761027341a8bc9f620d0b2ddbb8"
prev_out_index = 0
value = 100000
fee = 15000
tx = BTC::Transaction.new(version: 2)
tx.lock_time = 0
tx.add_input(BTC::TransactionInput.new( previous_id: prev_out,
previous_index: prev_out_index,
sequence: 0))
tx.add_output(BTC::TransactionOutput.new(value: value-fee, script: script_pub_key))
hashtype = BTC::SIGHASH_ALL
sighash = tx.signature_hash(input_index: 0,
output_script: BTC::PublicKeyAddress.parse(@user_key.address.to_s).script,
hash_type: hashtype)
tx.inputs[0].signature_script = BTC::Script.new
tx.inputs[0].signature_script << (@user_key.ecdsa_signature(sighash) + BTC::WireFormat.encode_uint8(hashtype))
tx.inputs[0].signature_script << @user_key.public_key
puts tx.to_hex
# Transaction spending from P2WSH
prev_out = "8f0d08b70fb21234df24f47d533601d6fbaa55dabb443c6f8290ffb58dd9241b"
prev_out_index = 0
value = 85000
script_pubkey = script_pub_key.to_hex.htb
fee = 15000
include Bitcoin::Builder
include Bitcoin::Protocol
include Bitcoin::Secp256k1
@destination_address = "1Bwyn5f5EvUPazh3H2rns6ENjTUYnK9ben"
user_key = Bitcoin.open_key("2594addf...cf7f7b2d9") # <- privkey
escrow_key = Bitcoin.open_key("4bd5e...d6975c")
@witness_script = witness_script.data
spend_tx = build_tx do |t|
t.lock_time 0
t.input do |i|
i.prev_out prev_out, prev_out_index, script_pubkey, value
i.sequence "ffffffff".htb
end
t.output do |o|
o.value value-fee
o.script {|s| s.recipient @destination_address }
end
end
tx = Bitcoin::Protocol::Tx.new(spend_tx.to_payload) # initial (unsigned) transaction
sig_hash0 = tx.signature_hash_for_witness_input(0, script_pubkey, value, @witness_script, Tx::SIGHASH_TYPE[:all])
sig0 = Bitcoin::Secp256k1.sign(sig_hash0, user_key.private_key.to_hex.htb) + [Bitcoin::Protocol::Tx::SIGHASH_TYPE[:all]].pack("C")
sig1 = Bitcoin::Secp256k1.sign(sig_hash0, escrow_key.private_key.to_hex.htb) + [Bitcoin::Protocol::Tx::SIGHASH_TYPE[:all]].pack("C")
tx.in[0].script_witness.stack << ''
tx.in[0].script_witness.stack << sig0
tx.in[0].script_witness.stack << sig1
tx.in[0].script_witness.stack << @witness_script
tx.to_witness_payload.bth # successful txid: 42b2c123ed8b96b26d5442d181cb6dd8c5403340e46d16e6ec6784a1d50f82f5 ( 305 bytes)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment