Skip to content
buybitcoinsmart

Glossary / Developer reference

Signature script

Also known as scriptSig, Unlocking script.

Definition
A signature script is the unlocking data an input carries to satisfy the pubkey script of the output it spends, and on modern SegWit inputs it is empty.

Every input in a transaction points at an earlier output and has to prove it is allowed to spend it. Bitcoin Core names the field scriptSig; on a legacy pay-to-public-key-hash input it holds a 71 or 72 byte signature and a 33-byte public key, roughly 107 bytes. Since SegWit that proof usually lives elsewhere, which is most of the reason a bech32 withdrawal costs you less.

How it works

The signature script runs first and leaves its results on the stack for the output's script to consume. The two do not run as one joined program: they are executed in sequence with the stack handed over between them, a separation introduced in 2010 after the original design proved exploitable.

Relay policy insists that this field contain nothing but data pushes. No conditional, no arithmetic, no opcode that does work. The restriction exists because a spender controls these bytes completely, and letting an attacker run logic on the way in reopens problems the network closed long ago. Pay-to-script-hash makes the rule a consensus requirement rather than a preference, since the redeem script must arrive as the last plain push.

Its size depends entirely on what it is unlocking. A legacy single-key input carries a signature and a key. A nested SegWit input carries exactly 23 bytes, a single push of the 22-byte witness program, and pushes everything else into the witness. A native bech32 or bech32m input carries nothing at all: the serialized field is a single zero length byte.

There is one input whose signature script is not a proof of anything. The lone input of a coinbase transaction has no earlier output to unlock, so the field is repurposed as free space between 2 and 100 bytes, and since BIP-34 it must start with the block height. Miners have signed messages, votes and jokes in there since 2009.

Where you see it

Decode any transaction and each input shows a scriptSig object with an assembly view and a hex view. On a native SegWit or Taproot input both are empty strings while a separate witness field holds the data, and that visual asymmetry is the quickest way to tell at a glance which address format an old transaction used.

It also explains a widely misread piece of history. Because scriptSig was covered by the transaction ID, a third party could re-encode a signature without invalidating it and change the ID of a transaction already broadcast. Mt. Gox halted withdrawals in February 2014 and blamed exactly this behaviour, though later academic analysis of the chain found the volume of malleated transactions was far too small to account for the missing coins. SegWit ended the argument in August 2017 by taking the unlocking data out of the ID calculation entirely.

Signature script vs Witness data

A signature script and witness data both carry the same kind of proof, and SegWit moved the job from one to the other without changing what a signature means. The differences that matter to you are price and permanence. Witness bytes are billed at one weight unit each while signature script bytes cost four, so the identical single-key spend is roughly 148 virtual bytes when the proof rides in the scriptSig and roughly 68 when it rides in the witness. Witness data also sits outside the transaction ID, so a spend cannot have its identifier altered in flight. A legacy input still uses the old field, which is why coins parked on an address beginning with 1 quietly cost more to move every time you move them.

Not to be confused with

Frequently asked questions

Why is the signature script empty on my SegWit transaction?

Because the signature and public key moved into the witness field, which is billed at a quarter of the weight. An empty scriptSig on a bech32 input is correct and expected, not a sign that anything failed.

Can anyone change my signature script after I broadcast?

On a legacy input a third party could once re-encode the signature and change the transaction ID without invalidating the spend. SegWit removed that possibility for witness inputs by excluding the unlocking data from the identifier.

Related terms

More in Developer reference