size_t script_hash_signature_operations_count( const script_type& output_script, const script_type& input_script) { if (output_script.type() != payment_type::script_hash) return 0; if (input_script.operations().empty()) return 0; const data_chunk& last_data = input_script.operations().back().data; script_type eval_script = parse_script(last_data); return count_script_sigops(eval_script.operations(), true); }
bool extract(payment_address& address, const script_type& script) { // Cast a data_chunk to a short_hash and set the address auto set_hash_data = [&address](uint8_t version, const data_chunk& raw_hash) { short_hash hash_data; BITCOIN_ASSERT(raw_hash.size() == hash_data.size()); std::copy(raw_hash.begin(), raw_hash.end(), hash_data.begin()); address.set(version, hash_data); }; const operation_stack& ops = script.operations(); payment_type pay_type = script.type(); switch (pay_type) { case payment_type::pubkey: BITCOIN_ASSERT(ops.size() == 2); set_public_key(address, ops[0].data); return true; case payment_type::pubkey_hash: BITCOIN_ASSERT(ops.size() == 5); set_hash_data(payment_address::pubkey_version, ops[2].data); return true; case payment_type::script_hash: BITCOIN_ASSERT(ops.size() == 3); set_hash_data(payment_address::script_version, ops[1].data); return true; case payment_type::multisig: // Unimplemented... return false; case payment_type::pubkey_hash_sig: BITCOIN_ASSERT(ops.size() == 2); set_public_key(address, ops[1].data); return true; case payment_type::script_code_sig: // Should have at least 1 sig and the script code. BITCOIN_ASSERT(ops.size() > 1); set_script_hash(address, bitcoin_short_hash(ops.back().data)); return true; default: return false; } // Should never happen! return false; }