Skip to content

Commit

Permalink
txscript: enable OP_CAT
Browse files Browse the repository at this point in the history
  • Loading branch information
halseth committed Jan 5, 2024
1 parent a4df044 commit 9541657
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 4 deletions.
3 changes: 1 addition & 2 deletions txscript/engine.go
Expand Up @@ -335,8 +335,6 @@ func (vm *Engine) isBranchExecuting() bool {
// conditional).
func isOpcodeDisabled(opcode byte) bool {
switch opcode {
case OP_CAT:
return true
case OP_SUBSTR:
return true
case OP_LEFT:
Expand Down Expand Up @@ -698,6 +696,7 @@ func (vm *Engine) verifyWitnessProgram(witness wire.TxWitness) error {
// An op success op code has been found, however if
// the policy flag forbidding them is active, then
// we'll return an error.
// TODO: add flag for discourage OP_CAT.
if vm.hasFlag(ScriptVerifyDiscourageOpSuccess) {
errStr := fmt.Sprintf("script contains " +
"OP_SUCCESS op code")
Expand Down
41 changes: 39 additions & 2 deletions txscript/opcode.go
Expand Up @@ -445,7 +445,7 @@ var opcodeArray = [256]opcode{
OP_TUCK: {OP_TUCK, "OP_TUCK", 1, opcodeTuck},

// Splice opcodes.
OP_CAT: {OP_CAT, "OP_CAT", 1, opcodeDisabled},
OP_CAT: {OP_CAT, "OP_CAT", 1, opcodeCat},
OP_SUBSTR: {OP_SUBSTR, "OP_SUBSTR", 1, opcodeDisabled},
OP_LEFT: {OP_LEFT, "OP_LEFT", 1, opcodeDisabled},
OP_RIGHT: {OP_RIGHT, "OP_RIGHT", 1, opcodeDisabled},
Expand Down Expand Up @@ -619,7 +619,6 @@ var opcodeOnelineRepls = map[string]string{
var successOpcodes = map[byte]struct{}{
OP_RESERVED: {}, // 80
OP_VER: {}, // 98
OP_CAT: {}, // 126
OP_SUBSTR: {}, // 127
OP_LEFT: {}, // 128
OP_RIGHT: {}, // 129
Expand Down Expand Up @@ -1944,6 +1943,44 @@ func opcodeHash256(op *opcode, data []byte, vm *Engine) error {
return nil
}

// opcodeCat concatenates the top two stack items, leaving the result on the
// stack.
//
// Stack transformation: [...x1 x2] -> [... x1|x2]
func opcodeCat(op *opcode, data []byte, vm *Engine) error {
// This op code can only be used if tapsript execution is active.
// Before the soft fork, this opcode was disabled.
if vm.taprootCtx == nil {
return opcodeDisabled(op, data, vm)
}

x2, err := vm.dstack.PopByteArray()
if err != nil {
return err
}

x1, err := vm.dstack.PopByteArray()
if err != nil {
return err
}

var buf bytes.Buffer
buf.Write(x1)
buf.Write(x2)

c := buf.Bytes()

// Ensure result is within the max allowed size.
if len(c) > MaxScriptElementSize {
str := fmt.Sprintf("element size %d exceeds max allowed size %d",
len(c), MaxScriptElementSize)
return scriptError(ErrElementTooBig, str)
}

vm.dstack.PushByteArray(c)
return nil
}

// opcodeCodeSeparator stores the current script offset as the most recently
// seen OP_CODESEPARATOR which is used during signature checking.
//
Expand Down

0 comments on commit 9541657

Please sign in to comment.