def test_serialization(): scr = 'OP_ADD OP_IF OP_DUP OP_HASH160 0x68bf827a2fa3b31e53215e5dd19260d21fdf053e OP_EQUALVERIFY OP_CHECKSIG OP_ELSE OP_IF OP_DUP OP_ELSE OP_2ROT OP_ENDIF OP_HASH160 0x68bf827a2fa3b31e53215e5dd19260d21fdf053e OP_EQUAL OP_ENDIF 0x010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101' # nopep8 s = Script(scr) assert s._tokens == ['OP_ADD', 'OP_IF', 'OP_DUP', 'OP_HASH160', b'h\xbf\x82z/\xa3\xb3\x1eS!^]\xd1\x92`\xd2\x1f\xdf\x05>', 'OP_EQUALVERIFY', 'OP_CHECKSIG', 'OP_ELSE', 'OP_IF', 'OP_DUP', 'OP_ELSE', 'OP_2ROT', 'OP_ENDIF', 'OP_HASH160', b'h\xbf\x82z/\xa3\xb3\x1eS!^]\xd1\x92`\xd2\x1f\xdf\x05>', 'OP_EQUAL', 'OP_ENDIF', b'\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01'] # nopep8 s_bytes = bytes(s) s_hex_str = bytes_to_str(s_bytes) s1 = Script.from_bytes(pack_var_str(s_bytes))[0] assert bytes(s1) == s_bytes raw_scr = "483045022100d60baf72dbaed8d15c3150e3309c9f7725fbdf91b0560330f3e2a0ccb606dfba02206422b1c73ce390766f0dc4e9143d0fbb400cc207e4a9fd9130e7f79e52bf81220121034ccd52d8f72cfdd680077a1a171458a1f7574ebaa196095390ae45e68adb3688" # nopep8 s = Script(bytes.fromhex(raw_scr)) s._check_tokenized() assert s._tokens assert s._ast s_hex_str = bytes_to_str(bytes(s)) assert s_hex_str == raw_scr s = Script('OP_0 OP_IF 0x1337c0de OP_ENDIF OP_1') b = bytes.fromhex("0063041337c0de6851") s1 = Script.from_bytes(pack_var_str(b))[0] assert bytes(s) == b assert bytes(s) == bytes(s1)
def test_multisig_sig(): sig_script = Script('OP_0 0x30440220762ce7bca626942975bfd5b130ed3470b9f538eb2ac120c2043b445709369628022051d73c80328b543f744aa64b7e9ebefa7ade3e5c716eab4a09b408d2c307ccd701 0x3045022100abf740b58d79cab000f8b0d328c2fff7eb88933971d1b63f8b99e89ca3f2dae602203354770db3cc2623349c87dea7a50cee1f78753141a5052b2d58aeb592bcf50f01 0x524104a882d414e478039cd5b52a92ffb13dd5e6bd4515497439dffd691a0f12af9575fa349b5694ed3155b136f09e63975a1700c9f4d4df849323dac06cf3bd6458cd41046ce31db9bdd543e72fe3039a1f1c047dab87037c36a669ff90e28da1848f640de68c2fe913d363a51154a0c62d7adea1b822d05035077418267b1a1379790187410411ffd36c70776538d079fbae117dc38effafb33304af83ce4894589747aee1ef992f63280567f52f5ba870678b4ab4ff6c8ea600bd217870a8b4f1f09f3a8e8353ae') # nopep8 assert sig_script.is_multisig_sig() r = sig_script.extract_multisig_sig_info() redeem_info = r['redeem_script'].extract_multisig_redeem_info() assert len(r['signatures']) == 2 assert r['redeem_script'] assert isinstance(r['redeem_script'], Script) s = Script.build_multisig_sig(r['signatures'], r['redeem_script']) assert bytes(s) == bytes(sig_script) # This is a test case where there is no OP_PUSHDATA raw_scr = "00483045022100fa1225f8828fd6fe52665c3c4258169a84af52b41525f2e288082f174c032f47022022758d5519db3ab2cec4a330e96568b9289fb77c5653bce49397df01a3fcff5101475221038b5fa60aee4c4e9ab3a66e6bb32211a54da6b054c6143dd221c122ce936315d921023180e1b49b7f3fd1254a19c7aa8016ad995089b99c9dac89752cd17e40d9072d52ae" # nopep8 s, _ = Script.from_bytes(pack_var_str(bytes.fromhex(raw_scr))) assert sig_script.is_multisig_sig() r = s.extract_multisig_sig_info() assert len(r['signatures']) == 1 assert r['redeem_script'] assert isinstance(r['redeem_script'], Script) sig_addresses = sig_script.get_addresses() assert len(sig_addresses) == redeem_info['n'] + 1 assert sig_addresses == ['1JzVFZSN1kxGLTHG41EVvY5gHxLAX7q1Rh', '14JfSvgEq8A8S7qcvxeaSCxhn1u1L71vo4', '1Kyy7pxzSKG75L9HhahRZgYoer9FePZL4R', '347N1Thc213QqfYCz3PZkjoJpNv5b14kBd']
def __bytes__(self): """ Serializes the object into a byte stream. Returns: b (bytes): byte stream containing the serialized transaction output. """ return pack_u64(self.value) + pack_var_str(bytes(self.script))
def __bytes__(self): """ Serializes the object into a byte stream. Returns: b (bytes): byte stream containing the serialized input. """ return ( bytes(self.outpoint) + pack_u32(self.outpoint_index) + pack_var_str(bytes(self.script)) + pack_u32(self.sequence_num) )
def from_hex(h, size_prepended=False): """ Deserializes a hex-encoded string into a Script. Args: h (str): hex-encoded string, starting with the length of the script as a compact int. size_prepended (bool): Should be True if the size of the script has already been prepended. Returns: Script: A Script object. """ b = bytes.fromhex(h) if not size_prepended: b = pack_var_str(b) s, _ = Script.from_bytes(b) return s
def txn_from_json(txn_json): """ Returns a new Transaction from a JSON-serialized transaction Args: txn_json: JSON with the following format: { "hash": "0bf0de38c26195919179f...", "block_hash": "000000000000000...", "block_height": 303404, "block_time": "2014-05-30T23:54:55Z", "chain_received_at": "2015-08-13T10:52:21.718Z", "confirmations": 69389, "lock_time": 0, "inputs": [ { "transaction_hash": "0bf0de38c2619...", "output_hash": "b84a66c46e24fe71f9...", "output_index": 0, "value": 300000, "addresses": [ "3L7dKYQGNoZub928CJ8NC2WfrM8U8GGBjr" ], "script_signature": "03046022100de7b67b9...", "script_signature_hex": "00493046022100de7b...", "sequence": 4294967295 } ], "outputs": [ { "transaction_hash": "0bf0de38c261959...", "output_index": 0, "value": 290000, "addresses": [ "1K4nPxBMy6sv7jssTvDLJWk1ADHBZEoUVb" ], "script": "OP_DUP OP_HASH160 c629680b8d...", "script_hex": "76a914c629680b8d13...", "script_type": "pubkeyhash", "required_signatures": 1, "spent": false, "spending_transaction": null } ], "fees": 10000, "amount": 290000 }, Transaction.DEFAULT_TRANSACTION_VERSION Returns: two1.bitcoin.Transaction: a deserialized transaction derived from the provided json. """ inputs = [] outputs = [] addr_keys = set() for i in txn_json["inputs"]: if 'coinbase' in i: inputs.append( CoinbaseInput(height=txn_json["block_height"] or 0, raw_script=bytes.fromhex(i['coinbase']), sequence=i['sequence'], block_version=1)) else: # Script length etc. are not returned so we need to # prepend that. script, _ = Script.from_bytes( pack_var_str(bytes.fromhex(i["script_signature_hex"]))) inputs.append( TransactionInput(Hash(i["output_hash"]), i["output_index"], script, i["sequence"])) if "addresses" in i: addr_keys.add(i["addresses"][0]) for i in txn_json["outputs"]: script, _ = Script.from_bytes( pack_var_str(bytes.fromhex(i["script_hex"]))) outputs.append(TransactionOutput(i["value"], script)) if "addresses" in i: addr_keys.add(i["addresses"][0]) txn = Transaction(Transaction.DEFAULT_TRANSACTION_VERSION, inputs, outputs, txn_json["lock_time"]) return txn, addr_keys
def txn_from_json(txn_json): """ Returns a new Transaction from a JSON-serialized transaction Args: txn_json: JSON with the following format: { "hash": "0bf0de38c26195919179f...", "block_hash": "000000000000000...", "block_height": 303404, "block_time": "2014-05-30T23:54:55Z", "chain_received_at": "2015-08-13T10:52:21.718Z", "confirmations": 69389, "lock_time": 0, "inputs": [ { "transaction_hash": "0bf0de38c2619...", "output_hash": "b84a66c46e24fe71f9...", "output_index": 0, "value": 300000, "addresses": [ "3L7dKYQGNoZub928CJ8NC2WfrM8U8GGBjr" ], "script_signature": "03046022100de7b67b9...", "script_signature_hex": "00493046022100de7b...", "sequence": 4294967295 } ], "outputs": [ { "transaction_hash": "0bf0de38c261959...", "output_index": 0, "value": 290000, "addresses": [ "1K4nPxBMy6sv7jssTvDLJWk1ADHBZEoUVb" ], "script": "OP_DUP OP_HASH160 c629680b8d...", "script_hex": "76a914c629680b8d13...", "script_type": "pubkeyhash", "required_signatures": 1, "spent": false, "spending_transaction": null } ], "fees": 10000, "amount": 290000 }, Transaction.DEFAULT_TRANSACTION_VERSION Returns: two1.bitcoin.Transaction: a deserialized transaction derived from the provided json. """ inputs = [] outputs = [] addr_keys = set() for i in txn_json["inputs"]: if 'coinbase' in i: inputs.append( CoinbaseInput( height=txn_json["block_height"] or 0, raw_script=bytes.fromhex(i['coinbase']), sequence=i['sequence'], block_version=1)) else: # Script length etc. are not returned so we need to # prepend that. script, _ = Script.from_bytes( pack_var_str(bytes.fromhex(i["script_signature_hex"]))) inputs.append(TransactionInput(Hash(i["output_hash"]), i["output_index"], script, i["sequence"])) if "addresses" in i: addr_keys.add(i["addresses"][0]) for i in txn_json["outputs"]: script, _ = Script.from_bytes( pack_var_str(bytes.fromhex(i["script_hex"]))) outputs.append(TransactionOutput(i["value"], script)) if "addresses" in i: addr_keys.add(i["addresses"][0]) txn = Transaction(Transaction.DEFAULT_TRANSACTION_VERSION, inputs, outputs, txn_json["lock_time"]) return txn, addr_keys