@@ -144,7 +144,7 @@ uint32_t transaction::input_index(const input_iterator& input) const NOEXCEPT
144
144
// *****************************************************************************
145
145
inline coverage transaction::mask_sighash (uint8_t sighash_flags) NOEXCEPT
146
146
{
147
- switch (sighash_flags & coverage::mask)
147
+ switch (bit_and< uint8_t >( sighash_flags, coverage::mask) )
148
148
{
149
149
case coverage::hash_single:
150
150
return coverage::hash_single;
@@ -155,6 +155,11 @@ inline coverage transaction::mask_sighash(uint8_t sighash_flags) NOEXCEPT
155
155
}
156
156
}
157
157
158
+ inline bool transaction::is_anyone_can_pay (uint8_t sighash_flags) NOEXCEPT
159
+ {
160
+ return to_bool (bit_and<uint8_t >(sighash_flags, coverage::anyone_can_pay));
161
+ }
162
+
158
163
// ****************************************************************************
159
164
// CONSENSUS: sighash flags are carried in a single byte but are encoded as 4
160
165
// bytes in the signature hash preimage serialization.
@@ -167,8 +172,8 @@ void transaction::signature_hash_single(writer& sink,
167
172
const auto write_inputs = [this , &input, &subscript, sighash_flags](
168
173
writer& sink) NOEXCEPT
169
174
{
170
- const auto anyone = to_bool (sighash_flags & coverage::anyone_can_pay);
171
175
input_cptrs::const_iterator in;
176
+ const auto anyone = is_anyone_can_pay (sighash_flags);
172
177
173
178
sink.write_variable (anyone ? one : inputs_->size ());
174
179
@@ -218,8 +223,8 @@ void transaction::signature_hash_none(writer& sink,
218
223
const auto write_inputs = [this , &input, &subscript, sighash_flags](
219
224
writer& sink) NOEXCEPT
220
225
{
221
- const auto anyone = to_bool (sighash_flags & coverage::anyone_can_pay);
222
226
input_cptrs::const_iterator in;
227
+ const auto anyone = is_anyone_can_pay (sighash_flags);
223
228
224
229
sink.write_variable (anyone ? one : inputs_->size ());
225
230
@@ -256,8 +261,8 @@ void transaction::signature_hash_all(writer& sink,
256
261
const auto write_inputs = [this , &input, &subscript, sighash_flags](
257
262
writer& sink) NOEXCEPT
258
263
{
259
- const auto anyone = to_bool (sighash_flags & coverage::anyone_can_pay);
260
264
input_cptrs::const_iterator in;
265
+ const auto anyone = is_anyone_can_pay (sighash_flags);
261
266
262
267
sink.write_variable (anyone ? one : inputs_->size ());
263
268
@@ -380,7 +385,7 @@ hash_digest transaction::version_0_sighash(const input_iterator& input,
380
385
uint8_t sighash_flags) const NOEXCEPT
381
386
{
382
387
// Set options.
383
- const auto anyone = to_bool (sighash_flags & coverage::anyone_can_pay );
388
+ const auto anyone = is_anyone_can_pay (sighash_flags);
384
389
const auto flag = mask_sighash (sighash_flags);
385
390
const auto all = (flag == coverage::hash_all);
386
391
const auto single = (flag == coverage::hash_single);
@@ -427,31 +432,48 @@ hash_digest transaction::version_0_sighash(const input_iterator& input,
427
432
// Because the codeseparator_position is the last input to the hash, the SHA256
428
433
// midstate can be efficiently cached for multiple OP_CODESEPARATOR in a script.
429
434
430
- // static
431
- // BIP341: Using any undefined hash_type causes validation failure if violated.
432
- // defined types: 0x00, 0x01, 0x02, 0x03, 0x81, 0x82, or 0x83. [zero is the
433
- // default and cannot be explicit, but is serialized for signature hashing.
434
- inline bool transaction::is_sighash_valid (uint8_t sighash_flags) NOEXCEPT
435
- {
436
- switch (sighash_flags)
437
- {
438
- case coverage::hash_default:
439
- case coverage::hash_all:
440
- case coverage::hash_none:
441
- case coverage::hash_single:
442
- case coverage::all_anyone_can_pay:
443
- case coverage::none_anyone_can_pay:
444
- case coverage::single_anyone_can_pay:
445
- return true ;
446
- default :
447
- return false ;
448
- }
449
- }
450
-
451
435
hash_digest transaction::version_1_sighash (const input_iterator& input,
452
436
const script& script, uint64_t value, uint8_t sighash_flags) const NOEXCEPT
453
437
{
454
- return {};
438
+ // Set options.
439
+ const auto anyone = is_anyone_can_pay (sighash_flags);
440
+ const auto flag = mask_sighash (sighash_flags);
441
+ const auto all = (flag == coverage::hash_all);
442
+ const auto single = (flag == coverage::hash_single);
443
+
444
+ // Create hash writer.
445
+ hash_digest digest{};
446
+ stream::out::fast stream{ digest };
447
+ hash::sha256x2::fast sink{ stream };
448
+
449
+ // Create signature hash.
450
+ sink.write_little_endian (version_);
451
+
452
+ // Conditioning points, sequences, and outputs writes on cache_ instead of
453
+ // conditionally passing them from methods avoids copying the cached hash.
454
+
455
+ // points
456
+ sink.write_bytes (!anyone ? points_hash () : null_hash);
457
+
458
+ // sequences
459
+ sink.write_bytes (!anyone && all ? sequences_hash () : null_hash);
460
+
461
+ (*input)->point ().to_data (sink);
462
+ script.to_data (sink, prefixed);
463
+ sink.write_little_endian (value);
464
+ sink.write_little_endian ((*input)->sequence ());
465
+
466
+ // outputs
467
+ if (single)
468
+ sink.write_bytes (output_hash (input));
469
+ else
470
+ sink.write_bytes (all ? outputs_hash () : null_hash);
471
+
472
+ sink.write_little_endian (locktime_);
473
+ sink.write_4_bytes_little_endian (sighash_flags);
474
+
475
+ sink.flush ();
476
+ return digest;
455
477
}
456
478
457
479
} // namespace chain
0 commit comments