Segwit txin. Asociación de datos de testigos

Estoy tratando de aprender más sobre el protocolo bitcoin y estoy escribiendo un software de python para hacer una billetera ligera. He avanzado bastante y me he encontrado con algo que realmente no entiendo al leer sobre los cambios en el protocolo de testigo segregado en términos de transacciones.

https://bitcoincore.org/en/segwit_wallet_dev/

Si va aquí y lee la parte con el título "Serialización de transacciones", el texto se lee así:

Si una txin no está asociada con ningún dato testigo, su campo testigo correspondiente es un 0x00 exacto, lo que indica que la cantidad de elementos de la pila testigo es cero.

¿Cómo sé si una entrada que estoy usando en mi secuencia de comandos está asociada con datos testigo? Intenté usar API públicas para ver los resultados que estoy usando y no puedo entender lo que significa. Veo campos testigo asociados con las entradas de la transacción que produjo las salidas que intento incluir en mi transacción, pero no al revés.

¿Está tratando de crear una transacción o de analizar una existente?
Intentando crear una transacción. Usaría las direcciones para determinarlo pero sé que es imposible distinguir un P2SH de un P2SH-P2WPKH
Necesitas saber lo que estás firmando. Obviamente, no puede crear una firma sin la clave privada; igualmente, necesita saber si es un multisig o P2SH o P2WPKH o cualquier script que esté firmando. La dirección nunca es suficiente.
Comprendido. Entonces, si tengo un bech32 o un p2sh-p2wpkh, ¿la entrada que poseo siempre se clasificará como asociada con datos de testigos? ¿Pero con una dirección heredada nunca se asociará?
Gastar una salida de segwit siempre requiere un testigo. Gastar una salida no segwit nunca requiere un testigo. Pero no veo cómo esta información es útil; aún necesita saber exactamente cómo construir el scriptSig y el testigo de todos modos, lo que depende del tipo de script que esté gastando. Da la casualidad de que todos los scripts de segwit necesitan un testigo que no esté vacío, mientras que otros no.
Solo estoy tratando de entender cambiando dinámicamente el formato de serialización en función de si quiero gastar una salida de una dirección segwit o ninguna dirección segwit.
La serialización no depende de la salida; solo los datos que se serializan lo hacen. El byte cero solo indica "testigo vacío", en cada situación (ya sea gastando una salida segwit o no segwit). Un testigo no vacío no puede ocurrir en una transacción válida que gasta una salida no segwit, pero su serializador no debería preocuparse por eso.
Estoy empezando a entender. Gracias
Una cosa más. Probablemente debería abrir otra pregunta, pero creo que sería una repetición de bitcoin.stackexchange.com/questions/61290/… . Si tengo varias entradas, ¿cuál sería la cantidad para el hash preImage? Estoy pensando en el importe de la última entrada pero no estoy seguro. No está muy claro.
El monto gastado por la entrada que está firmando.
Pero en los ejemplos en github.com/bitcoin/bips/blob/master/bip-0143.mediawiki tiene múltiples entradas pero solo firma una vez. Esto es tan confuso.
En la(s) firma(s) para la entrada 1, usted firma la cantidad que está gastando la entrada 1. En la(s) firma(s) para la entrada 2, usted firma la cantidad que está gastando la entrada 2, etc.
No me di cuenta de que tiene que firmar cada entrada por separado. Eso es frustrante.
Realmente es la única manera. Cada entrada puede gastar salidas no relacionadas (cada una desde una dirección diferente, con claves diferentes; todas esas claves deben cerrar sesión para autorizar la transacción). También es por eso que hay un scriptSig/witness por entrada, y no uno global para toda la transacción. Hay una investigación en curso sobre cómo integrar esquemas de firmas múltiples en Bitcoin, lo que permitiría una sola firma que demuestre que todas las claves están firmadas, pero eso no estará disponible en el corto plazo.

Respuestas (1)

¿Cómo sé si una entrada que estoy usando en mi secuencia de comandos está asociada con datos testigo? Intenté usar API públicas para ver los resultados que estoy usando y no puedo entender lo que significa. Veo campos testigo asociados con las entradas de la transacción que produjo las salidas que intento incluir en mi transacción, pero no al revés.

Creo que tu confusión se debe a esta línea.

Si una txin no está asociada con ningún dato testigo, su campo testigo correspondiente es un 0x00 exacto, lo que indica que la cantidad de elementos de la pila testigo es cero.

no aplicándose al formato de serialización, sino a los contenidos.

Un testigo siempre se serializa como:

  • Un entero de longitud variable que indica el número de elementos de la pila testigo n .
  • Para cada uno de los n elementos de la pila:
    • Un entero de longitud variable que indica el tamaño del elemento de pila b
    • Una matriz de bytes b con el contenido de ese elemento de la pila.

Un corolario es que un testigo vacío siempre se serializa como un byte 0x00 (lo que indica que no hay elementos de pila).

Por lo tanto, su código de serialización y análisis no necesita saber si una txin en particular tiene datos testigo asociados. Simplemente serializa/analiza el testigo, que puede estar vacío.

Ocurre que las reglas de validez exigen que el testigo de un gasto no segwit siempre tenga que estar vacío y, como resultado, la serialización de dicho testigo siempre será solo 0x00.