* [Bitcoin-development] RFC: empty scriptPubKeys and OP_RETURN for marking unspendable txouts
@ 2013-02-12 15:11 Peter Todd
2013-02-12 17:42 ` Gavin Andresen
0 siblings, 1 reply; 4+ messages in thread
From: Peter Todd @ 2013-02-12 15:11 UTC (permalink / raw)
To: bitcoin-development
[-- Attachment #1: Type: text/plain, Size: 3936 bytes --]
In my fidelity bond protocol (1) I'm proposing the use of two possible
new features:
The first is the use of OP_RETURN at the end of a scriptPubKey to
designate that the txout can be immediately pruned as it is obviously
unspendable. My use-case is the publish part of the two-step
publish-sacrifice protocol. I specifically want to use OP_RETURN rather
than a spendable scriptPubKey like <serialized tx> <pubkey> OP_CHECKSIG
so that implementors can not get lazy and fail to actually write the
code to spend the non-standard outputs created, thus polluting the UTXO
set. Simply using <serialized tx> by itself as the scriptPubKey -
spendable with an empty scriptSig - is another possiblity, but I suspect
no-one will want to spend the tx fees to clean up those txouts; note how
long it took for someone to bother doing that with p2pools share chain
hash txout, and the effort(2) seems to have been a one-time experiment.
Of course, P2Pool itself could use this mechanism too.
OP_RETURN marks the script as invalid upon execution, and since a script
is invalid if an OP_IF or OP_ELSE is not terminated with OP_ENDIF it is
guaranteed to execute. (there is no op-code that marks a script as valid
and returns immediately) OP_FALSE is another possibility too; I don't
see clear advantages for one or the other modulo OP_FALSE's more
intuitive name.
Finally OP_VERIF and OP_VERNOTIF say that "Transaction is invalid even
when occuring in an unexecuted OP_IF branch" on the wiki, although a
look at EvalScript() leaves me less than convinced this is true. More
to the point, the mechanism should be something that is as unlikely as
possible to have different behavior in alternate implementations.
(remember that often only valid transactions are put in unittests by
lazy implementors)
OP_RETURN doesn't need any special support in the reference client yet
nor am I suggesting to make it a standard transaction type, but I would
like some feedback on if the idea itself is reasonable.
The second idea is the use of an empty scriptPubKey to create trivially
spendable outputs; provide the the scriptKey OP_TRUE or similar. For
fidelity bonds the advantage is to create a mechanism where even
non-miners have a chance at taking the funds sacrificed, and thus
increase the incentive to scan the blockchain for sacrifices and makes
it more likely for the sacrifice to be a true sacrifice of value. An
additional advantage is you avoid having to provide the txin to prove
the value of the mining fee. The advantage over just using a pubkey with
a known secret key is that the transaction size is shorter; remember
that the sacrifice transaction has to be published as serialized data in
a prior transaction.
In the future another use would be as a way of multiple parties to
collectively sign an assurance contract(3) donating to miners. This is
effectively a mining fee because miners who chose to include the
transaction can always chose to include an additional transfer from the
txout to a scriptPubKey only they can spend.
For the purpose of fidelity bonds ideally an empty scriptPubKey spent by
the scriptSig OP_TRUE would be made a standard transaction type to make
collecting the funds as easy as possible until miners start doing so
themselves. Having it a standard transaction type would also make it
easier for miners to implement the code to do this themselves; in
particular this discourages them from just allowing all non-standard
transactions. The main disadvantage I see is that it makes it easier for
people with buggy custom transaction code to accidentally lose their
funds.
Again, thoughts?
1) https://github.com/petertodd/trustbits/blob/master/fidelitybond.md
2) See the transactions associated with 1HfA1KHC7bT1hnPPCjpj9CB4koLM4Hz8Va
3) https://en.bitcoin.it/wiki/Contracts#Example_3:_Assurance_contracts
--
'peter'[:-1]@petertodd.org
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 490 bytes --]
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [Bitcoin-development] RFC: empty scriptPubKeys and OP_RETURN for marking unspendable txouts
2013-02-12 15:11 [Bitcoin-development] RFC: empty scriptPubKeys and OP_RETURN for marking unspendable txouts Peter Todd
@ 2013-02-12 17:42 ` Gavin Andresen
2013-02-13 4:12 ` Peter Todd
0 siblings, 1 reply; 4+ messages in thread
From: Gavin Andresen @ 2013-02-12 17:42 UTC (permalink / raw)
To: Peter Todd; +Cc: bitcoin-development
[-- Attachment #1: Type: text/plain, Size: 851 bytes --]
On Tue, Feb 12, 2013 at 10:11 AM, Peter Todd <pete@petertodd.org> wrote:
> .... Again, thoughts?
>
First: I really like the fidelity bond concept, and want to see it happen.
RE: OP_RETURN : I've got a knee-jerk opposition to the OP_RETURN opcode,
because it was the cause of the nastiest bug ever Bitcoin history. So I'd
be more comfortable using either OP_FALSE or OP_INVALIDOPCODE for the
"provably unspendable" transaction.
RE: anyone-can-spend transactions: Thinking aloud... I wonder if we might
inadvertently cause "spend storms" on the network; if suddenly there are 11
BTC sitting in an anybody-can-spend txout, I could imagine EVERYBODY on the
network trying to race each other to spend it (maybe assuming that there
are a few miners on old versions of the software who are too dumb to claim
it for themselves).
--
--
Gavin Andresen
[-- Attachment #2: Type: text/html, Size: 1242 bytes --]
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [Bitcoin-development] RFC: empty scriptPubKeys and OP_RETURN for marking unspendable txouts
2013-02-12 17:42 ` Gavin Andresen
@ 2013-02-13 4:12 ` Peter Todd
2013-02-13 10:00 ` Mike Hearn
0 siblings, 1 reply; 4+ messages in thread
From: Peter Todd @ 2013-02-13 4:12 UTC (permalink / raw)
To: Gavin Andresen; +Cc: bitcoin-development
[-- Attachment #1: Type: text/plain, Size: 5406 bytes --]
On Tue, Feb 12, 2013 at 12:42:37PM -0500, Gavin Andresen wrote:
> On Tue, Feb 12, 2013 at 10:11 AM, Peter Todd <pete@petertodd.org> wrote:
>
> > .... Again, thoughts?
> >
>
> First: I really like the fidelity bond concept, and want to see it happen.
>
> RE: OP_RETURN : I've got a knee-jerk opposition to the OP_RETURN opcode,
> because it was the cause of the nastiest bug ever Bitcoin history. So I'd
So what exactly was the OP_RETURN bug anyway? I know it has something to
do with not executing the scriptSig and scriptPubKey separately
(https://bitcointalk.org/index.php?topic=58579.msg691432#msg691432) but
commit 7f7f07 that you reference isn't in the tree, nor is 0.3.5 tagged.
> be more comfortable using either OP_FALSE or OP_INVALIDOPCODE for the
> "provably unspendable" transaction.
You know, come to think of it, OP_FALSE doesn't get used by standard
transactions either, and it's behavior is a little odd in how it does
push to the stack. So lets make the standard OP_INVALIDOPCODE,
specifically 0xFF, and put it at the start of the scriptPubKey.
> RE: anyone-can-spend transactions: Thinking aloud... I wonder if we might
> inadvertently cause "spend storms" on the network; if suddenly there are 11
> BTC sitting in an anybody-can-spend txout, I could imagine EVERYBODY on the
> network trying to race each other to spend it (maybe assuming that there
> are a few miners on old versions of the software who are too dumb to claim
> it for themselves).
That's a good point. It would encourage efforts to identify as many
Bitcoin nodes as possible, particularly miners, and I don't think we
really want to incentivise that. It's not a problem unique to this
proposal - compromised private keys and SIGHASH_NONE (1) - but
fidelity bonds will give people incentive to develop the infrastructure
to exploit it.
1) Speaking of, maybe I'm missing something, but if I have a
transaction with one or more txin's and sign every signature with
SIGHASH_SINGLE, what stops an attacker from adding their own txout
at the end and diverting the mining fee to themselves?
Having said that, if we both make empty scriptPubKeys standard, and add
code so that miners will always try to spend the outputs for themselves
at the same time, we can get rid of this problem by removing the
incentive. It would also still make non-fidelity-bond uses viable as
well.
Of course, if you want to go down that path, we might as well add code
to detect and spend fidelity bonds too, and make the publish
transactions IsStandard(). Basically for every script in a confirmed
block check if any pushdata op happens to be a script that we would be
willing to add to the mempool at nBlockHeight + N. (assuming current
utxo set) If so, add it to the mempool now. N should be at least 100
blocks I think for the same reason that coinbase tx's take 100 blocks to
spend. The limit also means the size of the mempool can't get larger
than MAX_BLOCK_SIZE * N. Meanwhile IsStandard() would allow the
scriptPubKey OP_INVALIDOPCODE <valid serialized tx>
P2SH already treats data as scripts, so treating data as entire tx's
isn't that big of a leap. Also since the txout is unspendable, the
Satoshi criteria that block-reorgs should not make child tx's vanish is
still met. (though tx mutability sort of breaks this anyway)
We would however open quite a few cans of worms:
1) We just made non-final !IsStandard() for a reason.
2) What if there are transactions already in the mempool that spend the
txin's of the sacrifice? If we ignore them, we've just created another
way to double-spend unconfirmed transactions. On the other hand, if we
don't ignore them, we've just created a way to give us a chance to mine
the sacrifice for ourselves.
Personally I'm with you Gavin and think assuming miners are greedy is
best, but lets just say I probably shouldn't write an implementation
with a function named IsTxOutStealable()?
2a) What if multiple sacrifice publications exist spending the same
txin's? We should have deterministic behavior and mine the most valuable
one. If you don't do that, the attackers effective hashpower is
increased. (and thus the true sacrifice value of the bond decreases)
2b) ...but this is actually an annoying optmization problem. You could
create a whole bunch of sacrifices, each spending two or more inputs,
one small, one large. Then create one large sacrifice, that spends all
the *small* inputs. If the value of the large sacrifice is less than the
combined totals of the smaller sacrifices, you should be mining the
small ones rather than the large for maximum return.
3) With the 10KB limit on scripts, a naive IsStandard() could wind up
recursing about 200 times; we probably should say recursive publish
transactions are non-standard.
3b) ...on the other hand, if they are non-standard, implementations that
use fidelity bonds better make sure they don't accept such monsters.
We probably should just define one standard sacrifice tx form with one
txin, one txout, and a standard P2SH scriptPubKey, but miners can still
do their own thing and cause problems in determining the true value
sacrificed if they don't get the optimization problem right.
Fidelity bonds needs a lot more thought, and a testnet implementation...
--
'peter'[:-1]@petertodd.org
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 490 bytes --]
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [Bitcoin-development] RFC: empty scriptPubKeys and OP_RETURN for marking unspendable txouts
2013-02-13 4:12 ` Peter Todd
@ 2013-02-13 10:00 ` Mike Hearn
0 siblings, 0 replies; 4+ messages in thread
From: Mike Hearn @ 2013-02-13 10:00 UTC (permalink / raw)
To: Peter Todd; +Cc: Bitcoin Dev
[-- Attachment #1: Type: text/plain, Size: 1782 bytes --]
> So what exactly was the OP_RETURN bug anyway? I know it has something to
> do with not executing the scriptSig and scriptPubKey separately
> (https://bitcointalk.org/index.php?topic=58579.msg691432#msg691432) but
> commit 7f7f07 that you reference isn't in the tree, nor is 0.3.5 tagged.
>
It was fixed by Satoshi long ago, back when we used CVS I think.
The problem was how scripts were executed. They were concatenated together
and then run as a single unit. The now obsolete OP_CODESEPARATOR was put
between them to control what was hashed and what wasn't.
The obvious problem with that arrangement being that scriptSig ran first
(it has to, to push the signatures onto the stack), so nothing stopped you
setting a scriptSig to OP_RETURN and making the script evaluate to true,
always. A pretty amazing oversight given the thought and care that went
into Bitcoin generally, and its robustness since then.
The fix was to move to the current system whereby the two scripts are
executed independently but sharing a stack, and it's only the return value
of the scriptPubKey that matters.
The scripting system always struck me as a rather late addition to the
design. Satoshi admitted as much when he said that he added it after
encountering an explosion of special cases as he designed various types of
contracts. The fact that there's an obvious bug in CHECKMULTISIG is more
evidence of this part being a general rush job, along with Satoshis
willingness to disable much of its functionality later with the IsStandard
checks. Also the design of CHECKSIG is an obvious retrofit, it would have
made far more sense to decompose it, and we never found a use case for 99%
of the opcodes despite having successfully designed (redesigned?) all the
contract types he ever mentioned.
[-- Attachment #2: Type: text/html, Size: 2585 bytes --]
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2013-02-13 10:00 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-02-12 15:11 [Bitcoin-development] RFC: empty scriptPubKeys and OP_RETURN for marking unspendable txouts Peter Todd
2013-02-12 17:42 ` Gavin Andresen
2013-02-13 4:12 ` Peter Todd
2013-02-13 10:00 ` Mike Hearn
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox