示例#1
0
文件: balance.go 项目: vancsj/gocoin
// This function is only used when loading UTXO database
func NewUTXO(db *qdb.DB, k qdb.KeyType, rec *chain.OneWalkRecord) uint32 {
	if rec.IsP2KH() || rec.IsP2SH() {
		if adr := btc.NewAddrFromPkScript(rec.Script(), common.Testnet); adr != nil {
			if crec, ok := CachedAddrs[adr.Hash160]; ok {
				value := rec.Value()
				idx := rec.TxPrevOut()
				crec.Value += value
				utxo := new(chain.OneUnspentTx)
				utxo.TxPrevOut = *idx
				utxo.Value = value
				utxo.MinedAt = rec.BlockHeight()
				utxo.BtcAddr = CacheUnspent[crec.CacheIndex].BtcAddr
				CacheUnspent[crec.CacheIndex].AllUnspentTx = append(CacheUnspent[crec.CacheIndex].AllUnspentTx, utxo)
				CacheUnspentIdx[idx.UIdx()] = &OneCachedUnspentIdx{Index: crec.CacheIndex, Record: utxo}
			}
		}
	} else if len(StealthAdCache) > 0 && rec.IsStealthIdx() {
		StealthNotify(db, k, rec)
	}

	return 0
}
示例#2
0
文件: stealth.go 项目: vancsj/gocoin
// It is assumed that you call this function only after rec.IsStealthIdx() was true
func CheckStealthRec(db *qdb.DB, k qdb.KeyType, rec *chain.OneWalkRecord,
	addr *btc.BtcAddr, d []byte, inbrowse bool) (fl uint32, uo *chain.OneUnspentTx) {
	sth_scr := rec.Script()
	sa := addr.StealthAddr
	if sa.CheckNonce(sth_scr[3:]) {
		vo := rec.VOut() // get the spending output
		var spend_v []byte
		if inbrowse {
			spend_v = db.GetNoMutex(qdb.KeyType(uint64(k) ^ uint64(vo) ^ uint64(vo+1)))
		} else {
			spend_v = db.Get(qdb.KeyType(uint64(k) ^ uint64(vo) ^ uint64(vo+1)))
		}
		if spend_v != nil {
			rec = chain.NewWalkRecord(spend_v)

			if rec.IsP2KH() {
				var h160 [20]byte
				c := btc.StealthDH(sth_scr[7:40], d)
				spen_exp := btc.DeriveNextPublic(sa.SpendKeys[0][:], c)
				btc.RimpHash(spen_exp, h160[:])
				if bytes.Equal(rec.Script()[3:23], h160[:]) {
					adr := btc.NewAddrFromHash160(h160[:], btc.AddrVerPubkey(common.CFG.Testnet))
					uo = rec.ToUnspent(adr)
					adr.StealthAddr = sa
					adr.Extra = addr.Extra
					uo.StealthC = c
				}
			} else {
				fl = chain.WALK_NOMORE
			}
		} else {
			fl = chain.WALK_NOMORE
		}
	}
	return
}