本文整理汇总了Golang中github.com/conformal/btcwire.NewTxIn函数的典型用法代码示例。如果您正苦于以下问题:Golang NewTxIn函数的具体用法?Golang NewTxIn怎么用?Golang NewTxIn使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。
在下文中一共展示了NewTxIn函数的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的Golang代码示例。
示例1: makeTx
func makeTx(outputs []output, amount, value int64, toAddr, changeAddr string) (*btcwire.MsgTx, error) {
msgTx := btcwire.NewMsgTx()
for _, op := range outputs {
hash, err := btcwire.NewShaHashFromStr(op.TxHash)
if err != nil {
return nil, err
}
b, err := hex.DecodeString(op.Script)
if err != nil {
return nil, err
}
txIn := btcwire.NewTxIn(btcwire.NewOutPoint(hash, op.TxN), b)
msgTx.AddTxIn(txIn)
}
script, err := makeScriptPubKey(toAddr)
if err != nil {
return nil, err
}
txOut := btcwire.NewTxOut(value, script)
msgTx.AddTxOut(txOut)
if amount > value {
script, err = makeScriptPubKey(changeAddr)
if err != nil {
return nil, err
}
txOut := btcwire.NewTxOut(amount-value, script)
msgTx.AddTxOut(txOut)
}
return msgTx, nil
}
示例2: Build
func (bltnB *BulletinBuilder) Build() (*btcwire.MsgTx, error) {
utxo, err := selectUnspent(bltnB.SatNeeded(), bltnB.Params)
if err != nil {
return nil, err
}
msgtx := btcwire.NewMsgTx()
// Add data storing txouts.
txouts, err := bltnB.Bulletin.TxOuts(bltnB.BurnAmnt, bltnB.Params.NetParams)
if err != nil {
return nil, err
}
msgtx.TxOut = txouts
txin := btcwire.NewTxIn(utxo.OutPoint, []byte{})
msgtx.AddTxIn(txin)
// Deal with change
changeAmnt := utxo.TxOut.Value - bltnB.SatNeeded()
if changeAmnt > bltnB.Params.DustAmnt {
changeOut, err := makeChange(changeAmnt, bltnB.Params)
if err != nil {
return nil, err
}
msgtx.AddTxOut(changeOut)
}
// Sign the Bulletin
privkey := utxo.Wif.PrivKey
scriptSig, err := btcscript.SignatureScript(msgtx, 0, utxo.TxOut.PkScript, btcscript.SigHashAll, privkey, true)
if err != nil {
return nil, err
}
txin.SignatureScript = scriptSig
return msgtx, 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: Build
func (shsB *SigHashSingleBuilder) Build() (*btcwire.MsgTx, error) {
// RPC to setup previous TX
utxo, err := selectUnspent(shsB.SatNeeded()+shsB.Params.DustAmnt, shsB.Params)
if err != nil {
return nil, err
}
oldTxOut := utxo.TxOut
outpoint := utxo.OutPoint
wifkey := utxo.Wif
// Transaction building
txin := btcwire.NewTxIn(outpoint, []byte{})
// notice amount in
total := oldTxOut.Value
changeval := total - (shsB.SatNeeded())
change, ok := changeOutput(changeval, shsB.Params.DustAmnt,
wifToAddr(wifkey, shsB.Params.NetParams))
if !ok {
return nil, errors.New("Not enough for change.")
}
// Blank permutable txout for users to play with
blankval := shsB.Params.InTarget - shsB.Params.Fee
blank := btcwire.NewTxOut(blankval, change.PkScript) //[]byte{})
msgtx := btcwire.NewMsgTx()
msgtx.AddTxIn(txin)
msgtx.AddTxOut(change)
msgtx.AddTxOut(blank)
subscript := oldTxOut.PkScript
privkey := wifkey.PrivKey
scriptSig, err := btcscript.SignatureScript(msgtx, 0, subscript, btcscript.SigHashSingle, privkey, true)
if err != nil {
return nil, err
}
msgtx.TxIn[0].SignatureScript = scriptSig
// This demonstrates that we can sign and then permute a txout
//msgtx.TxOut[1].PkScript = oldTxOut.PkScript
blank.Value = blankval + 1
return msgtx, nil
}
示例5: TestCheckSerializedHeight
// TestCheckSerializedHeight tests the checkSerializedHeight function with
// various serialized heights and also does negative tests to ensure errors
// and handled properly.
func TestCheckSerializedHeight(t *testing.T) {
// Create an empty coinbase template to be used in the tests below.
coinbaseOutpoint := btcwire.NewOutPoint(&btcwire.ShaHash{}, math.MaxUint32)
coinbaseTx := btcwire.NewMsgTx()
coinbaseTx.Version = 2
coinbaseTx.AddTxIn(btcwire.NewTxIn(coinbaseOutpoint, nil))
//
tests := []struct {
sigScript []byte // Serialized data
wantHeight int64 // Expected height
err error // Expected error type
}{
// No serialized height length.
{[]byte{}, 0, btcchain.RuleError("")},
// Serialized height length with no height bytes.
{[]byte{0x02}, 0, btcchain.RuleError("")},
// Serialized height length with too few height bytes.
{[]byte{0x02, 0x4a}, 0, btcchain.RuleError("")},
// Serialized height that needs 2 bytes to encode.
{[]byte{0x02, 0x4a, 0x52}, 21066, nil},
// Serialized height that needs 2 bytes to encode, but backwards
// endianness.
{[]byte{0x02, 0x4a, 0x52}, 19026, btcchain.RuleError("")},
// Serialized height that needs 3 bytes to encode.
{[]byte{0x03, 0x40, 0x0d, 0x03}, 200000, nil},
// Serialized height that needs 3 bytes to encode, but backwards
// endianness.
{[]byte{0x03, 0x40, 0x0d, 0x03}, 1074594560, btcchain.RuleError("")},
}
t.Logf("Running %d tests", len(tests))
for i, test := range tests {
msgTx := coinbaseTx.Copy()
msgTx.TxIn[0].SignatureScript = test.sigScript
tx := btcutil.NewTx(msgTx)
err := btcchain.TstCheckSerializedHeight(tx, test.wantHeight)
if reflect.TypeOf(err) != reflect.TypeOf(test.err) {
t.Errorf("checkSerializedHeight #%d wrong error type "+
"got: %v <%T>, want: %T", i, err, err, test.err)
continue
}
}
}
示例6: 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
}
示例7: Build
func (ndB *NullDataBuilder) Build() (*btcwire.MsgTx, error) {
utxo, err := specificUnspent(ndB.SatNeeded(), ndB.Params)
if err != nil {
return nil, err
}
msgtx := btcwire.NewMsgTx()
if len(ndB.Data) > 40 {
return nil, errors.New("Data is too long to make this a standard tx.")
}
// OP Return output
retbuilder := btcscript.NewScriptBuilder().AddOp(btcscript.OP_RETURN).AddData(ndB.Data)
op_return := btcwire.NewTxOut(0, retbuilder.Script())
msgtx.AddTxOut(op_return)
if ndB.Change {
// change ouput
addr, _ := newAddr(ndB.Params.Client)
change, ok := changeOutput(ndB.SatNeeded()-ndB.Params.Fee, ndB.Params.DustAmnt, addr)
if !ok {
return nil, errors.New("Not enough for change")
}
msgtx.AddTxOut(change)
}
// funding input
txin := btcwire.NewTxIn(utxo.OutPoint, []byte{})
msgtx.AddTxIn(txin)
// sign msgtx
privkey := utxo.Wif.PrivKey
scriptSig, err := btcscript.SignatureScript(msgtx, 0, utxo.TxOut.PkScript, 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: 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
}
示例10: Build
// TODO This will add multisig Txouts to the unspent set be AWARE
func (msB *MultiSigBuilder) Build() (*btcwire.MsgTx, error) {
utxo, err := specificUnspent(msB.SatNeeded(), msB.Params)
if err != nil {
return nil, err
}
msgtx := btcwire.NewMsgTx()
txin := btcwire.NewTxIn(utxo.OutPoint, []byte{})
msgtx.AddTxIn(txin)
for _, pubkeys := range msB.PubKeyList {
// M pubkey pubkey pubkey N OP_CHECKMULTISIG
scriptBuilder := btcscript.NewScriptBuilder().AddInt64(msB.M)
for _, pk := range pubkeys {
scriptBuilder = scriptBuilder.AddData(pk)
}
scriptBuilder = scriptBuilder.AddInt64(msB.N).AddOp(btcscript.OP_CHECKMULTISIG)
PkScript := scriptBuilder.Script()
txout := btcwire.NewTxOut(msB.eachOutVal(), PkScript)
msgtx.AddTxOut(txout)
}
// Sign this puppy
privkey := utxo.Wif.PrivKey
subscript := utxo.TxOut.PkScript
sigflag := btcscript.SigHashAll
scriptSig, err := btcscript.SignatureScript(msgtx, 0, subscript,
sigflag, privkey, true)
if err != nil {
return nil, err
}
msgtx.TxIn[0].SignatureScript = scriptSig
return msgtx, nil
}
示例11: txToPairs
//.........这里部分代码省略.........
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)
if err != nil {
return nil, fmt.Errorf("cannot create txout script: %s", err)
}
msgtx.AddTxOut(btcwire.NewTxOut(int64(change), pkScript))
}
// Selected unspent outputs become new transaction's inputs.
for _, ip := range inputs {
msgtx.AddTxIn(btcwire.NewTxIn(ip.OutPoint(), nil))
}
for i, input := range inputs {
_, addrs, _, _ := input.Addresses(cfg.Net())
if len(addrs) != 1 {
continue
}
apkh, ok := addrs[0].(*btcutil.AddressPubKeyHash)
if !ok {
continue // don't handle inputs to this yes
}
ai, err := a.Address(apkh)
if err != nil {
return nil, fmt.Errorf("cannot get address info: %v", err)
}
pka := ai.(wallet.PubKeyAddress)
privkey, err := pka.PrivKey()
if err == wallet.ErrWalletLocked {
return nil, wallet.ErrWalletLocked
} else if err != nil {
return nil, fmt.Errorf("cannot get address key: %v", err)
}
sigscript, err := btcscript.SignatureScript(msgtx, i,
input.TxOut().PkScript, btcscript.SigHashAll, privkey,
ai.Compressed())
if err != nil {
return nil, fmt.Errorf("cannot create sigscript: %s", err)
}
msgtx.TxIn[i].SignatureScript = sigscript
示例12: TestTx
// TestTx tests the MsgTx API.
func TestTx(t *testing.T) {
pver := btcwire.ProtocolVersion
// Block 100000 hash.
hashStr := "3ba27aa200b1cecaad478d2b00432346c3f1f3986da1afd33e506"
hash, err := btcwire.NewShaHashFromStr(hashStr)
if err != nil {
t.Errorf("NewShaHashFromStr: %v", err)
}
// Ensure the command is expected value.
wantCmd := "tx"
msg := btcwire.NewMsgTx()
if cmd := msg.Command(); cmd != wantCmd {
t.Errorf("NewMsgAddr: wrong command - got %v want %v",
cmd, wantCmd)
}
// Ensure max payload is expected value for latest protocol version.
// Num addresses (varInt) + max allowed addresses.
wantPayload := uint32(1000 * 1000)
maxPayload := msg.MaxPayloadLength(pver)
if maxPayload != wantPayload {
t.Errorf("MaxPayloadLength: wrong max payload length for "+
"protocol version %d - got %v, want %v", pver,
maxPayload, wantPayload)
}
// Ensure we get the same transaction output point data back out.
prevOutIndex := uint32(1)
prevOut := btcwire.NewOutPoint(hash, prevOutIndex)
if !prevOut.Hash.IsEqual(hash) {
t.Errorf("NewOutPoint: wrong hash - got %v, want %v",
spew.Sprint(&prevOut.Hash), spew.Sprint(hash))
}
if prevOut.Index != prevOutIndex {
t.Errorf("NewOutPoint: wrong index - got %v, want %v",
prevOut.Index, prevOutIndex)
}
// Ensure we get the same transaction input back out.
sigScript := []byte{0x04, 0x31, 0xdc, 0x00, 0x1b, 0x01, 0x62}
txIn := btcwire.NewTxIn(prevOut, sigScript)
if !reflect.DeepEqual(&txIn.PreviousOutpoint, prevOut) {
t.Errorf("NewTxIn: wrong prev outpoint - got %v, want %v",
spew.Sprint(&txIn.PreviousOutpoint),
spew.Sprint(prevOut))
}
if !bytes.Equal(txIn.SignatureScript, sigScript) {
t.Errorf("NewTxIn: wrong signature script - got %v, want %v",
spew.Sdump(txIn.SignatureScript),
spew.Sdump(sigScript))
}
// Ensure we get the same transaction output back out.
txValue := int64(5000000000)
pkScript := []byte{
0x41, // OP_DATA_65
0x04, 0xd6, 0x4b, 0xdf, 0xd0, 0x9e, 0xb1, 0xc5,
0xfe, 0x29, 0x5a, 0xbd, 0xeb, 0x1d, 0xca, 0x42,
0x81, 0xbe, 0x98, 0x8e, 0x2d, 0xa0, 0xb6, 0xc1,
0xc6, 0xa5, 0x9d, 0xc2, 0x26, 0xc2, 0x86, 0x24,
0xe1, 0x81, 0x75, 0xe8, 0x51, 0xc9, 0x6b, 0x97,
0x3d, 0x81, 0xb0, 0x1c, 0xc3, 0x1f, 0x04, 0x78,
0x34, 0xbc, 0x06, 0xd6, 0xd6, 0xed, 0xf6, 0x20,
0xd1, 0x84, 0x24, 0x1a, 0x6a, 0xed, 0x8b, 0x63,
0xa6, // 65-byte signature
0xac, // OP_CHECKSIG
}
txOut := btcwire.NewTxOut(txValue, pkScript)
if txOut.Value != txValue {
t.Errorf("NewTxOut: wrong pk script - got %v, want %v",
txOut.Value, txValue)
}
if !bytes.Equal(txOut.PkScript, pkScript) {
t.Errorf("NewTxOut: wrong pk script - got %v, want %v",
spew.Sdump(txOut.PkScript),
spew.Sdump(pkScript))
}
// Ensure transaction inputs are added properly.
msg.AddTxIn(txIn)
if !reflect.DeepEqual(msg.TxIn[0], txIn) {
t.Errorf("AddTxIn: wrong transaction input added - got %v, want %v",
spew.Sprint(msg.TxIn[0]), spew.Sprint(txIn))
}
// Ensure transaction outputs are added properly.
msg.AddTxOut(txOut)
if !reflect.DeepEqual(msg.TxOut[0], txOut) {
t.Errorf("AddTxIn: wrong transaction output added - got %v, want %v",
spew.Sprint(msg.TxOut[0]), spew.Sprint(txOut))
}
// Ensure the copy produced an identical transaction message.
newMsg := msg.Copy()
if !reflect.DeepEqual(newMsg, msg) {
t.Errorf("Copy: mismatched tx messages - got %v, want %v",
//.........这里部分代码省略.........
示例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: InsertBlock
// InsertBlock inserts raw block and transaction data from a block into the
// database. The first block inserted into the database will be treated as the
// genesis block. Every subsequent block insert requires the referenced parent
// block to already exist.
func (db *LevelDb) InsertBlock(block *btcutil.Block) (height int64, rerr error) {
db.dbLock.Lock()
defer db.dbLock.Unlock()
defer func() {
if rerr == nil {
rerr = db.processBatches()
} else {
db.lBatch().Reset()
}
}()
blocksha, err := block.Sha()
if err != nil {
log.Warnf("Failed to compute block sha %v", blocksha)
return 0, err
}
mblock := block.MsgBlock()
rawMsg, err := block.Bytes()
if err != nil {
log.Warnf("Failed to obtain raw block sha %v", blocksha)
return 0, err
}
txloc, err := block.TxLoc()
if err != nil {
log.Warnf("Failed to obtain raw block sha %v", blocksha)
return 0, err
}
// Insert block into database
newheight, err := db.insertBlockData(blocksha, &mblock.Header.PrevBlock,
rawMsg)
if err != nil {
log.Warnf("Failed to insert block %v %v %v", blocksha,
&mblock.Header.PrevBlock, err)
return 0, err
}
// At least two blocks in the long past were generated by faulty
// miners, the sha of the transaction exists in a previous block,
// detect this condition and 'accept' the block.
for txidx, tx := range mblock.Transactions {
txsha, err := block.TxSha(txidx)
if err != nil {
log.Warnf("failed to compute tx name block %v idx %v err %v", blocksha, txidx, err)
return 0, err
}
spentbuflen := (len(tx.TxOut) + 7) / 8
spentbuf := make([]byte, spentbuflen, spentbuflen)
if len(tx.TxOut)%8 != 0 {
for i := uint(len(tx.TxOut) % 8); i < 8; i++ {
spentbuf[spentbuflen-1] |= (byte(1) << i)
}
}
err = db.insertTx(txsha, newheight, txloc[txidx].TxStart, txloc[txidx].TxLen, spentbuf)
if err != nil {
log.Warnf("block %v idx %v failed to insert tx %v %v err %v", blocksha, newheight, &txsha, txidx, err)
return 0, err
}
// Some old blocks contain duplicate transactions
// Attempt to cleanly bypass this problem by marking the
// first as fully spent.
// http://blockexplorer.com/b/91812 dup in 91842
// http://blockexplorer.com/b/91722 dup in 91880
if newheight == 91812 {
dupsha, err := btcwire.NewShaHashFromStr("d5d27987d2a3dfc724e359870c6644b40e497bdc0589a033220fe15429d88599")
if err != nil {
panic("invalid sha string in source")
}
if txsha.IsEqual(dupsha) {
// marking TxOut[0] as spent
po := btcwire.NewOutPoint(dupsha, 0)
txI := btcwire.NewTxIn(po, []byte("garbage"))
var spendtx btcwire.MsgTx
spendtx.AddTxIn(txI)
err = db.doSpend(&spendtx)
if err != nil {
log.Warnf("block %v idx %v failed to spend tx %v %v err %v", blocksha, newheight, &txsha, txidx, err)
}
}
}
if newheight == 91722 {
dupsha, err := btcwire.NewShaHashFromStr("e3bf3d07d4b0375638d5f1db5255fe07ba2c4cb067cd81b84ee974b6585fb468")
if err != nil {
panic("invalid sha string in source")
}
if txsha.IsEqual(dupsha) {
// marking TxOut[0] as spent
po := btcwire.NewOutPoint(dupsha, 0)
txI := btcwire.NewTxIn(po, []byte("garbage"))
var spendtx btcwire.MsgTx
spendtx.AddTxIn(txI)
err = db.doSpend(&spendtx)
//.........这里部分代码省略.........
示例15: TestTxWire
// TestTxWire tests the MsgTx wire encode and decode for various numbers
// of transaction inputs and outputs and protocol versions.
func TestTxWire(t *testing.T) {
// Previous transaction output point for coinbase to test.
prevOutIndex := uint32(0xffffffff)
prevOut := btcwire.NewOutPoint(&btcwire.ShaHash{}, prevOutIndex)
// Transaction input to test.
sigScript := []byte{0x04, 0x31, 0xdc, 0x00, 0x1b, 0x01, 0x62}
txIn := btcwire.NewTxIn(prevOut, sigScript)
txIn.Sequence = 0xffffffff
// Transaction output to test.
txValue := int64(5000000000)
pkScript := []byte{
0x41, // OP_DATA_65
0x04, 0xd6, 0x4b, 0xdf, 0xd0, 0x9e, 0xb1, 0xc5,
0xfe, 0x29, 0x5a, 0xbd, 0xeb, 0x1d, 0xca, 0x42,
0x81, 0xbe, 0x98, 0x8e, 0x2d, 0xa0, 0xb6, 0xc1,
0xc6, 0xa5, 0x9d, 0xc2, 0x26, 0xc2, 0x86, 0x24,
0xe1, 0x81, 0x75, 0xe8, 0x51, 0xc9, 0x6b, 0x97,
0x3d, 0x81, 0xb0, 0x1c, 0xc3, 0x1f, 0x04, 0x78,
0x34, 0xbc, 0x06, 0xd6, 0xd6, 0xed, 0xf6, 0x20,
0xd1, 0x84, 0x24, 0x1a, 0x6a, 0xed, 0x8b, 0x63,
0xa6, // 65-byte signature
0xac, // OP_CHECKSIG
}
txOut := btcwire.NewTxOut(txValue, pkScript)
// Empty tx message.
noTx := btcwire.NewMsgTx()
noTx.Version = 1
noTxEncoded := []byte{
0x01, 0x00, 0x00, 0x00, // Version
0x00, // Varint for number of input transactions
0x00, // Varint for number of output transactions
0x00, 0x00, 0x00, 0x00, // Lock time
}
multiTx := btcwire.NewMsgTx()
multiTx.Version = 1
multiTx.AddTxIn(txIn)
multiTx.AddTxOut(txOut)
multiTx.LockTime = 0
multiTxEncoded := []byte{
0x01, 0x00, 0x00, 0x00, // Version
0x01, // Varint for number of input transactions
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Previous output hash
0xff, 0xff, 0xff, 0xff, // Prevous output index
0x07, // Varint for length of signature script
0x04, 0x31, 0xdc, 0x00, 0x1b, 0x01, 0x62, // Signature script
0xff, 0xff, 0xff, 0xff, // Sequence
0x01, // Varint for number of output transactions
0x00, 0xf2, 0x05, 0x2a, 0x01, 0x00, 0x00, 0x00, // Transaction amount
0x43, // Varint for length of pk script
0x41, // OP_DATA_65
0x04, 0xd6, 0x4b, 0xdf, 0xd0, 0x9e, 0xb1, 0xc5,
0xfe, 0x29, 0x5a, 0xbd, 0xeb, 0x1d, 0xca, 0x42,
0x81, 0xbe, 0x98, 0x8e, 0x2d, 0xa0, 0xb6, 0xc1,
0xc6, 0xa5, 0x9d, 0xc2, 0x26, 0xc2, 0x86, 0x24,
0xe1, 0x81, 0x75, 0xe8, 0x51, 0xc9, 0x6b, 0x97,
0x3d, 0x81, 0xb0, 0x1c, 0xc3, 0x1f, 0x04, 0x78,
0x34, 0xbc, 0x06, 0xd6, 0xd6, 0xed, 0xf6, 0x20,
0xd1, 0x84, 0x24, 0x1a, 0x6a, 0xed, 0x8b, 0x63,
0xa6, // 65-byte signature
0xac, // OP_CHECKSIG
0x00, 0x00, 0x00, 0x00, // Lock time
}
tests := []struct {
in *btcwire.MsgTx // Message to encode
out *btcwire.MsgTx // Expected decoded message
buf []byte // Wire encoding
pver uint32 // Protocol version for wire encoding
}{
// Latest protocol version with no transactions.
{
noTx,
noTx,
noTxEncoded,
btcwire.ProtocolVersion,
},
// Latest protocol version with multiple transactions.
{
multiTx,
multiTx,
multiTxEncoded,
btcwire.ProtocolVersion,
},
// Protocol version BIP0035Version with no transactions.
{
noTx,
noTx,
noTxEncoded,
btcwire.BIP0035Version,
//.........这里部分代码省略.........