lib/bitcoin/script.rb in bitcoin-ruby-0.0.14 vs lib/bitcoin/script.rb in bitcoin-ruby-0.0.15
- old
+ new
@@ -597,23 +597,23 @@
# is this an op_return script
def is_op_return?
@chunks[0] == OP_RETURN && @chunks.size <= 2
end
- # is this a witness script(witness_v0_keyhash or witness_v0_scripthash)
+ # is this a witness script
def is_witness?
- is_witness_v0_keyhash? || is_witness_v0_scripthash?
+ @chunks.length == 2 && (0..16).include?(@chunks[0]) && @chunks[1].is_a?(String)
end
# is this a witness pubkey script
def is_witness_v0_keyhash?
- @chunks.length == 2 &&@chunks[0] == 0 && @chunks[1].is_a?(String) && @chunks[1].bytesize == 20
+ is_witness? && @chunks[0] == 0 && @chunks[1].bytesize == 20
end
# is this a witness script hash
def is_witness_v0_scripthash?
- @chunks.length == 2 &&@chunks[0] == 0 && @chunks[1].is_a?(String) && @chunks[1].bytesize == 32
+ is_witness? && @chunks[0] == 0 && @chunks[1].bytesize == 32
end
# Verify the script is only pushing data onto the stack
def is_push_only?(script_data=nil)
check_pushes(push_only=true, canonical_only=false, (script_data||@input_script))
@@ -729,10 +729,16 @@
def get_addresses
return [get_pubkey_address] if is_pubkey?
return [get_hash160_address] if is_hash160?
return get_multisig_addresses if is_multisig?
return [get_p2sh_address] if is_p2sh?
+
+ if is_witness_v0_keyhash? || is_witness_v0_scripthash?
+ program_hex = chunks[1].unpack("H*").first
+ return Bitcoin.encode_segwit_address(0, program_hex)
+ end
+
[]
end
# get single address, or first for multisig script
def get_address
@@ -760,32 +766,43 @@
return nil unless p2sh
# HASH160 length hash EQUAL
[ ["a9", "14", p2sh, "87"].join ].pack("H*")
end
+ # generate pay-to-witness output script for given +witness_version+ and
+ # +witness_program+. returns a raw binary script of the form:
+ # <witness_version> <witness_program>
+ def self.to_witness_script(witness_version, witness_program_hex)
+ return nil unless (0..16).include?(witness_version)
+ return nil unless witness_program_hex
+ version = witness_version != 0 ? 0x50 + witness_version : 0 # 0x50 for OP_1.. codes
+ [version].pack('C') + pack_pushdata(witness_program_hex.htb)
+ end
+
# generate p2wpkh tx for given +address+. returns a raw binary script of the form:
# 0 <hash160>
def self.to_witness_hash160_script(hash160)
return nil unless hash160
- # witness ver length hash160
- [ ["00", "14", hash160].join ].pack("H*")
+ to_witness_script(0, hash160)
end
# generate p2wsh output script for given +p2sh+ sha256. returns a raw binary script of the form:
# 0 <p2sh>
def self.to_witness_p2sh_script(p2sh)
return nil unless p2sh
- # witness ver length sha256
- [ [ "00", "20", p2sh].join].pack("H*")
+ to_witness_script(0, p2sh)
end
# generate hash160 or p2sh output script, depending on the type of the given +address+.
# see #to_hash160_script and #to_p2sh_script.
def self.to_address_script(address)
hash160 = Bitcoin.hash160_from_address(address)
case Bitcoin.address_type(address)
when :hash160; to_hash160_script(hash160)
when :p2sh; to_p2sh_script(hash160)
+ when :witness_v0_keyhash, :witness_v0_scripthash
+ witness_version, witness_program_hex = Bitcoin.decode_segwit_address(address)
+ to_witness_script(witness_version, witness_program_hex)
end
end
# generate multisig output script for given +pubkeys+, expecting +m+ signatures.
# returns a raw binary script of the form: