Skip to content

Commit

Permalink
Add p2sh
Browse files Browse the repository at this point in the history
  • Loading branch information
davidchocholaty committed Nov 7, 2024
1 parent d6f45c3 commit d9ef5b6
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 5 deletions.
6 changes: 3 additions & 3 deletions src/script.py
Original file line number Diff line number Diff line change
Expand Up @@ -430,12 +430,12 @@ def op_checkmultisig(self) -> int:
# 3. Handle proper error cases

verified = True # Replace with actual verification

self.stack.push(b'\x01' if verified else b'\x00')
return 1

@staticmethod
def combine_scripts(*scripts: Union[bytes, 'Script'], json_transaction: dict) -> 'Script':
def combine_scripts(*scripts: Union[bytes, 'Script'], json_transaction: dict, segwit: bool = False) -> 'Script':
"""
Combine multiple scripts into a single script.
Accepts both bytes and Script objects.
Expand All @@ -448,5 +448,5 @@ def combine_scripts(*scripts: Union[bytes, 'Script'], json_transaction: dict) ->
combined.extend(script)
else:
raise InvalidScriptException(f"Invalid script type: {type(script)}")
return Script(bytes(combined), json_transaction)
return Script(bytes(combined), json_transaction, segwit=segwit)

51 changes: 49 additions & 2 deletions src/transaction.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@
import json

from ecdsa import VerifyingKey, SECP256k1, BadSignatureError
from Crypto.Hash import RIPEMD160

from src.script import Script, InvalidScriptException
from src.serialize import serialize_transaction
from src.utils import decode_hex, get_filename_without_extension, hash160
from src.verify import parse_der_signature_bytes, valid_transaction_syntax


def calculate_txid(transaction_content, coinbase=False):
# Serialize the transaction content
if coinbase:
Expand Down Expand Up @@ -104,13 +106,14 @@ def valid_input(self, vin_idx, vin):
if scriptpubkey_type == "p2pkh":
return self.validate_p2pkh(vin_idx, vin)
elif scriptpubkey_type == "p2sh":
pass
return self.validate_p2sh(vin_idx, vin)
elif scriptpubkey_type == "v0_p2wsh":
pass
elif scriptpubkey_type == "v1_p2tr":
pass
elif scriptpubkey_type == "v0_p2wpkh":
return self.validate_p2wpkh(vin_idx, vin)
#return self.validate_p2wpkh(vin_idx, vin)
pass

# Unknown script type.
return False
Expand Down Expand Up @@ -139,6 +142,49 @@ def validate_p2pkh(self, vin_idx, vin):

return is_valid

def validate_p2sh(self, vin_idx, vin):
#################
# Pubkey script #
#################
scriptsig = decode_hex(vin.get("scriptsig", ""))
if not scriptsig:
return False
prevout = vin.get("prevout", {})
if not prevout:
return False
scriptpubkey = decode_hex(prevout.get("scriptpubkey", ""))

# Check if the scriptpubkey is a P2SH script
if scriptpubkey[:2] != b'\xa9\x14' or scriptpubkey[-1:] != b'\x87':
# Not a P2SH script, fallback to P2PKH validation
return self.validate_p2pkh(vin_idx, vin)

# Extract the script hash from the scriptpubkey
script_hash = scriptpubkey[2:-1]

# Find the redeem script in the scriptsig
redeem_script_len = int.from_bytes(scriptsig[0:1], byteorder='little')
redeem_script = scriptsig[1:1+redeem_script_len]

# Create the combined script
script = Script.combine_scripts(redeem_script, json_transaction=self.json_transaction)

# Hash the redeem script and compare with the script hash
# Compute the HASH160 (RIPEMD-160 of SHA-256) of the redeem script
sha256_hash = hashlib.sha256(redeem_script).digest()
ripemd160 = RIPEMD160.new()
ripemd160.update(sha256_hash)
computed_script_hash = ripemd160.digest()

# Compare with the provided script hash
if computed_script_hash != script_hash:
return False

# Execute the redeem script
is_valid = script.execute()

return is_valid

def validate_p2wpkh(self, vin_idx, vin):
"""
Validate a Pay-to-Witness-Public-Key-Hash (P2WPKH) transaction input
Expand Down Expand Up @@ -200,6 +246,7 @@ def validate_p2wpkh(self, vin_idx, vin):

# Execute the script
try:
#return script.execute()
return script.execute()
except Exception as e:
print(f"P2WPKH validation error: {str(e)}")
Expand Down

0 comments on commit d9ef5b6

Please sign in to comment.