From Biteasy's API for TXID fccf964964c34994e5dbbb9ff7f914159b524b0831f6eea12255aa424b39090e we can see the following info regarding inputs (for a P2SH Tx):

"script_sig_string": "[] [3044022016c09f09b6c55....]
"script_sig": "ff473044022016c09f09b6c55....

I do know a null byte vector (OP_0) is required for the off by 1 error for multisig Txs. But it's the raw hex where ff is representing the OP_0 (empty array) that is confusing me. Is this being read as 2's complement of 0x00 or is it reading OP_INVALIDOPCODE as outlined on the Bitcoin Wiki Script page (quoted below)?

OP_PUBKEYHASH      253  0xfd    Represents a public key hashed with OP_HASH160.
OP_PUBKEY          254  0xfe    Represents a public key compatible with OP_CHECKSIG.
OP_INVALIDOPCODE   255  0xff    Matches any opcode that is not yet assigned.

FYI, this Tx caused issues with the core software parsing the blockchain awhile back; that much I am aware. However I have yet to find an explanation online (omitting github/C++ code, which I am not well versed in reading)

2 Answers 2


Another very interesting question!

First, note the date of the transaction. Specifically:

"created_at": "2013-10-25T13:16:51.598Z"

It turns out that until this issue, ANY value could be used instead of OP_0. To quote Peter Todd:

While normally OP_0 is used, the actual value of this argument is not checked, and thus creates a source of mutability for any transaction with CHECKMULTISIG inputs.

The patch here actually made it so that the first argument of a standard multisig had to be OP_0 as to not cause transaction malleability.

Given that this transaction was before this commit got into the standard bitcoin client, that transaction was perfectly fine. You literally could have put almost any value as the first byte and it would have gone through.

Also note that this was a soft-forking change. It's still legal to put OP_INVALIDCODE instead of OP_0, it just won't be propagated by the standard bitcoin client and thus probably won't get into a block. Otherwise, this would have been a hard-forking change.

Edit: It looks like the API from biteasy is different than other places like blockchain:

Note that the script begins with 00, not ff as with biteasy.


"ver": 1,
"inputs": [
"sequence": 4294967295,
"prev_out": {
"spent": true,
"tx_index": 38094378,
"type": 0,
"addr": "35aHovjnZ9xdfYZsB2yBVTs6CWqnBpHNDY",
"value": 100000,
"n": 1,
"script": "a9142a9ada309638ec606f67e6b107867184c58a3aab87"
"script": "00473044022016c09f09b6c55c0afefa1c0f0b7fa5789b3fa486d19ba3e7f5338fc8a2701dc502203ab665792d477ffabcfb736b6d6951d238d5a8af8f9754cc29e9caab46b9b1dd01473044022016c09f09b6c55c0afefa1c0f0b7fa5789b3fa486d19ba3e7f5338fc8a2701dc502203ab665792d477ffabcfb736b6d6951d238d5a8af8f9754cc29e9caab46b9b1dd014cc9524104d9399e85461d925e4c3932cc033aee59873e1212216c81943d5634c2e45ee0f45181f69d63b236e53d286a43b2de2b0ee64850191771924430f92ac6542f3cf24104d9399e85461d925e4c3932cc033aee59873e1212216c81943d5634c2e45ee0f45181f69d63b236e53d286a43b2de2b0ee64850191771924430f92ac6542f3cf241046d38a48ed6f12b132cdf14e84d1d6678bbf0e148e1b4791ee39fa0945cecf86ecb870cd4c74a4e472b8e3034f771df0375a7c097adf2bc48ce9f2ea3e64e20dc53ae"
"block_height": 265976,
"relayed_by": "",
"out": [
"spent": true,
"tx_index": 38095095,
"type": 0,
"addr": "1QKjwQ7tJGaWrXyftce4ns47gvZ67GoqMt",
"value": 80000,
"n": 0,
"script": "76a914ffd6391cff55413edb04761ecf1a447d80bfe74188ac"
"lock_time": 0,
"size": 435,
"double_spend": false,
"time": 1382706718,
"tx_index": 38095095,
"vin_sz": 1,
"hash": "fccf964964c34994e5dbbb9ff7f914159b524b0831f6eea12255aa424b39090e",
"vout_sz": 1
  • I did notice that, as it's only biteasy which seems to flag the OP_0 as ff rather than 00 Mar 10, 2015 at 3:12

But it's the raw hex where ff is representing the OP_0 (empty array) that is confusing me

I do not see any problems with this tx. OK, pubkey1 == pubkey2 and there is one signature push repeated twice. But everything is correct



fd5c01 // scriptSig len
00     // push empty vector/zero value 

  • It's strange because I've got the same data when I run getrawtransaction, but the Python code I wrote which retrieves raw hex data from biteasy shows ff Mar 10, 2015 at 3:10
  • trust me. trust yourself. do not trust biteasy
    – amaclin
    Mar 10, 2015 at 5:09
  • I hear you mate: the Python code I wrote flags "interesting" Txs, which usually means a non-standard Tx template, but in this case it was both a non-standard Tx template and conflicting source hex data. I am acutely aware a full node (bitcoincore txindex=1) is "canonical" for Txs, whereas APIs are much less so. I know Blockchain.info and Blockexplorer.com have had issues with UTXOs balances and such, but wasn't aware APIs could differ in raw hex, since it implies the Blockchain data differs from consensus Mar 10, 2015 at 5:57

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.