Пример #1
0
// Input the password (that is the secret seed to your wallet)
func getseed(seed []byte) bool {
	var pass [1024]byte
	var n int
	var e error
	var f *os.File

	if !*ask4pass {
		f, e = os.Open(PassSeedFilename)
		if e == nil {
			n, e = f.Read(pass[:])
			f.Close()
			if n <= 0 {
				return false
			}
			goto calc_seed
		}

		fmt.Println("Seed file", PassSeedFilename, "not found")
	}

	fmt.Print("Enter your wallet's seed password: "******"Re-enter the seed password (to be sure): ")
			var pass2 [1024]byte
			p2len := utils.ReadPassword(pass2[:])
			if p2len != n || !bytes.Equal(pass[:n], pass2[:p2len]) {
				utils.ClearBuffer(pass2[:p2len])
				println("The two passwords you entered do not match")
				return false
			}
			utils.ClearBuffer(pass2[:p2len])
		}
		// Maybe he wants to save the password?
		if ask_yes_no("Save the password on disk, so you won't be asked for it later?") {
			e = ioutil.WriteFile(PassSeedFilename, pass[:n], 0600)
			if e != nil {
				fmt.Println("WARNING: Could not save the password", e.Error())
			}
		}
	}
calc_seed:
	for i := 0; i < n; i++ {
		if pass[i] < ' ' || pass[i] > 126 {
			fmt.Println("WARNING: Your secret contains non-printable characters")
			break
		}
	}
	btc.ShaHash(pass[:n], seed)
	utils.ClearBuffer(pass[:n])
	return true
}
Пример #2
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))
}
Пример #3
0
// Get the secret seed and generate "*keycnt" key pairs (both private and public)
func make_wallet() {
	var lab string

	if *testnet {
		verbyte = 0x6f
		privver = 0xef
	} else {
		// verbyte is be zero by definition
		privver = 0x80
	}
	load_others()

	seed_key := make([]byte, 32)
	if !getseed(seed_key) {
		os.Exit(0)
	}

	defer func() {
		utils.ClearBuffer(seed_key)
	}()

	if *waltype == 3 {
		lab = "TypC"
	} else if *waltype == 2 {
		if *type2sec != "" {
			d, e := hex.DecodeString(*type2sec)
			if e != nil {
				println("t2sec error:", e.Error())
				os.Exit(1)
			}
			type2_secret = d
		} else {
			type2_secret = make([]byte, 20)
			btc.RimpHash(seed_key, type2_secret)
		}
		lab = "TypB"
	} else {
		lab = "TypA"
	}

	if *verbose {
		fmt.Println("Generating", *keycnt, "keys, version", verbyte, "...")
	}
	for i := uint(0); i < *keycnt; {
		prv_key := make([]byte, 32)
		if *waltype == 3 {
			btc.ShaHash(seed_key, prv_key)
			seed_key = append(seed_key, byte(i))
		} else if *waltype == 2 {
			seed_key = btc.DeriveNextPrivate(seed_key, type2_secret)
			copy(prv_key, seed_key)
		} else {
			btc.ShaHash(seed_key, prv_key)
			copy(seed_key, prv_key)
		}
		priv_keys = append(priv_keys, prv_key)
		if *scankey != "" {
			new_stealth_address(prv_key)
			return
		}

		// for stealth keys
		if i == 0 {
			copy(first_seed[:], prv_key)
		}
		compressed_key = append(compressed_key, !*uncompressed)
		pub := btc.PublicFromPrivate(prv_key, !*uncompressed)
		if pub != nil {
			adr := btc.NewAddrFromPubkey(pub, verbyte)

			if *pubkey != "" && *pubkey == adr.String() {
				fmt.Println(adr.String(), "=>", hex.EncodeToString(pub))
				return
			}
			publ_addrs = append(publ_addrs, adr)
			labels = append(labels, fmt.Sprint(lab, " ", i+1))
			i++
		} else {
			println("PublicFromPrivate error 3")
		}
	}
	if *verbose {
		fmt.Println("Private keys re-generated")
	}
}
Пример #4
0
// Thanks @dabura667 - https://bitcointalk.org/index.php?topic=590349.msg6560332#msg6560332
func stealth_txout(sa *btc.StealthAddr, value uint64) (res []*btc.TxOut) {
	if sa.Version != btc.StealthAddressVersion(*testnet) {
		fmt.Println("ERROR: Unsupported version of a stealth address", sa.Version)
		os.Exit(1)
	}

	if len(sa.SpendKeys) != 1 {
		fmt.Println("ERROR: Currently only non-multisig stealth addresses are supported",
			len(sa.SpendKeys))
		os.Exit(1)
	}

	// Make two outpus
	res = make([]*btc.TxOut, 2)
	var e, ephemkey, pkscr []byte
	var nonce, nonce_from uint32
	var look4pref bool
	sha := sha256.New()

	// 6. create a new pub/priv keypair (lets call its pubkey "ephemkey" and privkey "e")
pick_different_e:
	e = make([]byte, 32)
	rand.Read(e)
	defer utils.ClearBuffer(e)
	ephemkey = btc.PublicFromPrivate(e, true)
	if *verbose {
		fmt.Println("e", hex.EncodeToString(e))
		fmt.Println("ephemkey", hex.EncodeToString(ephemkey))
	}

	// 7. IF there is a prefix in the stealth address, brute force a nonce such
	// that SHA256(nonce.concate(ephemkey)) first 4 bytes are equal to the prefix.
	// IF NOT, then just run through the loop once and pickup a random nonce.
	// (probably make the while condition include "or prefix = null" or something to that nature.
	look4pref = len(sa.Prefix) > 0 && sa.Prefix[0] > 0
	if look4pref {
		fmt.Print("Prefix is ", sa.Prefix[0], ":", hex.EncodeToString(sa.Prefix[1:]), " - looking for nonce...")
	}
	binary.Read(rand.Reader, binary.LittleEndian, &nonce_from)
	nonce = nonce_from
	for {
		binary.Write(sha, binary.LittleEndian, nonce)
		sha.Write(ephemkey)

		if sa.CheckPrefix(sha.Sum(nil)[:4]) {
			break
		}
		sha.Reset()

		nonce++
		if nonce == nonce_from {
			fmt.Println("EOF")
			goto pick_different_e
		}

		if (nonce & 0xfffff) == 0 {
			fmt.Print(".")
		}
	}
	if look4pref {
		fmt.Println(uint32(nonce - nonce_from))
	}

	// 8. Once you have the nonce and the ephemkey, you can create the first output, which is
	pkscr = make([]byte, 40)
	pkscr[0] = 0x6a // OP_RETURN
	pkscr[1] = 38   // length
	pkscr[2] = 0x06 // always 6
	binary.LittleEndian.PutUint32(pkscr[3:7], nonce)
	copy(pkscr[7:40], ephemkey)
	res[0] = &btc.TxOut{Pk_script: pkscr}

	// 9. Now use ECC multiplication to calculate e*Q where Q = scan_pubkey
	// an e = privkey to ephemkey and then hash it.
	c := btc.StealthDH(sa.ScanKey[:], e)
	if *verbose {
		fmt.Println("c", hex.EncodeToString(c))
	}

	// 10. That hash is now "c". use ECC multiplication and addition to
	// calculate D + (c*G) where D = spend_pubkey, and G is the reference
	// point for secp256k1. This will give you a new pubkey. (we'll call it D')
	Dpr := btc.DeriveNextPublic(sa.SpendKeys[0][:], c)
	if *verbose {
		fmt.Println("Dpr", hex.EncodeToString(Dpr))
	}

	// 11. Create a normal P2KH output spending to D' as public key.
	adr := btc.NewAddrFromPubkey(Dpr, btc.AddrVerPubkey(*testnet))
	res[1] = &btc.TxOut{Value: value, Pk_script: adr.OutScript()}
	fmt.Println("Sending to stealth", adr.String())

	return
}