Bitcoin Forum
April 28, 2017, 04:42:04 AM *
News: Latest stable version of Bitcoin Core: 0.14.1  [Torrent]. (New!)
 
   Home   Help Search Donate Login Register  
Pages: [1]
  Print  
Author Topic: What purpose was OP_CODESEPARATOR intended for?  (Read 3966 times)
fivebells
Sr. Member
****
Offline Offline

Activity: 462


View Profile
November 26, 2011, 01:41:23 PM
 #1

I get the impression that bitcoin's current implementation has since moved on, but I am curious about the original intent behind the OP_CODESEPARATOR opcode. 

More generally,is there a forum or document where early design decisions like this are discussed?  (I realize it's unlikely, but it's just possible I've missed it and it would be so useful to have.)
Advertised sites are not endorsed by the Bitcoin Forum. They may be unsafe, untrustworthy, or illegal in your jurisdiction. Advertise here.
1493354524
Hero Member
*
Offline Offline

Posts: 1493354524

View Profile Personal Message (Offline)

Ignore
1493354524
Reply with quote  #2

1493354524
Report to moderator
Mike Hearn
Legendary
*
expert
Offline Offline

Activity: 1526


View Profile
November 26, 2011, 02:07:01 PM
 #2

That's a great question. Unfortunately, the only design document for Bitcoin is the paper written by Satoshi. It covers the basic design but doesn't even mention scripting or contracts. Everything we know about this system has been effectively "rediscovered". Satoshi gave me a brief tutorial in contracts design before he left and the rest I figured out myself.

I spent some time a few months ago trying to figure out OP_CODESEPARATOR. Its definition is clear, but I failed to find any situations in which it would be helpful and I ended up wondering if it was actually mis-designed. We know there are bugs in the scripting system which imply parts of the code was written without ever being really tested.

The reasoning is as follows. There are obviously two places you can use an OP_CODESEPARATOR. One is scriptSig and the other is scriptPubKey. There's basically no point putting anything except data blocks in a scriptSig because it's evaluated without anything as input, so, anything that is put there can always be statically evaluated. The exception is if you find a way to represent the result more compactly and thus need lower fees, but from a logic perspective it may as well contain only data.

That leaves the scriptPubKey. Putting an OP_CODESEPARATOR here lets you create an "empty space" which the signature wouldn't cover. That's useful only if you can change the contents of that empty space after a signature is created. But you can't, because a signature always covers the COutPoint structure, ie, it contains the hash of the connected transaction, thus you are indirectly signing the contents of that empty space regardless of the presence of a code separator or not. Changing what comes before the separator changes the tx hash and thus breaks any signatures on transactions that were trying to spend that output.

It's possible that I have missed something and there is a way to use it I can't see yet. But the indirect-signing thing seems pretty clear. There's no way to sign a spend of a transaction that later changes. If there was, there'd be ways to use the feature.
theymos
Administrator
Legendary
*
expert
Offline Offline

Activity: 2632


View Profile
November 26, 2011, 03:50:02 PM
 #3

Hmm... I was thinking you'd use it like this to avoid having signatures depend on one another:
Code:
<sigA> <pubkeyA> OP_CHECKSIGVERIFY OP_CODESEPARATOR <sigB> <pubkeyB> OP_CHECKSIG

1NXYoJ5xU91Jp83XfVMHwwTUyZFK64BoAD
Mike Hearn
Legendary
*
expert
Offline Offline

Activity: 1526


View Profile
November 27, 2011, 11:18:09 AM
 #4

How would that work? The act of inserting sigA or sigB changes the hash of the transaction containing the output, invalidating the other signature.
Gavin Andresen
Legendary
*
qt
Offline Offline

Activity: 1652


Chief Scientist


View Profile WWW
November 27, 2011, 03:49:54 PM
 #5

How would that work? The act of inserting sigA or sigB changes the hash of the transaction containing the output, invalidating the other signature.

I can't see how OP_CODESEPARATOR can be used, either. I'm tempted to suggest that any transactions using it be 'discouraged' (have miners refuse to build on blocks that contain transactions using it).

Transaction hashes might be another, separate discussion topic-- I've been thinking that the way transaction hashes are calculated/used could be improved, although I don't think it is a critical design flaw but in the category of "stuff we can live with but that maybe could have been done better".

How often do you get the chance to work on a potentially world-changing project?
fivebells
Sr. Member
****
Offline Offline

Activity: 462


View Profile
November 27, 2011, 04:58:34 PM
 #6

Thanks for the explanations, everyone.  That was very helpful.
theymos
Administrator
Legendary
*
expert
Offline Offline

Activity: 2632


View Profile
November 27, 2011, 07:44:30 PM
 #7

How would that work? The act of inserting sigA or sigB changes the hash of the transaction containing the output, invalidating the other signature.

I was thinking in terms of a "full" concatenated script, but I've found that pbegincodehash is not preserved between scriptSig and scriptPubKey, so that kind of thing isn't going to work.

Is having two checksig/checkmultisig commands in the same script actually even a problem? I'm now thinking that maybe scriptSigs are not even part of the sig hash, which would eliminate the problem entirely.

1NXYoJ5xU91Jp83XfVMHwwTUyZFK64BoAD
Mike Hearn
Legendary
*
expert
Offline Offline

Activity: 1526


View Profile
November 28, 2011, 09:56:17 AM
 #8

I don't think we should discourage it. It's possible there's something we're missing and a use may be discovered in future. The Bitcoin protocol is full of subtleties that aren't immediately apparent. It doesn't seem harmful and it'd be "discouraged" by the IsStandard checks anyway.

A way to refer to a transaction that isn't using its hash could be helpful for some protocols, but I think that would violate all kinds of invariants and make the codebase a lot more complex. It's likely that anything which at first looks like it needs this, can be redesigned to not need it.
Mike Hearn
Legendary
*
expert
Offline Offline

Activity: 1526


View Profile
November 28, 2011, 10:16:45 AM
 #9

Is having two checksig/checkmultisig commands in the same script actually even a problem? I'm now thinking that maybe scriptSigs are not even part of the sig hash, which would eliminate the problem entirely.

It's not a problem as long as the signatures are always in the scriptSig and never in the scriptPubKey.

For a while I thought including a signature in the output might allow you to do some neat things like restricting the form of the spending transaction, but it can't work - the signature is calculated in the context of the spending transaction and thus always signs over the hash of the connected transaction, which is the thing you need to insert the signature into. Signatures can't sign themselves.

The scripting system is flexible, but not as flexible as it might at first appear - scriptPubKeys can't contain signatures, and whilst scriptSigs are allowed to contain code there's (as far as I can see) no point in doing so. It really is primarily meant for containing signatures.

It would have been cool if OP_CHECKSIG allowed for signatures over arbitrary data rather than requiring it to be transaction hashes. However that isn't possible.
Pages: [1]
  Print  
 
Jump to:  

Sponsored by , a Bitcoin-accepting VPN.
Powered by MySQL Powered by PHP Powered by SMF 1.1.19 | SMF © 2006-2009, Simple Machines Valid XHTML 1.0! Valid CSS!