size_t validate_block::script_hash_signature_operations_count( const script& output_script, const script& input_script) { if (output_script.type() != payment_type::script_hash) return count_script_sigops(output_script.operations(), true); if (input_script.operations().empty()) return 0; script eval_script = parse_script(input_script.operations().back().data); return count_script_sigops(eval_script.operations(), true); }
bool extract(payment_address& address, const script& scr) { // Cast a data_chunk to a short_hash and set the address auto set_hash_data = [&address](payment_type pay_type, 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(pay_type, hash_data); }; const operation_stack& ops = scr.operations(); payment_type pay_type = scr.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(pay_type, ops[2].data); return true; case payment_type::script_hash: BITCOIN_ASSERT(ops.size() == 3); set_hash_data(pay_type, 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, generate_ripemd_hash(ops.back().data)); return true; default: return false; } // Should never happen! return false; }