Consensus-correct SignatureHash Returns (hash, err) to precisely match the consensus-critical behavior of the SIGHASH_SINGLE bug. (inIdx is *not* checked for validity)
(script, txTo, inIdx, hashtype)
| 592 | |
| 593 | |
| 594 | def SignatureHash(script, txTo, inIdx, hashtype): |
| 595 | """Consensus-correct SignatureHash |
| 596 | |
| 597 | Returns (hash, err) to precisely match the consensus-critical behavior of |
| 598 | the SIGHASH_SINGLE bug. (inIdx is *not* checked for validity) |
| 599 | """ |
| 600 | assert not (hashtype & SIGHASH_FORKID), "BIP143 is mandatory for FORKID enabled transactions." |
| 601 | |
| 602 | HASH_ONE = b'\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' |
| 603 | |
| 604 | if inIdx >= len(txTo.vin): |
| 605 | return (HASH_ONE, "inIdx %d out of range (%d)" % (inIdx, len(txTo.vin))) |
| 606 | txtmp = CTransaction(txTo) |
| 607 | |
| 608 | for txin in txtmp.vin: |
| 609 | txin.scriptSig = b'' |
| 610 | txtmp.vin[inIdx].scriptSig = FindAndDelete(script, CScript([OP_CODESEPARATOR])) |
| 611 | |
| 612 | if (hashtype & 0x1f) == SIGHASH_NONE: |
| 613 | txtmp.vout = [] |
| 614 | |
| 615 | for i in range(len(txtmp.vin)): |
| 616 | if i != inIdx: |
| 617 | txtmp.vin[i].nSequence = 0 |
| 618 | |
| 619 | elif (hashtype & 0x1f) == SIGHASH_SINGLE: |
| 620 | outIdx = inIdx |
| 621 | if outIdx >= len(txtmp.vout): |
| 622 | return (HASH_ONE, "outIdx %d out of range (%d)" % (outIdx, len(txtmp.vout))) |
| 623 | |
| 624 | tmp = txtmp.vout[outIdx] |
| 625 | txtmp.vout = [] |
| 626 | for i in range(outIdx): |
| 627 | txtmp.vout.append(CTxOut(-1)) |
| 628 | txtmp.vout.append(tmp) |
| 629 | |
| 630 | for i in range(len(txtmp.vin)): |
| 631 | if i != inIdx: |
| 632 | txtmp.vin[i].nSequence = 0 |
| 633 | |
| 634 | if hashtype & SIGHASH_ANYONECANPAY: |
| 635 | tmp = txtmp.vin[inIdx] |
| 636 | txtmp.vin = [] |
| 637 | txtmp.vin.append(tmp) |
| 638 | |
| 639 | s = txtmp.serialize_without_witness() |
| 640 | s += struct.pack(b"<I", hashtype) |
| 641 | |
| 642 | hash = hash256(s) |
| 643 | |
| 644 | return (hash, None) |
| 645 | |
| 646 | # TODO: Allow cached hashPrevouts/hashSequence/hashOutputs to be provided. |
| 647 | # Performance optimization probably not necessary for python tests, however. |