Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Template encoding/decoding #866

Closed
dcousens opened this issue Aug 24, 2017 · 3 comments
Closed

Template encoding/decoding #866

dcousens opened this issue Aug 24, 2017 · 3 comments

Comments

@dcousens
Copy link
Contributor

dcousens commented Aug 24, 2017

As is, with #863 the templates have the following type signatures:

OP_INT = Int8
OP = Int8
Chunks = [OP_INT | OP | Buffer]
Script = Buffer
Stack = [Buffer]

check :: Script -> Bool
checkRaw :: Chunks -> Bool
checkStack :: Stack -> Bool

encode :: ... -> Script
encodeRaw :: ... -> Chunks
encodeStack :: ... -> Stack

decode :: Script -> ...
decodeRaw :: Chunks -> ...
decodeStack :: Stack -> ...

For 4.0.0, we could instead have:

OP_INT = Int8
OP = Int8
Chunks = [OP_INT | OP | Buffer]

check :: Chunks -> Bool
encode :: ... -> Chunks
decode :: Chunks -> ...

And then leave it to the user to decide whether they use script.toStack or script.compile?
This would add boilerplate to using these functions however... which would suck.

@afk11
Copy link
Contributor

afk11 commented Aug 24, 2017

Most of the reason for stack is that it can be (assuming MINIMAL_DATA) be parsed and reserialized into transaction script, and it happens to be the form of the witness data.

I don't intend the stack convention to get in the way of other elements and operations (we store all the data as keys/signatures how, not as a stack representation), perhaps it could only used internally and we remove the confusion for consumers?

@dcousens
Copy link
Contributor Author

dcousens commented Aug 24, 2017

@afk11 users will need to use stack if they use setWitness(vin,

@afk11
Copy link
Contributor

afk11 commented Aug 24, 2017

Ah, I understand now. There's an impeccibly timed issue about it: #856 (comment) since the consumer of the lib set a witness of [OP_4, OP_9] for a script of ADD OP_13 EQUALVERIFY

We've been trained that the CHECKMULTISIG bug means you have to put OP_0 at the start of your script. But opcodes aren't pushed onto the stack, values are (OP_0 takes up 1 byte to encode, but we push a 0-length byte vector to the stack) (Here the bug would be passing a 1 byte value instead of a 0 byte value.. likewise, witness: [OP_4, OP_9] gives you 0x5459 instead of 0x0409)

But the only values that exist in witness-space are byte vectors (not opcodes), making the smallint opcodes a bit tricky. We use smallint's casually in script, but they are a special case of data-push opcode which denotes the minimal form always.

IIRC we remarked before how if we limit the 'opcodes' to PUSHDATA only while compiling it would produce a script that produces the same stack when evaluated as the actual witness. If this is rigorous enough, we could provide a convenience function to achieve roughly: toStack(decompile(compile(listOfPushdataOpsAndBuffers)))

...ensuring the compile function rejects non-PUSHDATA opcodes. That way people can work with a script-like representation and easily get the witness from it.

PS: thank god there isn't a different representation for scriptPubKeys - witness programs/bech32 addresses already make me nervous

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants