This is an example of some very early testing that was used. However now the standard is to use 2 bytes to determine the length of the string so this will need to be adjusted (initially in testing this was one byte which contained the hex value to validate the length of the string)
from bitcoinrpc.authproxy import AuthServiceProxy, JSONRPCException
import json
import os
import binascii
import decimal
from arc4 import arc4_decrypt
rpc_user = os.environ.get("rpc_user", 'rpc')
rpc_password = os.environ.get("rpc_password", 'rpc')
global_rpc_ip = os.environ.get("rpc_ip", '127.0.0.1')
rpc_ip = os.environ.get("rpc_ip", '127.0.0.1')
rpc_port = os.environ.get("rpc_port",'8332')
rpc_connection = AuthServiceProxy(f"http://{rpc_user}:{rpc_password}@{rpc_ip}:{rpc_port}")
# tx = "6005ee8cc02e528e20c8e5ff71191723b0260391020862a03587a985f813dabe"
# tx = "1db33fe19983d26d9e228169a9092f26eca52d62ae656e3b7a51adf9b339a4d3"
tx = "fc3aca4cc5119aa2aa0bbae959c61352af18000a40b848ecf1eba912f79c4635"
burnkeys = [
"022222222222222222222222222222222222222222222222222222222222222222",
"033333333333333333333333333333333333333333333333333333333333333333",
"020202020202020202020202020202020202020202020202020202020202020202",
"030303030303030303030303030303030303030303030303030303030303030303"
]
def decimal_default(obj):
if isinstance(obj, decimal.Decimal):
return float(obj)
raise TypeError
def get_transaction_info_from_node(tx):
try:
return rpc_connection.getrawtransaction(tx, True)
except JSONRPCException as e:
print(e)
return None
def process_tx(tx):
tx_dict = get_transaction_info_from_node(tx)
print(json.dumps(tx_dict, indent=4, default=decimal_default))
try:
rc4_key = tx_dict['vin'][0]['txid']
rc4_key_bytes = binascii.unhexlify(rc4_key)
asm_fields = []
# print(rc4_key_bytes)
for utxo in tx_dict['vout']:
print("utxo", utxo, "\n \n")
if utxo['scriptPubKey'].get('type') == 'multisig':
asm_fields.append(utxo['scriptPubKey']['asm'])
print("asm_fields", asm_fields)
# print("multisig", utxo)
asm_string = utxo['scriptPubKey']['asm']
hex_strings = asm_string.split()[1:3] # extract the first two hex strings
print("hex_strings", hex_strings, "\n") # list of first two hex strings
stripped_hex_strings = [hex_string[2:-2] for hex_string in hex_strings] # strip the first and last byte
print("stripped_hex_strings", stripped_hex_strings) # hex strings without first and last byte
data_chunk_hex = ''.join(stripped_hex_strings) # concatenate them together
print("data_chunk_hex len", len(data_chunk_hex) /2 ) #validate length
bytestring = bytes.fromhex(data_chunk_hex) # convert the hex string to a bytestring
print("bytestring", bytestring)
arc4_decrypted_byte_script = arc4_decrypt(rc4_key_bytes, bytestring) #[2:]) # decrypt the bytestring less the first byte / message length
# i need to strip the first ttwo bytes from the arc4_decrypted_byte_script
# don't decode the first byte, that is in hex and it's the bytecount
arc4_decrypted_byte_script = arc4_decrypted_byte_script[2:]
print("arc4_decrypted_byte_script", arc4_decrypted_byte_script.decode)
utf8_decrypted_script = arc4_decrypted_byte_script.decode('utf-8')
if "stamp" in utf8_decrypted_script.lower():
print("decrypted_script", utf8_decrypted_script)
return tx_dict
else:
return None
except:
return None
process_tx(tx)
# stpes to decode:
# 1. do a rc4 decrypt.
# 2. take the first 2 pubkeySripts
# 3. parse each one of them:
# (1)ditch the first byte and last byte. that would give you 33 - 2 = 31 bytes.
# 4. combine them
# 5. after that you get a hex string. the first byte of the hex is "byte count of the message".
# 6. do a hex to utf-8 decode.
This is an example of some very early testing that was used. However now the standard is to use 2 bytes to determine the length of the string so this will need to be adjusted (initially in testing this was one byte which contained the hex value to validate the length of the string)