def SignatureHashForkId(script, txTo, inIdx, hashtype, amount): hashPrevouts = 0 hashSequence = 0 hashOutputs = 0 if not (hashtype & SIGHASH_ANYONECANPAY): serialize_prevouts = bytes() for i in txTo.vin: serialize_prevouts += i.prevout.serialize() hashPrevouts = uint256_from_str(hash256(serialize_prevouts)) if (not (hashtype & SIGHASH_ANYONECANPAY) and (hashtype & 0x1f) != SIGHASH_SINGLE and (hashtype & 0x1f) != SIGHASH_NONE): serialize_sequence = bytes() for i in txTo.vin: serialize_sequence += struct.pack("<I", i.nSequence) hashSequence = uint256_from_str(hash256(serialize_sequence)) if ((hashtype & 0x1f) != SIGHASH_SINGLE and (hashtype & 0x1f) != SIGHASH_NONE): serialize_outputs = bytes() for o in txTo.vout: serialize_outputs += o.serialize() hashOutputs = uint256_from_str(hash256(serialize_outputs)) elif ((hashtype & 0x1f) == SIGHASH_SINGLE and inIdx < len(txTo.vout)): serialize_outputs = txTo.vout[inIdx].serialize() hashOutputs = uint256_from_str(hash256(serialize_outputs)) ss = bytes() ss += struct.pack("<i", txTo.nVersion) ss += ser_uint256(hashPrevouts) ss += ser_uint256(hashSequence) ss += txTo.vin[inIdx].prevout.serialize() ss += ser_string(script) ss += struct.pack("<q", amount) ss += struct.pack("<I", txTo.vin[inIdx].nSequence) ss += ser_uint256(hashOutputs) ss += struct.pack("<i", txTo.nLockTime) ss += struct.pack("<I", hashtype) return hash256(ss)
def SignatureHash(script, txTo, inIdx, hashtype): """Consensus-correct SignatureHash Returns (hash, err) to precisely match the consensus-critical behavior of the SIGHASH_SINGLE bug. (inIdx is *not* checked for validity) """ 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' if inIdx >= len(txTo.vin): return (HASH_ONE, "inIdx %d out of range (%d)" % (inIdx, len(txTo.vin))) txtmp = CTransaction(txTo) for txin in txtmp.vin: txin.scriptSig = b'' txtmp.vin[inIdx].scriptSig = FindAndDelete(script, CScript([OP_CODESEPARATOR])) if (hashtype & 0x1f) == SIGHASH_NONE: txtmp.vout = [] for i in range(len(txtmp.vin)): if i != inIdx: txtmp.vin[i].nSequence = 0 elif (hashtype & 0x1f) == SIGHASH_SINGLE: outIdx = inIdx if outIdx >= len(txtmp.vout): return (HASH_ONE, "outIdx %d out of range (%d)" % (outIdx, len(txtmp.vout))) tmp = txtmp.vout[outIdx] txtmp.vout = [] for i in range(outIdx): txtmp.vout.append(CTxOut()) txtmp.vout.append(tmp) for i in range(len(txtmp.vin)): if i != inIdx: txtmp.vin[i].nSequence = 0 if hashtype & SIGHASH_ANYONECANPAY: tmp = txtmp.vin[inIdx] txtmp.vin = [] txtmp.vin.append(tmp) s = txtmp.serialize() s += struct.pack(b"<I", hashtype) hash = hash256(s) return (hash, None)
def signaturehash(script, txto, inidx, hashtype): """consensus-correct signaturehash returns (hash, err) to precisely match the consensus-critical behavior of the sighash_single bug. (inidx is *not* checked for validity) """ 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' if inidx >= len(txto.vin): return (hash_one, "inidx %d out of range (%d)" % (inidx, len(txto.vin))) txtmp = ctransaction(txto) for txin in txtmp.vin: txin.scriptsig = b'' txtmp.vin[inidx].scriptsig = findanddelete(script, cscript([op_codeseparator])) if (hashtype & 0x1f) == sighash_none: txtmp.vout = [] for i in range(len(txtmp.vin)): if i != inidx: txtmp.vin[i].nsequence = 0 elif (hashtype & 0x1f) == sighash_single: outidx = inidx if outidx >= len(txtmp.vout): return (hash_one, "outidx %d out of range (%d)" % (outidx, len(txtmp.vout))) tmp = txtmp.vout[outidx] txtmp.vout = [] for i in range(outidx): txtmp.vout.append(ctxout()) txtmp.vout.append(tmp) for i in range(len(txtmp.vin)): if i != inidx: txtmp.vin[i].nsequence = 0 if hashtype & sighash_anyonecanpay: tmp = txtmp.vin[inidx] txtmp.vin = [] txtmp.vin.append(tmp) s = txtmp.serialize() s += struct.pack(b"<i", hashtype) hash = hash256(s) return (hash, none)
def SignatureHash(script, txTo, inIdx, hashtype, amount, consensusBranchId): """Consensus-correct SignatureHash""" if inIdx >= len(txTo.vin): raise ValueError("inIdx %d out of range (%d)" % (inIdx, len(txTo.vin))) if consensusBranchId != 0: # ZIP 243 hashPrevouts = b'\x00' * 32 hashSequence = b'\x00' * 32 hashOutputs = b'\x00' * 32 hashJoinSplits = b'\x00' * 32 hashShieldedSpends = b'\x00' * 32 hashShieldedOutputs = b'\x00' * 32 if not (hashtype & SIGHASH_ANYONECANPAY): hashPrevouts = getHashPrevouts(txTo) if (not (hashtype & SIGHASH_ANYONECANPAY)) and \ (hashtype & 0x1f) != SIGHASH_SINGLE and \ (hashtype & 0x1f) != SIGHASH_NONE: hashSequence = getHashSequence(txTo) if (hashtype & 0x1f) != SIGHASH_SINGLE and \ (hashtype & 0x1f) != SIGHASH_NONE: hashOutputs = getHashOutputs(txTo) elif (hashtype & 0x1f) == SIGHASH_SINGLE and \ 0 <= inIdx and inIdx < len(txTo.vout): digest = blake2b(digest_size=32, person=b'ZcashOutputsHash') digest.update(txTo.vout[inIdx].serialize()) hashOutputs = digest.digest() if len(txTo.vJoinSplit) > 0: hashJoinSplits = getHashJoinSplits(txTo) if len(txTo.shieldedSpends) > 0: hashShieldedSpends = getHashShieldedSpends(txTo) if len(txTo.shieldedOutputs) > 0: hashShieldedOutputs = getHashShieldedOutputs(txTo) digest = blake2b( digest_size=32, person=b'ZcashSigHash' + struct.pack('<I', consensusBranchId), ) digest.update( struct.pack('<I', (int(txTo.fOverwintered) << 31) | txTo.nVersion)) digest.update(struct.pack('<I', txTo.nVersionGroupId)) digest.update(hashPrevouts) digest.update(hashSequence) digest.update(hashOutputs) digest.update(hashJoinSplits) digest.update(hashShieldedSpends) digest.update(hashShieldedOutputs) digest.update(struct.pack('<I', txTo.nLockTime)) digest.update(struct.pack('<I', txTo.nExpiryHeight)) digest.update(struct.pack('<Q', txTo.valueBalance)) digest.update(struct.pack('<I', hashtype)) if inIdx is not None: digest.update(txTo.vin[inIdx].prevout.serialize()) digest.update(ser_string(script)) digest.update(struct.pack('<Q', amount)) digest.update(struct.pack('<I', txTo.vin[inIdx].nSequence)) return (digest.digest(), None) else: # Pre-Overwinter txtmp = CTransaction(txTo) for txin in txtmp.vin: txin.scriptSig = b'' txtmp.vin[inIdx].scriptSig = script if (hashtype & 0x1f) == SIGHASH_NONE: txtmp.vout = [] for i in range(len(txtmp.vin)): if i != inIdx: txtmp.vin[i].nSequence = 0 elif (hashtype & 0x1f) == SIGHASH_SINGLE: outIdx = inIdx if outIdx >= len(txtmp.vout): raise ValueError("outIdx %d out of range (%d)" % (outIdx, len(txtmp.vout))) tmp = txtmp.vout[outIdx] txtmp.vout = [] for i in range(outIdx): txtmp.vout.append(CTxOut()) txtmp.vout.append(tmp) for i in range(len(txtmp.vin)): if i != inIdx: txtmp.vin[i].nSequence = 0 if hashtype & SIGHASH_ANYONECANPAY: tmp = txtmp.vin[inIdx] txtmp.vin = [] txtmp.vin.append(tmp) s = txtmp.serialize() s += struct.pack(b"<I", hashtype) hash = hash256(s) return (hash, None)
from test_framework.mininode import hash256, ser_string from test_framework.mc_test.mc_test import * from binascii import a2b_hex, b2a_hex from hashlib import sha256 from decimal import Decimal from struct import unpack, pack import binascii import codecs # this is defined in src/primitives/block.h SC_CERTIFICATE_BLOCK_VERSION = 3 # this is defined in src/primitives/block.cpp SC_NULL_HASH = hash256(ser_string("Horizen ScTxsCommitment null hash string")) SC_EPOCH_LENGTH = 5 SC_CREATION_AMOUNT = Decimal("1.0") SC_CERT_AMOUNT = Decimal("0.5") DEBUG_MODE = 1 NODE_LIST = [] def check_array_result(object_array, to_match, expected): """ Pass in array of JSON objects, a dictionary with key/value pairs to match against, and another dictionary with expected key/value pairs.
block.rehash() # Get the difficulty on the BStash chain hex_bits = aux['bits'] nBits = struct.unpack(">I", hex_str_to_bytes(hex_bits))[0] target = uint256_from_compact(nBits) # Construct BCash block block_ser = b"" block_ser += struct.pack("<i", block.nVersion) block_ser += ser_uint256(block.hashPrevBlock) block_ser += ser_uint256(block.hashMerkleRoot) block_ser += struct.pack("<I", block.nTime) block_ser += struct.pack("<I", block.nBits) block_ser_final = block_ser + struct.pack("<I", block.nNonce) hash_result = uint256_from_str(hash256(block_ser_final)) print("Starting mining, difficulty:{}".format(hex_bits)) i = 0 start_time = time.time() maxnonce = 2**32 block.nNonce = 0 nNonce = 0 while hash_result > target: nNonce += 1 if nNonce >= maxnonce: print("Finished mining:{} per sec".format(nNonce / (time.time() - start_time))) sys.exit() hash_result = uint256_from_str( hash256(block_ser + struct.pack("<I", nNonce)))