Class: Bitcoin::SigHashGenerator::SchnorrSigHashGenerator
- Inherits:
-
Object
- Object
- Bitcoin::SigHashGenerator::SchnorrSigHashGenerator
- Defined in:
- lib/bitcoin/sighash_generator.rb
Overview
v1 witness sighash generator see: github.com/bitcoin/bips/blob/master/bip-0341.mediawiki
Instance Method Summary collapse
-
#generate(tx, input_index, hash_type, opts) ⇒ String
generate signature hash for taproot and tapscript - sig_version: sig version.
Instance Method Details
#generate(tx, input_index, hash_type, opts) ⇒ String
generate signature hash for taproot and tapscript
-
sig_version: sig version. :taproot or :tapscript
-
prevouts: array of all prevout
-
annex: annex value with binary format if annex exist.
-
leaf_hash: leaf hash with binary format if sig_version is :tapscript, it required
-
last_code_separator_pos: the position of last code separator
110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 |
# File 'lib/bitcoin/sighash_generator.rb', line 110 def generate(tx, input_index, hash_type, opts) raise ArgumentError, 'Invalid sig_version was specified.' unless [:taproot, :tapscript].include?(opts[:sig_version]) ext_flag = opts[:sig_version] == :taproot ? 0 : 1 key_version = 0 output_ype = hash_type == SIGHASH_TYPE[:default] ? SIGHASH_TYPE[:all] : (hash_type & 0x03) input_type = hash_type & 0x80 epoc = '00'.htb buf = epoc # EPOC buf << [hash_type, tx.version, tx.lock_time].pack('CVV') unless input_type == SIGHASH_TYPE[:anyonecanpay] buf << Bitcoin.sha256(tx.in.map{|i|i.out_point.to_payload}.join) # sha_prevouts buf << Bitcoin.sha256(opts[:prevouts].map(&:value).pack('Q*'))# sha_amounts buf << Bitcoin.sha256(opts[:prevouts].map{|o|o.script_pubkey.to_payload(true)}.join) # sha_scriptpubkeys buf << Bitcoin.sha256(tx.in.map(&:sequence).pack('V*')) # sha_sequences end buf << Bitcoin.sha256(tx.out.map(&:to_payload).join) if output_ype == SIGHASH_TYPE[:all] spend_type = (ext_flag << 1) + (opts[:annex] ? 1 : 0) buf << [spend_type].pack('C') if input_type == SIGHASH_TYPE[:anyonecanpay] buf << tx.in[input_index].out_point.to_payload buf << opts[:prevouts][input_index].to_payload buf << [tx.in[input_index].sequence].pack('V') else buf << [input_index].pack('V') end buf << Bitcoin.sha256(Bitcoin.pack_var_string(opts[:annex])) if opts[:annex] if output_ype == SIGHASH_TYPE[:single] raise ArgumentError, "Tx does not have #{input_index} th output." if input_index >= tx.out.size buf << Bitcoin.sha256(tx.out[input_index].to_payload) end if opts[:sig_version] == :tapscript buf << opts[:leaf_hash] buf << [key_version, opts[:last_code_separator_pos]].pack("CV") end Bitcoin.tagged_hash('TapSighash', buf) end |