Last active
November 16, 2020 08:47
-
-
Save pierrenoizat/a418968f2af4eaacfbff71e7a99c47fd to your computer and use it in GitHub Desktop.
Generate a P2SH-P2WSH address, create a tx spending from it.
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' | |
include Bitcoin | |
include Bitcoin::Builder | |
include Bitcoin::Protocol | |
include Bitcoin::Util | |
include Bitcoin::Secp256k1 | |
base_factor = 100000000 | |
mnemonic = "beyond .. satoshi" | |
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" | |
public_key_1 = Key.new(nil,@btc_node.public_key).pub_compressed | |
@btc_node = @btc_wallet.sub_wallet "m/0/2" | |
public_key_2 = Key.new(nil,@btc_node.public_key).pub_compressed | |
@btc_node = @btc_wallet.sub_wallet "m/0/3" | |
public_key_3 = Key.new(nil,@btc_node.public_key).pub_compressed | |
# Compute P2SH-P2WSH address: | |
witness_string = "2 #{public_key_1} #{public_key_2} #{public_key_3} 3 OP_CHECKMULTISIG" | |
witness_script = Script.from_string(witness_string).to_payload | |
redeem_string = "0 #{sha256(witness_script.bth)}" | |
redeem_script = Script.from_string(redeem_string).to_payload | |
p2sh_p2wsh_address = hash160_to_p2sh_address(hash160(redeem_script.bth)) | |
# example: 356yCBhiW9tqg5iiPDhEZ8f8t3JfqkEihA | |
# Build Segwit transaction spending from P2SH-P2WSH address: | |
utxo_txid="c57007980fabfd7c44895d8fc2c28c6ead93483b7c2bfec682ce0a3eaa4008ce" | |
utxo_index = 0 | |
amount = 0.00074465 * base_factor | |
fee = 0.0001 * base_factor | |
destination_address = "12qeTKzrK7wm1V8rCjYEysAdtD5D3PxfPV" | |
spend_tx = build_tx do |t| | |
t.lock_time 0 | |
t.input do |i| | |
i.prev_out utxo_txid, utxo_index, redeem_script, amount | |
i.sequence "ffffffff".htb | |
end | |
t.output do |o| | |
o.value amount-fee | |
o.script {|s| s.recipient destination_address } | |
end | |
end | |
tx = Tx.new(spend_tx.to_payload) # unsigned tx | |
tx.in[0].script_sig = Script.new(Script.pack_pushdata(redeem_script)).to_payload | |
sig_hash = tx.signature_hash_for_witness_input(0, redeem_script, amount, witness_script, Tx::SIGHASH_TYPE[:all]) | |
@btc_node = @btc_wallet.sub_wallet "m/0/2" | |
sig_2 = Secp256k1.sign(sig_hash, @btc_node.private_key.htb) + [Tx::SIGHASH_TYPE[:all]].pack("C") | |
@btc_node = @btc_wallet.sub_wallet "m/0/3" | |
sig_3 = 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 << sig_2 << sig_3 << witness_script | |
tx.to_payload.bth # signed transaction | |
# example transaction tid: 55c7c71c63b87478cd30d401e7ca5344a2e159dc8d6990df695c7e0cb2f82783 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment