本文整理汇总了Golang中github.com/conformal/btcscript.PayToAddrScript函数的典型用法代码示例。如果您正苦于以下问题:Golang PayToAddrScript函数的具体用法?Golang PayToAddrScript怎么用?Golang PayToAddrScript使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。
在下文中一共展示了PayToAddrScript函数的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的Golang代码示例。
示例1: ExamplePayToAddrScript
// This example demonstrates creating a script which pays to a bitcoin address.
// It also prints the created script hex and uses the DisasmString function to
// display the disassembled script.
func ExamplePayToAddrScript() {
// Parse the address to send the coins to into a btcutil.Address
// which is useful to ensure the accuracy of the address and determine
// the address type. It is also required for the upcoming call to
// PayToAddrScript.
addressStr := "12gpXQVcCL2qhTNQgyLVdCFG2Qs2px98nV"
address, err := btcutil.DecodeAddress(addressStr, &btcnet.MainNetParams)
if err != nil {
fmt.Println(err)
return
}
// Create a public key script that pays to the address.
script, err := btcscript.PayToAddrScript(address)
if err != nil {
fmt.Println(err)
return
}
fmt.Printf("Script Hex: %x\n", script)
disasm, err := btcscript.DisasmString(script)
if err != nil {
fmt.Println(err)
return
}
fmt.Println("Script Disassembly:", disasm)
// Output:
// Script Hex: 76a914128004ff2fcaf13b2b91eb654b1dc2b674f7ec6188ac
// Script Disassembly: OP_DUP OP_HASH160 128004ff2fcaf13b2b91eb654b1dc2b674f7ec61 OP_EQUALVERIFY OP_CHECKSIG
}
示例2: createCoinbaseTx
// createCoinbaseTx returns a coinbase transaction paying an appropriate subsidy
// based on the passed block height to the provided address. When the address
// is nil, the coinbase transaction will instead be redeemable by anyone.
//
// See the comment for NewBlockTemplate for more information about why the nil
// address handling is useful.
func createCoinbaseTx(coinbaseScript []byte, nextBlockHeight int64, addr btcutil.Address) (*btcutil.Tx, error) {
// Create the script to pay to the provided payment address if one was
// specified. Otherwise create a script that allows the coinbase to be
// redeemable by anyone.
var pkScript []byte
if addr != nil {
var err error
pkScript, err = btcscript.PayToAddrScript(addr)
if err != nil {
return nil, err
}
} else {
scriptBuilder := btcscript.NewScriptBuilder()
pkScript = scriptBuilder.AddOp(btcscript.OP_TRUE).Script()
}
tx := btcwire.NewMsgTx()
tx.AddTxIn(&btcwire.TxIn{
// Coinbase transactions have no inputs, so previous outpoint is
// zero hash and max index.
PreviousOutPoint: *btcwire.NewOutPoint(&btcwire.ShaHash{},
btcwire.MaxPrevOutIndex),
SignatureScript: coinbaseScript,
Sequence: btcwire.MaxTxInSequenceNum,
})
tx.AddTxOut(&btcwire.TxOut{
Value: btcchain.CalcBlockSubsidy(nextBlockHeight,
activeNetParams.Params),
PkScript: pkScript,
})
return btcutil.NewTx(tx), nil
}
示例3: Build
func (fanB *FanOutBuilder) Build() (*btcwire.MsgTx, error) {
totalSpent := fanB.SatNeeded()
// Compose a set of Txins with enough to fund this transactions needs
inParamSet, totalIn, err := composeUnspents(
totalSpent,
fanB.Params)
if err != nil {
return nil, err
}
msgtx := btcwire.NewMsgTx()
// funding inputs speced out with blank
for _, inpParam := range inParamSet {
txin := btcwire.NewTxIn(inpParam.OutPoint, []byte{})
msgtx.AddTxIn(txin)
}
for i := range fanB.Builders {
builder := fanB.Builders[i]
amnt := builder.SatNeeded()
for j := int64(0); j < fanB.Copies; j++ {
addr, err := newAddr(fanB.Params.Client)
if err != nil {
return nil, err
}
script, _ := btcscript.PayToAddrScript(addr)
txout := btcwire.NewTxOut(amnt, script)
msgtx.AddTxOut(txout)
}
}
changeAddr, err := newAddr(fanB.Params.Client)
if err != nil {
return nil, err
}
// change to solve unevenness
change, ok := changeOutput(totalIn-totalSpent, fanB.Params.DustAmnt, changeAddr)
if ok {
msgtx.AddTxOut(change)
}
// sign msgtx for each input
for i, inpParam := range inParamSet {
privkey := inpParam.Wif.PrivKey
subscript := inpParam.TxOut.PkScript
sigflag := btcscript.SigHashAll
scriptSig, err := btcscript.SignatureScript(msgtx, i, subscript,
sigflag, privkey, true)
if err != nil {
return nil, err
}
msgtx.TxIn[i].SignatureScript = scriptSig
}
fanB.Log(fmt.Sprintf("InVal: %d\n", sumInputs(inParamSet)))
fanB.Log(fmt.Sprintf("OutVal: %d\n", sumOutputs(msgtx)))
return msgtx, nil
}
示例4: changeOutput
// generates a change output funding provided addr
func changeOutput(change, dustAmnt int64, addr btcutil.Address) (*btcwire.TxOut, bool) {
if change < dustAmnt {
return nil, false
}
script, _ := btcscript.PayToAddrScript(addr)
txout := btcwire.NewTxOut(change, script)
return txout, true
}
示例5: TestFakeTxs
func TestFakeTxs(t *testing.T) {
// First we need a wallet.
w, err := wallet.NewWallet("banana wallet", "", []byte("banana"),
btcwire.MainNet, &wallet.BlockStamp{}, 100)
if err != nil {
t.Errorf("Can not create encrypted wallet: %s", err)
return
}
a := &Account{
Wallet: w,
lockedOutpoints: map[btcwire.OutPoint]struct{}{},
}
w.Unlock([]byte("banana"))
// Create and add a fake Utxo so we have some funds to spend.
//
// This will pass validation because btcscript is unaware of invalid
// tx inputs, however, this example would fail in btcd.
utxo := &tx.Utxo{}
addr, err := w.NextChainedAddress(&wallet.BlockStamp{}, 100)
if err != nil {
t.Errorf("Cannot get next address: %s", err)
return
}
copy(utxo.AddrHash[:], addr.ScriptAddress())
ophash := (btcwire.ShaHash)([...]byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,
12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27,
28, 29, 30, 31, 32})
out := btcwire.NewOutPoint(&ophash, 0)
utxo.Out = tx.OutPoint(*out)
ss, err := btcscript.PayToAddrScript(addr)
if err != nil {
t.Errorf("Could not create utxo PkScript: %s", err)
return
}
utxo.Subscript = tx.PkScript(ss)
utxo.Amt = 1000000
utxo.Height = 12345
a.UtxoStore = append(a.UtxoStore, utxo)
// Fake our current block height so btcd doesn't need to be queried.
curBlock.BlockStamp.Height = 12346
// Create the transaction.
pairs := map[string]int64{
"17XhEvq9Nahdj7Xe1nv6oRe1tEmaHUuynH": 5000,
}
_, err = a.txToPairs(pairs, 1)
if err != nil {
t.Errorf("Tx creation failed: %s", err)
return
}
}
示例6: PayToAddrScript
func PayToAddrScript(addressStr string) {
// Parse the address to send the coins to into a btcutil.Address
// which is useful to ensure the accuracy of the address and determine
// the address type. It is also required for the upcoming call to
// PayToAddrScript.
address, err := btcutil.DecodeAddress(addressStr, &btcnet.MainNetParams)
handle(err)
// Create a public key script that pays to the address.
script, err := btcscript.PayToAddrScript(address)
handle(err)
fmt.Printf("Script Hex: %x\n", script)
disasm, err := btcscript.DisasmString(script)
handle(err)
fmt.Println("Script Disassembly:", disasm)
}
示例7: Build
func (builder *ToAddrBuilder) Build() (*btcwire.MsgTx, error) {
utxo, err := selectUnspent(builder.SatNeeded(), builder.Params)
if err != nil {
return nil, err
}
txin := btcwire.NewTxIn(utxo.OutPoint, []byte{})
msgtx := btcwire.NewMsgTx()
msgtx.AddTxIn(txin)
// add send to addr
valout := builder.Params.InTarget - builder.Params.Fee
outscript, _ := btcscript.PayToAddrScript(builder.Addr)
txout := btcwire.NewTxOut(valout, outscript)
msgtx.AddTxOut(txout)
// add send to change addr
total := utxo.TxOut.Value
changeval := total - builder.SatNeeded()
if changeval > builder.Params.DustAmnt {
// Change needed
changeAddr, err := builder.Params.Client.GetNewAddress()
if err != nil {
return nil, err
}
change, ok := changeOutput(changeval, builder.Params.DustAmnt, changeAddr)
if ok {
msgtx.AddTxOut(change)
}
}
subscript := utxo.TxOut.PkScript
privkey := utxo.Wif.PrivKey
scriptSig, err := btcscript.SignatureScript(msgtx, 0, subscript, btcscript.SigHashAll, privkey, true)
if err != nil {
return nil, err
}
txin.SignatureScript = scriptSig
return msgtx, nil
}
示例8: Build
// A transaction that contains only dust ouputs and obeys the TxBuilder interface
func (builder *DustBuilder) Build() (*btcwire.MsgTx, error) {
var inparams *TxInParams
var err error
inparams, err = specificUnspent(
builder.SatNeeded(),
builder.Params)
if err != nil {
return nil, err
}
oldTxOut := inparams.TxOut
outpoint := inparams.OutPoint
wifkey := inparams.Wif
msgtx := btcwire.NewMsgTx()
txin := btcwire.NewTxIn(outpoint, []byte{})
msgtx.AddTxIn(txin)
for i := int64(0); i < builder.NumOuts; i++ {
dumb := bytes.Repeat([]byte{66}, 20)
addr := dataAddr(dumb, builder.Params.NetParams)
addrScript, err := btcscript.PayToAddrScript(addr)
if err != nil {
return nil, err
}
txOut := btcwire.NewTxOut(builder.Params.DustAmnt, addrScript)
msgtx.AddTxOut(txOut)
}
// sign as usual
privkey := wifkey.PrivKey
sig, err := btcscript.SignatureScript(msgtx, 0, oldTxOut.PkScript, btcscript.SigHashAll, privkey, true)
if err != nil {
return nil, err
}
txin.SignatureScript = sig
return msgtx, nil
}
示例9: TxOuts
// Converts a bulletin into public key scripts for encoding
func (bltn *Bulletin) TxOuts(toBurn int64, net *btcnet.Params) ([]*btcwire.TxOut, error) {
rawbytes, err := bltn.Bytes()
if err != nil {
return []*btcwire.TxOut{}, err
}
numcuts, _ := bltn.NumOuts()
cuts := make([][]byte, numcuts, numcuts)
for i := 0; i < numcuts; i++ {
sliceb := make([]byte, 20, 20)
copy(sliceb, rawbytes)
cuts[i] = sliceb
if len(rawbytes) >= 20 {
rawbytes = rawbytes[20:]
}
}
// Convert raw data into txouts
txouts := make([]*btcwire.TxOut, 0)
for _, cut := range cuts {
fakeaddr, err := btcutil.NewAddressPubKeyHash(cut, net)
if err != nil {
return []*btcwire.TxOut{}, err
}
pkscript, err := btcscript.PayToAddrScript(fakeaddr)
if err != nil {
return []*btcwire.TxOut{}, err
}
txout := &btcwire.TxOut{
PkScript: pkscript,
Value: toBurn,
}
txouts = append(txouts, txout)
}
return txouts, nil
}
示例10: Build
func (pkhB *PubKeyHashBuilder) Build() (*btcwire.MsgTx, error) {
inparams, err := specificUnspent(pkhB.SatNeeded(), pkhB.Params)
if err != nil {
return nil, err
}
msgtx := btcwire.NewMsgTx()
txin := btcwire.NewTxIn(inparams.OutPoint, []byte{})
msgtx.AddTxIn(txin)
for i := int64(0); i < pkhB.NumOuts; i++ {
addr, err := newAddr(pkhB.Params.Client)
if err != nil {
return nil, err
}
addrScript, err := btcscript.PayToAddrScript(addr)
amntSend := pkhB.eachOutVal()
if amntSend < pkhB.Params.DustAmnt {
return nil, errors.New("Output would be under the dust limit")
}
txout := btcwire.NewTxOut(pkhB.eachOutVal(), addrScript)
msgtx.AddTxOut(txout)
}
privkey := inparams.Wif.PrivKey
sig, err := btcscript.SignatureScript(msgtx,
0,
inparams.TxOut.PkScript,
btcscript.SigHashAll,
privkey,
true)
if err != nil {
return nil, err
}
txin.SignatureScript = sig
return msgtx, nil
}
示例11: createCoinbaseTx
// createCoinbaseTx returns a coinbase transaction paying an appropriate subsidy
// based on the passed block height to the passed public key. It also accepts
// an extra nonce value for the signature script. This extra nonce helps ensure
// the transaction is not a duplicate transaction (paying the same value to the
// same public key address would otherwise be an identical transaction for
// block version 1).
func createCoinbaseTx(coinbaseScript []byte, nextBlockHeight int64, addr btcutil.Address) (*btcutil.Tx, error) {
// Create a script to pay to the specific address.
pkScript, err := btcscript.PayToAddrScript(addr)
if err != nil {
return nil, err
}
tx := btcwire.NewMsgTx()
tx.AddTxIn(&btcwire.TxIn{
// Coinbase transactions have no inputs, so previous outpoint is
// zero hash and max index.
PreviousOutpoint: *btcwire.NewOutPoint(&btcwire.ShaHash{},
btcwire.MaxPrevOutIndex),
SignatureScript: coinbaseScript,
Sequence: btcwire.MaxTxInSequenceNum,
})
tx.AddTxOut(&btcwire.TxOut{
Value: btcchain.CalcBlockSubsidy(nextBlockHeight,
activeNetParams.Params),
PkScript: pkScript,
})
return btcutil.NewTx(tx), nil
}
示例12: txToPairs
// txToPairs creates a raw transaction sending the amounts for each
// address/amount pair and fee to each address and the miner. minconf
// specifies the minimum number of confirmations required before an
// unspent output is eligible for spending. Leftover input funds not sent
// to addr or as a fee for the miner are sent to a newly generated
// address. If change is needed to return funds back to an owned
// address, changeUtxo will point to a unconfirmed (height = -1, zeroed
// block hash) Utxo. ErrInsufficientFunds is returned if there are not
// enough eligible unspent outputs to create the transaction.
func (a *Account) txToPairs(pairs map[string]btcutil.Amount,
minconf int) (*CreatedTx, error) {
// Wallet must be unlocked to compose transaction.
if a.IsLocked() {
return nil, wallet.ErrWalletLocked
}
// Create a new transaction which will include all input scripts.
msgtx := btcwire.NewMsgTx()
// Calculate minimum amount needed for inputs.
var amt btcutil.Amount
for _, v := range pairs {
// Error out if any amount is negative.
if v <= 0 {
return nil, ErrNonPositiveAmount
}
amt += v
}
// Add outputs to new tx.
for addrStr, amt := range pairs {
addr, err := btcutil.DecodeAddress(addrStr, cfg.Net())
if err != nil {
return nil, fmt.Errorf("cannot decode address: %s", err)
}
// Add output to spend amt to addr.
pkScript, err := btcscript.PayToAddrScript(addr)
if err != nil {
return nil, fmt.Errorf("cannot create txout script: %s", err)
}
txout := btcwire.NewTxOut(int64(amt), pkScript)
msgtx.AddTxOut(txout)
}
// Get current block's height and hash.
bs, err := GetCurBlock()
if err != nil {
return nil, err
}
// Make a copy of msgtx before any inputs are added. This will be
// used as a starting point when trying a fee and starting over with
// a higher fee if not enough was originally chosen.
txNoInputs := msgtx.Copy()
unspent, err := a.TxStore.UnspentOutputs()
if err != nil {
return nil, err
}
var selectedInputs []*txstore.Credit
// These are nil/zeroed until a change address is needed, and reused
// again in case a change utxo has already been chosen.
var changeAddr btcutil.Address
// Get the number of satoshis to increment fee by when searching for
// the minimum tx fee needed.
fee := btcutil.Amount(0)
for {
msgtx = txNoInputs.Copy()
// Select unspent outputs to be used in transaction based on the amount
// neededing to sent, and the current fee estimation.
inputs, btcin, err := selectInputs(unspent, amt+fee, minconf)
if err != nil {
return nil, err
}
// Check if there are leftover unspent outputs, and return coins back to
// a new address we own.
//
// TODO: change needs to be inserted into a random txout index, or else
// this is a privacy risk.
change := btcin - amt - fee
if change > 0 {
// Get a new change address if one has not already been found.
if changeAddr == nil {
changeAddr, err = a.ChangeAddress(&bs, cfg.KeypoolSize)
if err != nil {
return nil, fmt.Errorf("failed to get next address: %s", err)
}
// Mark change address as belonging to this account.
AcctMgr.MarkAddressForAccount(changeAddr, a)
}
// Spend change.
pkScript, err := btcscript.PayToAddrScript(changeAddr)
//.........这里部分代码省略.........
示例13: handleCreateRawTransaction
// handleCreateRawTransaction handles createrawtransaction commands.
func handleCreateRawTransaction(s *rpcServer, cmd btcjson.Cmd) (interface{}, error) {
c := cmd.(*btcjson.CreateRawTransactionCmd)
// Add all transaction inputs to a new transaction after performing
// some validity checks.
mtx := btcwire.NewMsgTx()
for _, input := range c.Inputs {
txHash, err := btcwire.NewShaHashFromStr(input.Txid)
if err != nil {
return nil, btcjson.ErrDecodeHexString
}
if input.Vout < 0 {
return nil, btcjson.Error{
Code: btcjson.ErrInvalidParameter.Code,
Message: "Invalid parameter, vout must be positive",
}
}
prevOut := btcwire.NewOutPoint(txHash, uint32(input.Vout))
txIn := btcwire.NewTxIn(prevOut, []byte{})
mtx.AddTxIn(txIn)
}
// Add all transaction outputs to the transaction after performing
// some validity checks.
for encodedAddr, amount := range c.Amounts {
// Ensure amount is in the valid range for monetary amounts.
if amount <= 0 || amount > btcutil.MaxSatoshi {
return nil, btcjson.Error{
Code: btcjson.ErrType.Code,
Message: "Invalid amount",
}
}
// Decode the provided address.
addr, err := btcutil.DecodeAddress(encodedAddr,
activeNetParams.btcnet)
if err != nil {
return nil, btcjson.Error{
Code: btcjson.ErrInvalidAddressOrKey.Code,
Message: btcjson.ErrInvalidAddressOrKey.Message +
": " + err.Error(),
}
}
// Ensure the address is one of the supported types and that
// the network encoded with the address matches the network the
// server is currently on.
switch addr.(type) {
case *btcutil.AddressPubKeyHash:
case *btcutil.AddressScriptHash:
default:
return nil, btcjson.ErrInvalidAddressOrKey
}
if !addr.IsForNet(s.server.btcnet) {
return nil, btcjson.Error{
Code: btcjson.ErrInvalidAddressOrKey.Code,
Message: fmt.Sprintf("%s: %q",
btcjson.ErrInvalidAddressOrKey.Message,
encodedAddr),
}
}
// Create a new script which pays to the provided address.
pkScript, err := btcscript.PayToAddrScript(addr)
if err != nil {
return nil, btcjson.Error{
Code: btcjson.ErrInternal.Code,
Message: err.Error(),
}
}
txOut := btcwire.NewTxOut(amount, pkScript)
mtx.AddTxOut(txOut)
}
// Return the serialized and hex-encoded transaction.
mtxHex, err := messageToHex(mtx)
if err != nil {
return nil, err
}
return mtxHex, nil
}
示例14: txToPairs
// txToPairs creates a raw transaction sending the amounts for each
// address/amount pair and fee to each address and the miner. minconf
// specifies the minimum number of confirmations required before an
// unspent output is eligible for spending. Leftover input funds not sent
// to addr or as a fee for the miner are sent to a newly generated
// address. If change is needed to return funds back to an owned
// address, changeUtxo will point to a unconfirmed (height = -1, zeroed
// block hash) Utxo. ErrInsufficientFunds is returned if there are not
// enough eligible unspent outputs to create the transaction.
func (a *Account) txToPairs(pairs map[string]btcutil.Amount,
minconf int) (*CreatedTx, error) {
// Wallet must be unlocked to compose transaction.
if a.IsLocked() {
return nil, wallet.ErrWalletLocked
}
// Create a new transaction which will include all input scripts.
msgtx := btcwire.NewMsgTx()
// Calculate minimum amount needed for inputs.
var amt btcutil.Amount
for _, v := range pairs {
// Error out if any amount is negative.
if v <= 0 {
return nil, ErrNonPositiveAmount
}
amt += v
}
// Add outputs to new tx.
for addrStr, amt := range pairs {
addr, err := btcutil.DecodeAddress(addrStr, activeNet.Params)
if err != nil {
return nil, fmt.Errorf("cannot decode address: %s", err)
}
// Add output to spend amt to addr.
pkScript, err := btcscript.PayToAddrScript(addr)
if err != nil {
return nil, fmt.Errorf("cannot create txout script: %s", err)
}
txout := btcwire.NewTxOut(int64(amt), pkScript)
msgtx.AddTxOut(txout)
}
// Get current block's height and hash.
bs, err := GetCurBlock()
if err != nil {
return nil, err
}
// Make a copy of msgtx before any inputs are added. This will be
// used as a starting point when trying a fee and starting over with
// a higher fee if not enough was originally chosen.
txNoInputs := msgtx.Copy()
unspent, err := a.TxStore.UnspentOutputs()
if err != nil {
return nil, err
}
// Filter out unspendable outputs, that is, remove those that (at this
// time) are not P2PKH outputs. Other inputs must be manually included
// in transactions and sent (for example, using createrawtransaction,
// signrawtransaction, and sendrawtransaction).
eligible := make([]txstore.Credit, 0, len(unspent))
for i := range unspent {
switch btcscript.GetScriptClass(unspent[i].TxOut().PkScript) {
case btcscript.PubKeyHashTy:
if !unspent[i].Confirmed(minconf, bs.Height) {
continue
}
// Coinbase transactions must have have reached maturity
// before their outputs may be spent.
if unspent[i].IsCoinbase() {
target := btcchain.CoinbaseMaturity
if !unspent[i].Confirmed(target, bs.Height) {
continue
}
}
// Locked unspent outputs are skipped.
if a.LockedOutpoint(*unspent[i].OutPoint()) {
continue
}
eligible = append(eligible, unspent[i])
}
}
// Sort eligible inputs, as selectInputs expects these to be sorted
// by amount in reverse order.
sort.Sort(sort.Reverse(ByAmount(eligible)))
var selectedInputs []txstore.Credit
// changeAddr is nil/zeroed until a change address is needed, and reused
// again in case a change utxo has already been chosen.
var changeAddr btcutil.Address
//.........这里部分代码省略.........
示例15: txToPairs
// txToPairs creates a raw transaction sending the amounts for each
// address/amount pair and fee to each address and the miner. minconf
// specifies the minimum number of confirmations required before an
// unspent output is eligible for spending. Leftover input funds not sent
// to addr or as a fee for the miner are sent to a newly generated
// address. If change is needed to return funds back to an owned
// address, changeUtxo will point to a unconfirmed (height = -1, zeroed
// block hash) Utxo. ErrInsufficientFunds is returned if there are not
// enough eligible unspent outputs to create the transaction.
func (a *Account) txToPairs(pairs map[string]int64, minconf int) (*CreatedTx, error) {
// Create a new transaction which will include all input scripts.
msgtx := btcwire.NewMsgTx()
// Calculate minimum amount needed for inputs.
var amt int64
for _, v := range pairs {
// Error out if any amount is negative.
if v <= 0 {
return nil, ErrNonPositiveAmount
}
amt += v
}
// outputs is a tx.Pair slice representing each output that is created
// by the transaction.
outputs := make([]tx.Pair, 0, len(pairs)+1)
// Add outputs to new tx.
for addrStr, amt := range pairs {
addr, err := btcutil.DecodeAddr(addrStr)
if err != nil {
return nil, fmt.Errorf("cannot decode address: %s", err)
}
// Add output to spend amt to addr.
pkScript, err := btcscript.PayToAddrScript(addr)
if err != nil {
return nil, fmt.Errorf("cannot create txout script: %s", err)
}
txout := btcwire.NewTxOut(int64(amt), pkScript)
msgtx.AddTxOut(txout)
// Create amount, address pair and add to outputs.
out := tx.Pair{
Amount: amt,
PubkeyHash: addr.ScriptAddress(),
}
outputs = append(outputs, out)
}
// Get current block's height and hash.
bs, err := GetCurBlock()
if err != nil {
return nil, err
}
// Make a copy of msgtx before any inputs are added. This will be
// used as a starting point when trying a fee and starting over with
// a higher fee if not enough was originally chosen.
txNoInputs := msgtx.Copy()
// These are nil/zeroed until a change address is needed, and reused
// again in case a change utxo has already been chosen.
var changeAddr *btcutil.AddressPubKeyHash
var btcspent int64
var selectedInputs []*tx.Utxo
var finalChangeUtxo *tx.Utxo
// Get the number of satoshis to increment fee by when searching for
// the minimum tx fee needed.
fee := int64(0)
for {
msgtx = txNoInputs.Copy()
// Select unspent outputs to be used in transaction based on the amount
// neededing to sent, and the current fee estimation.
inputs, btcin, err := selectInputs(a.UtxoStore, uint64(amt+fee),
minconf)
if err != nil {
return nil, err
}
// Check if there are leftover unspent outputs, and return coins back to
// a new address we own.
var changeUtxo *tx.Utxo
change := btcin - uint64(amt+fee)
if change > 0 {
// Create a new address to spend leftover outputs to.
// Get a new change address if one has not already been found.
if changeAddr == nil {
changeAddr, err = a.ChangeAddress(&bs, cfg.KeypoolSize)
if err != nil {
return nil, fmt.Errorf("failed to get next address: %s", err)
}
// Mark change address as belonging to this account.
MarkAddressForAccount(changeAddr.EncodeAddress(), a.Name())
}
//.........这里部分代码省略.........