Author

Topic: Length of redeemScript (Read 2199 times)

donator
Activity: 1218
Merit: 1079
Gerald Davis
May 19, 2014, 08:16:33 PM
#7
Yes that is right (except you have a typo in the P2SH script and IIRC it is reversed on the stack).

Still nobody is going to patch out Pay2Pubkeyhash.  I was just pointing out that because it was added after the fact in order to work with the existing scripting engine it is kinda a kludge.  You have a script in the output which says to use a second script in the input (which is located in the signature of all places) to determine the condition required to redeem the output.   It was done this way in order to shoe horn scripthashes into Bitcoin 2 years after the genesis block without breaking compatibility with existing scripting.  

Still if you were going to build a scripting engine with no legacy support I think you can see it wouldn't be built that way.   If starting from a blank page, the output could contain the ScriptHash.  I don't mean a ScriptHash buried in a script but just the ScriptHash (i.e. ScriptHash vs OP_HASH160 OP_EQUALVERIFY).  Then all inputs would have a field for the redeemScript and there would be a seperate signature.  All transactions would have the same format for inputs and outputs.  If nothing else it would make figuring the damn thing out a lot easier. Smiley
legendary
Activity: 924
Merit: 1132
May 19, 2014, 07:34:31 PM
#6
I've been meaning to look at it in more detail.  Thanks for providing info.

https://en.bitcoin.it/wiki/Transactions gives info but it's a bit hard to understand.

Each input of a transaction contains a 'ScriptSig' and each output contains a 'ScriptPubKey'.

The checking mechanism is that the ScriptSig is concatenated with the 'ScriptPubKey' and the result is treated as a script for the script engine to work on, right? 

And the distinction between 'pay to script hash' and 'pay to pubkey hash' is:

In the 'pay to pubkey hash' the scriptsig consists of and the script instructions are in the ScriptPubKey.  The ScriptPubKey says something like OP_DUP ,OP_HASH160, , OP_EQUALVERIFY, OP_CHECKSIG, so the initial 'script' when the script engine starts is

OP_DUP OP_HASH160 OP_EQUALVERIFY, OP_CHECKSIG.

In the 'pay to script hash' the Scriptsig consists of OP_HASH160 OP_EQUAL and the ScriptPubKey consists of whatever signatures and script the spender puts in, making the initial script when the script engine starts be

OP_HASH160 OP_EQUALVERIFY ...signatures.... ... custom spending script .... 

But the script engine works exactly the same way regardless and doesn't even realize there's any difference between these two cases.  You'd have to patch it to detect and exclude the pay-to-pubkey case if you wanted to make pay-to-script-hash uniform, right?  It doesn't care what's in these fields, it just concatenates them with each other and treats the result as a script to run.

donator
Activity: 1218
Merit: 1079
Gerald Davis
May 19, 2014, 03:37:19 PM
#5
Quote
When you're talking about a 'redeemscript' you need to be specific as to which transaction you're talking about it in.

redeemScript is a proper name.  It has a single specific meaning.  Scripts are limited to 520 bytes.  redeemScript is always in the input of a transaction which is referencing a P2SH output of a prior transaction.

Quote
Let's say you have a transaction B, which is using as its inputs the outputs from transaction A.
In transaction A, the 'redeemscript' would be a fixed-length hash.  (8 bytes?  16? I'd have to go look)

That is close but not correct.  This gets a little in the weed so someone just wanting to know what redeemScript is see above.

Outputs define the terms which encumber how the output can be used, this is (poorly) named the scriptPubKey.  The scriptPubKey does (normally) contain a hash but it will either be a scriptHash or PubKeyHash.  Both are 32 bytes (SHA256 is 256 bits) but they are not the redeemScript.

scriptPubKey ("output script")
Pay2PubKeyHash Tx: OP_DUP OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG
Pay2ScriptHash Tx: OP_HASH160 OP_EQUAL

When technical docs refer to the redeemScript, it is referring to the script in the ScriptSig (yet another poorly named element) of the input of a transactions.  There is only a redeemScript when redeeming a P2SH.

scriptSig ("input script")
Pay2PubKeyHash:
Pay2ScriptHash: ... <redeemScript>

For an input to be valid it must meet the conditions which encumber ("lock") the output.  For P2SH transactions the terms are defined but unknown as a P2SH output only contains a ScriptHash.   So the redeemScript is appended to the signatures in the ScriptSig.  In validation the redeemScript is hashed to verify it matches the ScriptHash in the prior output.  The input is then verified to ensure the signatures meet the requirements of the script.  

There is no redeemScript in an input which references a Pay2PubKeyHash output.  The output contains the actual script not a hash of the script.  It is also possible to create other non-standard transactions which define the conditions in the actual output however those are deprecated in favor of P2SH outputs.  Anything you can do directly in the output can be done in a redeemscript and the ScriptHash placed in the output.  P2SH provides a better way to handle "where to put the conditions".  Still the use of P2SH for almost everything except Pay2PubKeyHash kinda sticks out as this weird special exception.  There is no reason it couldn't just work like any other P2SH script (i.e. address becomes not the encoded PubKeyHash but the encoded ScriptHash) then all inputs are P2SH inputs.  If you wonder why we have two different ways of doing the same thing see the semi-OT side note below.


side note (just some pointless D&T pontificating):
If it seems like Pay2PubKeyHash is treated as a "special case" well it is.  More generally the script can either be in the output or a hash of the script in the output (and then a copy of the script added to the input).  All transactions from the most complex to the simplest could be done either way but there is no reason to have two redundant methods to accomplish the same task.  The reason this exists is because P2SH didn't exist in the original Bitcoin.  Outputs (even for "sending coins to an address") are always scripts.  It works for simple scripts but more complex scripts become clunky as the sender needs to know the entire script not just which key to use.  Providing the sender with a hash of the script is superior for a lot of reasons.  It is a good separation of concerns.  So Bitcoin was forked to support P2SH.  Technically support for Pay2PubKeyHash outputs could have been removed (you can generate a P2SH address for a single key script) but it wasn't.  Support for having the output contain the script remained (primarily to support "normal" Pay2PubKeyHash transactions).  It is very likely that P2SH will eventually replace all other transactions leaving only Pay2PubKeyHash which defines the script in the output making it a special exception in practice if not protocol.

If Satoshi had thought of P2SH from the beginning it could have eliminated the redundancy of having scripts in both input and output.  P2SH is normally used for complex scripts but there is no reason a very simple script like OP_CHECKSIG can't be used.  Instead of providing the sender an address which decodes to the PubKeyHash (and then the client knows to stick it into a special output script) you would provide the sender an address that decodes the the hash of this simple script.  You can use it right now for your existing keys - it will produce a different address for the same key though*.  If an altcoin supported this from day zero then the output could be simplified further.  There would be no need for any opcodes in the output.  They would just contain the script hash.  This would not only make transactions smaller it would more importantly reduce the size of the UXTO.

* Warning: Any time you work with custom scripts always use testnet.  You can permanently lose funds due to invalid or misformatted scripts.
legendary
Activity: 924
Merit: 1132
May 19, 2014, 01:23:59 PM
#4
When you're talking about a 'redeemscript' you need to be specific as to which transaction you're talking about it in.

Let's say you have a transaction B, which is using as its inputs the outputs from transaction A. 

In transaction A, the 'redeemscript' would be a fixed-length hash.  (8 bytes?  16? I'd have to go look)

In transaction B, it's two pieces; the first piece (script) has to hash and match up to the hash given in transaction A.   Both pieces (script and data) have to be loaded onto the stack and then the script engine is run. 

Anyway, the scripts are limited to 201 steps. 



legendary
Activity: 1260
Merit: 1168
May 18, 2014, 04:09:27 PM
#3
This message was too old and has been purged
newbie
Activity: 50
Merit: 0
May 18, 2014, 04:05:09 PM
#1
What is the maximum length of a redeemScript? I think it is 8 bytes, but I don't know.
Jump to: