def serialize_unit(unit): if isinstance(unit, Opcode): return convert.int_to_byte(unit.value) if isinstance(unit, bytes): if len(unit) <= 75: return convert.int_to_byte(len(unit)) + unit elif len(unit) < 256: return convert.int_to_byte(76) + convert.int_to_byte(len(unit))+unit elif len(unit) < 65536: return convert.int_to_byte(77) + convert.int_to_bytes_le(len(unit), 2) + unit else: return convert.int_to_byte(78) + convert.int_to_bytes_le(len(unit), 4) + unit raise Exception('Bad script unit type')
def sighash(tx, i, prevScript, hashtype = SIGHASH_ALL): assert isinstance(tx, dict) i = int(i) newtx = copy.deepcopy(tx) for inp in newtx["ins"]: inp["script"] = b'' s = script.deserialize(prevScript) s = [x for x in s if x is not script.Opcode.OP_CODESEPARATOR] newtx["ins"][i]["script"] = script.serialize(s) if hashtype & 0x1f == SIGHASH_NONE: newtx["outs"] = [] for inp in range(len(newtx['ins'])): if inp != i: newtx['ins'][inp]['sequence'] = 0 elif hashtype & 0x1f == SIGHASH_SINGLE: newtx["outs"] = newtx["outs"][:i+1] for out in range(i): newtx["outs"][out]['value'] = 2**64 - 1 newtx["outs"][out]['script'] = b'' for inp in range(len(newtx['ins'])): if inp != i: newtx['ins'][inp]['sequence'] = 0 if hashtype & SIGHASH_ANYONECANPAY != 0: newtx["ins"] = [newtx["ins"][i]] hashbytes = convert.int_to_bytes_le(hashtype, 4) return hashes.hash256(serialize(newtx) + hashbytes)
def serialize(txobj): o = bytearray() o += convert.int_to_bytes_le(txobj["version"], 4) o += encode_var_int(len(txobj["ins"])) for inp in txobj["ins"]: o += inp["outpoint"]["hash"][::-1] o += convert.int_to_bytes_le(inp["outpoint"]["index"], 4) o += encode_var_int(len(inp["script"])) + inp["script"] o += convert.int_to_bytes_le(inp["sequence"], 4) o += encode_var_int(len(txobj["outs"])) for out in txobj["outs"]: o += convert.int_to_bytes_le(out["value"], 8) o += encode_var_int(len(out["script"])) + out["script"] o += convert.int_to_bytes_le(txobj["locktime"], 4) return bytes(o)
def encode_var_int(x): x = int(x) if x < 253: return convert.int_to_byte(x) elif x < 65536: return convert.int_to_byte(253) + convert.int_to_bytes_le(x, 2) elif x < 4294967296: return convert.int_to_byte(254) + convert.int_to_bytes_le(x, 4) else: return convert.int_to_byte(255) + convert.int_to_bytes_le(x, 8)