// 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 }
// 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 }