Author

Topic: If you could redo the scripting system, how would you do it? (Read 1324 times)

donator
Activity: 826
Merit: 1060
This would be interesting:
- RISC-like simple ops only.
- Each block can define one new script function which can be called in scripts by specifying that block number.

That's certainly very interesting, but...

I think the security of this system would be easier to prove. Since functions are only aliases for a sequence of simple ops, you'd only need to prove the security of a handful of simple ops...

The security of the design is easy to prove, and the security of a naiive implementation will be fairly easy to prove, but exploits will target bugs within complex, performance-optimising implementations.
hero member
Activity: 868
Merit: 1008
This would be interesting:
- RISC-like simple ops only.
- Each block can define one new script function which can be called in scripts by specifying that block number.

That's clever :-) close to being life.

I wonder what the script in block 1 would look like?
Yes, I agree, very clever!  To get it to perform acceptably (since you'd be doing the actual mathematics for signing in script) you'd probably need a pretty sophisticated engine (i.e. one that JITs the functions)…but that could be left as an exercise for miners who would be strongly incentivized to run those scripts as efficiently as possible.
hero member
Activity: 504
Merit: 502
This would be interesting:
- RISC-like simple ops only.
- Each block can define one new script function which can be called in scripts by specifying that block number.

That's clever :-) close to being life.

I wonder what the script in block 1 would look like?
administrator
Activity: 5222
Merit: 13032
This would be interesting:
- RISC-like simple ops only.
- Each block can define one new script function which can be called in scripts by specifying that block number.
    - Obviously functions should only be called once the block is so deep in the chain that there is no chance of it ever being replaced.
    - Most scripts will just call a single function, keeping the block chain size low.
    - Frequently-used functions (like the normal CHECKSIG function) can be handled specially by nodes so that the script processing doesn't need to be done every time the function is used.
- Input to scriptPubKey goes in two separate fields: one unsigned for scripts and one signed for non-signature data. Neither can contain any "raw" script. The length of each item in the unsigned field can also be optionally signed.
- For P2SH-style functionality (and looping), the script will be allowed to execute any data with something like OP_EVAL. However, each OP_EVAL must be given a constant number which will be used as the maximum number of opcodes that can be executed through that OP_EVAL (possibly through multiple nesting levels, and including the opcodes used in functions). The maximum cost of running the script can then be calculated accurately without actually running it.

I think the security of this system would be easier to prove. Since functions are only aliases for a sequence of simple ops, you'd only need to prove the security of a handful of simple ops. There are also no weird special cases like OP_CHECKSIG and OP_CODESEPARATOR.

This system also allows much of the crypto to be replaced without requiring everyone to upgrade.
hero member
Activity: 504
Merit: 502
The suggestion I've always made is the addition of extra fields in the transaction structure; and isn't a million miles from what you've suggested.

Namely: an unsigned parameter array.  Then you add a couple of script operators for fetching from that array, e.g.  OP_FETCHPARAMETER1, and you're done.

The parameter block would mostly be holding the signature; and given that it's not included in the input to the signature generator would make all that crazy manipulation that goes on in OP_CHECKSIG unnecessary.

It would be equally capable of storing a script hash though.  It would be pretty easy to introduce operators to do:

  • OP_HASHOFSCRIPTSIG
  • OP_HASHOFPUBKEYSCRIPT

Or possibly some more generic operators for pulling out arbitrary bytes.

For example:

  • OP_PUSH(OP_CODESEPARATOR)
  • OP_FINDLASTOFINPUBKEYSCRIPT
  • OP_HASHFROMINDEX
  • OP_FETCHPARAMETER1
  • OP_EQUALVERIFY

(I've been a bit slapdash, but you get the idea).
hero member
Activity: 868
Merit: 1008
I started thinking about this question when studying the proposals for p2sh implementations.  Here's how I would change it:

First, the scriptPubKey shouldn't be a script at all, it should just be a hash value (a bitcoin address).  All transactions would be a "p2sh" transaction.  Second, the scriptSig would not include the operations that setup the initial stack (the initial push operations that you typically see).  Instead, there would be another field that holds the values for the initial stack (which would typically just be a signature).  The scriptSig would also include an assertion at the beginning that verifies that the proper number of values are on the initial stack (this would prevent the hole that Gavin mentions that allows nodes to stick extra stuff at the beginning of a scriptSig).

You could probably mimic this in with bitcoin in the following ways:
1. Only allow 2 types of scriptPubKey transaction types (the traditional one, and one that verifies the code hash similar to the BIP-17 proposal)
2. Only allow PUSH operations before OP_CODESEPARATOR in the scriptSig
3. Add a bit of code after the code separator that verifies the number of items on the stack (note, I think this would close the hole that Gavin mentioned about pre-pending stuff to the scriptSig)
4. Add a new opcode for pushing a code hash onto the stack

So, a typical transaction would look like:

   scriptSig: [signature] OP_CODESEPARATOR OP_DEPTH [1] OP_EQUALVERIFY [pubkey] OP_CHECKSIGVERIFY
   scriptPubKey: OP_CODEHASH [20-byte-hash of {OP_DEPTH [1] OP_EQUALVERIFY [pubkey] OP_CHECKSIGVERIFY} ] OP_EQUAL

(note: OP_CODEHASH is a fictitious op code that computes the HASH160 of the code starting from the most recent separator and pushes it on the stack)
Jump to: