def depush(script: bytes) -> bytes: if len(script) == 0: raise ScriptValidationError('Empty script') push_byte, script = script[0], script[1:] op = OP(push_byte) if push_byte not in range(1, 76): raise ScriptValidationError( f'Script does not start with a PUSH opcode: {op}') if len(script) < push_byte: raise ScriptValidationError('Script too short') elif len(script) > push_byte: raise ScriptValidationError('Script too long') return script
def get_type(script): """https://github.com/bitcoin/bitcoin/blob/5961b23898ee7c0af2626c46d5d70e80136578d3/src/script/script.cpp#L202""" script = hex_to_bytes(script) if isinstance(script, str) else script if script.startswith(OP.HASH160.byte + OP.PUSH20.byte) and script.endswith( OP.EQUAL.byte) and len(script) == 23: return TX.P2SH elif script.startswith(OP.DUP.byte + OP.HASH160.byte) and script.endswith( OP.EQUALVERIFY.byte + OP.CHECKSIG.byte) and len(script) == 25: return TX.P2PKH elif script.startswith(b'\x00' + OP.PUSH32.byte) and len(script) == 34: return TX.P2WSH elif script.startswith(b'\x00' + OP.PUSH20.byte) and len(script) == 22: return TX.P2WPKH elif script.startswith(OP.PUSH65.byte + b'\x04') and script.endswith( OP.CHECKSIG.byte) and len(script) == 67: # uncompressed PK return TX.P2PK elif script.startswith((b'\x21\x03', b'\x21\x02')) and script.endswith( OP.CHECKSIG.byte) and len(script) == 35: # compressed PK return TX.P2PK else: raise ScriptValidationError( f"Unknown script type: {bytes_to_hex(script)}")
def version_byte(script): if not is_witness_program(script): raise ScriptValidationError("Script is not a witness program") return script[0]
def witness_program(script): if not is_witness_program(script): raise ScriptValidationError("Script is not a witness program") return script[2:]