Example #1
0
// Generate a new stealth address
func new_stealth_address(prv_key []byte) {
	sk, er := hex.DecodeString(*scankey)
	if er != nil {
		println(er.Error())
		cleanExit(1)
	}
	if len(sk) != 33 || sk[0] != 2 && sk[0] != 3 {
		println("scankey must be a compressed public key (33 bytes long)")
		cleanExit(1)
	}

	if *prefix > 16 {
		if *prefix > 24 {
			fmt.Println("The stealth prefix cannot be bigger than 24", *prefix)
			cleanExit(1)
		}
		fmt.Println("WARNING: You chose a prefix length of", *prefix)
		fmt.Println(" Long prefixes endanger anonymity of stealth address.")
	}

	pub := btc.PublicFromPrivate(prv_key, true)
	if pub == nil {
		println("PublicFromPrivate error 2")
		cleanExit(1)
	}

	sa := new(btc.StealthAddr)
	sa.Version = btc.StealthAddressVersion(testnet)
	sa.Options = 0
	copy(sa.ScanKey[:], sk)
	sa.SpendKeys = make([][33]byte, 1)
	copy(sa.SpendKeys[0][:], pub)
	sa.Sigs = 1
	sa.Prefix = make([]byte, 1+(byte(*prefix)+7)>>3)
	if *prefix > 0 {
		sa.Prefix[0] = byte(*prefix)
		rand.Read(sa.Prefix[1:])
	}
	fmt.Println(sa.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
	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))
}
Example #3
0
File: stuff.go Project: wchh/gocoin
// version byte for stealth addresses
func ver_stealth() byte {
	return btc.StealthAddressVersion(testnet)
}