Skip to content

Instantly share code, notes, and snippets.

@loon3
Created May 23, 2023 14:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save loon3/ec519ed75e960e71ffa81466fc646ab8 to your computer and use it in GitHub Desktop.
Save loon3/ec519ed75e960e71ffa81466fc646ab8 to your computer and use it in GitHub Desktop.
filter blocks for burned sats
import os
import requests
import json
import subprocess
from bitcoin.core import b2lx, b2x, CBlock
from bitcoin.core.script import OP_RETURN, CScript
from Crypto.Cipher import ARC4
def read_cookie_file(cookie_file_path):
with open(cookie_file_path, "r") as file:
cookie_content = file.read().strip()
return tuple(cookie_content.split(':', 1))
def get_block_height(rpc_url, auth):
headers = {
'Content-Type': 'application/json',
}
payload = {
"jsonrpc": "1.0",
"id": "getblockcount",
"method": "getblockcount",
"params": [],
}
response = requests.post(rpc_url, auth=auth, headers=headers, data=json.dumps(payload))
return response.json()['result']
def get_block_hash(rpc_url, auth, block_height):
headers = {
'Content-Type': 'application/json',
}
payload = {
"jsonrpc": "1.0",
"id": "getblockhash",
"method": "getblockhash",
"params": [block_height],
}
response = requests.post(rpc_url, auth=auth, headers=headers, data=json.dumps(payload))
return response.json()['result']
def get_raw_block(rpc_url, auth, block_hash):
headers = {
'Content-Type': 'application/json',
}
payload = {
"jsonrpc": "1.0",
"id": "getblock",
"method": "getblock",
"params": [block_hash, 0], # The second parameter '0' indicates that we want the raw block as a hexadecimal string
}
response = requests.post(rpc_url, auth=auth, headers=headers, data=json.dumps(payload))
return response.json()['result']
def filter_op_return_txs(raw_block_hex):
raw_block = bytes.fromhex(raw_block_hex)
block = CBlock.deserialize(raw_block)
op_return_data = []
for tx in block.vtx:
for vout_index, txout in enumerate(tx.vout):
if txout.scriptPubKey and txout.scriptPubKey[0] == OP_RETURN:
# Get the ASM data after OP_RETURN
asm_data = b2x(txout.scriptPubKey[2:])
# Get the txid of the first input in the transaction
first_input_txid_bytes = tx.vin[0].prevout.hash
reversed_txid_bytes = bytearray(first_input_txid_bytes)[::-1] # Reverse the byte order
first_input_txid = b2x(reversed_txid_bytes) # Convert the reversed bytes to a hex string
# Perform ARC4 cipher on the ASM data using the first input txid as the key
cipher = ARC4.new(reversed_txid_bytes)
decrypted_asm_data = cipher.decrypt(bytes.fromhex(asm_data))
decrypted_asm_hex = b2x(decrypted_asm_data) # Convert decrypted bytes to a hex string
# Check if decrypted data begins with the bytes '434e545250525459'
if decrypted_asm_hex.startswith('434e545250525459'):
# Get the transaction ID (txid) of the tx containing the OP_RETURN output
txid_bytes = tx.GetTxid()
reversed_txid_bytes = bytearray(txid_bytes)[::-1] # Reverse the byte order
txid = b2x(reversed_txid_bytes) # Convert the reversed bytes to a hex string
# Get the value in satoshis of the OP_RETURN output
op_return_value = txout.nValue
txid_vout_str = "{}:{}".format(txid, vout_index)
if op_return_value > 0:
# Execute the command and save the result as an array
command = "D:\\ord\\ord.exe --bitcoin-data-dir=D:\\Bitcoin\\AppData\\Bitcoin --data-dir=D:\\ord\\AppData\\ord list " + txid_vout_str
result = subprocess.run(command, capture_output=True, text=True, shell=True)
result_text = result.stdout.strip()
# Parse the JSON result and extract "start" and "size" values
result_json = json.loads(result_text)
start_size_values = [[item["start"], item["size"]] for item in result_json]
op_return_data.append([txid_vout_str, decrypted_asm_hex, op_return_value, start_size_values])
return op_return_data
if __name__ == "__main__":
bitcoin_data_dir = 'D:\\Bitcoin' # Updated Bitcoin data directory path
cookie_file_path = os.path.join(bitcoin_data_dir, '.cookie')
rpc_url = 'http://127.0.0.1:8332' # Change this to your Bitcoin RPC URL
rpc_user, rpc_password = read_cookie_file(cookie_file_path)
auth = requests.auth.HTTPBasicAuth(rpc_user, rpc_password)
# block_height = get_block_height(rpc_url, auth)
# print(f"Current block height: {block_height}")
block_height = 776363
# Get raw block at a specific height, e.g., 100000
block_hash = get_block_hash(rpc_url, auth, block_height)
raw_block = get_raw_block(rpc_url, auth, block_hash)
op_return_txs = filter_op_return_txs(raw_block)
print(f"Transactions containing OP_RETURN outputs with counterparty data and sat burns at height {block_height}: {op_return_txs}")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment