-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
5 changed files
with
257 additions
and
2 deletions.
There are no files selected for viewing
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
import json | ||
import os | ||
import hashlib | ||
|
||
# Constants | ||
DIFFICULTY_TARGET = "0000ffff00000000000000000000000000000000000000000000000000000000" | ||
BLOCK_SIZE_LIMIT = 4000000 # Assuming block size limit is 4,000,000 bytes | ||
|
||
# Validate a transaction | ||
def validate_transaction(transaction): | ||
# Implement your validation logic here | ||
return True # Placeholder, actual validation needed | ||
|
||
# Read transactions from the mempool folder | ||
mempool_folder = "mempool" | ||
transactions = [] | ||
for filename in os.listdir(mempool_folder): | ||
if filename.endswith(".json"): | ||
with open(os.path.join(mempool_folder, filename)) as file: | ||
transaction_data = json.load(file) | ||
transactions.append(transaction_data) | ||
|
||
# Validate transactions and filter valid ones | ||
valid_transactions = [tx for tx in transactions if validate_transaction(tx)] | ||
|
||
# Sort valid transactions by fee in descending order | ||
# Sort valid transactions by fee in descending order | ||
valid_transactions.sort(key=lambda x: x.get("fee", 0), reverse=True) | ||
|
||
|
||
# Calculate total fee and block size | ||
total_fee = 0 | ||
block_size = 0 | ||
for tx in valid_transactions: | ||
try: | ||
total_fee += tx["fee"] | ||
block_size += len(json.dumps(tx)) | ||
except KeyError: | ||
pass # Ignore transactions without a fee field | ||
# total_fee = sum(tx["fee"] for tx in valid_transactions) | ||
# block_size = sum(len(json.dumps(tx)) for tx in valid_transactions) | ||
mined_transactions = [] | ||
|
||
# Create the block header | ||
block_header = { | ||
"previous_block_hash": "0000000000000000000000000000000000000000000000000000000000000000", | ||
"merkle_root": "merkle_root_placeholder", | ||
"timestamp": "timestamp_placeholder", | ||
"bits": DIFFICULTY_TARGET, | ||
"nonce": 0 | ||
} | ||
|
||
# Create the coinbase transaction | ||
coinbase_transaction = { | ||
"txid": "coinbase", | ||
"vin": [], | ||
"vout": [{"value": total_fee, "scriptpubkey_asm": "coinbase_script"}] | ||
} | ||
|
||
# Mine the block | ||
while True: | ||
block_data = json.dumps([block_header, coinbase_transaction] + mined_transactions) | ||
block_hash = hashlib.sha256(block_data.encode()).hexdigest() | ||
if block_hash[:16] == DIFFICULTY_TARGET: | ||
break | ||
block_header["nonce"] += 1 | ||
|
||
# Write the output file | ||
with open("output.txt", "w") as output_file: | ||
output_file.write(f"Block Header: {json.dumps(block_header)}\n") | ||
output_file.write(f"Coinbase Transaction: {json.dumps(coinbase_transaction)}\n") | ||
output_file.write(f"Transactions:\n") | ||
for transaction in mined_transactions: | ||
output_file.write(f"{transaction['txid']}\n") |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -27,4 +27,5 @@ | |
"value": 1100665 | ||
} | ||
] | ||
} | ||
} | ||
|
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,10 @@ | ||
# Update this file to run your own code | ||
# Update this file to run your own code | ||
#!/bin/bash | ||
|
||
if command -v python3 &>/dev/null; then | ||
python3 main.py | ||
elif command -v python &>/dev/null; then | ||
python main.py | ||
else | ||
echo "Python not found. Please install Python to run this script." | ||
fi |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
import json | ||
import os | ||
import hashlib | ||
import binascii | ||
import bitcoinlib | ||
from libsecp256k1 import libsecp256k1_context, SECP256K1_EC_VERIFY | ||
|
||
|
||
def scriptpubkey_asm_to_hex(scriptpubkey_asm,script): | ||
scriptpubkey_hex = "" | ||
words = scriptpubkey_asm.split() | ||
if script=='p2pkh' : | ||
if len(words) == 6 and words[0] == "OP_DUP" and words[1] == "OP_HASH160" and words[2]== "OP_PUSHBYTES_20" and words[4] == "OP_EQUALVERIFY" and words[5] == "OP_CHECKSIG": | ||
scriptpubkey_hex = "76a014" + words[3]+ "88ac" | ||
elif script=='v0_p2wsh' : | ||
if len(words) == 3 and words[0] == "OP_0" and words[1] == "OP_PUSHBYTES_32": | ||
scriptpubkey_hex = "0020" + words[2] | ||
elif script == 'p2sh': | ||
if len(words) == 4 and words[0] == "OP_HASH160" and words[1] == "OP_PUSHBYTES_20" and words[3]=="OP_EQUAL": | ||
scriptpubkey_hex= "a914"+words[2]+"87" | ||
elif script=='v0_p2wpkh': | ||
if len(words) == 3 and words[0] == "OP_0" and words[1] == "OP_PUSHBYTES_20": | ||
scriptpubkey_hex = "0014" + words[2] | ||
elif script== 'v1_p2tr': | ||
if len(words) == 3 and words[0] == "OP_PUSHNUM_1" and words[1] == "OP_PUSHBYTES_32": | ||
scriptpubkey_hex = "5120" + words[2] | ||
|
||
|
||
return scriptpubkey_hex | ||
|
||
def op_hash160(data): | ||
|
||
# SHA-256 hash | ||
sha256_hash = hashlib.sha256(data).digest() | ||
# RIPEMD-160 hash | ||
ripemd160_hash = hashlib.new('ripemd160', sha256_hash).digest() | ||
return ripemd160_hash.hex() | ||
|
||
|
||
def validate_p2tr(): | ||
def validate_p2pkh(dict): | ||
signature = dict["scriptsig_asm"].split(" ")[1] | ||
pub_key= dict["scriptsig_asm"].split(" ")[3] | ||
pub_key_hash = op_hash160(pub_key) | ||
bitcoin_add= dict["prevout"]["scriptpubkey_asm"].split(" ")[3] | ||
if(pub_key_hash != bitcoin_add): return False | ||
|
||
|
||
def validate_p2wsh(): | ||
def validate_p2sh(): | ||
def validate_p2wpkh(): | ||
|
||
|
||
|
||
#validate transaction og | ||
def validate_transaction(transaction): | ||
|
||
vin_value=0 | ||
vout_value=0 | ||
for dict in transaction['vin']: | ||
vin_value=vin_value+dict['prevout']['value'] | ||
script= dict['prevout']['scriptpubkey_type'] | ||
scriptpubkey_hex = scriptpubkey_asm_to_hex(dict['prevout']['scriptpubkey_asm'],script) | ||
if scriptpubkey_hex == dict['prevout']['scriptpubkey']: | ||
if script == 'v1_p2tr': | ||
validate_p2tr() | ||
elif script == 'p2pkh': | ||
validate_p2pkh(dict) | ||
elif script== 'v0_p2wsh': | ||
validate_p2wsh() | ||
elif script== 'p2sh': | ||
validate_p2sh() | ||
elif script== 'v0_p2wpkh': | ||
validate_p2wpkh() | ||
|
||
|
||
for dict in transaction['vout']: | ||
vout_value=vout_value+dict['value'] | ||
transaction_fees= vin_value-vout_value | ||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
## main function | ||
mempool_folder = "mempool" | ||
transactions = [] | ||
for filename in os.listdir(mempool_folder): | ||
if filename.endswith(".json"): | ||
with open(os.path.join(mempool_folder, filename)) as file: | ||
transaction_data = json.load(file) | ||
transactions.append(transaction_data) | ||
|
||
for idx,tx in enumerate(transactions): | ||
print(idx) | ||
validate_transaction(tx) | ||
|
||
|
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
# import hashlib | ||
# import json | ||
# from ecdsa import VerifyingKey, BadSignatureError, SECP256k1 | ||
|
||
# message = bytes.fromhex('1764c3596c9499e1e5420a547a594874f2ec97589208cc62a580ebf27a33fa14') | ||
# signature = bytes.fromhex('451008b776cb507dcdb1ad15bf5c0555add8e8c839ff146e73122c328105c45900923813f4487b624d1bf98e49ab9da9f2b3dc081e3c11fbf7070439787c2aaa') | ||
# public_key = bytes.fromhex('03bea5d859ec5d95c449c736a0f19a5e52fdacf8b6b96afeaa415cd49f11e6a07c') | ||
|
||
# vk = VerifyingKey.from_string(public_key, curve=SECP256k1) | ||
# if vk.verify(signature, message, hashlib.sha256): | ||
# print("Signature is valid.") | ||
# else: | ||
# print("Signature is not valid.") | ||
from bitcoinlib.transactions import Tx, TxIn, TxOut | ||
from bitcoinlib.keys import Address | ||
|
||
# Transaction JSON | ||
transaction_json = { | ||
"version": 1, | ||
"locktime": 0, | ||
"vin": [ | ||
{ | ||
"txid": "d1283ec7f6a2bcb65a5905033168258ca282e806c9dc7164415519a5ef041b14", | ||
"vout": 0, | ||
"prevout": { | ||
"scriptpubkey": "76a91496bc8310635539000a65a7cc95cb773c0cc7009788ac", | ||
"scriptpubkey_asm": "OP_DUP OP_HASH160 OP_PUSHBYTES_20 96bc8310635539000a65a7cc95cb773c0cc70097 OP_EQUALVERIFY OP_CHECKSIG", | ||
"scriptpubkey_type": "p2pkh", | ||
"scriptpubkey_address": "1Ek2BpKHUbr6SrrWq4P3Tf2jB6UCST2bwx", | ||
"value": 1103367 | ||
}, | ||
"scriptsig": "4730440220200b9a61529151f9f264a04e9aa17bb6e1d53fb345747c44885b1e185a82c17502200e41059f8ab4d3b3709dcb91b050c344b06c5086f05598d62bc06a8b746db4290121025f0ba0cdc8aa97ec1fffd01fac34d3a7f700baf07658048263a2c925825e8d33", | ||
"scriptsig_asm": "OP_PUSHBYTES_71 30440220200b9a61529151f9f264a04e9aa17bb6e1d53fb345747c44885b1e185a82c17502200e41059f8ab4d3b3709dcb91b050c344b06c5086f05598d62bc06a8b746db42901 OP_PUSHBYTES_33 025f0ba0cdc8aa97ec1fffd01fac34d3a7f700baf07658048263a2c925825e8d33", | ||
"is_coinbase": False, | ||
"sequence": 4294967295 | ||
} | ||
], | ||
"vout": [ | ||
{ | ||
"scriptpubkey": "76a914e5977cf916acdba010b9d847b9682135aa3ea81a88ac", | ||
"scriptpubkey_asm": "OP_DUP OP_HASH160 OP_PUSHBYTES_20 e5977cf916acdba010b9d847b9682135aa3ea81a OP_EQUALVERIFY OP_CHECKSIG", | ||
"scriptpubkey_type": "p2pkh", | ||
"scriptpubkey_address": "1MvyDWhroVV7BAL1twmwvY88DdvBEmPbG7", | ||
"value": 1100665 | ||
} | ||
] | ||
} | ||
|
||
# Create transaction object | ||
tx = Tx() | ||
|
||
# Set transaction version and locktime | ||
tx.version = transaction_json["version"] | ||
tx.locktime = transaction_json["locktime"] | ||
|
||
# Add inputs | ||
for vin in transaction_json["vin"]: | ||
txin = TxIn(vin["txid"], vin["vout"]) | ||
txin.scriptSig = vin["scriptsig"] | ||
tx.add_input(txin) | ||
|
||
# Add outputs | ||
for vout in transaction_json["vout"]: | ||
txout = TxOut(vout["value"], Address.from_string(vout["scriptpubkey_address"])) | ||
txout.scriptPubKey = vout["scriptpubkey"] | ||
tx.add_output(txout) | ||
|
||
# Serialize the transaction to hex | ||
transaction_hex = tx.serialize() | ||
|
||
print(transaction_hex) |