func fetch(db btcdb.Db, rd *rData) error { sha, err := db.FetchBlockShaByHeight(rd.in.H) if err != nil { return fmt.Errorf("failed FetchBlockShaByHeight(%v): %v\n", rd.in.H, err) } blk, err := db.FetchBlockBySha(sha) if err != nil { return fmt.Errorf("failed FetchBlockBySha(%v) - h %v: %v\n", sha, rd.in.H, err) } tx := blk.Transactions()[rd.in.Tx] rd.blkSha = sha rd.blk = blk rd.tx = tx rd.txInIndex = rd.in.TxIn rd.txIn = tx.MsgTx().TxIn[rd.in.TxIn] txPrevList, err := db.FetchTxBySha(&rd.txIn.PreviousOutPoint.Hash) if err != nil { return fmt.Errorf("failed FetchTxBySha(%v) - h %v: %v\n", rd.txIn.PreviousOutPoint.Hash, rd.in.H, err) } if len(txPrevList) != 1 { return fmt.Errorf("not single FetchTxBySha(%v) - h %v: %v\n", rd.txIn.PreviousOutPoint.Hash, rd.in.H, len(txPrevList)) } blkPrev, err := db.FetchBlockBySha(txPrevList[0].BlkSha) if err != nil { return fmt.Errorf("failed prev FetchBlockBySha(%v) - h %v: %v\n", txPrevList[0].BlkSha, rd.in.H, err) } rd.txPrev = txPrevList[0] rd.txPrevOutIndex = rd.txIn.PreviousOutPoint.Index rd.txPrevOut = rd.txPrev.Tx.TxOut[rd.txPrevOutIndex] rd.blkPrev = blkPrev return nil }
func FindSender(txIns []*btcwire.TxIn, btcdb btcdb.Db) (Address, error) { inputs := make(map[string]int64) for _, txIn := range txIns { op := txIn.PreviousOutpoint hash := op.Hash index := op.Index transactions, err := btcdb.FetchTxBySha(&hash) if err != nil { return Address{}, err } // TODO: During initial sync unconfirmed transactions might be picked up // We should prevent that from showing up but this is a work around // When a transaction is not in the database yet if len(transactions) == 0 { continue } previousOutput := transactions[0].Tx.TxOut[index] // The largest contributor receives the Mastercoins, so add multiple address values together address, _ := GetAddrs(previousOutput.PkScript) inputs[address[0].Addr] += previousOutput.Value } // Decide which input has the most value so we know who is sending this transaction var highest int64 var highestAddress string for k, v := range inputs { if v > highest { highest = v highestAddress = k } } return Address{Addr: highestAddress}, nil }