Release v0.3.0

This commit is contained in:
Manu Herrera
2020-11-09 10:05:29 -03:00
parent 4e9aa7a3c5
commit 8107c4478b
1265 changed files with 440488 additions and 107809 deletions

16
vendor/github.com/btcsuite/btcutil/psbt/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,16 @@
ISC License
Copyright (c) 2013-2017 The btcsuite developers
Copyright (c) 2016-2017 The Lightning Network Developers
Permission to use, copy, modify, and distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

77
vendor/github.com/btcsuite/btcutil/psbt/bip32.go generated vendored Normal file
View File

@@ -0,0 +1,77 @@
package psbt
import (
"bytes"
"encoding/binary"
)
// Bip32Derivation encapsulates the data for the input and output
// Bip32Derivation key-value fields.
//
// TODO(roasbeef): use hdkeychain here instead?
type Bip32Derivation struct {
// PubKey is the raw pubkey serialized in compressed format.
PubKey []byte
// MasterKeyFingerprint is the finger print of the master pubkey.
MasterKeyFingerprint uint32
// Bip32Path is the BIP 32 path with child index as a distinct integer.
Bip32Path []uint32
}
// checkValid ensures that the PubKey in the Bip32Derivation struct is valid.
func (pb *Bip32Derivation) checkValid() bool {
return validatePubkey(pb.PubKey)
}
// Bip32Sorter implements sort.Interface for the Bip32Derivation struct.
type Bip32Sorter []*Bip32Derivation
func (s Bip32Sorter) Len() int { return len(s) }
func (s Bip32Sorter) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
func (s Bip32Sorter) Less(i, j int) bool {
return bytes.Compare(s[i].PubKey, s[j].PubKey) < 0
}
// readBip32Derivation deserializes a byte slice containing chunks of 4 byte
// little endian encodings of uint32 values, the first of which is the
// masterkeyfingerprint and the remainder of which are the derivation path.
func readBip32Derivation(path []byte) (uint32, []uint32, error) {
if len(path)%4 != 0 || len(path)/4-1 < 1 {
return 0, nil, ErrInvalidPsbtFormat
}
masterKeyInt := binary.LittleEndian.Uint32(path[:4])
var paths []uint32
for i := 4; i < len(path); i += 4 {
paths = append(paths, binary.LittleEndian.Uint32(path[i:i+4]))
}
return masterKeyInt, paths, nil
}
// SerializeBIP32Derivation takes a master key fingerprint as defined in BIP32,
// along with a path specified as a list of uint32 values, and returns a
// bytestring specifying the derivation in the format required by BIP174: //
// master key fingerprint (4) || child index (4) || child index (4) || ....
func SerializeBIP32Derivation(masterKeyFingerprint uint32,
bip32Path []uint32) []byte {
var masterKeyBytes [4]byte
binary.LittleEndian.PutUint32(masterKeyBytes[:], masterKeyFingerprint)
derivationPath := make([]byte, 0, 4+4*len(bip32Path))
derivationPath = append(derivationPath, masterKeyBytes[:]...)
for _, path := range bip32Path {
var pathbytes [4]byte
binary.LittleEndian.PutUint32(pathbytes[:], path)
derivationPath = append(derivationPath, pathbytes[:]...)
}
return derivationPath
}

63
vendor/github.com/btcsuite/btcutil/psbt/creator.go generated vendored Normal file
View File

@@ -0,0 +1,63 @@
// Copyright (c) 2018 The btcsuite developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package psbt
import (
"github.com/btcsuite/btcd/wire"
)
// MinTxVersion is the lowest transaction version that we'll permit.
const MinTxVersion = 1
// New on provision of an input and output 'skeleton' for the transaction, a
// new partially populated PBST packet. The populated packet will include the
// unsigned transaction, and the set of known inputs and outputs contained
// within the unsigned transaction. The values of nLockTime, nSequence (per
// input) and transaction version (must be 1 of 2) must be specified here. Note
// that the default nSequence value is wire.MaxTxInSequenceNum. Referencing
// the PSBT BIP, this function serves the roles of teh Creator.
func New(inputs []*wire.OutPoint,
outputs []*wire.TxOut, version int32, nLockTime uint32,
nSequences []uint32) (*Packet, error) {
// Create the new struct; the input and output lists will be empty, the
// unsignedTx object must be constructed and serialized, and that
// serialization should be entered as the only entry for the
// globalKVPairs list.
//
// Ensure that the version of the transaction is greater then our
// minimum allowed transaction version. There must be one sequence
// number per input.
if version < MinTxVersion || len(nSequences) != len(inputs) {
return nil, ErrInvalidPsbtFormat
}
unsignedTx := wire.NewMsgTx(version)
unsignedTx.LockTime = nLockTime
for i, in := range inputs {
unsignedTx.AddTxIn(&wire.TxIn{
PreviousOutPoint: *in,
Sequence: nSequences[i],
})
}
for _, out := range outputs {
unsignedTx.AddTxOut(out)
}
// The input and output lists are empty, but there is a list of those
// two lists, and each one must be of length matching the unsigned
// transaction; the unknown list can be nil.
pInputs := make([]PInput, len(unsignedTx.TxIn))
pOutputs := make([]POutput, len(unsignedTx.TxOut))
// This new Psbt is "raw" and contains no key-value fields, so sanity
// checking with c.Cpsbt.SanityCheck() is not required.
return &Packet{
UnsignedTx: unsignedTx,
Inputs: pInputs,
Outputs: pOutputs,
Unknowns: nil,
}, nil
}

81
vendor/github.com/btcsuite/btcutil/psbt/extractor.go generated vendored Normal file
View File

@@ -0,0 +1,81 @@
// Copyright (c) 2018 The btcsuite developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package psbt
// The Extractor requires provision of a single PSBT
// in which all necessary signatures are encoded, and
// uses it to construct a fully valid network serialized
// transaction.
import (
"bytes"
"github.com/btcsuite/btcd/txscript"
"github.com/btcsuite/btcd/wire"
)
// Extract takes a finalized psbt.Packet and outputs a finalized transaction
// instance. Note that if the PSBT is in-complete, then an error
// ErrIncompletePSBT will be returned. As the extracted transaction has been
// fully finalized, it will be ready for network broadcast once returned.
func Extract(p *Packet) (*wire.MsgTx, error) {
// If the packet isn't complete, then we'll return an error as it
// doesn't have all the required witness data.
if !p.IsComplete() {
return nil, ErrIncompletePSBT
}
// First, we'll make a copy of the underlying unsigned transaction (the
// initial template) so we don't mutate it during our activates below.
finalTx := p.UnsignedTx.Copy()
// For each input, we'll now populate any relevant witness and
// sigScript data.
for i, tin := range finalTx.TxIn {
// We'll grab the corresponding internal packet input which
// matches this materialized transaction input and emplace that
// final sigScript (if present).
pInput := p.Inputs[i]
if pInput.FinalScriptSig != nil {
tin.SignatureScript = pInput.FinalScriptSig
}
// Similarly, if there's a final witness, then we'll also need
// to extract that as well, parsing the lower-level transaction
// encoding.
if pInput.FinalScriptWitness != nil {
// In order to set the witness, need to re-deserialize
// the field as encoded within the PSBT packet. For
// each input, the witness is encoded as a stack with
// one or more items.
witnessReader := bytes.NewReader(
pInput.FinalScriptWitness,
)
// First we extract the number of witness elements
// encoded in the above witnessReader.
witCount, err := wire.ReadVarInt(witnessReader, 0)
if err != nil {
return nil, err
}
// Now that we know how may inputs we'll need, we'll
// construct a packing slice, then read out each input
// (with a varint prefix) from the witnessReader.
tin.Witness = make(wire.TxWitness, witCount)
for j := uint64(0); j < witCount; j++ {
wit, err := wire.ReadVarBytes(
witnessReader, 0, txscript.MaxScriptSize, "witness",
)
if err != nil {
return nil, err
}
tin.Witness[j] = wit
}
}
}
return finalTx, nil
}

462
vendor/github.com/btcsuite/btcutil/psbt/finalizer.go generated vendored Normal file
View File

@@ -0,0 +1,462 @@
// Copyright (c) 2018 The btcsuite developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package psbt
// The Finalizer requires provision of a single PSBT input
// in which all necessary signatures are encoded, and
// uses it to construct valid final sigScript and scriptWitness
// fields.
// NOTE that p2sh (legacy) and p2wsh currently support only
// multisig and no other custom script.
import (
"github.com/btcsuite/btcd/txscript"
)
// isFinalized considers this input finalized if it contains at least one of
// the FinalScriptSig or FinalScriptWitness are filled (which only occurs in a
// successful call to Finalize*).
func isFinalized(p *Packet, inIndex int) bool {
input := p.Inputs[inIndex]
return input.FinalScriptSig != nil || input.FinalScriptWitness != nil
}
// isFinalizableWitnessInput returns true if the target input is a witness UTXO
// that can be finalized.
func isFinalizableWitnessInput(pInput *PInput) bool {
pkScript := pInput.WitnessUtxo.PkScript
switch {
// If this is a native witness output, then we require both
// the witness script, but not a redeem script.
case txscript.IsWitnessProgram(pkScript):
if txscript.IsPayToWitnessScriptHash(pkScript) {
if pInput.WitnessScript == nil ||
pInput.RedeemScript != nil {
return false
}
} else {
// A P2WKH output on the other hand doesn't need
// neither a witnessScript or redeemScript.
if pInput.WitnessScript != nil ||
pInput.RedeemScript != nil {
return false
}
}
// For nested P2SH inputs, we verify that a witness script is known.
case txscript.IsPayToScriptHash(pkScript):
if pInput.RedeemScript == nil {
return false
}
// If this is a nested P2SH input, then it must also have a
// witness script, while we don't need one for P2WKH.
if txscript.IsPayToWitnessScriptHash(pInput.RedeemScript) {
if pInput.WitnessScript == nil {
return false
}
} else if txscript.IsPayToWitnessPubKeyHash(pInput.RedeemScript) {
if pInput.WitnessScript != nil {
return false
}
} else {
// unrecognized type
return false
}
// If this isn't a nested nested P2SH output or a native witness
// output, then we can't finalize this input as we don't understand it.
default:
return false
}
return true
}
// isFinalizableLegacyInput returns true of the passed input a legacy input
// (non-witness) that can be finalized.
func isFinalizableLegacyInput(p *Packet, pInput *PInput, inIndex int) bool {
// If the input has a witness, then it's invalid.
if pInput.WitnessScript != nil {
return false
}
// Otherwise, we'll verify that we only have a RedeemScript if the prev
// output script is P2SH.
outIndex := p.UnsignedTx.TxIn[inIndex].PreviousOutPoint.Index
if txscript.IsPayToScriptHash(pInput.NonWitnessUtxo.TxOut[outIndex].PkScript) {
if pInput.RedeemScript == nil {
return false
}
} else {
if pInput.RedeemScript != nil {
return false
}
}
return true
}
// isFinalizable checks whether the structure of the entry for the input of the
// psbt.Packet at index inIndex contains sufficient information to finalize
// this input.
func isFinalizable(p *Packet, inIndex int) bool {
pInput := p.Inputs[inIndex]
// The input cannot be finalized without any signatures
if pInput.PartialSigs == nil {
return false
}
// For an input to be finalized, we'll one of two possible top-level
// UTXOs present. Each UTXO type has a distinct set of requirements to
// be considered finalized.
switch {
// A witness input must be either native P2WSH or nested P2SH with all
// relevant sigScript or witness data populated.
case pInput.WitnessUtxo != nil:
if !isFinalizableWitnessInput(&pInput) {
return false
}
case pInput.NonWitnessUtxo != nil:
if !isFinalizableLegacyInput(p, &pInput, inIndex) {
return false
}
// If neither a known UTXO type isn't present at all, then we'll
// return false as we need one of them.
default:
return false
}
return true
}
// MaybeFinalize attempts to finalize the input at index inIndex in the PSBT p,
// returning true with no error if it succeeds, OR if the input has already
// been finalized.
func MaybeFinalize(p *Packet, inIndex int) (bool, error) {
if isFinalized(p, inIndex) {
return true, nil
}
if !isFinalizable(p, inIndex) {
return false, ErrNotFinalizable
}
if err := Finalize(p, inIndex); err != nil {
return false, err
}
return true, nil
}
// MaybeFinalizeAll attempts to finalize all inputs of the psbt.Packet that are
// not already finalized, and returns an error if it fails to do so.
func MaybeFinalizeAll(p *Packet) error {
for i := range p.UnsignedTx.TxIn {
success, err := MaybeFinalize(p, i)
if err != nil || !success {
return err
}
}
return nil
}
// Finalize assumes that the provided psbt.Packet struct has all partial
// signatures and redeem scripts/witness scripts already prepared for the
// specified input, and so removes all temporary data and replaces them with
// completed sigScript and witness fields, which are stored in key-types 07 and
// 08. The witness/non-witness utxo fields in the inputs (key-types 00 and 01)
// are left intact as they may be needed for validation (?). If there is any
// invalid or incomplete data, an error is returned.
func Finalize(p *Packet, inIndex int) error {
pInput := p.Inputs[inIndex]
// Depending on the UTXO type, we either attempt to finalize it as a
// witness or legacy UTXO.
switch {
case pInput.WitnessUtxo != nil:
if err := finalizeWitnessInput(p, inIndex); err != nil {
return err
}
case pInput.NonWitnessUtxo != nil:
if err := finalizeNonWitnessInput(p, inIndex); err != nil {
return err
}
default:
return ErrInvalidPsbtFormat
}
// Before returning we sanity check the PSBT to ensure we don't extract
// an invalid transaction or produce an invalid intermediate state.
if err := p.SanityCheck(); err != nil {
return err
}
return nil
}
// checkFinalScriptSigWitness checks whether a given input in the psbt.Packet
// struct already has the fields 07 (FinalInScriptSig) or 08 (FinalInWitness).
// If so, it returns true. It does not modify the Psbt.
func checkFinalScriptSigWitness(p *Packet, inIndex int) bool {
pInput := p.Inputs[inIndex]
if pInput.FinalScriptSig != nil {
return true
}
if pInput.FinalScriptWitness != nil {
return true
}
return false
}
// finalizeNonWitnessInput attempts to create a PsbtInFinalScriptSig field for
// the input at index inIndex, and removes all other fields except for the UTXO
// field, for an input of type non-witness, or returns an error.
func finalizeNonWitnessInput(p *Packet, inIndex int) error {
// If this input has already been finalized, then we'll return an error
// as we can't proceed.
if checkFinalScriptSigWitness(p, inIndex) {
return ErrInputAlreadyFinalized
}
// Our goal here is to construct a sigScript given the pubkey,
// signature (keytype 02), of which there might be multiple, and the
// redeem script field (keytype 04) if present (note, it is not present
// for p2pkh type inputs).
var sigScript []byte
pInput := p.Inputs[inIndex]
containsRedeemScript := pInput.RedeemScript != nil
var (
pubKeys [][]byte
sigs [][]byte
)
for _, ps := range pInput.PartialSigs {
pubKeys = append(pubKeys, ps.PubKey)
sigOK := checkSigHashFlags(ps.Signature, &pInput)
if !sigOK {
return ErrInvalidSigHashFlags
}
sigs = append(sigs, ps.Signature)
}
// We have failed to identify at least 1 (sig, pub) pair in the PSBT,
// which indicates it was not ready to be finalized. As a result, we
// can't proceed.
if len(sigs) < 1 || len(pubKeys) < 1 {
return ErrNotFinalizable
}
// If this input doesn't need a redeem script (P2PKH), then we'll
// construct a simple sigScript that's just the signature then the
// pubkey (OP_CHECKSIG).
var err error
if !containsRedeemScript {
// At this point, we should only have a single signature and
// pubkey.
if len(sigs) != 1 || len(pubKeys) != 1 {
return ErrNotFinalizable
}
// In this case, our sigScript is just: <sig> <pubkey>.
builder := txscript.NewScriptBuilder()
builder.AddData(sigs[0]).AddData(pubKeys[0])
sigScript, err = builder.Script()
if err != nil {
return err
}
} else {
// This is assumed p2sh multisig Given redeemScript and pubKeys
// we can decide in what order signatures must be appended.
orderedSigs, err := extractKeyOrderFromScript(
pInput.RedeemScript, pubKeys, sigs,
)
if err != nil {
return err
}
// At this point, we assume that this is a mult-sig input, so
// we construct our sigScript which looks something like this
// (mind the extra element for the extra multi-sig pop):
// * <nil> <sigs...> <redeemScript>
//
// TODO(waxwing): the below is specific to the multisig case.
builder := txscript.NewScriptBuilder()
builder.AddOp(txscript.OP_FALSE)
for _, os := range orderedSigs {
builder.AddData(os)
}
builder.AddData(pInput.RedeemScript)
sigScript, err = builder.Script()
if err != nil {
return err
}
}
// At this point, a sigScript has been constructed. Remove all fields
// other than non-witness utxo (00) and finaliscriptsig (07)
newInput := NewPsbtInput(pInput.NonWitnessUtxo, nil)
newInput.FinalScriptSig = sigScript
// Overwrite the entry in the input list at the correct index. Note
// that this removes all the other entries in the list for this input
// index.
p.Inputs[inIndex] = *newInput
return nil
}
// finalizeWitnessInput attempts to create PsbtInFinalScriptSig field and
// PsbtInFinalScriptWitness field for input at index inIndex, and removes all
// other fields except for the utxo field, for an input of type witness, or
// returns an error.
func finalizeWitnessInput(p *Packet, inIndex int) error {
// If this input has already been finalized, then we'll return an error
// as we can't proceed.
if checkFinalScriptSigWitness(p, inIndex) {
return ErrInputAlreadyFinalized
}
// Depending on the actual output type, we'll either populate a
// serializedWitness or a witness as well asa sigScript.
var (
sigScript []byte
serializedWitness []byte
)
pInput := p.Inputs[inIndex]
// First we'll validate and collect the pubkey+sig pairs from the set
// of partial signatures.
var (
pubKeys [][]byte
sigs [][]byte
)
for _, ps := range pInput.PartialSigs {
pubKeys = append(pubKeys, ps.PubKey)
sigOK := checkSigHashFlags(ps.Signature, &pInput)
if !sigOK {
return ErrInvalidSigHashFlags
}
sigs = append(sigs, ps.Signature)
}
// If at this point, we don't have any pubkey+sig pairs, then we bail
// as we can't proceed.
if len(sigs) == 0 || len(pubKeys) == 0 {
return ErrNotFinalizable
}
containsRedeemScript := pInput.RedeemScript != nil
cointainsWitnessScript := pInput.WitnessScript != nil
// If there's no redeem script, then we assume that this is native
// segwit input.
var err error
if !containsRedeemScript {
// If we have only a sigley pubkey+sig pair, and no witness
// script, then we assume this is a P2WKH input.
if len(pubKeys) == 1 && len(sigs) == 1 &&
!cointainsWitnessScript {
serializedWitness, err = writePKHWitness(
sigs[0], pubKeys[0],
)
if err != nil {
return err
}
} else {
// Otherwise, we must have a witnessScript field, so
// we'll generate a valid multi-sig witness.
//
// NOTE: We tacitly assume multisig.
//
// TODO(roasbeef): need to add custom finalize for
// non-multisig P2WSH outputs (HTLCs, delay outputs,
// etc).
if !cointainsWitnessScript {
return ErrNotFinalizable
}
serializedWitness, err = getMultisigScriptWitness(
pInput.WitnessScript, pubKeys, sigs,
)
if err != nil {
return err
}
}
} else {
// Otherwise, we assume that this is a p2wsh multi-sig output,
// which is nested in a p2sh, or a p2wkh nested in a p2sh.
//
// In this case, we'll take the redeem script (the witness
// program in this case), and push it on the stack within the
// sigScript.
builder := txscript.NewScriptBuilder()
builder.AddData(pInput.RedeemScript)
sigScript, err = builder.Script()
if err != nil {
return err
}
// If don't have a witness script, then we assume this is a
// nested p2wkh output.
if !cointainsWitnessScript {
// Assumed p2sh-p2wkh Here the witness is just (sig,
// pub) as for p2pkh case
if len(sigs) != 1 || len(pubKeys) != 1 {
return ErrNotFinalizable
}
serializedWitness, err = writePKHWitness(sigs[0], pubKeys[0])
if err != nil {
return err
}
} else {
// Otherwise, we assume that this is a p2wsh multi-sig,
// so we generate the proper witness.
serializedWitness, err = getMultisigScriptWitness(
pInput.WitnessScript, pubKeys, sigs,
)
if err != nil {
return err
}
}
}
// At this point, a witness has been constructed, and a sigScript (if
// nested; else it's []). Remove all fields other than witness utxo
// (01) and finalscriptsig (07), finalscriptwitness (08).
newInput := NewPsbtInput(nil, pInput.WitnessUtxo)
if len(sigScript) > 0 {
newInput.FinalScriptSig = sigScript
}
newInput.FinalScriptWitness = serializedWitness
// Finally, we overwrite the entry in the input list at the correct
// index.
p.Inputs[inIndex] = *newInput
return nil
}

9
vendor/github.com/btcsuite/btcutil/psbt/go.mod generated vendored Normal file
View File

@@ -0,0 +1,9 @@
module github.com/btcsuite/btcutil/psbt
go 1.13
require (
github.com/btcsuite/btcd v0.20.1-beta
github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d
github.com/davecgh/go-spew v1.1.1
)

36
vendor/github.com/btcsuite/btcutil/psbt/go.sum generated vendored Normal file
View File

@@ -0,0 +1,36 @@
github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII=
github.com/btcsuite/btcd v0.20.1-beta h1:Ik4hyJqN8Jfyv3S4AGBOmyouMsYE3EdYODkMbQjwPGw=
github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ=
github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f h1:bAs4lUbRJpnnkd9VhRV3jjAVU7DJVjMaK+IsvSeZvFo=
github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA=
github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d h1:yJzD/yFppdVCf6ApMkVy8cUxV0XrxdP9rVf6D87/Mng=
github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg=
github.com/btcsuite/btcutil v0.0.0-20191219182022-e17c9730c422 h1:EqnrgSSg0SFWRlEZLExgjtuUR/IPnuQ6qw6nwRda4Uk=
github.com/btcsuite/btcutil v0.0.0-20191219182022-e17c9730c422/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg=
github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg=
github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVaaLLH7j4eDXPRvw78tMflu7Ie2bzYOH4Y8rRKBY=
github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc=
github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY=
github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs=
github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ=
github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44 h1:9lP3x0pW80sDI6t1UMSLA4to18W7R7imwAI/sWS9S8Q=
golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=

View File

@@ -0,0 +1,367 @@
package psbt
import (
"bytes"
"encoding/binary"
"io"
"sort"
"github.com/btcsuite/btcd/txscript"
"github.com/btcsuite/btcd/wire"
)
// PInput is a struct encapsulating all the data that can be attached to any
// specific input of the PSBT.
type PInput struct {
NonWitnessUtxo *wire.MsgTx
WitnessUtxo *wire.TxOut
PartialSigs []*PartialSig
SighashType txscript.SigHashType
RedeemScript []byte
WitnessScript []byte
Bip32Derivation []*Bip32Derivation
FinalScriptSig []byte
FinalScriptWitness []byte
Unknowns []*Unknown
}
// NewPsbtInput creates an instance of PsbtInput given either a nonWitnessUtxo
// or a witnessUtxo.
//
// NOTE: Only one of the two arguments should be specified, with the other
// being `nil`; otherwise the created PsbtInput object will fail IsSane()
// checks and will not be usable.
func NewPsbtInput(nonWitnessUtxo *wire.MsgTx,
witnessUtxo *wire.TxOut) *PInput {
return &PInput{
NonWitnessUtxo: nonWitnessUtxo,
WitnessUtxo: witnessUtxo,
PartialSigs: []*PartialSig{},
SighashType: 0,
RedeemScript: nil,
WitnessScript: nil,
Bip32Derivation: []*Bip32Derivation{},
FinalScriptSig: nil,
FinalScriptWitness: nil,
Unknowns: nil,
}
}
// IsSane returns true only if there are no conflicting values in the Psbt
// PInput. It checks that witness and non-witness utxo entries do not both
// exist, and that witnessScript entries are only added to witness inputs.
func (pi *PInput) IsSane() bool {
if pi.NonWitnessUtxo != nil && pi.WitnessUtxo != nil {
return false
}
if pi.WitnessUtxo == nil && pi.WitnessScript != nil {
return false
}
if pi.WitnessUtxo == nil && pi.FinalScriptWitness != nil {
return false
}
return true
}
// deserialize attempts to deserialize a new PInput from the passed io.Reader.
func (pi *PInput) deserialize(r io.Reader) error {
for {
keyint, keydata, err := getKey(r)
if err != nil {
return err
}
if keyint == -1 {
// Reached separator byte
break
}
value, err := wire.ReadVarBytes(
r, 0, MaxPsbtValueLength, "PSBT value",
)
if err != nil {
return err
}
switch InputType(keyint) {
case NonWitnessUtxoType:
if pi.NonWitnessUtxo != nil {
return ErrDuplicateKey
}
if keydata != nil {
return ErrInvalidKeydata
}
tx := wire.NewMsgTx(2)
err := tx.Deserialize(bytes.NewReader(value))
if err != nil {
return err
}
pi.NonWitnessUtxo = tx
case WitnessUtxoType:
if pi.WitnessUtxo != nil {
return ErrDuplicateKey
}
if keydata != nil {
return ErrInvalidKeydata
}
txout, err := readTxOut(value)
if err != nil {
return err
}
pi.WitnessUtxo = txout
case PartialSigType:
newPartialSig := PartialSig{
PubKey: keydata,
Signature: value,
}
if !newPartialSig.checkValid() {
return ErrInvalidPsbtFormat
}
// Duplicate keys are not allowed
for _, x := range pi.PartialSigs {
if bytes.Equal(x.PubKey, newPartialSig.PubKey) {
return ErrDuplicateKey
}
}
pi.PartialSigs = append(pi.PartialSigs, &newPartialSig)
case SighashType:
if pi.SighashType != 0 {
return ErrDuplicateKey
}
if keydata != nil {
return ErrInvalidKeydata
}
// Bounds check on value here since the sighash type must be a
// 32-bit unsigned integer.
if len(value) != 4 {
return ErrInvalidKeydata
}
shtype := txscript.SigHashType(
binary.LittleEndian.Uint32(value),
)
pi.SighashType = shtype
case RedeemScriptInputType:
if pi.RedeemScript != nil {
return ErrDuplicateKey
}
if keydata != nil {
return ErrInvalidKeydata
}
pi.RedeemScript = value
case WitnessScriptInputType:
if pi.WitnessScript != nil {
return ErrDuplicateKey
}
if keydata != nil {
return ErrInvalidKeydata
}
pi.WitnessScript = value
case Bip32DerivationInputType:
if !validatePubkey(keydata) {
return ErrInvalidPsbtFormat
}
master, derivationPath, err := readBip32Derivation(value)
if err != nil {
return err
}
// Duplicate keys are not allowed
for _, x := range pi.Bip32Derivation {
if bytes.Equal(x.PubKey, keydata) {
return ErrDuplicateKey
}
}
pi.Bip32Derivation = append(
pi.Bip32Derivation,
&Bip32Derivation{
PubKey: keydata,
MasterKeyFingerprint: master,
Bip32Path: derivationPath,
},
)
case FinalScriptSigType:
if pi.FinalScriptSig != nil {
return ErrDuplicateKey
}
if keydata != nil {
return ErrInvalidKeydata
}
pi.FinalScriptSig = value
case FinalScriptWitnessType:
if pi.FinalScriptWitness != nil {
return ErrDuplicateKey
}
if keydata != nil {
return ErrInvalidKeydata
}
pi.FinalScriptWitness = value
default:
// A fall through case for any proprietary types.
keyintanddata := []byte{byte(keyint)}
keyintanddata = append(keyintanddata, keydata...)
newUnknown := &Unknown{
Key: keyintanddata,
Value: value,
}
// Duplicate key+keydata are not allowed
for _, x := range pi.Unknowns {
if bytes.Equal(x.Key, newUnknown.Key) &&
bytes.Equal(x.Value, newUnknown.Value) {
return ErrDuplicateKey
}
}
pi.Unknowns = append(pi.Unknowns, newUnknown)
}
}
return nil
}
// serialize attempts to serialize the target PInput into the passed io.Writer.
func (pi *PInput) serialize(w io.Writer) error {
if !pi.IsSane() {
return ErrInvalidPsbtFormat
}
if pi.NonWitnessUtxo != nil {
var buf bytes.Buffer
err := pi.NonWitnessUtxo.Serialize(&buf)
if err != nil {
return err
}
err = serializeKVPairWithType(
w, uint8(NonWitnessUtxoType), nil, buf.Bytes(),
)
if err != nil {
return err
}
}
if pi.WitnessUtxo != nil {
var buf bytes.Buffer
err := wire.WriteTxOut(&buf, 0, 0, pi.WitnessUtxo)
if err != nil {
return err
}
err = serializeKVPairWithType(
w, uint8(WitnessUtxoType), nil, buf.Bytes(),
)
if err != nil {
return err
}
}
if pi.FinalScriptSig == nil && pi.FinalScriptWitness == nil {
sort.Sort(PartialSigSorter(pi.PartialSigs))
for _, ps := range pi.PartialSigs {
err := serializeKVPairWithType(
w, uint8(PartialSigType), ps.PubKey,
ps.Signature,
)
if err != nil {
return err
}
}
if pi.SighashType != 0 {
var shtBytes [4]byte
binary.LittleEndian.PutUint32(
shtBytes[:], uint32(pi.SighashType),
)
err := serializeKVPairWithType(
w, uint8(SighashType), nil, shtBytes[:],
)
if err != nil {
return err
}
}
if pi.RedeemScript != nil {
err := serializeKVPairWithType(
w, uint8(RedeemScriptInputType), nil,
pi.RedeemScript,
)
if err != nil {
return err
}
}
if pi.WitnessScript != nil {
err := serializeKVPairWithType(
w, uint8(WitnessScriptInputType), nil,
pi.WitnessScript,
)
if err != nil {
return err
}
}
sort.Sort(Bip32Sorter(pi.Bip32Derivation))
for _, kd := range pi.Bip32Derivation {
err := serializeKVPairWithType(
w,
uint8(Bip32DerivationInputType), kd.PubKey,
SerializeBIP32Derivation(
kd.MasterKeyFingerprint, kd.Bip32Path,
),
)
if err != nil {
return err
}
}
}
if pi.FinalScriptSig != nil {
err := serializeKVPairWithType(
w, uint8(FinalScriptSigType), nil, pi.FinalScriptSig,
)
if err != nil {
return err
}
}
if pi.FinalScriptWitness != nil {
err := serializeKVPairWithType(
w, uint8(FinalScriptWitnessType), nil, pi.FinalScriptWitness,
)
if err != nil {
return err
}
}
// Unknown is a special case; we don't have a key type, only a key and
// a value field
for _, kv := range pi.Unknowns {
err := serializeKVpair(w, kv.Key, kv.Value)
if err != nil {
return err
}
}
return nil
}

View File

@@ -0,0 +1,139 @@
package psbt
import (
"bytes"
"io"
"sort"
"github.com/btcsuite/btcd/wire"
)
// POutput is a struct encapsulating all the data that can be attached
// to any specific output of the PSBT.
type POutput struct {
RedeemScript []byte
WitnessScript []byte
Bip32Derivation []*Bip32Derivation
}
// NewPsbtOutput creates an instance of PsbtOutput; the three parameters
// redeemScript, witnessScript and Bip32Derivation are all allowed to be
// `nil`.
func NewPsbtOutput(redeemScript []byte, witnessScript []byte,
bip32Derivation []*Bip32Derivation) *POutput {
return &POutput{
RedeemScript: redeemScript,
WitnessScript: witnessScript,
Bip32Derivation: bip32Derivation,
}
}
// deserialize attempts to recode a new POutput from the passed io.Reader.
func (po *POutput) deserialize(r io.Reader) error {
for {
keyint, keydata, err := getKey(r)
if err != nil {
return err
}
if keyint == -1 {
// Reached separator byte
break
}
value, err := wire.ReadVarBytes(
r, 0, MaxPsbtValueLength, "PSBT value",
)
if err != nil {
return err
}
switch OutputType(keyint) {
case RedeemScriptOutputType:
if po.RedeemScript != nil {
return ErrDuplicateKey
}
if keydata != nil {
return ErrInvalidKeydata
}
po.RedeemScript = value
case WitnessScriptOutputType:
if po.WitnessScript != nil {
return ErrDuplicateKey
}
if keydata != nil {
return ErrInvalidKeydata
}
po.WitnessScript = value
case Bip32DerivationOutputType:
if !validatePubkey(keydata) {
return ErrInvalidKeydata
}
master, derivationPath, err := readBip32Derivation(value)
if err != nil {
return err
}
// Duplicate keys are not allowed
for _, x := range po.Bip32Derivation {
if bytes.Equal(x.PubKey, keydata) {
return ErrDuplicateKey
}
}
po.Bip32Derivation = append(po.Bip32Derivation,
&Bip32Derivation{
PubKey: keydata,
MasterKeyFingerprint: master,
Bip32Path: derivationPath,
},
)
default:
// Unknown type is allowed for inputs but not outputs.
return ErrInvalidPsbtFormat
}
}
return nil
}
// serialize attempts to write out the target POutput into the passed
// io.Writer.
func (po *POutput) serialize(w io.Writer) error {
if po.RedeemScript != nil {
err := serializeKVPairWithType(
w, uint8(RedeemScriptOutputType), nil, po.RedeemScript,
)
if err != nil {
return err
}
}
if po.WitnessScript != nil {
err := serializeKVPairWithType(
w, uint8(WitnessScriptOutputType), nil, po.WitnessScript,
)
if err != nil {
return err
}
}
sort.Sort(Bip32Sorter(po.Bip32Derivation))
for _, kd := range po.Bip32Derivation {
err := serializeKVPairWithType(w,
uint8(Bip32DerivationOutputType),
kd.PubKey,
SerializeBIP32Derivation(
kd.MasterKeyFingerprint,
kd.Bip32Path,
),
)
if err != nil {
return err
}
}
return nil
}

58
vendor/github.com/btcsuite/btcutil/psbt/partialsig.go generated vendored Normal file
View File

@@ -0,0 +1,58 @@
package psbt
import (
"bytes"
"github.com/btcsuite/btcd/btcec"
)
// PartialSig encapsulate a (BTC public key, ECDSA signature)
// pair, note that the fields are stored as byte slices, not
// btcec.PublicKey or btcec.Signature (because manipulations will
// be with the former not the latter, here); compliance with consensus
// serialization is enforced with .checkValid()
type PartialSig struct {
PubKey []byte
Signature []byte
}
// PartialSigSorter implements sort.Interface for PartialSig.
type PartialSigSorter []*PartialSig
func (s PartialSigSorter) Len() int { return len(s) }
func (s PartialSigSorter) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
func (s PartialSigSorter) Less(i, j int) bool {
return bytes.Compare(s[i].PubKey, s[j].PubKey) < 0
}
// validatePubkey checks if pubKey is *any* valid pubKey serialization in a
// Bitcoin context (compressed/uncomp. OK).
func validatePubkey(pubKey []byte) bool {
_, err := btcec.ParsePubKey(pubKey, btcec.S256())
if err != nil {
return false
}
return true
}
// validateSignature checks that the passed byte slice is a valid DER-encoded
// ECDSA signature, including the sighash flag. It does *not* of course
// validate the signature against any message or public key.
func validateSignature(sig []byte) bool {
_, err := btcec.ParseDERSignature(sig, btcec.S256())
if err != nil {
return false
}
return true
}
// checkValid checks that both the pbukey and sig are valid. See the methods
// (PartialSig, validatePubkey, validateSignature) for more details.
//
// TODO(waxwing): update for Schnorr will be needed here if/when that
// activates.
func (ps *PartialSig) checkValid() bool {
return validatePubkey(ps.PubKey) && validateSignature(ps.Signature)
}

407
vendor/github.com/btcsuite/btcutil/psbt/psbt.go generated vendored Normal file
View File

@@ -0,0 +1,407 @@
// Copyright (c) 2018 The btcsuite developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
// Package psbt is an implementation of Partially Signed Bitcoin
// Transactions (PSBT). The format is defined in BIP 174:
// https://github.com/bitcoin/bips/blob/master/bip-0174.mediawiki
package psbt
import (
"bytes"
"encoding/base64"
"errors"
"io"
"github.com/btcsuite/btcd/wire"
)
// psbtMagicLength is the length of the magic bytes used to signal the start of
// a serialized PSBT packet.
const psbtMagicLength = 5
var (
// psbtMagic is the separator
psbtMagic = [psbtMagicLength]byte{0x70,
0x73, 0x62, 0x74, 0xff, // = "psbt" + 0xff sep
}
)
// MaxPsbtValueLength is the size of the largest transaction serialization
// that could be passed in a NonWitnessUtxo field. This is definitely
//less than 4M.
const MaxPsbtValueLength = 4000000
// MaxPsbtKeyLength is the length of the largest key that we'll successfully
// deserialize from the wire. Anything more will return ErrInvalidKeydata.
const MaxPsbtKeyLength = 10000
var (
// ErrInvalidPsbtFormat is a generic error for any situation in which a
// provided Psbt serialization does not conform to the rules of BIP174.
ErrInvalidPsbtFormat = errors.New("Invalid PSBT serialization format")
// ErrDuplicateKey indicates that a passed Psbt serialization is invalid
// due to having the same key repeated in the same key-value pair.
ErrDuplicateKey = errors.New("Invalid Psbt due to duplicate key")
// ErrInvalidKeydata indicates that a key-value pair in the PSBT
// serialization contains data in the key which is not valid.
ErrInvalidKeydata = errors.New("Invalid key data")
// ErrInvalidMagicBytes indicates that a passed Psbt serialization is invalid
// due to having incorrect magic bytes.
ErrInvalidMagicBytes = errors.New("Invalid Psbt due to incorrect magic bytes")
// ErrInvalidRawTxSigned indicates that the raw serialized transaction in the
// global section of the passed Psbt serialization is invalid because it
// contains scriptSigs/witnesses (i.e. is fully or partially signed), which
// is not allowed by BIP174.
ErrInvalidRawTxSigned = errors.New("Invalid Psbt, raw transaction must " +
"be unsigned.")
// ErrInvalidPrevOutNonWitnessTransaction indicates that the transaction
// hash (i.e. SHA256^2) of the fully serialized previous transaction
// provided in the NonWitnessUtxo key-value field doesn't match the prevout
// hash in the UnsignedTx field in the PSBT itself.
ErrInvalidPrevOutNonWitnessTransaction = errors.New("Prevout hash does " +
"not match the provided non-witness utxo serialization")
// ErrInvalidSignatureForInput indicates that the signature the user is
// trying to append to the PSBT is invalid, either because it does
// not correspond to the previous transaction hash, or redeem script,
// or witness script.
// NOTE this does not include ECDSA signature checking.
ErrInvalidSignatureForInput = errors.New("Signature does not correspond " +
"to this input")
// ErrInputAlreadyFinalized indicates that the PSBT passed to a Finalizer
// already contains the finalized scriptSig or witness.
ErrInputAlreadyFinalized = errors.New("Cannot finalize PSBT, finalized " +
"scriptSig or scriptWitnes already exists")
// ErrIncompletePSBT indicates that the Extractor object
// was unable to successfully extract the passed Psbt struct because
// it is not complete
ErrIncompletePSBT = errors.New("PSBT cannot be extracted as it is " +
"incomplete")
// ErrNotFinalizable indicates that the PSBT struct does not have
// sufficient data (e.g. signatures) for finalization
ErrNotFinalizable = errors.New("PSBT is not finalizable")
// ErrInvalidSigHashFlags indicates that a signature added to the PSBT
// uses Sighash flags that are not in accordance with the requirement
// according to the entry in PsbtInSighashType, or otherwise not the
// default value (SIGHASH_ALL)
ErrInvalidSigHashFlags = errors.New("Invalid Sighash Flags")
// ErrUnsupportedScriptType indicates that the redeem script or
// scriptwitness given is not supported by this codebase, or is otherwise
// not valid.
ErrUnsupportedScriptType = errors.New("Unsupported script type")
)
// Unknown is a struct encapsulating a key-value pair for which the key type is
// unknown by this package; these fields are allowed in both the 'Global' and
// the 'Input' section of a PSBT.
type Unknown struct {
Key []byte
Value []byte
}
// Packet is the actual psbt repreesntation. It is a is a set of 1 + N + M
// key-value pair lists, 1 global, defining the unsigned transaction structure
// with N inputs and M outputs. These key-value pairs can contain scripts,
// signatures, key derivations and other transaction-defining data.
type Packet struct {
// UnsignedTx is the decoded unsigned transaction for this PSBT.
UnsignedTx *wire.MsgTx // Deserialization of unsigned tx
// Inputs contains all the information needed to properly sign this
// target input within the above transaction.
Inputs []PInput
// Outputs contains all information required to spend any outputs
// produced by this PSBT.
Outputs []POutput
// Unknowns are the set of custom types (global only) within this PSBT.
Unknowns []Unknown
}
// validateUnsignedTx returns true if the transaction is unsigned. Note that
// more basic sanity requirements, such as the presence of inputs and outputs,
// is implicitly checked in the call to MsgTx.Deserialize().
func validateUnsignedTX(tx *wire.MsgTx) bool {
for _, tin := range tx.TxIn {
if len(tin.SignatureScript) != 0 || len(tin.Witness) != 0 {
return false
}
}
return true
}
// NewFromUnsignedTx creates a new Psbt struct, without any signatures (i.e.
// only the global section is non-empty) using the passed unsigned transaction.
func NewFromUnsignedTx(tx *wire.MsgTx) (*Packet, error) {
if !validateUnsignedTX(tx) {
return nil, ErrInvalidRawTxSigned
}
inSlice := make([]PInput, len(tx.TxIn))
outSlice := make([]POutput, len(tx.TxOut))
unknownSlice := make([]Unknown, 0)
retPsbt := Packet{
UnsignedTx: tx,
Inputs: inSlice,
Outputs: outSlice,
Unknowns: unknownSlice,
}
return &retPsbt, nil
}
// NewFromRawBytes returns a new instance of a Packet struct created by reading
// from a byte slice. If the format is invalid, an error is returned. If the
// argument b64 is true, the passed byte slice is decoded from base64 encoding
// before processing.
//
// NOTE: To create a Packet from one's own data, rather than reading in a
// serialization from a counterparty, one should use a psbt.New.
func NewFromRawBytes(r io.Reader, b64 bool) (*Packet, error) {
// If the PSBT is encoded in bas64, then we'll create a new wrapper
// reader that'll allow us to incrementally decode the contents of the
// io.Reader.
if b64 {
based64EncodedReader := r
r = base64.NewDecoder(base64.StdEncoding, based64EncodedReader)
}
// The Packet struct does not store the fixed magic bytes, but they
// must be present or the serialization must be explicitly rejected.
var magic [5]byte
if _, err := io.ReadFull(r, magic[:]); err != nil {
return nil, err
}
if magic != psbtMagic {
return nil, ErrInvalidMagicBytes
}
// Next we parse the GLOBAL section. There is currently only 1 known
// key type, UnsignedTx. We insist this exists first; unknowns are
// allowed, but only after.
keyint, keydata, err := getKey(r)
if err != nil {
return nil, err
}
if GlobalType(keyint) != UnsignedTxType || keydata != nil {
return nil, ErrInvalidPsbtFormat
}
// Now that we've verified the global type is present, we'll decode it
// into a proper unsigned transaction, and validate it.
value, err := wire.ReadVarBytes(
r, 0, MaxPsbtValueLength, "PSBT value",
)
if err != nil {
return nil, err
}
msgTx := wire.NewMsgTx(2)
err = msgTx.Deserialize(bytes.NewReader(value))
if err != nil {
// If there are no inputs in this yet incomplete transaction,
// the wire package still incorrectly assumes it's encoded in
// the witness format. We can fix this by just trying the non-
// witness encoding too. If that also fails, it's probably an
// invalid transaction.
msgTx = wire.NewMsgTx(2)
err2 := msgTx.DeserializeNoWitness(bytes.NewReader(value))
// If the second attempt also failed, something else is wrong
// and it probably makes more sense to return the original
// error instead of the error from the workaround.
if err2 != nil {
return nil, err
}
}
if !validateUnsignedTX(msgTx) {
return nil, ErrInvalidRawTxSigned
}
// Next we parse any unknowns that may be present, making sure that we
// break at the separator.
var unknownSlice []Unknown
for {
keyint, keydata, err := getKey(r)
if err != nil {
return nil, ErrInvalidPsbtFormat
}
if keyint == -1 {
break
}
value, err := wire.ReadVarBytes(
r, 0, MaxPsbtValueLength, "PSBT value",
)
if err != nil {
return nil, err
}
keyintanddata := []byte{byte(keyint)}
keyintanddata = append(keyintanddata, keydata...)
newUnknown := Unknown{
Key: keyintanddata,
Value: value,
}
unknownSlice = append(unknownSlice, newUnknown)
}
// Next we parse the INPUT section.
inSlice := make([]PInput, len(msgTx.TxIn))
for i := range msgTx.TxIn {
input := PInput{}
err = input.deserialize(r)
if err != nil {
return nil, err
}
inSlice[i] = input
}
// Next we parse the OUTPUT section.
outSlice := make([]POutput, len(msgTx.TxOut))
for i := range msgTx.TxOut {
output := POutput{}
err = output.deserialize(r)
if err != nil {
return nil, err
}
outSlice[i] = output
}
// Populate the new Packet object
newPsbt := Packet{
UnsignedTx: msgTx,
Inputs: inSlice,
Outputs: outSlice,
Unknowns: unknownSlice,
}
// Extended sanity checking is applied here to make sure the
// externally-passed Packet follows all the rules.
if err = newPsbt.SanityCheck(); err != nil {
return nil, err
}
return &newPsbt, nil
}
// Serialize creates a binary serialization of the referenced Packet struct
// with lexicographical ordering (by key) of the subsections.
func (p *Packet) Serialize(w io.Writer) error {
// First we write out the precise set of magic bytes that identify a
// valid PSBT transaction.
if _, err := w.Write(psbtMagic[:]); err != nil {
return err
}
// Next we prep to write out the unsigned transaction by first
// serializing it into an intermediate buffer.
serializedTx := bytes.NewBuffer(
make([]byte, 0, p.UnsignedTx.SerializeSize()),
)
if err := p.UnsignedTx.Serialize(serializedTx); err != nil {
return err
}
// Now that we have the serialized transaction, we'll write it out to
// the proper global type.
err := serializeKVPairWithType(
w, uint8(UnsignedTxType), nil, serializedTx.Bytes(),
)
if err != nil {
return err
}
// With that our global section is done, so we'll write out the
// separator.
separator := []byte{0x00}
if _, err := w.Write(separator); err != nil {
return err
}
for _, pInput := range p.Inputs {
err := pInput.serialize(w)
if err != nil {
return err
}
if _, err := w.Write(separator); err != nil {
return err
}
}
for _, pOutput := range p.Outputs {
err := pOutput.serialize(w)
if err != nil {
return err
}
if _, err := w.Write(separator); err != nil {
return err
}
}
return nil
}
// B64Encode returns the base64 encoding of the serialization of
// the current PSBT, or an error if the encoding fails.
func (p *Packet) B64Encode() (string, error) {
var b bytes.Buffer
if err := p.Serialize(&b); err != nil {
return "", err
}
return base64.StdEncoding.EncodeToString(b.Bytes()), nil
}
// IsComplete returns true only if all of the inputs are
// finalized; this is particularly important in that it decides
// whether the final extraction to a network serialized signed
// transaction will be possible.
func (p *Packet) IsComplete() bool {
for i := 0; i < len(p.UnsignedTx.TxIn); i++ {
if !isFinalized(p, i) {
return false
}
}
return true
}
// SanityCheck checks conditions on a PSBT to ensure that it obeys the
// rules of BIP174, and returns true if so, false if not.
func (p *Packet) SanityCheck() error {
if !validateUnsignedTX(p.UnsignedTx) {
return ErrInvalidRawTxSigned
}
for _, tin := range p.Inputs {
if !tin.IsSane() {
return ErrInvalidPsbtFormat
}
}
return nil
}

152
vendor/github.com/btcsuite/btcutil/psbt/signer.go generated vendored Normal file
View File

@@ -0,0 +1,152 @@
// Copyright (c) 2018 The btcsuite developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package psbt
// signer encapsulates the role 'Signer' as specified in BIP174; it controls
// the insertion of signatures; the Sign() function will attempt to insert
// signatures using Updater.addPartialSignature, after first ensuring the Psbt
// is in the correct state.
import (
"github.com/btcsuite/btcd/txscript"
)
// SignOutcome is a enum-like value that expresses the outcome of a call to the
// Sign method.
type SignOutcome int
const (
// SignSuccesful indicates that the partial signature was successfully
// attached.
SignSuccesful = 0
// SignFinalized indicates that this input is already finalized, so the provided
// signature was *not* attached
SignFinalized = 1
// SignInvalid indicates that the provided signature data was not valid. In this case
// an error will also be returned.
SignInvalid = -1
)
// Sign allows the caller to sign a PSBT at a particular input; they
// must provide a signature and a pubkey, both as byte slices; they can also
// optionally provide both witnessScript and/or redeemScript, otherwise these
// arguments must be set as nil (and in that case, they must already be present
// in the PSBT if required for signing to succeed).
//
// This serves as a wrapper around Updater.addPartialSignature; it ensures that
// the redeemScript and witnessScript are updated as needed (note that the
// Updater is allowed to add redeemScripts and witnessScripts independently,
// before signing), and ensures that the right form of utxo field
// (NonWitnessUtxo or WitnessUtxo) is included in the input so that signature
// insertion (and then finalization) can take place.
func (u *Updater) Sign(inIndex int, sig []byte, pubKey []byte,
redeemScript []byte, witnessScript []byte) (SignOutcome, error) {
if isFinalized(u.Upsbt, inIndex) {
return SignFinalized, nil
}
// Add the witnessScript to the PSBT in preparation. If it already
// exists, it will be overwritten.
if witnessScript != nil {
err := u.AddInWitnessScript(witnessScript, inIndex)
if err != nil {
return SignInvalid, err
}
}
// Add the redeemScript to the PSBT in preparation. If it already
// exists, it will be overwritten.
if redeemScript != nil {
err := u.AddInRedeemScript(redeemScript, inIndex)
if err != nil {
return SignInvalid, err
}
}
// At this point, the PSBT must have the requisite witnessScript or
// redeemScript fields for signing to succeed.
//
// Case 1: if witnessScript is present, it must be of type witness;
// if not, signature insertion will of course fail.
switch {
case u.Upsbt.Inputs[inIndex].WitnessScript != nil:
if u.Upsbt.Inputs[inIndex].WitnessUtxo == nil {
err := nonWitnessToWitness(u.Upsbt, inIndex)
if err != nil {
return SignInvalid, err
}
}
err := u.addPartialSignature(inIndex, sig, pubKey)
if err != nil {
return SignInvalid, err
}
// Case 2: no witness script, only redeem script; can be legacy p2sh or
// p2sh-wrapped p2wkh.
case u.Upsbt.Inputs[inIndex].RedeemScript != nil:
// We only need to decide if the input is witness, and we don't
// rely on the witnessutxo/nonwitnessutxo in the PSBT, instead
// we check the redeemScript content.
if txscript.IsWitnessProgram(redeemScript) {
if u.Upsbt.Inputs[inIndex].WitnessUtxo == nil {
err := nonWitnessToWitness(u.Upsbt, inIndex)
if err != nil {
return SignInvalid, err
}
}
}
// If it is not a valid witness program, we here assume that
// the provided WitnessUtxo/NonWitnessUtxo field was correct.
err := u.addPartialSignature(inIndex, sig, pubKey)
if err != nil {
return SignInvalid, err
}
// Case 3: Neither provided only works for native p2wkh, or non-segwit
// non-p2sh. To check if it's segwit, check the scriptPubKey of the
// output.
default:
if u.Upsbt.Inputs[inIndex].WitnessUtxo == nil {
outIndex := u.Upsbt.UnsignedTx.TxIn[inIndex].PreviousOutPoint.Index
script := u.Upsbt.Inputs[inIndex].NonWitnessUtxo.TxOut[outIndex].PkScript
if txscript.IsWitnessProgram(script) {
err := nonWitnessToWitness(u.Upsbt, inIndex)
if err != nil {
return SignInvalid, err
}
}
}
err := u.addPartialSignature(inIndex, sig, pubKey)
if err != nil {
return SignInvalid, err
}
}
return SignSuccesful, nil
}
// nonWitnessToWitness extracts the TxOut from the existing NonWitnessUtxo
// field in the given PSBT input and sets it as type witness by replacing the
// NonWitnessUtxo field with a WitnessUtxo field. See
// https://github.com/bitcoin/bitcoin/pull/14197.
func nonWitnessToWitness(p *Packet, inIndex int) error {
outIndex := p.UnsignedTx.TxIn[inIndex].PreviousOutPoint.Index
txout := p.Inputs[inIndex].NonWitnessUtxo.TxOut[outIndex]
// Remove the non-witness first, else sanity check will not pass:
p.Inputs[inIndex].NonWitnessUtxo = nil
u := Updater{
Upsbt: p,
}
return u.AddInWitnessUtxo(txout, inIndex)
}

149
vendor/github.com/btcsuite/btcutil/psbt/types.go generated vendored Normal file
View File

@@ -0,0 +1,149 @@
package psbt
// GlobalType is the set of types that are used at the global scope level
// within the PSBT.
type GlobalType uint8
const (
// UnsignedTxType is the global scope key that houses the unsigned
// transaction of the PSBT. The value is a transaction in network
// serialization. The scriptSigs and witnesses for each input must be
// empty. The transaction must be in the old serialization format
// (without witnesses). A PSBT must have a transaction, otherwise it is
// invalid.
UnsignedTxType GlobalType = 0
// XpubType houses a global xpub for the entire PSBT packet.
//
// The key ({0x01}|{xpub}) is he 78 byte serialized extended public key
// as defined by BIP 32. Extended public keys are those that can be
// used to derive public keys used in the inputs and outputs of this
// transaction. It should be the public key at the highest hardened
// derivation index so that
// the unhardened child keys used in the transaction can be derived.
//
// The value is the master key fingerprint as defined by BIP 32
// concatenated with the derivation path of the public key. The
// derivation path is represented as 32-bit little endian unsigned
// integer indexes concatenated with each other. The number of 32 bit
// unsigned integer indexes must match the depth provided in the
// extended public key.
XpubType GlobalType = 1
// VersionType houses the global version number of this PSBT. There is
// no key (only contains the byte type), then the value if omitted, is
// assumed to be zero.
VersionType GlobalType = 0xFB
// ProprietaryGlobalType is used to house any proper chary global-scope
// keys within the PSBT.
//
// The key is ({0xFC}|<prefix>|{subtype}|{key data}) a variable length
// identifier prefix, followed by a subtype, followed by the key data
// itself.
//
// The value is any data as defined by the proprietary type user.
ProprietaryGlobalType = 0xFC
)
// InputType is the set of types that are defined for each input included
// within the PSBT.
type InputType uint32
const (
// NonWitnessUtxoType has no key ({0x00}) and houses the transaction in
// network serialization format the current input spends from. This
// should only be present for inputs which spend non-segwit outputs.
// However, if it is unknown whether an input spends a segwit output,
// this type should be used. The entire input transaction is needed in
// order to be able to verify the values of the input (pre-segwit they
// aren't in the signature digest).
NonWitnessUtxoType InputType = 0
// WitnessUtxoType has no key ({0x01}), and houses the entire
// transaction output in network serialization which the current input
// spends from. This should only be present for inputs which spend
// segwit outputs, including P2SH embedded ones (value || script).
WitnessUtxoType InputType = 1
// PartialSigType is used to include a partial signature with key
// ({0x02}|{public key}).
//
// The value is the signature as would be pushed to the stack from a
// scriptSig or witness..
PartialSigType InputType = 2
// SighashType is an empty key ({0x03}).
//
// The value contains the 32-bit unsigned integer specifying the
// sighash type to be used for this input. Signatures for this input
// must use the sighash type, finalizers must fail to finalize inputs
// which have signatures that do not match the specified sighash type.
// Signers who cannot produce signatures with the sighash type must not
// provide a signature.
SighashType InputType = 3
// RedeemScriptInputType is an empty key ({0x40}).
//
// The value is the redeem script of the input if present.
RedeemScriptInputType InputType = 4
// WitnessScriptInputType is an empty key ({0x05}).
//
// The value is the witness script of this input, if it has one.
WitnessScriptInputType InputType = 5
// Bip32DerivationInputType is a type that carries the pubkey along
// with the key ({0x06}|{public key}).
//
// The value is master key fingerprint as defined by BIP 32
// concatenated with the derivation path of the public key. The
// derivation path is represented as 32 bit unsigned integer indexes
// concatenated with each other. Public keys are those that will be
// needed to sign this input.
Bip32DerivationInputType InputType = 6
// FinalScriptSigType is an empty key ({0x07}).
//
// The value contains a fully constructed scriptSig with signatures and
// any other scripts necessary for the input to pass validation.
FinalScriptSigType InputType = 7
// FinalScriptWitnessType is an empty key ({0x08}). The value is a
// fully constructed scriptWitness with signatures and any other
// scripts necessary for the input to pass validation.
FinalScriptWitnessType InputType = 8
// ProprietaryInputType is a custom type for use by devs.
//
// The key ({0xFC}|<prefix>|{subtype}|{key data}), is a Variable length
// identifier prefix, followed by a subtype, followed by the key data
// itself.
//
// The value is any value data as defined by the proprietary type user.
ProprietaryInputType InputType = 0xFC
)
// OutputType is the set of types defined per output within the PSBT.
type OutputType uint32
const (
// RedeemScriptOutputType is an empty key ({0x00}>
//
// The value is the redeemScript for this output if it has one.
RedeemScriptOutputType OutputType = 0
// WitnessScriptOutputType is an empty key ({0x01}).
//
// The value is the witness script of this input, if it has one.
WitnessScriptOutputType OutputType = 1
j // Bip32DerivationOutputType is used to communicate derivation information
// needed to spend this output. The key is ({0x02}|{public key}).
//
// The value is master key fingerprint concatenated with the derivation
// path of the public key. The derivation path is represented as 32-bit
// little endian unsigned integer indexes concatenated with each other.
// Public keys are those needed to spend this output.
Bip32DerivationOutputType OutputType = 2
)

367
vendor/github.com/btcsuite/btcutil/psbt/updater.go generated vendored Normal file
View File

@@ -0,0 +1,367 @@
// Copyright (c) 2018 The btcsuite developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package psbt
// The Updater requires provision of a single PSBT and is able to add data to
// both input and output sections. It can be called repeatedly to add more
// data. It also allows addition of signatures via the addPartialSignature
// function; this is called internally to the package in the Sign() function of
// Updater, located in signer.go
import (
"bytes"
"crypto/sha256"
"github.com/btcsuite/btcd/txscript"
"github.com/btcsuite/btcd/wire"
"github.com/btcsuite/btcutil"
)
// Updater encapsulates the role 'Updater' as specified in BIP174; it accepts
// Psbt structs and has methods to add fields to the inputs and outputs.
type Updater struct {
Upsbt *Packet
}
// NewUpdater returns a new instance of Updater, if the passed Psbt struct is
// in a valid form, else an error.
func NewUpdater(p *Packet) (*Updater, error) {
if err := p.SanityCheck(); err != nil {
return nil, err
}
return &Updater{Upsbt: p}, nil
}
// AddInNonWitnessUtxo adds the utxo information for an input which is
// non-witness. This requires provision of a full transaction (which is the
// source of the corresponding prevOut), and the input index. If addition of
// this key-value pair to the Psbt fails, an error is returned.
func (p *Updater) AddInNonWitnessUtxo(tx *wire.MsgTx, inIndex int) error {
if inIndex > len(p.Upsbt.Inputs)-1 {
return ErrInvalidPrevOutNonWitnessTransaction
}
p.Upsbt.Inputs[inIndex].NonWitnessUtxo = tx
if err := p.Upsbt.SanityCheck(); err != nil {
return ErrInvalidPsbtFormat
}
return nil
}
// AddInWitnessUtxo adds the utxo information for an input which is witness.
// This requires provision of a full transaction *output* (which is the source
// of the corresponding prevOut); not the full transaction because BIP143 means
// the output information is sufficient, and the input index. If addition of
// this key-value pair to the Psbt fails, an error is returned.
func (p *Updater) AddInWitnessUtxo(txout *wire.TxOut, inIndex int) error {
if inIndex > len(p.Upsbt.Inputs)-1 {
return ErrInvalidPsbtFormat
}
p.Upsbt.Inputs[inIndex].WitnessUtxo = txout
if err := p.Upsbt.SanityCheck(); err != nil {
return ErrInvalidPsbtFormat
}
return nil
}
// addPartialSignature allows the Updater role to insert fields of type partial
// signature into a Psbt, consisting of both the pubkey (as keydata) and the
// ECDSA signature (as value). Note that the Signer role is encapsulated in
// this function; signatures are only allowed to be added that follow the
// sanity-check on signing rules explained in the BIP under `Signer`; if the
// rules are not satisfied, an ErrInvalidSignatureForInput is returned.
//
// NOTE: This function does *not* validate the ECDSA signature itself.
func (p *Updater) addPartialSignature(inIndex int, sig []byte,
pubkey []byte) error {
partialSig := PartialSig{
PubKey: pubkey, Signature: sig,
}
// First validate the passed (sig, pub).
if !partialSig.checkValid() {
return ErrInvalidPsbtFormat
}
pInput := p.Upsbt.Inputs[inIndex]
// First check; don't add duplicates.
for _, x := range pInput.PartialSigs {
if bytes.Equal(x.PubKey, partialSig.PubKey) {
return ErrDuplicateKey
}
}
// Next, we perform a series of additional sanity checks.
if pInput.NonWitnessUtxo != nil {
if len(p.Upsbt.UnsignedTx.TxIn) < inIndex+1 {
return ErrInvalidPrevOutNonWitnessTransaction
}
if pInput.NonWitnessUtxo.TxHash() !=
p.Upsbt.UnsignedTx.TxIn[inIndex].PreviousOutPoint.Hash {
return ErrInvalidSignatureForInput
}
// To validate that the redeem script matches, we must pull out
// the scriptPubKey of the corresponding output and compare
// that with the P2SH scriptPubKey that is generated by
// redeemScript.
if pInput.RedeemScript != nil {
outIndex := p.Upsbt.UnsignedTx.TxIn[inIndex].PreviousOutPoint.Index
scriptPubKey := pInput.NonWitnessUtxo.TxOut[outIndex].PkScript
scriptHash := btcutil.Hash160(pInput.RedeemScript)
scriptHashScript, err := txscript.NewScriptBuilder().
AddOp(txscript.OP_HASH160).
AddData(scriptHash).
AddOp(txscript.OP_EQUAL).
Script()
if err != nil {
return err
}
if !bytes.Equal(scriptHashScript, scriptPubKey) {
return ErrInvalidSignatureForInput
}
}
} else if pInput.WitnessUtxo != nil {
scriptPubKey := pInput.WitnessUtxo.PkScript
var script []byte
if pInput.RedeemScript != nil {
scriptHash := btcutil.Hash160(pInput.RedeemScript)
scriptHashScript, err := txscript.NewScriptBuilder().
AddOp(txscript.OP_HASH160).
AddData(scriptHash).
AddOp(txscript.OP_EQUAL).
Script()
if err != nil {
return err
}
if !bytes.Equal(scriptHashScript, scriptPubKey) {
return ErrInvalidSignatureForInput
}
script = pInput.RedeemScript
} else {
script = scriptPubKey
}
// If a witnessScript field is present, this is a P2WSH,
// whether nested or not (that is handled by the assignment to
// `script` above); in that case, sanity check that `script` is
// the p2wsh of witnessScript. Contrariwise, if no
// witnessScript field is present, this will be signed as
// p2wkh.
if pInput.WitnessScript != nil {
witnessScriptHash := sha256.Sum256(pInput.WitnessScript)
witnessScriptHashScript, err := txscript.NewScriptBuilder().
AddOp(txscript.OP_0).
AddData(witnessScriptHash[:]).
Script()
if err != nil {
return err
}
if !bytes.Equal(script, witnessScriptHashScript[:]) {
return ErrInvalidSignatureForInput
}
} else {
// Otherwise, this is a p2wkh input.
pubkeyHash := btcutil.Hash160(pubkey)
pubkeyHashScript, err := txscript.NewScriptBuilder().
AddOp(txscript.OP_0).
AddData(pubkeyHash).
Script()
if err != nil {
return err
}
// Validate that we're able to properly reconstruct the
// witness program.
if !bytes.Equal(pubkeyHashScript, script) {
return ErrInvalidSignatureForInput
}
}
} else {
// Attaching signature without utxo field is not allowed.
return ErrInvalidPsbtFormat
}
p.Upsbt.Inputs[inIndex].PartialSigs = append(
p.Upsbt.Inputs[inIndex].PartialSigs, &partialSig,
)
if err := p.Upsbt.SanityCheck(); err != nil {
return err
}
// Addition of a non-duplicate-key partial signature cannot violate
// sanity-check rules.
return nil
}
// AddInSighashType adds the sighash type information for an input. The
// sighash type is passed as a 32 bit unsigned integer, along with the index
// for the input. An error is returned if addition of this key-value pair to
// the Psbt fails.
func (p *Updater) AddInSighashType(sighashType txscript.SigHashType,
inIndex int) error {
p.Upsbt.Inputs[inIndex].SighashType = sighashType
if err := p.Upsbt.SanityCheck(); err != nil {
return err
}
return nil
}
// AddInRedeemScript adds the redeem script information for an input. The
// redeem script is passed serialized, as a byte slice, along with the index of
// the input. An error is returned if addition of this key-value pair to the
// Psbt fails.
func (p *Updater) AddInRedeemScript(redeemScript []byte,
inIndex int) error {
p.Upsbt.Inputs[inIndex].RedeemScript = redeemScript
if err := p.Upsbt.SanityCheck(); err != nil {
return ErrInvalidPsbtFormat
}
return nil
}
// AddInWitnessScript adds the witness script information for an input. The
// witness script is passed serialized, as a byte slice, along with the index
// of the input. An error is returned if addition of this key-value pair to the
// Psbt fails.
func (p *Updater) AddInWitnessScript(witnessScript []byte,
inIndex int) error {
p.Upsbt.Inputs[inIndex].WitnessScript = witnessScript
if err := p.Upsbt.SanityCheck(); err != nil {
return err
}
return nil
}
// AddInBip32Derivation takes a master key fingerprint as defined in BIP32, a
// BIP32 path as a slice of uint32 values, and a serialized pubkey as a byte
// slice, along with the integer index of the input, and inserts this data into
// that input.
//
// NOTE: This can be called multiple times for the same input. An error is
// returned if addition of this key-value pair to the Psbt fails.
func (p *Updater) AddInBip32Derivation(masterKeyFingerprint uint32,
bip32Path []uint32, pubKeyData []byte, inIndex int) error {
bip32Derivation := Bip32Derivation{
PubKey: pubKeyData,
MasterKeyFingerprint: masterKeyFingerprint,
Bip32Path: bip32Path,
}
if !bip32Derivation.checkValid() {
return ErrInvalidPsbtFormat
}
// Don't allow duplicate keys
for _, x := range p.Upsbt.Inputs[inIndex].Bip32Derivation {
if bytes.Equal(x.PubKey, bip32Derivation.PubKey) {
return ErrDuplicateKey
}
}
p.Upsbt.Inputs[inIndex].Bip32Derivation = append(
p.Upsbt.Inputs[inIndex].Bip32Derivation, &bip32Derivation,
)
if err := p.Upsbt.SanityCheck(); err != nil {
return err
}
return nil
}
// AddOutBip32Derivation takes a master key fingerprint as defined in BIP32, a
// BIP32 path as a slice of uint32 values, and a serialized pubkey as a byte
// slice, along with the integer index of the output, and inserts this data
// into that output.
//
// NOTE: That this can be called multiple times for the same output. An error
// is returned if addition of this key-value pair to the Psbt fails.
func (p *Updater) AddOutBip32Derivation(masterKeyFingerprint uint32,
bip32Path []uint32, pubKeyData []byte, outIndex int) error {
bip32Derivation := Bip32Derivation{
PubKey: pubKeyData,
MasterKeyFingerprint: masterKeyFingerprint,
Bip32Path: bip32Path,
}
if !bip32Derivation.checkValid() {
return ErrInvalidPsbtFormat
}
// Don't allow duplicate keys
for _, x := range p.Upsbt.Outputs[outIndex].Bip32Derivation {
if bytes.Equal(x.PubKey, bip32Derivation.PubKey) {
return ErrDuplicateKey
}
}
p.Upsbt.Outputs[outIndex].Bip32Derivation = append(
p.Upsbt.Outputs[outIndex].Bip32Derivation, &bip32Derivation,
)
if err := p.Upsbt.SanityCheck(); err != nil {
return err
}
return nil
}
// AddOutRedeemScript takes a redeem script as a byte slice and appends it to
// the output at index outIndex.
func (p *Updater) AddOutRedeemScript(redeemScript []byte,
outIndex int) error {
p.Upsbt.Outputs[outIndex].RedeemScript = redeemScript
if err := p.Upsbt.SanityCheck(); err != nil {
return ErrInvalidPsbtFormat
}
return nil
}
// AddOutWitnessScript takes a witness script as a byte slice and appends it to
// the output at index outIndex.
func (p *Updater) AddOutWitnessScript(witnessScript []byte,
outIndex int) error {
p.Upsbt.Outputs[outIndex].WitnessScript = witnessScript
if err := p.Upsbt.SanityCheck(); err != nil {
return err
}
return nil
}

277
vendor/github.com/btcsuite/btcutil/psbt/utils.go generated vendored Normal file
View File

@@ -0,0 +1,277 @@
// Copyright (c) 2018 The btcsuite developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package psbt
import (
"bytes"
"encoding/binary"
"errors"
"io"
"sort"
"github.com/btcsuite/btcd/txscript"
"github.com/btcsuite/btcd/wire"
)
// writeTxWitness is a A utility function due to non-exported witness
// serialization (writeTxWitness encodes the bitcoin protocol encoding for a
// transaction input's witness into w).
func writeTxWitness(w io.Writer, wit [][]byte) error {
if err := wire.WriteVarInt(w, 0, uint64(len(wit))); err != nil {
return err
}
for _, item := range wit {
err := wire.WriteVarBytes(w, 0, item)
if err != nil {
return err
}
}
return nil
}
// writePKHWitness writes a witness for a p2wkh spending input
func writePKHWitness(sig []byte, pub []byte) ([]byte, error) {
var (
buf bytes.Buffer
witnessItems = [][]byte{sig, pub}
)
if err := writeTxWitness(&buf, witnessItems); err != nil {
return nil, err
}
return buf.Bytes(), nil
}
// checkIsMultisigScript is a utility function to check whether a given
// redeemscript fits the standard multisig template used in all P2SH based
// multisig, given a set of pubkeys for redemption.
func checkIsMultiSigScript(pubKeys [][]byte, sigs [][]byte,
script []byte) bool {
// First insist that the script type is multisig.
if txscript.GetScriptClass(script) != txscript.MultiSigTy {
return false
}
// Inspect the script to ensure that the number of sigs and pubkeys is
// correct
numSigs, numPubKeys, err := txscript.CalcMultiSigStats(script)
if err != nil {
return false
}
// If the number of sigs provided, doesn't match the number of required
// pubkeys, then we can't proceed as we're not yet final.
if numPubKeys != len(pubKeys) || numSigs != len(sigs) {
return false
}
return true
}
// extractKeyOrderFromScript is a utility function to extract an ordered list
// of signatures, given a serialized script (redeemscript or witness script), a
// list of pubkeys and the signatures corresponding to those pubkeys. This
// function is used to ensure that the signatures will be embedded in the final
// scriptSig or scriptWitness in the correct order.
func extractKeyOrderFromScript(script []byte, expectedPubkeys [][]byte,
sigs [][]byte) ([][]byte, error) {
// If this isn't a proper finalized multi-sig script, then we can't
// proceed.
if !checkIsMultiSigScript(expectedPubkeys, sigs, script) {
return nil, ErrUnsupportedScriptType
}
// Arrange the pubkeys and sigs into a slice of format:
// * [[pub,sig], [pub,sig],..]
type sigWithPub struct {
pubKey []byte
sig []byte
}
var pubsSigs []sigWithPub
for i, pub := range expectedPubkeys {
pubsSigs = append(pubsSigs, sigWithPub{
pubKey: pub,
sig: sigs[i],
})
}
// Now that we have the set of (pubkey, sig) pairs, we'll construct a
// position map that we can use to swap the order in the slice above to
// match how things are laid out in the script.
type positionEntry struct {
index int
value sigWithPub
}
var positionMap []positionEntry
// For each pubkey in our pubsSigs slice, we'll now construct a proper
// positionMap entry, based on _where_ in the script the pubkey first
// appears.
for _, p := range pubsSigs {
pos := bytes.Index(script, p.pubKey)
if pos < 0 {
return nil, errors.New("script does not contain pubkeys")
}
positionMap = append(positionMap, positionEntry{
index: pos,
value: p,
})
}
// Now that we have the position map full populated, we'll use the
// index data to properly sort the entries in the map based on where
// they appear in the script.
sort.Slice(positionMap, func(i, j int) bool {
return positionMap[i].index < positionMap[j].index
})
// Finally, we can simply iterate through the position map in order to
// extract the proper signature ordering.
sortedSigs := make([][]byte, 0, len(positionMap))
for _, x := range positionMap {
sortedSigs = append(sortedSigs, x.value.sig)
}
return sortedSigs, nil
}
// getMultisigScriptWitness creates a full psbt serialized Witness field for
// the transaction, given the public keys and signatures to be appended. This
// function will only accept witnessScripts of the type M of N multisig. This
// is used for both p2wsh and nested p2wsh multisig cases.
func getMultisigScriptWitness(witnessScript []byte, pubKeys [][]byte,
sigs [][]byte) ([]byte, error) {
// First using the script as a guide, we'll properly order the sigs
// according to how their corresponding pubkeys appear in the
// witnessScript.
orderedSigs, err := extractKeyOrderFromScript(
witnessScript, pubKeys, sigs,
)
if err != nil {
return nil, err
}
// Now that we know the proper order, we'll append each of the
// signatures into a new witness stack, then top it off with the
// witness script at the end, prepending the nil as we need the extra
// pop..
witnessElements := make(wire.TxWitness, 0, len(sigs)+2)
witnessElements = append(witnessElements, nil)
for _, os := range orderedSigs {
witnessElements = append(witnessElements, os)
}
witnessElements = append(witnessElements, witnessScript)
// Now that we have the full witness stack, we'll serialize it in the
// expected format, and return the final bytes.
var buf bytes.Buffer
if err = writeTxWitness(&buf, witnessElements); err != nil {
return nil, err
}
return buf.Bytes(), nil
}
// checkSigHashFlags compares the sighash flag byte on a signature with the
// value expected according to any PsbtInSighashType field in this section of
// the PSBT, and returns true if they match, false otherwise.
// If no SighashType field exists, it is assumed to be SIGHASH_ALL.
//
// TODO(waxwing): sighash type not restricted to one byte in future?
func checkSigHashFlags(sig []byte, input *PInput) bool {
expectedSighashType := txscript.SigHashAll
if input.SighashType != 0 {
expectedSighashType = input.SighashType
}
return expectedSighashType == txscript.SigHashType(sig[len(sig)-1])
}
// serializeKVpair writes out a kv pair using a varbyte prefix for each.
func serializeKVpair(w io.Writer, key []byte, value []byte) error {
if err := wire.WriteVarBytes(w, 0, key); err != nil {
return err
}
return wire.WriteVarBytes(w, 0, value)
}
// serializeKVPairWithType writes out to the passed writer a type coupled with
// a key.
func serializeKVPairWithType(w io.Writer, kt uint8, keydata []byte,
value []byte) error {
// If the key has no data, then we write a blank slice.
if keydata == nil {
keydata = []byte{}
}
// The final key to be written is: {type} || {keyData}
serializedKey := append([]byte{byte(kt)}, keydata...)
return serializeKVpair(w, serializedKey, value)
}
// getKey retrieves a single key - both the key type and the keydata (if
// present) from the stream and returns the key type as an integer, or -1 if
// the key was of zero length. This integer is is used to indicate the presence
// of a separator byte which indicates the end of a given key-value pair list,
// and the keydata as a byte slice or nil if none is present.
func getKey(r io.Reader) (int, []byte, error) {
// For the key, we read the varint separately, instead of using the
// available ReadVarBytes, because we have a specific treatment of 0x00
// here:
count, err := wire.ReadVarInt(r, 0)
if err != nil {
return -1, nil, ErrInvalidPsbtFormat
}
if count == 0 {
// A separator indicates end of key-value pair list.
return -1, nil, nil
}
// Check that we don't attempt to decode a dangerously large key.
if count > MaxPsbtKeyLength {
return -1, nil, ErrInvalidKeydata
}
// Next, we ready out the designated number of bytes, which may include
// a type, key, and optional data.
keyTypeAndData := make([]byte, count)
if _, err := io.ReadFull(r, keyTypeAndData[:]); err != nil {
return -1, nil, err
}
keyType := int(string(keyTypeAndData)[0])
// Note that the second return value will usually be empty, since most
// keys contain no more than the key type byte.
if len(keyTypeAndData) == 1 {
return keyType, nil, nil
}
// Otherwise, we return the key, along with any data that it may
// contain.
return keyType, keyTypeAndData[1:], nil
}
// readTxOut is a limited version of wire.ReadTxOut, because the latter is not
// exported.
func readTxOut(txout []byte) (*wire.TxOut, error) {
if len(txout) < 10 {
return nil, ErrInvalidPsbtFormat
}
valueSer := binary.LittleEndian.Uint64(txout[:8])
scriptPubKey := txout[9:]
return wire.NewTxOut(int64(valueSer), scriptPubKey), nil
}