¿Qué está mal con mi ScriptSig? Obtengo 64: scriptsig-not-pushonly

Actualmente trato de crear y firmar transacciones desde cero. Lo hice para construir y firmar una transacción. Si lo verifico manualmente, se ve bien, pero al usar una billetera "adecuada", mi transacción es rechazada:

error code: -26
error message:
64: scriptsig-not-pushonly

Eso es lo que obtengo debitcoin-cli

Mi ScriptSig es:4a304602210090c4fc2369cf225559c1141a1e9be3d7598f0fb7affe8a29f86e737972c7587a022100cbd8619ecae3baa40fdb565014fdac28a95deb90c0fcd4adcbd97d58d0e96f9801410442718de90a0a10f0cd10054ff4ab6037fd230c5d4b50c07eed0bc247e1e3dbd9ad3f4c65680396813bd96b0c2db5647e355082db34c7106a74337d51e5730f45

Yo lo decodificaría de la siguiente manera:

4a=> longitud de la firma, 74 bytes

304602210090c4fc2369cf225559c1141a1e9be3d7598f0fb7affe8a29f86e737972c7587a022100cbd8619ecae3baa40fdb565014fdac28a95deb90c0fcd4adcbd97d58d0e96f98firma DER

01código de operación SIGHASH_ALL

41longitud de la clave pública, 65 bytes

0442718de90a0a10f0cd10054ff4ab6037fd230c5d4b50c07eed0bc247e1e3dbd9ad3f4c65680396813bd96b0c2db5647e355082db34c7106a74337d51e5730f45Llave pública

¿Puedes detectar un problema con este ScriptSig?

Respuestas (3)

Tu firma no es correcta. En primer lugar, su longitud no puede ser de 74 bytes. Según la wiki de Bitcoin :

Las firmas tienen una longitud de 73, 72 o 71 bytes, con probabilidades de aproximadamente 25 %, 50 % y 25 % respectivamente, aunque son posibles tamaños incluso más pequeños con una probabilidad decreciente exponencial.

Habiendo dicho eso, parece que ha calculado mal la longitud de la firma dos veces. Primero, lo que decodificó como la firma DER no tiene una longitud de 74 bytes, sino 72:

sig = "304602210090c4fc2369cf225559c1141a1e9be3d7598f0fb7affe8a29f86e737972c7587a022100cbd8619ecae3baa40fdb565014fdac28a95deb90c0fcd4adcbd97d58d0e96f98"

len(sig/2) = 72 

Además, no contó la bandera hash como parte de la longitud de la firma, y ​​debería hacerlo. Eso agregará un byte adicional, haciendo que la firma tenga una longitud de 73 bytes.

Poniendo todo junto, el guión debería ser:

ScriptSig = 49304602210090c4fc2369cf225559c1141a1e9be3d7598f0fb7affe8a29f86e737972c7587a022100cbd8619ecae3baa40fdb565014fdac28a95deb90c0fcd4adcbd97d58d0e96f9801410442718de90a0a10f0cd10054ff4ab6037fd230c5d4b50c07eed0bc247e1e3dbd9ad3f4c65680396813bd96b0c2db5647e355082db34c7106a74337d51e5730f45

Finalmente, tenga en cuenta que, de acuerdo con lo que @pebwindkraft le dijo en su respuesta, está produciendo firmas de S alta, por lo que también debe evitar eso.

Si también necesita ayuda con el componente de firma high-S, hágamelo saber y actualizaré la respuesta.
vea mi corrección a continuación (en negrita). Parece que S-Value es correcto.

Se supone que el scriptSigcampo contiene solo operaciones de envío de datos. Un testamento válido scriptSigserá de la forma

[Operator to push x bytes][x bytes of data][Operator to push y bytes][y bytes of data]...

Lo scriptSigque especificó se interpretó de la siguiente manera (al principio):

`4a` // Empuje 74 bytes
`30460...96f980141` // 74 bytes de datos
`04` // Empuje 4 bytes
`42718de9` // 4 bytes de datos
`0a` // Empuje 10 bytes
`0a10f0cd10054ff4ab60` // 10 bytes de datos

El siguiente byte que encuentra el intérprete es fdque no es un operador de datos de inserción (solo los códigos de operación a continuación 0x60se consideran operadores de datos de inserción). Termina con un error quejándose de que scriptSigno es un "solo push".

Descubrí esto usando python-bitcoinlib .

de importación bitcoin.core *
de importación bitcoin.core.script *

s = x('4a304602210090c4fc2369cf225559c1141a1e9be3d7598f0fb7affe8a29f86e737972c7587a022100cbd8619ecae3baa40fdb565014fdac28a95deb90c0fcd4adcbd97d58d0e96f9801410442718de90a0a10f0cd10054ff4ab6037fd230c5d4b50c07eed0bc247e1e3dbd9ad3f4c65680396813bd96b0c2db5647e355082db34c7106a74337d51e5730f45')
CScript(s)

El comando final da la salida:

CScript([x('30460...96f980141'),
 x('42718de9'),
 x('0a10f0cd10054ff4ab60'),
 x('fd230c...30f45') ERROR: PUSHDATA(55): datos truncados])

Como han señalado las otras respuestas, si cambia el primer byte en su scriptSigde 4aa 49entonces la salida de CScript(s)no tiene errores. Es como sigue:

CScript([x('3046022...96f9801'), x('0442718de...30f45')])

No estoy seguro de qué sistema operativo y de qué billetera hablas... Tengo dos observaciones.

printf "304602210090c4fc2369cf225559c1141a1e9be3d7598f0fb7affe8a29f86e737972c7587a022100cbd8619ecae3baa40fdb565014fdac28a95deb90c0fcd4adcbd97d58d0e96f9801" | wc -c
     146

que es solo de 73 bytes, y si elimina 01, que finaliza el script sig, obtiene 72 bytes (hexadecimal 0x48). Eso es probablemente lo que quieres usar.

También:

#########################################################
### procedure to strictly check DER-encoded signature ###
#########################################################
Minimum and maximum size constraints                        - ok
scriptsig always starts with 0x30                           - ok
length 140 chars is less than actual sig length (144 chars) - ok
       (hex 0x46, decimal 70, 140 chars)
length of R coordinate (66) >= 0                            - ok
length of S coordinate (66) >= 0                            - ok
S-Value is within scriptsig boundaries                      - ok
Make sure the R & S length covers the entire signature      - ok
--> S is not smaller than N/2, need new S-Value (new_s = N - s)

¿Es esta tal vez una versión anterior? La versión más reciente corrige valores S menores que N/2.

corrección en el valor S (noviembre de 2017):

el valor S aquí es: 00cbd8619ecae3baa40fdb565014fdac28a95deb90c0fcd4adcbd97d58d0e96f98

Pieter explica Zero Padding y S-Value en este hilo: http://bitcoin-development.narkive.com/OOU2XVSG/bitcoin-development-who-is-creating-non-der-signatures

Para valores S, dice:

... 2. Las firmas están estrictamente codificadas en DER (+ byte tipo hash). El formato es:

0x30 <lenT> 0x02 <lenR> <R> 0x02 <lenS> <S> <hashtype>

R y S son enteros con signo, codificados como una secuencia de bytes big-endian. Se almacenan en la menor cantidad de bytes posible (es decir, sin relleno 0x00 al frente), excepto que se necesita un solo byte 0x00 e incluso se requiere cuando el byte siguiente tiene su bit más alto establecido, para evitar que se interprete como negativo. número.

En base a esto, el valor S se rellena con ceros y, como tal, es correcto.

Si el valor S fuera el problema, recibiría un mensaje de falla diferente.
El push de la firma no está bien configurado (4a), debería ser 49. Como está ahora mismo se cuenta un byte extra como parte de la firma, que corresponde al push de la clave pública (41), haciendo que el guión inválido.
@pebwindkraft el 01 es parte de la firma. Pero mi longitud de hecho estaba errada por 1. Algunos problemas lógicos en mi cerebro :)