feat(core): Recognize Taproot inputs.

pull/1918/head
Andrew Kozlik 3 years ago committed by Andrew Kozlik
parent 57fddcfd9d
commit 68ad1b07d2

@ -20,6 +20,10 @@ SIGHASH_ALL = const(0x01)
# The number of bip32 levels used in a wallet (chain and address)
BIP32_WALLET_DEPTH = const(2)
# Bitcoin opcodes
OP_0 = const(0x00)
OP_1 = const(0x51)
# supported witness versions for bech32 addresses
_BECH32_WITVERS = (0, 1)
@ -48,6 +52,7 @@ CHANGE_OUTPUT_SCRIPT_TYPES = tuple(CHANGE_OUTPUT_TO_INPUT_SCRIPT_TYPES.keys())
SEGWIT_INPUT_SCRIPT_TYPES = (
InputScriptType.SPENDP2SHWITNESS,
InputScriptType.SPENDWITNESS,
InputScriptType.SPENDTAPROOT,
)
SEGWIT_OUTPUT_SCRIPT_TYPES = (
@ -101,10 +106,16 @@ def input_is_segwit(txi: TxInput) -> bool:
)
def input_is_nonsegwit(txi: TxInput) -> bool:
return txi.script_type in NONSEGWIT_INPUT_SCRIPT_TYPES or (
txi.script_type == InputScriptType.EXTERNAL and txi.witness is None
)
def input_is_taproot(txi: TxInput) -> bool:
if txi.script_type == InputScriptType.SPENDTAPROOT:
return True
if txi.script_type == InputScriptType.EXTERNAL:
assert txi.script_pubkey is not None
if txi.script_pubkey[0] == OP_1:
return True
return False
def input_is_external(txi: TxInput) -> bool:

@ -223,7 +223,7 @@ class Bitcoin:
if i in self.segwit:
if i in self.external:
txi = await helpers.request_tx_input(self.tx_req, i, self.coin)
self.serialized_tx.extend(txi.witness or b"")
self.serialized_tx.extend(txi.witness or b"\0")
else:
await self.sign_segwit_input(i)
else:
@ -455,7 +455,7 @@ class Bitcoin:
# STAGE_REQUEST_SEGWIT_INPUT in legacy
txi = await helpers.request_tx_input(self.tx_req, i, self.coin)
if not input_is_segwit(txi):
if txi.script_type not in common.SEGWIT_INPUT_SCRIPT_TYPES:
raise wire.ProcessError("Transaction has changed during signing")
self.tx_info.check_input(txi)
@ -491,8 +491,7 @@ class Bitcoin:
async def sign_segwit_input(self, i: int) -> None:
# STAGE_REQUEST_SEGWIT_WITNESS in legacy
txi = await helpers.request_tx_input(self.tx_req, i, self.coin)
if not input_is_segwit(txi):
if txi.script_type not in common.SEGWIT_INPUT_SCRIPT_TYPES:
raise wire.ProcessError("Transaction has changed during signing")
public_key, signature = self.sign_bip143_input(txi)

@ -6,7 +6,7 @@ from trezor.messages import PrevTx, SignTx, TxInput
from apps.common.writers import write_bitcoin_varint
from .. import multisig, writers
from ..common import input_is_nonsegwit
from ..common import NONSEGWIT_INPUT_SCRIPT_TYPES
from . import helpers
from .bitcoin import Bitcoin
@ -21,7 +21,7 @@ class Bitcoinlike(Bitcoin):
async def sign_nonsegwit_bip143_input(self, i_sign: int) -> None:
txi = await helpers.request_tx_input(self.tx_req, i_sign, self.coin)
if not input_is_nonsegwit(txi):
if txi.script_type not in NONSEGWIT_INPUT_SCRIPT_TYPES:
raise wire.ProcessError("Transaction has changed during signing")
public_key, signature = self.sign_bip143_input(txi)

Loading…
Cancel
Save