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 sign_p2pk(tx, i, priv, pub, hashtype = SIGHASH_ALL): assert isinstance(tx, dict) i = int(i) assert isinstance(priv, int) assert isinstance(pub, bytes) prev_script = script.make_p2pk(pub) txhash = sighash(tx, i, prev_script, hashtype) sig = ecdsa.sign(txhash, priv) sig = ecdsa.serialize_sig(sig) + convert.int_to_byte(hashtype) tx["ins"][i]["script"] = script.serialize([sig])
def sign_multisig(tx, i, prev_script, privs, pubs, hashtype = SIGHASH_ALL): assert isinstance(tx, dict) i = int(i) assert len(privs) == len(pubs) txhash = sighash(tx, i, prev_script, hashtype) s = [ script.Opcode.OP_0, ] for j in range(len(privs)): priv = privs[j] pub = pubs[j] sig = ecdsa.sign(txhash, priv) sig = ecdsa.serialize_sig(sig) + convert.int_to_byte(hashtype) s.append(sig) tx["ins"][i]["script"] = script.serialize(s)
def test_serialize(self): for s in self.scripts: self.assertEqual( s[0], script.serialize(s[1]) )