| 2858 | |
| 2859 | template <class T> |
| 2860 | uint256 SignatureHash(const CScript& scriptCode, const T& txTo, unsigned int nIn, int nHashType, const CConfidentialValue& amount, SigVersion sigversion, unsigned int flags, const PrecomputedTransactionData* cache, SigHashCache* sighash_cache) |
| 2861 | { |
| 2862 | assert(nIn < txTo.vin.size()); |
| 2863 | |
| 2864 | if (sigversion != SigVersion::WITNESS_V0) { |
| 2865 | // Check for invalid use of SIGHASH_SINGLE |
| 2866 | if ((nHashType & 0x1f) == SIGHASH_SINGLE) { |
| 2867 | if (nIn >= txTo.vout.size()) { |
| 2868 | // nOut out of range |
| 2869 | return uint256::ONE; |
| 2870 | } |
| 2871 | } |
| 2872 | } |
| 2873 | |
| 2874 | CHashWriter ss(SER_GETHASH, 0); |
| 2875 | |
| 2876 | // Try to compute using cached SHA256 midstate. |
| 2877 | if (sighash_cache && sighash_cache->Load(nHashType, scriptCode, ss)) { |
| 2878 | // Add sighash type and hash. |
| 2879 | ss << nHashType; |
| 2880 | return ss.GetHash(); |
| 2881 | } |
| 2882 | |
| 2883 | if (sigversion == SigVersion::WITNESS_V0) { |
| 2884 | uint256 hashPrevouts; |
| 2885 | uint256 hashSequence; |
| 2886 | uint256 hashIssuance; |
| 2887 | uint256 hashOutputs; |
| 2888 | uint256 hashRangeproofs; |
| 2889 | const bool cacheready = cache && cache->m_bip143_segwit_ready; |
| 2890 | bool fRangeproof = !!(flags & SCRIPT_SIGHASH_RANGEPROOF) && !!(nHashType & SIGHASH_RANGEPROOF); |
| 2891 | |
| 2892 | if (!(nHashType & SIGHASH_ANYONECANPAY)) { |
| 2893 | hashPrevouts = cacheready ? cache->hashPrevouts : SHA256Uint256(GetPrevoutsSHA256(txTo)); |
| 2894 | } |
| 2895 | |
| 2896 | if (!(nHashType & SIGHASH_ANYONECANPAY) && (nHashType & 0x1f) != SIGHASH_SINGLE && (nHashType & 0x1f) != SIGHASH_NONE) { |
| 2897 | hashSequence = cacheready ? cache->hashSequence : SHA256Uint256(GetSequencesSHA256(txTo)); |
| 2898 | } |
| 2899 | |
| 2900 | if (!(nHashType & SIGHASH_ANYONECANPAY)) { |
| 2901 | hashIssuance = cacheready ? cache->hashIssuance : SHA256Uint256(GetIssuanceSHA256(txTo)); |
| 2902 | } |
| 2903 | |
| 2904 | if ((nHashType & 0x1f) != SIGHASH_SINGLE && (nHashType & 0x1f) != SIGHASH_NONE) { |
| 2905 | hashOutputs = cacheready ? cache->hashOutputs : SHA256Uint256(GetOutputsSHA256(txTo)); |
| 2906 | |
| 2907 | if (fRangeproof) { |
| 2908 | hashRangeproofs = cacheready ? cache->hashRangeproofs : GetRangeproofsHash(txTo); |
| 2909 | } |
| 2910 | } else if ((nHashType & 0x1f) == SIGHASH_SINGLE && nIn < txTo.vout.size()) { |
| 2911 | CHashWriter inner_ss(SER_GETHASH, 0); |
| 2912 | inner_ss << txTo.vout[nIn]; |
| 2913 | hashOutputs = inner_ss.GetHash(); |
| 2914 | |
| 2915 | if (fRangeproof) { |
| 2916 | CHashWriter inner_ss(SER_GETHASH, 0); |
| 2917 | if (nIn < txTo.witness.vtxoutwit.size()) { |