Example #1
0
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
}
Example #2
0
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
}