0

I currently try to create and sign transaction from scratch. I made it to construct and sign a transaction. If I verify it manually it looks good but using a "proper" wallet my transaction is refused:

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

That's what I get from bitcoin-cli

My ScriptSig is: 4a304602210090c4fc2369cf225559c1141a1e9be3d7598f0fb7affe8a29f86e737972c7587a022100cbd8619ecae3baa40fdb565014fdac28a95deb90c0fcd4adcbd97d58d0e96f9801410442718de90a0a10f0cd10054ff4ab6037fd230c5d4b50c07eed0bc247e1e3dbd9ad3f4c65680396813bd96b0c2db5647e355082db34c7106a74337d51e5730f45

I would decode it as follows:

4a => length of signature, 74 byte

304602210090c4fc2369cf225559c1141a1e9be3d7598f0fb7affe8a29f86e737972c7587a022100cbd8619ecae3baa40fdb565014fdac28a95deb90c0fcd4adcbd97d58d0e96f98 DER signature

01 opcode SIGHASH_ALL

41 public key length, 65 byte

0442718de90a0a10f0cd10054ff4ab6037fd230c5d4b50c07eed0bc247e1e3dbd9ad3f4c65680396813bd96b0c2db5647e355082db34c7106a74337d51e5730f45 public key

Can you spot a problem with this ScriptSig?

3 Answers 3

2

Your signature is not correct. First of all, its length can't be 74 bytes long. According to the Bitcoin wiki:

Signatures are either 73, 72, or 71 bytes long, with probabilities approximately 25%, 50% and 25% respectively, although sizes even smaller than that are possible with exponentially decreasing probability.

Having said that, it seems that you have computed the length of the signature wrong twice. First, what you decoded as the DER signature is not 74-byte long, but 72:

sig = "304602210090c4fc2369cf225559c1141a1e9be3d7598f0fb7affe8a29f86e737972c7587a022100cbd8619ecae3baa40fdb565014fdac28a95deb90c0fcd4adcbd97d58d0e96f98"

len(sig/2) = 72 

Moreover, you didn't count the hash flag as part of the signature length, and you should. That will add an extra byte, making the signature 73-byte long.

Putting all together, the script should be:

ScriptSig = 49304602210090c4fc2369cf225559c1141a1e9be3d7598f0fb7affe8a29f86e737972c7587a022100cbd8619ecae3baa40fdb565014fdac28a95deb90c0fcd4adcbd97d58d0e96f9801410442718de90a0a10f0cd10054ff4ab6037fd230c5d4b50c07eed0bc247e1e3dbd9ad3f4c65680396813bd96b0c2db5647e355082db34c7106a74337d51e5730f45

Finally, notice that, according to what @pebwindkraft told you in his answer, you are producing high-S signatures, so you should also work around that.

2
  • If you also need help with the high-S signature component, let me know and I'll update the answer.
    – sr_gi
    Commented Sep 27, 2017 at 5:07
  • see my correction below (in bold). Seems like S-Value is correct. Commented Nov 3, 2017 at 15:32
1

The scriptSig field is supposed to contain only data push operations. A valid scriptSig will be of the form

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

The scriptSig you specified was interpreted as follows (in the beginning):

`4a`                   // Push 74 bytes
`30460...96f980141`    // 74 bytes of data
`04`                   // Push 4 bytes
`42718de9`             // 4 bytes of data
`0a`                   // Push 10 bytes
`0a10f0cd10054ff4ab60` // 10 bytes of data

The next byte the interpreter encounters is fd which is not a push data operator (only opcodes below 0x60 are considered push data operators). It terminates with an error complaining that the scriptSig is not a "push only".

I figured this out using python-bitcoinlib.

from bitcoin.core import *
from bitcoin.core.script import *

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

The final command gives the output:

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

As the other answers have pointed out, if you change the first byte in your scriptSig from 4a to 49 then the output of CScript(s) has no errors. It is as follows:

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

not sure which OS and which wallet you talk about... I have two observations.

printf "304602210090c4fc2369cf225559c1141a1e9be3d7598f0fb7affe8a29f86e737972c7587a022100cbd8619ecae3baa40fdb565014fdac28a95deb90c0fcd4adcbd97d58d0e96f9801" | wc -c
     146

which is 73 Bytes only, and if you remove 01, which ends script sig, it gets 72 bytes (hex 0x48). That's probably what you want to use.

Also:

#########################################################
### 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)

Is this maybe an older version? Newer version correct S-values smaller than N/2.

correction on the S-Value (November 2017):

the S-Value here is: 00cbd8619ecae3baa40fdb565014fdac28a95deb90c0fcd4adcbd97d58d0e96f98

Pieter explains zero Padding and S-Value in this thread: http://bitcoin-development.narkive.com/OOU2XVSG/bitcoin-development-who-is-creating-non-der-signatures

For S-Values he says:

... 2. Signatures are strictly DER-encoded (+ hashtype byte). The format is:

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

R and S are signed integers, encoded as a big-endian byte sequence. They are stored in as few bytes as possible (i.e., no 0x00 padding in front), except that a single 0x00 byte is needed and even required when the byte following it has its highest bit set, to prevent it from being interpreted as a negative number.

Based on this the S-Value is zero padded, and as such correct.

3
  • If the S value was the problem, he'd get a different failure message. Commented Sep 26, 2017 at 20:59
  • 1
    The push of the signature is not properly set (4a), it should be 49. As it is right now it is counting one extra byte as part of the signature, which corresponds to the push of the public key (41), making the script invalid.
    – sr_gi
    Commented Sep 27, 2017 at 5:12
  • @pebwindkraft the 01 is part of the signature. But my length indeed was off by 1. Some logic problems in my brain :)
    – soupdiver
    Commented Sep 27, 2017 at 12:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.