OSDN Git Service

Merge pull request #201 from Bytom/v0.1
[bytom/vapor.git] / vendor / github.com / btcsuite / btcd / txscript / scriptbuilder.go
diff --git a/vendor/github.com/btcsuite/btcd/txscript/scriptbuilder.go b/vendor/github.com/btcsuite/btcd/txscript/scriptbuilder.go
deleted file mode 100644 (file)
index 7984dd9..0000000
+++ /dev/null
@@ -1,274 +0,0 @@
-// Copyright (c) 2013-2015 The btcsuite developers
-// Use of this source code is governed by an ISC
-// license that can be found in the LICENSE file.
-
-package txscript
-
-import (
-       "encoding/binary"
-       "fmt"
-)
-
-const (
-       // defaultScriptAlloc is the default size used for the backing array
-       // for a script being built by the ScriptBuilder.  The array will
-       // dynamically grow as needed, but this figure is intended to provide
-       // enough space for vast majority of scripts without needing to grow the
-       // backing array multiple times.
-       defaultScriptAlloc = 500
-)
-
-// ErrScriptNotCanonical identifies a non-canonical script.  The caller can use
-// a type assertion to detect this error type.
-type ErrScriptNotCanonical string
-
-// Error implements the error interface.
-func (e ErrScriptNotCanonical) Error() string {
-       return string(e)
-}
-
-// ScriptBuilder provides a facility for building custom scripts.  It allows
-// you to push opcodes, ints, and data while respecting canonical encoding.  In
-// general it does not ensure the script will execute correctly, however any
-// data pushes which would exceed the maximum allowed script engine limits and
-// are therefore guaranteed not to execute will not be pushed and will result in
-// the Script function returning an error.
-//
-// For example, the following would build a 2-of-3 multisig script for usage in
-// a pay-to-script-hash (although in this situation MultiSigScript() would be a
-// better choice to generate the script):
-//     builder := txscript.NewScriptBuilder()
-//     builder.AddOp(txscript.OP_2).AddData(pubKey1).AddData(pubKey2)
-//     builder.AddData(pubKey3).AddOp(txscript.OP_3)
-//     builder.AddOp(txscript.OP_CHECKMULTISIG)
-//     script, err := builder.Script()
-//     if err != nil {
-//             // Handle the error.
-//             return
-//     }
-//     fmt.Printf("Final multi-sig script: %x\n", script)
-type ScriptBuilder struct {
-       script []byte
-       err    error
-}
-
-// AddOp pushes the passed opcode to the end of the script.  The script will not
-// be modified if pushing the opcode would cause the script to exceed the
-// maximum allowed script engine size.
-func (b *ScriptBuilder) AddOp(opcode byte) *ScriptBuilder {
-       if b.err != nil {
-               return b
-       }
-
-       // Pushes that would cause the script to exceed the largest allowed
-       // script size would result in a non-canonical script.
-       if len(b.script)+1 > MaxScriptSize {
-               str := fmt.Sprintf("adding an opcode would exceed the maximum "+
-                       "allowed canonical script length of %d", MaxScriptSize)
-               b.err = ErrScriptNotCanonical(str)
-               return b
-       }
-
-       b.script = append(b.script, opcode)
-       return b
-}
-
-// AddOps pushes the passed opcodes to the end of the script.  The script will
-// not be modified if pushing the opcodes would cause the script to exceed the
-// maximum allowed script engine size.
-func (b *ScriptBuilder) AddOps(opcodes []byte) *ScriptBuilder {
-       if b.err != nil {
-               return b
-       }
-
-       // Pushes that would cause the script to exceed the largest allowed
-       // script size would result in a non-canonical script.
-       if len(b.script)+len(opcodes) > MaxScriptSize {
-               str := fmt.Sprintf("adding opcodes would exceed the maximum "+
-                       "allowed canonical script length of %d", MaxScriptSize)
-               b.err = ErrScriptNotCanonical(str)
-               return b
-       }
-
-       b.script = append(b.script, opcodes...)
-       return b
-}
-
-// canonicalDataSize returns the number of bytes the canonical encoding of the
-// data will take.
-func canonicalDataSize(data []byte) int {
-       dataLen := len(data)
-
-       // When the data consists of a single number that can be represented
-       // by one of the "small integer" opcodes, that opcode will be instead
-       // of a data push opcode followed by the number.
-       if dataLen == 0 {
-               return 1
-       } else if dataLen == 1 && data[0] <= 16 {
-               return 1
-       } else if dataLen == 1 && data[0] == 0x81 {
-               return 1
-       }
-
-       if dataLen < OP_PUSHDATA1 {
-               return 1 + dataLen
-       } else if dataLen <= 0xff {
-               return 2 + dataLen
-       } else if dataLen <= 0xffff {
-               return 3 + dataLen
-       }
-
-       return 5 + dataLen
-}
-
-// addData is the internal function that actually pushes the passed data to the
-// end of the script.  It automatically chooses canonical opcodes depending on
-// the length of the data.  A zero length buffer will lead to a push of empty
-// data onto the stack (OP_0).  No data limits are enforced with this function.
-func (b *ScriptBuilder) addData(data []byte) *ScriptBuilder {
-       dataLen := len(data)
-
-       // When the data consists of a single number that can be represented
-       // by one of the "small integer" opcodes, use that opcode instead of
-       // a data push opcode followed by the number.
-       if dataLen == 0 || dataLen == 1 && data[0] == 0 {
-               b.script = append(b.script, OP_0)
-               return b
-       } else if dataLen == 1 && data[0] <= 16 {
-               b.script = append(b.script, (OP_1-1)+data[0])
-               return b
-       } else if dataLen == 1 && data[0] == 0x81 {
-               b.script = append(b.script, byte(OP_1NEGATE))
-               return b
-       }
-
-       // Use one of the OP_DATA_# opcodes if the length of the data is small
-       // enough so the data push instruction is only a single byte.
-       // Otherwise, choose the smallest possible OP_PUSHDATA# opcode that
-       // can represent the length of the data.
-       if dataLen < OP_PUSHDATA1 {
-               b.script = append(b.script, byte((OP_DATA_1-1)+dataLen))
-       } else if dataLen <= 0xff {
-               b.script = append(b.script, OP_PUSHDATA1, byte(dataLen))
-       } else if dataLen <= 0xffff {
-               buf := make([]byte, 2)
-               binary.LittleEndian.PutUint16(buf, uint16(dataLen))
-               b.script = append(b.script, OP_PUSHDATA2)
-               b.script = append(b.script, buf...)
-       } else {
-               buf := make([]byte, 4)
-               binary.LittleEndian.PutUint32(buf, uint32(dataLen))
-               b.script = append(b.script, OP_PUSHDATA4)
-               b.script = append(b.script, buf...)
-       }
-
-       // Append the actual data.
-       b.script = append(b.script, data...)
-
-       return b
-}
-
-// AddFullData should not typically be used by ordinary users as it does not
-// include the checks which prevent data pushes larger than the maximum allowed
-// sizes which leads to scripts that can't be executed.  This is provided for
-// testing purposes such as regression tests where sizes are intentionally made
-// larger than allowed.
-//
-// Use AddData instead.
-func (b *ScriptBuilder) AddFullData(data []byte) *ScriptBuilder {
-       if b.err != nil {
-               return b
-       }
-
-       return b.addData(data)
-}
-
-// AddData pushes the passed data to the end of the script.  It automatically
-// chooses canonical opcodes depending on the length of the data.  A zero length
-// buffer will lead to a push of empty data onto the stack (OP_0) and any push
-// of data greater than MaxScriptElementSize will not modify the script since
-// that is not allowed by the script engine.  Also, the script will not be
-// modified if pushing the data would cause the script to exceed the maximum
-// allowed script engine size.
-func (b *ScriptBuilder) AddData(data []byte) *ScriptBuilder {
-       if b.err != nil {
-               return b
-       }
-
-       // Pushes that would cause the script to exceed the largest allowed
-       // script size would result in a non-canonical script.
-       dataSize := canonicalDataSize(data)
-       if len(b.script)+dataSize > MaxScriptSize {
-               str := fmt.Sprintf("adding %d bytes of data would exceed the "+
-                       "maximum allowed canonical script length of %d",
-                       dataSize, MaxScriptSize)
-               b.err = ErrScriptNotCanonical(str)
-               return b
-       }
-
-       // Pushes larger than the max script element size would result in a
-       // script that is not canonical.
-       dataLen := len(data)
-       if dataLen > MaxScriptElementSize {
-               str := fmt.Sprintf("adding a data element of %d bytes would "+
-                       "exceed the maximum allowed script element size of %d",
-                       dataLen, MaxScriptElementSize)
-               b.err = ErrScriptNotCanonical(str)
-               return b
-       }
-
-       return b.addData(data)
-}
-
-// AddInt64 pushes the passed integer to the end of the script.  The script will
-// not be modified if pushing the data would cause the script to exceed the
-// maximum allowed script engine size.
-func (b *ScriptBuilder) AddInt64(val int64) *ScriptBuilder {
-       if b.err != nil {
-               return b
-       }
-
-       // Pushes that would cause the script to exceed the largest allowed
-       // script size would result in a non-canonical script.
-       if len(b.script)+1 > MaxScriptSize {
-               str := fmt.Sprintf("adding an integer would exceed the "+
-                       "maximum allow canonical script length of %d",
-                       MaxScriptSize)
-               b.err = ErrScriptNotCanonical(str)
-               return b
-       }
-
-       // Fast path for small integers and OP_1NEGATE.
-       if val == 0 {
-               b.script = append(b.script, OP_0)
-               return b
-       }
-       if val == -1 || (val >= 1 && val <= 16) {
-               b.script = append(b.script, byte((OP_1-1)+val))
-               return b
-       }
-
-       return b.AddData(scriptNum(val).Bytes())
-}
-
-// Reset resets the script so it has no content.
-func (b *ScriptBuilder) Reset() *ScriptBuilder {
-       b.script = b.script[0:0]
-       b.err = nil
-       return b
-}
-
-// Script returns the currently built script.  When any errors occurred while
-// building the script, the script will be returned up the point of the first
-// error along with the error.
-func (b *ScriptBuilder) Script() ([]byte, error) {
-       return b.script, b.err
-}
-
-// NewScriptBuilder returns a new instance of a script builder.  See
-// ScriptBuilder for details.
-func NewScriptBuilder() *ScriptBuilder {
-       return &ScriptBuilder{
-               script: make([]byte, 0, defaultScriptAlloc),
-       }
-}