Example #1
0
func list_unspent(addr string) {
	fmt.Println("Checking unspent coins for addr", addr)

	defer func() { // in case if ad.OutScript() would panic
		if r := recover(); r != nil {
			err := r.(error)
			fmt.Println("main panic recovered:", err.Error())
		}
	}()

	var ad *btc.BtcAddr
	var e error
	ad, e = btc.NewAddrFromString(addr)
	if e != nil {
		println(e.Error())
		return
	}
	sa := ad.StealthAddr
	exp_scr := ad.OutScript()
	var walk chain.FunctionWalkUnspent
	var unsp chain.AllUnspentTx

	if sa == nil {
		walk = func(db *qdb.DB, k qdb.KeyType, rec *chain.OneWalkRecord) uint32 {
			if bytes.Equal(rec.Script(), exp_scr) {
				unsp = append(unsp, rec.ToUnspent(ad))
			}
			return 0
		}
	} else {
		wallet.FetchStealthKeys()
		d := wallet.FindStealthSecret(sa)
		if d == nil {
			fmt.Println("No matching secret found in your wallet/stealth folder")
			return
		}
		walk = func(db *qdb.DB, k qdb.KeyType, rec *chain.OneWalkRecord) uint32 {
			if !rec.IsStealthIdx() {
				return 0
			}
			fl, uo := wallet.CheckStealthRec(db, k, rec, ad, d, true)
			if uo != nil {
				unsp = append(unsp, uo)
			}
			return fl
		}
	}
	common.BlockChain.Unspent.BrowseUTXO(false, walk)

	sort.Sort(unsp)
	var sum uint64
	for i := range unsp {
		if len(unsp) < 200 {
			fmt.Println(unsp[i].String())
		}
		sum += unsp[i].Value
	}
	fmt.Printf("Total %.8f unspent BTC in %d outputs at address %s\n",
		float64(sum)/1e8, len(unsp), ad.String())
}
Example #2
0
func do_scan_stealth(p string, ignore_prefix bool) {
	ad, _ := btc.NewAddrFromString(p)
	if ad == nil {
		fmt.Println("Specify base58 encoded bitcoin address")
		return
	}

	sa := ad.StealthAddr
	if sa == nil {
		fmt.Println("Specify base58 encoded stealth address")
		return
	}
	if sa.Version != btc.StealthAddressVersion(common.Testnet) {
		fmt.Println("Incorrect version of the stealth address")
		return
	}
	if len(sa.SpendKeys) != 1 {
		fmt.Println("Currently only single spend keys are supported. This address has", len(sa.SpendKeys))
		return
	}

	//fmt.Println("scankey", hex.EncodeToString(sa.ScanKey[:]))
	if ignore_prefix {
		sa.Prefix = []byte{0}
		fmt.Println("Ignoring Prefix inside the address")
	} else if len(sa.Prefix) == 0 {
		fmt.Println("Prefix not present in the address")
	} else {
		fmt.Println("Prefix", sa.Prefix[0], hex.EncodeToString(sa.Prefix[1:]))
	}

	wallet.FetchStealthKeys()
	d := wallet.FindStealthSecret(sa)
	if d == nil {
		fmt.Println("No matching secret found in your wallet/stealth folder")
		return
	}

	var unsp chain.AllUnspentTx

	common.BlockChain.Unspent.BrowseUTXO(true, func(db *qdb.DB, k qdb.KeyType, rec *chain.OneWalkRecord) uint32 {
		if !rec.IsStealthIdx() {
			return 0
		}
		fl, uo := wallet.CheckStealthRec(db, k, rec, ad, d, true)
		if uo != nil {
			unsp = append(unsp, uo)
		}
		return fl
	})

	sort.Sort(unsp)
	os.RemoveAll("balance")
	os.MkdirAll("balance/", 0770)
	utxt, _ := os.Create("balance/unspent.txt")
	fmt.Print(wallet.DumpBalance(unsp, utxt, true, false))
}
Example #3
0
func listarmkeys(p string) {
	if p != "seed" {
		if len(wallet.StealthSecrets) > 0 {
			fmt.Println("Persistent secret scan keys:")
			for i := range wallet.StealthSecrets {
				pk := btc.PublicFromPrivate(wallet.StealthSecrets[i], true)
				fmt.Print(" #", i, "  ", hex.EncodeToString(pk))
				if p == "addr" {
					fmt.Print("  ", btc.NewAddrFromPubkey(pk, btc.AddrVerPubkey(common.Testnet)).String())
				}
				fmt.Println()
			}
		} else {
			fmt.Println("You have no persistent secret scan keys")
		}
	}
	if p != "file" {
		if len(wallet.ArmedStealthSecrets) > 0 {
			fmt.Println("Volatile secret scan keys:")
			for i := range wallet.ArmedStealthSecrets {
				pk := btc.PublicFromPrivate(wallet.ArmedStealthSecrets[i], true)
				fmt.Print(" #", i, "  ", hex.EncodeToString(pk))
				if p == "addr" {
					fmt.Print("  ", btc.NewAddrFromPubkey(pk, btc.AddrVerPubkey(common.Testnet)).String())
				}
				if p == "save" {
					fn := common.GocoinHomeDir + "wallet/stealth/" + hex.EncodeToString(pk)
					if fi, er := os.Stat(fn); er == nil && fi.Size() >= 32 {
						fmt.Print("  already on disk")
					} else {
						ioutil.WriteFile(fn, wallet.ArmedStealthSecrets[i], 0600)
						fmt.Print("  saved")
					}
					sys.ClearBuffer(wallet.ArmedStealthSecrets[i])
				}
				fmt.Println()
			}
		} else {
			fmt.Println("You have no volatile secret scan keys")
		}
	}
	if p == "save" {
		wallet.ArmedStealthSecrets = nil
		wallet.FetchStealthKeys()
	}
}
Example #4
0
func do_scan_stealth(p string, ignore_prefix bool) {
	sa, _ := btc.NewStealthAddrFromString(p)
	if sa == nil {
		fmt.Println("Specify base58 encoded stealth address")
		return
	}
	if sa.Version != btc.StealthAddressVersion(common.CFG.Testnet) {
		fmt.Println("Incorrect version of the stealth address")
		return
	}
	if len(sa.SpendKeys) != 1 {
		fmt.Println("Currently only single spend keys are supported. This address has", len(sa.SpendKeys))
		return
	}

	//fmt.Println("scankey", hex.EncodeToString(sa.ScanKey[:]))
	if ignore_prefix {
		sa.Prefix = []byte{0}
		fmt.Println("Ignoring Prefix inside the address")
	} else if len(sa.Prefix) == 0 {
		fmt.Println("Prefix not present in the address")
	} else {
		fmt.Println("Prefix", sa.Prefix[0], hex.EncodeToString(sa.Prefix[1:]))
	}

	ds := wallet.FetchStealthKeys()
	if len(ds) == 0 {
		return
	}

	defer func() {
		for i := range ds {
			utils.ClearBuffer(ds[i])
		}
	}() // clear the keys in mem after all

	var d []byte

	for i := range ds {
		if bytes.Equal(btc.PublicFromPrivate(ds[i], true), sa.ScanKey[:]) {
			d = ds[i]
		}
	}

	if d == nil {
		fmt.Println("No matching secret found your wallet/stealth folder")
		return
	}

	var pos []*btc.TxPrevOut
	cs := make(map[uint64][]byte)
	as := make(map[uint64]*btc.BtcAddr)
	var ncnt uint

	common.BlockChain.Unspent.ScanStealth(sa, func(eth, txid []byte, vout uint32, scr []byte) bool {
		if len(scr) == 25 && scr[0] == 0x76 && scr[1] == 0xa9 && scr[2] == 0x14 && scr[23] == 0x88 && scr[24] == 0xac {
			var h160 [20]byte
			//yes := btc.NewUint256(txid).String()=="9cc90ff2528b49dfd9c53e5e90c98a1fd45d577af7f3a9e7a9f8a86b52fb0280"
			c := btc.StealthDH(eth, d)
			spen_exp := btc.DeriveNextPublic(sa.SpendKeys[0][:], c)
			btc.RimpHash(spen_exp, h160[:])
			if bytes.Equal(scr[3:23], h160[:]) {
				po := new(btc.TxPrevOut)
				copy(po.Hash[:], txid)
				po.Vout = vout
				pos = append(pos, po)
				cs[po.UIdx()] = c
				as[po.UIdx()] = btc.NewAddrFromHash160(h160[:], btc.AddrVerPubkey(common.CFG.Testnet))
			}
			ncnt++
			/*fmt.Printf("%s with c=%s",
				btc.NewAddrFromHash160(h160[:], btc.AddrVerPubkey(common.CFG.Testnet)).String(),
				hex.EncodeToString(c))
			fmt.Println()*/
			return true
		} else {
			return false
		}
	})

	fmt.Println(len(pos), "outputs, out of", ncnt, "notifications belonged to our wallet")

	var unsp btc.AllUnspentTx
	for i := range pos {
		po, e := common.BlockChain.Unspent.UnspentGet(pos[i])
		if e != nil {
			println("UnspentGet:", e.Error())
			println("This should not happen - please, report a bug.")
			println("You can probably fix it by launching the client with -rescan")
			os.Exit(1)
		}
		//fmt.Println(btc.NewUint256(pos[i].Hash[:]), pos[i].Vout+1, hex.EncodeToString(cs[pos[i].UIdx()]))
		one := &btc.OneUnspentTx{
			TxPrevOut: *pos[i],
			Value:     po.Value,
			MinedAt:   po.BlockHeight,
			BtcAddr:   as[pos[i].UIdx()],
			StealthC:  cs[pos[i].UIdx()]}
		unsp = append(unsp, one)
	}
	sort.Sort(unsp)
	os.RemoveAll("balance")
	os.MkdirAll("balance/", 0770)
	utxt, _ := os.Create("balance/unspent.txt")
	fmt.Print(wallet.DumpBalance(unsp, utxt, true, false))
}
Example #5
0
func list_unspent(addr string) {
	fmt.Println("Checking unspent coins for addr", addr)

	defer func() { // in case if ad.OutScript() would panic
		if r := recover(); r != nil {
			err := r.(error)
			fmt.Println("main panic recovered:", err.Error())
		}
	}()

	var ad *btc.BtcAddr
	var e error
	ad, e = btc.NewAddrFromString(addr)
	if e != nil {
		println(e.Error())
		return
	}
	sa := ad.StealthAddr
	var walk chain.FunctionWalkUnspent
	var unsp chain.AllUnspentTx

	if sa == nil {
		exp_scr := ad.OutScript()
		walk = func(tx *chain.QdbRec) {
			for idx, rec := range tx.Outs {
				if rec != nil && bytes.Equal(rec.PKScr, exp_scr) {
					unsp = append(unsp, tx.ToUnspent(uint32(idx), ad))
				}
			}
		}
	} else {
		var c, spen_exp []byte
		var rec, out *chain.QdbTxOut
		var h160 [20]byte

		wallet.FetchStealthKeys()
		d := wallet.FindStealthSecret(sa)
		if d == nil {
			fmt.Println("No matching secret found in your wallet/stealth folder")
			return
		}
		walk = func(tx *chain.QdbRec) {
			for i := 0; i < len(tx.Outs)-1; i++ {
				if rec = tx.Outs[i]; rec == nil {
					continue
				}
				if out = tx.Outs[i+1]; out == nil {
					continue
				}
				if !rec.IsStealthIdx() || !out.IsP2KH() || !ad.StealthAddr.CheckNonce(rec.PKScr[3:40]) {
					continue
				}
				c = btc.StealthDH(rec.PKScr[7:40], d)
				spen_exp = btc.DeriveNextPublic(sa.SpendKeys[0][:], c)
				btc.RimpHash(spen_exp, h160[:])
				if bytes.Equal(out.PKScr[3:23], h160[:]) {
					uo := new(chain.OneUnspentTx)
					uo.TxPrevOut.Hash = tx.TxID
					uo.TxPrevOut.Vout = uint32(i + 1)
					uo.Value = out.Value
					uo.MinedAt = tx.InBlock
					uo.BtcAddr = btc.NewAddrFromHash160(h160[:], btc.AddrVerPubkey(common.CFG.Testnet))
					uo.FixDestString()
					uo.BtcAddr.StealthAddr = sa
					uo.BtcAddr.Extra = ad.Extra
					uo.StealthC = c
					unsp = append(unsp, uo)
				}
			}
		}
	}
	common.BlockChain.Unspent.BrowseUTXO(false, walk)

	sort.Sort(unsp)
	var sum uint64
	for i := range unsp {
		if len(unsp) < 200 {
			fmt.Println(unsp[i].String())
		}
		sum += unsp[i].Value
	}
	fmt.Printf("Total %.8f unspent BTC in %d outputs at address %s\n",
		float64(sum)/1e8, len(unsp), ad.String())
}
Example #6
0
func do_scan_stealth(p string, ignore_prefix bool) {
	ad, _ := btc.NewAddrFromString(p)
	if ad == nil {
		fmt.Println("Specify base58 encoded bitcoin address")
		return
	}

	sa := ad.StealthAddr
	if sa == nil {
		fmt.Println("Specify base58 encoded stealth address")
		return
	}
	if sa.Version != btc.StealthAddressVersion(common.Testnet) {
		fmt.Println("Incorrect version of the stealth address")
		return
	}
	if len(sa.SpendKeys) != 1 {
		fmt.Println("Currently only single spend keys are supported. This address has", len(sa.SpendKeys))
		return
	}

	//fmt.Println("scankey", hex.EncodeToString(sa.ScanKey[:]))
	if ignore_prefix {
		sa.Prefix = []byte{0}
		fmt.Println("Ignoring Prefix inside the address")
	} else if len(sa.Prefix) == 0 {
		fmt.Println("Prefix not present in the address")
	} else {
		fmt.Println("Prefix", sa.Prefix[0], hex.EncodeToString(sa.Prefix[1:]))
	}

	wallet.FetchStealthKeys()
	d := wallet.FindStealthSecret(sa)
	if d == nil {
		fmt.Println("No matching secret found in your wallet/stealth folder")
		return
	}

	var unsp chain.AllUnspentTx
	var c, spen_exp []byte
	var rec, out *chain.QdbTxOut
	var h160 [20]byte

	common.BlockChain.Unspent.BrowseUTXO(true, func(tx *chain.QdbRec) {
		for i := 0; i < len(tx.Outs)-1; i++ {
			if rec = tx.Outs[i]; rec == nil {
				continue
			}
			if out = tx.Outs[i+1]; out == nil {
				continue
			}
			if !rec.IsStealthIdx() || !out.IsP2KH() || !ad.StealthAddr.CheckNonce(rec.PKScr[3:40]) {
				continue
			}
			c = btc.StealthDH(rec.PKScr[7:40], d)
			spen_exp = btc.DeriveNextPublic(sa.SpendKeys[0][:], c)
			btc.RimpHash(spen_exp, h160[:])
			if bytes.Equal(out.PKScr[3:23], h160[:]) {
				uo := new(chain.OneUnspentTx)
				uo.TxPrevOut.Hash = tx.TxID
				uo.TxPrevOut.Vout = uint32(i + 1)
				uo.Value = out.Value
				uo.MinedAt = tx.InBlock
				uo.BtcAddr = btc.NewAddrFromHash160(h160[:], btc.AddrVerPubkey(common.CFG.Testnet))
				uo.FixDestString()
				uo.BtcAddr.StealthAddr = sa
				uo.BtcAddr.Extra = ad.Extra
				uo.StealthC = c
				unsp = append(unsp, uo)
			}
		}
	})

	sort.Sort(unsp)
	os.RemoveAll("balance")
	os.MkdirAll("balance/", 0770)
	utxt, _ := os.Create("balance/unspent.txt")
	fmt.Print(wallet.DumpBalance(unsp, utxt, true, false))
}