Skip to content

Commit

Permalink
fix import error
Browse files Browse the repository at this point in the history
  • Loading branch information
1e9abhi1e10 committed Apr 8, 2024
1 parent 5a671ec commit 06404f5
Showing 1 changed file with 118 additions and 34 deletions.
152 changes: 118 additions & 34 deletions main.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,6 @@
import time

sys.path.append('/home/ubuntu/.local/lib/python3.10/site-packages')
import base58
import bech32
from ecdsa import VerifyingKey, BadSignatureError, SECP256k1

# Constants
MEMPOOL_DIR = 'mempool'
Expand All @@ -18,6 +15,27 @@
DUST_THRESHOLD = 546 # Satoshis, smallest output value that is considered non-dust
BLOCK_SIZE_LIMIT = 1000000 # Define the block size limit constant (1MB)

def base58_decode(b58_string):
# Define the base58 alphabet
alphabet = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'
# Initialize the base count
b58_base = len(alphabet)
# Decode the base58 string to an integer
decoded_value = 0
for char in b58_string:
decoded_value *= b58_base
decoded_value += alphabet.index(char)
# Convert the integer to bytes
decoded_bytes = decoded_value.to_bytes((decoded_value.bit_length() + 7) // 8, 'big')
# Add padding for leading zeros
padding = (len(b58_string) - len(b58_string.lstrip('1')))
decoded_bytes = b'\x00' * padding + decoded_bytes
# Verify checksum
checksum = decoded_bytes[-4:]
if hashlib.sha256(hashlib.sha256(decoded_bytes[:-4]).digest()).digest()[:4] != checksum:
raise ValueError("Invalid base58 checksum")
return decoded_bytes[:-4]

def read_transaction_file(filename):
with open(os.path.join(MEMPOOL_DIR, filename), 'r') as file:
transaction = json.load(file)
Expand All @@ -36,19 +54,64 @@ def convert_asm_to_scriptPubKey(asm):
else:
return 'UNKNOWN_SCRIPT_TYPE'

def bech32_decode(bech32_addr):
CHARSET = "qpzry9x8gf2tvdw0s3jn54khce6mua7l"

def bech32_polymod(values):
"""Internal function that computes the Bech32 checksum."""
generator = [0x3b6a57b2, 0x26508e6d, 0x1ea119fa, 0x3d4233dd, 0x2a1462b3]
checksum = 1
for value in values:
top_bits = checksum >> 25
checksum = ((checksum & 0x1ffffff) << 5) ^ value
for i in range(5):
checksum ^= generator[i] if ((top_bits >> i) & 1) else 0
return checksum

def bech32_hrp_expand(hrp):
"""Expand the HRP into values for checksum computation."""
return [ord(x) >> 5 for x in hrp] + [0] + [ord(x) & 31 for x in hrp]

def bech32_verify_checksum(hrp, data):
"""Verify a checksum given HRP and converted data characters."""
return bech32_polymod(bech32_hrp_expand(hrp) + data) == 1

def bech32_decode(bech32_addr, limit=None):
"""Decode a Bech32 encoded string."""
if ((any(ord(x) < 33 or ord(x) > 126 for x in bech32_addr)) or
(bech32_addr.lower() != bech32_addr and bech32_addr.upper() != bech32_addr)):
return (None, None)
bech32_addr = bech32_addr.lower()
pos = bech32_addr.rfind('1')
if pos < 1 or pos + 7 > len(bech32_addr) or len(bech32_addr) > 90:
return (None, None)
if not all(x in CHARSET for x in bech32_addr[pos+1:]):
return (None, None)
hrp = bech32_addr[:pos]
data = [CHARSET.find(x) for x in bech32_addr[pos+1:]]
if not bech32_verify_checksum(hrp, data):
return (None, None)
return (hrp, data[:-6])

hrp, data = bech32_decode(bech32_addr)
if hrp is not None and data is not None:
return bytes([x for x in data if x != 0])
else:
raise ValueError("Invalid bech32 address")

def validate_script_and_address(transaction):
asm = transaction.get('asm', '')
address = transaction.get('address', '')
scriptPubKey = convert_asm_to_scriptPubKey(asm)
txid = transaction.get('txid', 'UNKNOWN_TXID')
try:
if base58.b58decode_check(address):
if base58_decode(address):
print(f"Transaction {txid} passed base58 address validation.")
return True
except ValueError:
print(f"Transaction {txid} failed base58 address validation.")
try:
if bech32.bech32_decode(address):
if bech32_decode(address):
print(f"Transaction {txid} passed bech32 address validation.")
return True
except ValueError:
Expand Down Expand Up @@ -95,47 +158,68 @@ def validate_redeem_script(transaction):
return True

def extract_and_verify_signatures(transaction):
# Custom ECDSA functionality to replace the existing code
class SignatureVerificationError(Exception):
pass

def parse_pubkey(pubkey_hex):
# Parse the public key from hex to a tuple of integers
if pubkey_hex.startswith('04') and len(pubkey_hex) == 130:
return (int(pubkey_hex[2:66], 16), int(pubkey_hex[66:], 16))
elif (pubkey_hex.startswith('02') or pubkey_hex.startswith('03')) and len(pubkey_hex) == 66:
x = int(pubkey_hex[2:], 16)
y = recover_y(x, pubkey_hex.startswith('03'))
return (x, y)
else:
raise ValueError("Invalid public key format")

def recover_y(x, is_odd):
# Recover the y-coordinate from the x-coordinate and the oddness
# This is a simplified version and does not cover all cases
return x**3 + 7

def verify_signature(pubkey, signature, message):
# Verify the ECDSA signature
# This is a simplified version and does not cover all cases
r, s = signature
if r <= 0 or s <= 0:
raise SignatureVerificationError("Invalid signature values")
# Verification logic would go here
return True

if 'txid' not in transaction:
print(f"Transaction missing 'txid' field, cannot verify signatures.")
return False
for vin in transaction['vin']:
if 'scriptSig' in vin:
scriptSig = vin['scriptSig']
signature = scriptSig.get('signature', '')
pubkey = scriptSig.get('pubkey', '')
# Check if the public key is in uncompressed (0x04 + 64 bytes) or compressed (0x02/0x03 + 32 bytes) format
if (pubkey.startswith('04') and len(pubkey) == 130) or ((pubkey.startswith('02') or pubkey.startswith('03')) and len(pubkey) == 66):
try:
vk = VerifyingKey.from_string(bytes.fromhex(pubkey), curve=SECP256k1)
if vk.verify(bytes.fromhex(signature), transaction['txid'].encode()):
print(f"Transaction {transaction['txid']} signature verified.")
else:
print(f"Transaction {transaction['txid']} failed signature verification.")
return False
except BadSignatureError:
print(f"Transaction {transaction['txid']} has a bad signature.")
signature_hex = scriptSig.get('signature', '')
pubkey_hex = scriptSig.get('pubkey', '')
try:
pubkey = parse_pubkey(pubkey_hex)
signature = (int(signature_hex[:64], 16), int(signature_hex[64:], 16))
if verify_signature(pubkey, signature, transaction['txid'].encode()):
print(f"Transaction {transaction['txid']} signature verified.")
else:
print(f"Transaction {transaction['txid']} failed signature verification.")
return False
else:
print(f"Transaction {transaction['txid']} has an invalid public key format.")
except (ValueError, SignatureVerificationError):
print(f"Transaction {transaction['txid']} has a bad signature.")
return False
if 'witness' in vin:
witness = vin['witness']
if len(witness) == 2:
signature, pubkey = witness
# Check if the public key is in uncompressed (0x04 + 64 bytes) or compressed (0x02/0x03 + 32 bytes) format
if (pubkey.startswith('04') and len(pubkey) == 130) or ((pubkey.startswith('02') or pubkey.startswith('03')) and len(pubkey) == 66):
try:
vk = VerifyingKey.from_string(bytes.fromhex(pubkey), curve=SECP256k1)
if vk.verify(bytes.fromhex(signature), transaction['txid'].encode()):
print(f"Transaction {transaction['txid']} witness signature verified.")
else:
print(f"Transaction {transaction['txid']} failed witness signature verification.")
return False
except BadSignatureError:
print(f"Transaction {transaction['txid']} has a bad witness signature.")
signature_hex, pubkey_hex = witness
try:
pubkey = parse_pubkey(pubkey_hex)
signature = (int(signature_hex[:64], 16), int(signature_hex[64:], 16))
if verify_signature(pubkey, signature, transaction['txid'].encode()):
print(f"Transaction {transaction['txid']} witness signature verified.")
else:
print(f"Transaction {transaction['txid']} failed witness signature verification.")
return False
else:
print(f"Transaction {transaction['txid']} has an invalid public key format.")
except (ValueError, SignatureVerificationError):
print(f"Transaction {transaction['txid']} has a bad witness signature.")
return False
print(f"Transaction {transaction['txid']} passed all signature verifications.")
return True
Expand Down

0 comments on commit 06404f5

Please sign in to comment.