Created
May 23, 2023 14:25
-
-
Save loon3/ec519ed75e960e71ffa81466fc646ab8 to your computer and use it in GitHub Desktop.
filter blocks for burned sats
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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