Beispiel #1
0
func main() {
	var testnet bool
	if len(os.Args) != 2 {
		fmt.Println("Specify one P2KH bitcoin address to see it's P2SH-P2WPKH deposit address")
		fmt.Println("WARNING: Make sure the input address comes from an uncompressed key!!!!!")
		return
	}
	aa, er := btc.NewAddrFromString(os.Args[1])
	if er != nil {
		println(er.Error())
		return
	}

	if btc.AddrVerPubkey(false) == aa.Version {
	} else if btc.AddrVerPubkey(true) == aa.Version {
		testnet = true
	} else {
		fmt.Println("This does nto seem to be P2KH type address")
		return
	}

	h160 := btc.Rimp160AfterSha256(append([]byte{0, 20}, aa.Hash160[:]...))
	aa = btc.NewAddrFromHash160(h160[:], btc.AddrVerScript(testnet))
	fmt.Println(aa.String())
}
Beispiel #2
0
// version byte for P2KH addresses
func ver_pubkey() byte {
	if litecoin {
		return ltc.AddrVerPubkey(testnet)
	} else {
		return btc.AddrVerPubkey(testnet)
	}
}
Beispiel #3
0
func NewAddrFromPkScript(scr []byte, testnet bool) (ad *btc.BtcAddr) {
	ad = btc.NewAddrFromPkScript(scr, testnet)
	if ad != nil && ad.Version == btc.AddrVerPubkey(false) {
		ad.Version = LTC_ADDR_VERSION
	}
	return
}
Beispiel #4
0
func GetAllUnspent(aa *btc.BtcAddr) (thisbal chain.AllUnspentTx) {
	var rec *OneAllAddrBal
	if aa.Version == btc.AddrVerPubkey(common.Testnet) {
		rec = AllBalancesP2KH[aa.Hash160]
	} else if aa.Version == btc.AddrVerScript(common.Testnet) {
		rec = AllBalancesP2SH[aa.Hash160]
	} else {
		return
	}
	if rec != nil {
		for _, v := range rec.Unsp {
			if qr, vout := v.GetRec(); qr != nil {
				if oo := qr.Outs[vout]; oo != nil {
					unsp := &chain.OneUnspentTx{TxPrevOut: btc.TxPrevOut{Hash: qr.TxID, Vout: vout},
						Value: oo.Value, MinedAt: qr.InBlock, Coinbase: qr.Coinbase, BtcAddr: aa}

					if int(vout+1) < len(qr.Outs) {
						var msg []byte
						if qr.Outs[vout+1] != nil && len(qr.Outs[vout+1].PKScr) > 1 && qr.Outs[vout+1].PKScr[0] == 0x6a {
							msg = qr.Outs[vout+1].PKScr[1:]
						} else if int(vout+1) != len(qr.Outs) && qr.Outs[len(qr.Outs)-1] != nil &&
							len(qr.Outs[len(qr.Outs)-1].PKScr) > 1 && qr.Outs[len(qr.Outs)-1].PKScr[0] == 0x6a {
							msg = qr.Outs[len(qr.Outs)-1].PKScr[1:]
						}
						if msg != nil {
							_, unsp.Message, _, _ = btc.GetOpcode(msg)
						}
					}
					thisbal = append(thisbal, unsp)
				}
			}
		}
	}
	return
}
Beispiel #5
0
func main() {
	var testnet bool

	if len(os.Args) < 3 {
		fmt.Println("Specify secret, public_key and optionaly number of addresses you want.")
		fmt.Println("Use a negative value for number of addresses, to work with Testnet addresses.")
		return
	}
	public_key, er := hex.DecodeString(os.Args[2])
	if er != nil {
		println("Error parsing public_key:", er.Error())
		os.Exit(1)
	}

	if len(public_key) == 33 && (public_key[0] == 2 || public_key[0] == 3) {
		fmt.Println("Compressed")
	} else if len(public_key) == 65 && (public_key[0] == 4) {
		fmt.Println("Uncompressed")
	} else {
		println("Incorrect public key")
	}

	secret, er := hex.DecodeString(os.Args[1])
	if er != nil {
		println("Error parsing secret:", er.Error())
		os.Exit(1)
	}

	n := int64(25)

	if len(os.Args) > 3 {
		n, er = strconv.ParseInt(os.Args[3], 10, 32)
		if er != nil {
			println("Error parsing number of keys value:", er.Error())
			os.Exit(1)
		}
		if n == 0 {
			return
		}

		if n < 0 {
			n = -n
			testnet = true
		}
	}

	fmt.Println("# Type-2")
	fmt.Println("#", hex.EncodeToString(public_key))
	fmt.Println("#", hex.EncodeToString(secret))

	for i := 1; i <= int(n); i++ {
		fmt.Println(btc.NewAddrFromPubkey(public_key, btc.AddrVerPubkey(testnet)).String(), "TypB", i)
		if i >= int(n) {
			break
		}

		public_key = btc.DeriveNextPublic(public_key, secret)
	}
}
Beispiel #6
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()
	}
}
Beispiel #7
0
func main() {
	if len(os.Args) < 3 {
		fmt.Println("Specify secret and public_key to get the next Type-2 deterministic address")
		fmt.Println("Add -t as the third argument to work with Testnet addresses.")
		return
	}
	public_key, er := hex.DecodeString(os.Args[2])
	if er != nil {
		println("Error parsing public_key:", er.Error())
		os.Exit(1)
	}

	if len(public_key) == 33 && (public_key[0] == 2 || public_key[0] == 3) {
		fmt.Println("Compressed")
	} else if len(public_key) == 65 && (public_key[0] == 4) {
		fmt.Println("Uncompressed")
	} else {
		println("Incorrect public key")
	}

	secret, er := hex.DecodeString(os.Args[1])
	if er != nil {
		println("Error parsing secret:", er.Error())
		os.Exit(1)
	}

	testnet := len(os.Args) > 3 && os.Args[3] == "-t"

	// Old address
	public_key = btc.DeriveNextPublic(public_key, secret)

	// New address
	fmt.Println(btc.NewAddrFromPubkey(public_key, btc.AddrVerPubkey(testnet)).String())
	// New key
	fmt.Println(hex.EncodeToString(public_key))

}
Beispiel #8
0
// 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
}
Beispiel #9
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())
}
Beispiel #10
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))
}
Beispiel #11
0
func json_balance(w http.ResponseWriter, r *http.Request) {
	if !ipchecker(r) {
		return
	}

	if r.Method != "POST" {
		return
	}

	summary := len(r.Form["summary"]) > 0

	inp, er := ioutil.ReadAll(r.Body)
	if er != nil {
		println(er.Error())
		return
	}

	var addrs []string
	er = json.Unmarshal(inp, &addrs)
	if er != nil {
		println(er.Error())
		return
	}

	type OneOut struct {
		TxId     string
		Vout     uint32
		Value    uint64
		Height   uint32
		Coinbase bool
		Message  string
		Addr     string
	}

	type OneOuts struct {
		Value      uint64
		OutCnt     int
		SegWitCnt  int
		SegWitAddr string
		Outs       []OneOut
	}

	out := make(map[string]*OneOuts)

	lck := new(usif.OneLock)
	lck.In.Add(1)
	lck.Out.Add(1)
	usif.LocksChan <- lck
	lck.In.Wait()

	for _, a := range addrs {
		aa, e := btc.NewAddrFromString(a)
		if e != nil {
			continue
		}

		unsp := wallet.GetAllUnspent(aa)
		newrec := new(OneOuts)
		if len(unsp) > 0 {
			newrec.OutCnt = len(unsp)
			for _, u := range unsp {
				newrec.Value += u.Value
				if !summary {
					newrec.Outs = append(newrec.Outs, OneOut{
						TxId: btc.NewUint256(u.TxPrevOut.Hash[:]).String(), Vout: u.Vout,
						Value: u.Value, Height: u.MinedAt, Coinbase: u.Coinbase,
						Message: html.EscapeString(string(u.Message)), Addr: a})
				}
			}
		}
		out[aa.String()] = newrec

		/* Segwit P2WPKH: */
		if aa.Version == btc.AddrVerPubkey(common.Testnet) {
			// SegWit if applicable
			h160 := btc.Rimp160AfterSha256(append([]byte{0, 20}, aa.Hash160[:]...))
			aa = btc.NewAddrFromHash160(h160[:], btc.AddrVerScript(common.Testnet))
			newrec.SegWitAddr = aa.String()
			unsp = wallet.GetAllUnspent(aa)
			if len(unsp) > 0 {
				newrec.OutCnt += len(unsp)
				newrec.SegWitCnt = len(unsp)
				as := aa.String()
				for _, u := range unsp {
					newrec.Value += u.Value
					if !summary {
						newrec.Outs = append(newrec.Outs, OneOut{
							TxId: btc.NewUint256(u.TxPrevOut.Hash[:]).String(), Vout: u.Vout,
							Value: u.Value, Height: u.MinedAt, Coinbase: u.Coinbase,
							Message: html.EscapeString(string(u.Message)), Addr: as})
					}
				}
			}
		}
	}

	lck.Out.Done()

	bx, er := json.Marshal(out)
	if er == nil {
		w.Header()["Content-Type"] = []string{"application/json"}
		w.Write(bx)
	} else {
		println(er.Error())
	}
}
Beispiel #12
0
func dl_balance(w http.ResponseWriter, r *http.Request) {
	if !ipchecker(r) {
		return
	}

	if r.Method != "POST" {
		return
	}

	var addrs []string
	var labels []string

	if len(r.Form["addrcnt"]) != 1 {
		println("no addrcnt")
		return
	}
	addrcnt, _ := strconv.ParseUint(r.Form["addrcnt"][0], 10, 32)

	for i := 0; i < int(addrcnt); i++ {
		is := fmt.Sprint(i)
		if len(r.Form["addr"+is]) == 1 {
			addrs = append(addrs, r.Form["addr"+is][0])
			if len(r.Form["label"+is]) == 1 {
				labels = append(labels, r.Form["label"+is][0])
			} else {
				labels = append(labels, "")
			}
		}
	}

	type one_unsp_rec struct {
		btc.TxPrevOut
		Value    uint64
		Addr     string
		MinedAt  uint32
		Coinbase bool
	}

	var thisbal chain.AllUnspentTx

	lck := new(usif.OneLock)
	lck.In.Add(1)
	lck.Out.Add(1)
	usif.LocksChan <- lck
	lck.In.Wait()

	for idx, a := range addrs {
		aa, e := btc.NewAddrFromString(a)
		aa.Extra.Label = labels[idx]
		if e == nil {
			newrecs := wallet.GetAllUnspent(aa)
			if len(newrecs) > 0 {
				thisbal = append(thisbal, newrecs...)
			}

			/* Segwit P2WPKH: */
			if aa.Version == btc.AddrVerPubkey(common.Testnet) {
				// SegWit if applicable
				h160 := btc.Rimp160AfterSha256(append([]byte{0, 20}, aa.Hash160[:]...))
				aa = btc.NewAddrFromHash160(h160[:], btc.AddrVerScript(common.Testnet))
				newrecs = wallet.GetAllUnspent(aa)
				if len(newrecs) > 0 {
					thisbal = append(thisbal, newrecs...)
				}
			}
		}
	}
	lck.Out.Done()

	buf := new(bytes.Buffer)
	zi := zip.NewWriter(buf)
	was_tx := make(map[[32]byte]bool)

	sort.Sort(thisbal)
	for i := range thisbal {
		if was_tx[thisbal[i].TxPrevOut.Hash] {
			continue
		}
		was_tx[thisbal[i].TxPrevOut.Hash] = true
		txid := btc.NewUint256(thisbal[i].TxPrevOut.Hash[:])
		fz, _ := zi.Create("balance/" + txid.String() + ".tx")
		if dat, er := common.BlockChain.GetRawTx(thisbal[i].MinedAt, txid); er == nil {
			fz.Write(dat)
		} else {
			println(er.Error())
		}
	}

	fz, _ := zi.Create("balance/unspent.txt")
	for i := range thisbal {
		fmt.Fprintln(fz, thisbal[i].UnspentTextLine())
	}

	zi.Close()
	w.Header()["Content-Type"] = []string{"application/zip"}
	w.Write(buf.Bytes())

}
Beispiel #13
0
// This function is only used when loading UTXO database
func newUTXO(tx *chain.QdbRec) (update_wallet bool) {
	var c, spen_exp []byte
	var rec *chain.QdbTxOut
	var h160 [20]byte

check_next_address:
	for idx, out := range tx.Outs {
		if out == nil {
			continue
		}

		// check for stealth
		if len(StealthAdCache) > 0 && idx > 0 {
			if rec = tx.Outs[idx-1]; rec == nil {
				goto not_stealth
			}
			if !rec.IsStealthIdx() || !out.IsP2KH() {
				goto not_stealth
			}

			for _, ad := range StealthAdCache {
				if sa := ad.addr.StealthAddr; sa.CheckNonce(rec.PKScr[3:40]) {
					c = btc.StealthDH(rec.PKScr[7:40], ad.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(idx)
						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.addr.Extra
						uo.StealthC = c

						carec := CachedAddrs[ad.h160]
						carec.Value += uo.Value
						CacheUnspent[carec.CacheIndex].AllUnspentTx = append(CacheUnspent[carec.CacheIndex].AllUnspentTx, uo)
						CacheUnspentIdx[uo.TxPrevOut.UIdx()] = &OneCachedUnspentIdx{Index: carec.CacheIndex, Record: uo}
						if carec.InWallet {
							update_wallet = true
						}
						continue check_next_address // it it was setalth, cannot be enythign else
					}
				}
			}
		}

	not_stealth:
		// Extract hash160 from pkscript
		adr := btc.NewAddrFromPkScript(out.PKScr, common.Testnet)
		if adr != nil {
			if carec, ok := CachedAddrs[adr.Hash160]; ok {
				carec.Value += out.Value
				utxo := new(chain.OneUnspentTx)
				utxo.TxPrevOut.Hash = tx.TxID
				utxo.TxPrevOut.Vout = uint32(idx)
				utxo.Value = out.Value
				utxo.MinedAt = tx.InBlock
				utxo.BtcAddr = CacheUnspent[carec.CacheIndex].BtcAddr
				CacheUnspent[carec.CacheIndex].AllUnspentTx = append(CacheUnspent[carec.CacheIndex].AllUnspentTx, utxo)
				CacheUnspentIdx[utxo.TxPrevOut.UIdx()] = &OneCachedUnspentIdx{Index: carec.CacheIndex, Record: utxo}
				if carec.InWallet {
					update_wallet = true
				}
			}
		}
	}
	return
}
Beispiel #14
0
func update_balance() {
	var tofetch_stealh []*btc.BtcAddr
	var tofetch_secrets [][]byte
	tofetch_regular := make(map[uint64]*btc.BtcAddr)

	MyBalance = nil

	for _, v := range CachedAddrs {
		v.InWallet = false
	}

	FetchStealthKeys()

	for i := range MyWallet.Addrs {
		if rec, pres := CachedAddrs[MyWallet.Addrs[i].Hash160]; pres {
			rec.InWallet = true
			cu := CacheUnspent[rec.CacheIndex]
			cu.BtcAddr = MyWallet.Addrs[i]
			for j := range cu.AllUnspentTx {
				// update BtcAddr in each of AllUnspentTx to reflect the latest label
				cu.AllUnspentTx[j].BtcAddr = MyWallet.Addrs[i]
			}
			MyBalance = append(MyBalance, CacheUnspent[rec.CacheIndex].AllUnspentTx...)
		} else {
			add_it := true
			// Add a new address to the balance cache
			if MyWallet.Addrs[i].StealthAddr == nil {
				tofetch_regular[MyWallet.Addrs[i].AIdx()] = MyWallet.Addrs[i]
			} else {
				sa := MyWallet.Addrs[i].StealthAddr
				if ssecret := FindStealthSecret(sa); ssecret != nil {
					tofetch_stealh = append(tofetch_stealh, MyWallet.Addrs[i])
					tofetch_secrets = append(tofetch_secrets, ssecret)
					var rec stealthCacheRec
					rec.addr = MyWallet.Addrs[i]
					copy(rec.d[:], ssecret)
					copy(rec.h160[:], MyWallet.Addrs[i].Hash160[:])
					StealthAdCache = append(StealthAdCache, rec)
				} else {
					if MyWallet.Addrs[i].Extra.Wallet != AddrBookFileName {
						fmt.Println("No matching secret for", sa.String())
					}
					add_it = false
				}
			}
			if add_it {
				CachedAddrs[MyWallet.Addrs[i].Hash160] = &OneCachedAddrBalance{InWallet: true, CacheIndex: uint(len(CacheUnspent))}
				CacheUnspent = append(CacheUnspent, &OneCachedUnspent{BtcAddr: MyWallet.Addrs[i]})
			}
		}
	}

	if len(tofetch_regular) > 0 || len(tofetch_stealh) > 0 {
		fmt.Println("Fetching a new blance for", len(tofetch_regular), "regular and", len(tofetch_stealh), "stealth addresses")
		// There are new addresses which we have not monitored yet
		var new_addrs chain.AllUnspentTx
		var c, spen_exp []byte
		var out *chain.QdbTxOut
		var h160 [20]byte

		common.BlockChain.Unspent.BrowseUTXO(true, func(tx *chain.QdbRec) {
			for idx, rec := range tx.Outs {
				if rec == nil {
					continue
				}
				if rec.IsP2KH() {
					if ad, ok := tofetch_regular[binary.LittleEndian.Uint64(rec.PKScr[3:3+8])]; ok {
						new_addrs = append(new_addrs, tx.ToUnspent(uint32(idx), ad))
					}
				} else if rec.IsP2SH() {
					if ad, ok := tofetch_regular[binary.LittleEndian.Uint64(rec.PKScr[2:2+8])]; ok {
						new_addrs = append(new_addrs, tx.ToUnspent(uint32(idx), ad))
					}
				} else if idx < len(tx.Outs)-1 {
					// check for stealth
					if out = tx.Outs[idx+1]; out == nil {
						continue
					}
					if !rec.IsStealthIdx() || !out.IsP2KH() {
						continue
					}

				stealth_check:
					for _, ad := range tofetch_stealh {
						if sa := ad.StealthAddr; sa.CheckNonce(rec.PKScr[3:40]) {
							for _, d := range tofetch_secrets {
								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(idx + 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
									new_addrs = append(new_addrs, uo)
									break stealth_check
								}
							}
						}
					}
				}
			}
		})

		for i := range new_addrs {
			poi := new_addrs[i].TxPrevOut.UIdx()
			if _, ok := CacheUnspentIdx[poi]; ok {
				fmt.Println(new_addrs[i].TxPrevOut.String(), "- already on the list")
				continue
			}

			var rec *OneCachedAddrBalance
			if new_addrs[i].BtcAddr.StealthAddr != nil {
				var h160 [20]byte
				copy(h160[:], new_addrs[i].BtcAddr.StealthAddr.Hash160())
				rec = CachedAddrs[h160]
			} else {
				rec = CachedAddrs[new_addrs[i].BtcAddr.Hash160]
			}
			if rec == nil {
				println("Hash160 not in CachedAddrs for", new_addrs[i].BtcAddr.String())
				continue
			}
			rec.Value += new_addrs[i].Value
			CacheUnspent[rec.CacheIndex].AllUnspentTx = append(CacheUnspent[rec.CacheIndex].AllUnspentTx, new_addrs[i])
			CacheUnspentIdx[new_addrs[i].TxPrevOut.UIdx()] = &OneCachedUnspentIdx{Index: rec.CacheIndex, Record: new_addrs[i]}
		}
		MyBalance = append(MyBalance, new_addrs...)
	}

	sort_and_sum()
}
Beispiel #15
0
func AddrVerPubkey(testnet bool) byte {
	if !testnet {
		return LTC_ADDR_VERSION
	}
	return btc.AddrVerPubkey(testnet)
}
Beispiel #16
0
/*
{
"address" : "2NAHUDSC1EmbTBwQQp4VQ2FNzWDqHtmk1i6",
"redeemScript" : "512102cdc4fff0ad031ea5f2d0d4337e2bf976b84334f8f80b08fe3f69886d58bc5a8a2102ebf54926d3edaae51bde71f2976948559a8d43fce52f5e7ed9ed85dbaa449d7f52ae"
}
*/
func main() {
	var testnet bool
	if len(os.Args) < 3 {
		fmt.Println("Specify one integer and at least one public key.")
		fmt.Println("For Testent, make the integer negative.")
		return
	}
	cnt, er := strconv.ParseInt(os.Args[1], 10, 32)
	if er != nil {
		println("Count value:", er.Error())
		return
	}
	if cnt < 0 {
		testnet = true
		cnt = -cnt
	}
	if cnt < 1 || cnt > 16 {
		println("The integer (required number of keys) must be between 1 and 16")
		return
	}
	buf := new(bytes.Buffer)
	buf.WriteByte(byte(0x50 + cnt))
	fmt.Println("Trying to prepare multisig address for", cnt, "out of", len(os.Args)-2, "public keys ...")
	var pkeys byte
	var ads string
	for i := 2; i < len(os.Args); i++ {
		if pkeys == 16 {
			println("Oh, give me a break. You don't need more than 16 public keys - stopping here!")
			break
		}
		d, er := hex.DecodeString(os.Args[i])
		if er != nil {
			println("pubkey", i, er.Error())
		}
		_, er = btc.NewPublicKey(d)
		if er != nil {
			println("pubkey", i, er.Error())
			return
		}
		pkeys++
		buf.WriteByte(byte(len(d)))
		buf.Write(d)
		if ads != "" {
			ads += ", "
		}
		ads += "\"" + btc.NewAddrFromPubkey(d, btc.AddrVerPubkey(testnet)).String() + "\""
	}
	buf.WriteByte(0x50 + pkeys)
	buf.WriteByte(0xae)

	p2sh := buf.Bytes()
	addr := btc.NewAddrFromPubkey(p2sh, btc.AddrVerScript(testnet))

	rec := "{\n"
	rec += fmt.Sprintf("\t\"multiAddress\" : \"%s\",\n", addr.String())
	rec += fmt.Sprintf("\t\"scriptPubKey\" : \"a914%s87\",\n", hex.EncodeToString(addr.Hash160[:]))
	rec += fmt.Sprintf("\t\"keysRequired\" : %d,\n", cnt)
	rec += fmt.Sprintf("\t\"keysProvided\" : %d,\n", pkeys)
	rec += fmt.Sprintf("\t\"redeemScript\" : \"%s\",\n", hex.EncodeToString(p2sh))
	rec += fmt.Sprintf("\t\"listOfAddres\" : [%s]\n", ads)
	rec += "}\n"
	fname := addr.String() + ".json"
	ioutil.WriteFile(fname, []byte(rec), 0666)
	fmt.Println("The address record stored in", fname)
}