View in context in the libbitcoin Slack #general mirror.
tapscript bool and tapleaf hash values):
bool transaction::version1_sighash(hash_digest& out,
const input_iterator& input, const script& script, uint64_t value,
uint8_t sighash_flags) const NOEXCEPT
{
constexpr uint8_t epoch{};
// TODO: obtain tapscript indicator and access to tapleaf hash.
constexpr bool tapscript{};
constexpr hash_digest tapleaf{};
const auto& in = **input;
const auto& annex = in.witness().annex();
// Mask anyone_can_pay, and set hash_all by default.
// sighash_flags previously verified (see schnorr_split).
const auto flag = mask_sighash(sighash_flags);
const auto anyone = is_anyone_can_pay(sighash_flags);
const auto single = (flag == coverage::hash_single);
const auto all = (flag == coverage::hash_all);
// Create tagged hash writer.
stream::out::fast stream{ out };
hash::sha256t::fast<"TapSighash"> sink{ stream };
sink.write_byte(epoch);
sink.write_byte(sighash_flags);
sink.write_4_bytes_little_endian(version_);
sink.write_4_bytes_little_endian(locktime_);
if (!anyone)
{
sink.write_bytes(single_hash_points());
sink.write_bytes(single_hash_amounts());
sink.write_bytes(single_hash_scripts());
sink.write_bytes(single_hash_sequences());
}
if (all)
{
sink.write_bytes(single_hash_outputs());
}
sink.write_byte(spend_type_v1(annex, tapscript));
if (anyone)
{
in.point().to_data(sink);
sink.write_8_bytes_little_endian(value);
script.to_data(sink, true);
sink.write_4_bytes_little_endian(in.sequence());
}
else
{
sink.write_4_bytes_little_endian(input_index(input));
}
if (annex)
{
sink.write_variable(annex.size());
sink.write_bytes(annex.hash());
}
if (single)
{
const auto index = input_index(input);
if (output_overflow(index))
return false;
sink.write_bytes(outputs_->at(index)->hash());
}
// Additional for tapscript [bip342].
if (tapscript)
{
sink.write_bytes(tapleaf);
sink.write_byte(to_value(key_version::tapscript));
sink.write_4_bytes_little_endian(subscript_v1(script));
}
sink.flush();
return true;
}