-
Notifications
You must be signed in to change notification settings - Fork 2.2k
Stack template fixes #863
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
Stack template fixes #863
Conversation
src/script.js
Outdated
| // data? | ||
| if (Buffer.isBuffer(chunk)) return chunk.toString('hex') | ||
| if (Buffer.isBuffer(chunk)) { | ||
| if (chunk.length === 0) return 'OP_0' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Gross
|
This isn't turning out as elegant as I think we hoped. 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 -> ...Witness inputs don't have a What we had previously: check :: (Script | Chunks | Stack) -> Bool
encode :: ... -> Script
encodeStack :: ... -> Stack -- often used as Chunks
decode :: (Script | Chunks | Stack) -> ...
decodeStack :: (Stack | Chunks) -> ... |
|
The issue was |
|
Hopefully we can use |
|
I think maybe The question:
|
676380d to
6af3034
Compare
113e6c6 to
8d60758
Compare
It should return OP_... and leave interpreting the opcodes up to the caller. The more information they have, the better :) |
|
weak nack, I would avoid using opcodes as an intermediate (as encodeRaw seems to do) It would mean doing this: chunks -> stack -> scriptSig which doesn't make a good constraint, since not all chunks have a stack? (scriptPubKeys don't have the properties that allow a stack representation - they have opcodes and operate on a stack.. but scriptSigs do get evaluated and have a stack respresentation) Whereas the following are invariant when SIGPUSHONLY and MINIMALDATA are in effect: stack -> chunks -> scriptSig |
The opcodes are used intermediately as they are how those script templates are typically defined. Not as a stack?
We have two typical flows for encoding... Chunks -> Stack -- a witness stack
Chunks -> Script -- scriptSig, scriptPubKey
I think the conflation of stack being anything other than the witness stack is confusing, and may be leading to our different approaches. |
|
As mentioned on slack
OP_INT = Int8
OP = Int8
Chunks = [OP_INT | OP | Buffer]
Script = Buffer
Witness = [Buffer]
check :: Script -> Bool
checkRaw :: Chunks -> Bool
checkWitness :: Witness -> Bool
encode :: ... -> Script
encodeRaw :: ... -> Chunks
encodeWitness :: ... -> Witness
decode :: Script -> ...
decodeRaw :: Chunks -> ...
decodeWitness :: Witness -> ...
compile :: Chunks -> Script
decompile :: Script -> Chunks
toWitness :: Chunks -> Maybe WitnessThere is no An important distinction to understand is that chunks are semantic, contextual. For a chunk, OP_0 is not equal to Any deprecations to be removed in ping @afk11 ACK if you are on the same page |
|
This could be insanely simplified by removing the encoding to bitcoin.script.p2pk.encode(pubKey) // existing
bitcoin.script.toScript(bitcoin.script.p2pk.encode(pubKey)) // replacement? booooo
// other ideas
bitcoin.p2pkh.fromKeyPair(kp).address
bitcoin.p2pkh.fromKeyPair(kp).script
bitcoin.p2pkh.fromAddress(address).script
bitcoin.p2pkh.fromOutputScript(script).address
// how validate??? try/catch?
// and then how redeem... ?
bitcoin.p2pkh.redeem(kp, signature).script
bitcoin.p2pkh.redeem(kp, signature).witness
bitcoin.p2pkh.redeem.fromScript(script)
bitcoin.p2pkh.redeem.fromWitness(witness)
// how check???
// what about reqSigs?Above is related to #787 We need to be able to unify these two interfaces entirely, consistently, and powerfully to support simpler Transaction building with less verbosity and easy inspection. edit: extra ideas from slack let { maybe witness, maybe input, output } = p2sh(p2wsh(p2pkh(pubkey, maybe signature)))
let { maybe witness, maybe input, output } = p2sh(p2wsh(p2ms(pubkeys, maybe signatures)))
let { output } = p2sh(p2wsh(p2ms(pubkeys)))
let { witness, input } = p2sh(p2wsh(p2ms(pubkeys, signatures))) // fails without pubkeys, missing redeemscript
let { witness, input } = p2ms([], signatures)
let { witness, output, pubKeys, signatures } = p2ms({ witness, scriptPubKey }) |
|
I think We may have needed instead, a plain Handling that in a |
|
Too many breaking changes, or potentially confusing ambiguities, and while this PR would make things stricter, it doesn't help the clumsiness of the API. I think it will be better to simply move faster towards |
The
OP_0/Buffer< >interchange is a nightmare.I don't know if there is a solution other than minimizing interchange between Stack/Chunks/Script types, because the distinction is immediately lost without classification.
As for decoding from a stack... we can't make assumptions about whether it is OP_INT or
Buffer.