Exemple #1
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)
	}
}
Exemple #2
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()
	}
}
Exemple #3
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))

}
Exemple #4
0
// this function signs either a message or a raw transaction hash
func sign_message() {
	var hash []byte

	if *signhash != "" {
		var er error
		hash, er = hex.DecodeString(*signhash)
		if er != nil {
			println("Incorrect content of -hash parameter")
			println(er.Error())
			return
		}
	}

	ad2s, e := btc.NewAddrFromString(*signaddr)
	if e != nil {
		println(e.Error())
		if *signhash != "" {
			println("Always use -sign <addr> along with -hash <msghash>")
		}
		return
	}

	var privkey []byte
	var compr bool

	for i := range publ_addrs {
		if publ_addrs[i].Hash160 == ad2s.Hash160 {
			privkey = priv_keys[i][:]
			compr = compressed_key[i]

			// Sign raw hash?
			if hash != nil {
				txsig := new(btc.Signature)
				txsig.HashType = 0x01
				r, s, e := btc.EcdsaSign(privkey, hash)
				if e != nil {
					println(e.Error())
					return
				}
				txsig.R.Set(r)
				txsig.S.Set(s)
				fmt.Println("PublicKey:", hex.EncodeToString(publ_addrs[i].Pubkey))
				fmt.Println(hex.EncodeToString(txsig.Bytes()))
				return
			}

			break
		}
	}
	if privkey == nil {
		println("You do not have a private key for", ad2s.String())
		return
	}

	var msg []byte
	if *message == "" {
		msg, _ = ioutil.ReadAll(os.Stdin)
	} else {
		msg = []byte(*message)
	}

	hash = make([]byte, 32)
	if litecoin {
		ltc.HashFromMessage(msg, hash)
	} else {
		btc.HashFromMessage(msg, hash)
	}

	btcsig := new(btc.Signature)
	var sb [65]byte
	sb[0] = 27
	if compr {
		sb[0] += 4
	}

	r, s, e := btc.EcdsaSign(privkey, hash)
	if e != nil {
		println(e.Error())
		return
	}
	btcsig.R.Set(r)
	btcsig.S.Set(s)

	rd := btcsig.R.Bytes()
	sd := btcsig.S.Bytes()
	copy(sb[1+32-len(rd):], rd)
	copy(sb[1+64-len(sd):], sd)

	rpk := btcsig.RecoverPublicKey(hash[:], 0)
	sa := btc.NewAddrFromPubkey(rpk.Bytes(compr), ad2s.Version)
	if sa.Hash160 == ad2s.Hash160 {
		fmt.Println(base64.StdEncoding.EncodeToString(sb[:]))
		return
	}

	rpk = btcsig.RecoverPublicKey(hash[:], 1)
	sa = btc.NewAddrFromPubkey(rpk.Bytes(compr), ad2s.Version)
	if sa.Hash160 == ad2s.Hash160 {
		sb[0]++
		fmt.Println(base64.StdEncoding.EncodeToString(sb[:]))
		return
	}
	println("Something went wrong. The message has not been signed.")
}
Exemple #5
0
func main() {
	var msg []byte

	flag.Parse()

	if *help || *addr == "" || *sign == "" {
		flag.PrintDefaults()
		return
	}

	ad, er := btc.NewAddrFromString(*addr)
	if !*litecoin && ad != nil && ad.Version == ltc.AddrVerPubkey(false) {
		*litecoin = true
	}
	if er != nil {
		println("Address:", er.Error())
		flag.PrintDefaults()
		return
	}

	nv, btcsig, er := btc.ParseMessageSignature(*sign)
	if er != nil {
		println("ParseMessageSignature:", er.Error())
		return
	}

	if *mess != "" {
		msg = []byte(*mess)
	} else if *mfil != "" {
		msg, er = ioutil.ReadFile(*mfil)
		if er != nil {
			println(er.Error())
			return
		}
	} else {
		fmt.Println("Enter the message:")
		msg, _ = ioutil.ReadAll(os.Stdin)
	}

	if *unix {
		fmt.Println("Enforcing Unix text format")
		msg = []byte(strings.Replace(string(msg), "\r", "", -1))
	}

	hash := make([]byte, 32)
	if *litecoin {
		ltc.HashFromMessage(msg, hash)
	} else {
		btc.HashFromMessage(msg, hash)
	}

	compressed := false
	if nv >= 31 {
		//println("compressed key")
		nv -= 4
		compressed = true
	}

	pub := btcsig.RecoverPublicKey(hash[:], int(nv-27))
	if pub != nil {
		pk := pub.Bytes(compressed)
		ok := btc.EcdsaVerify(pk, btcsig.Bytes(), hash)
		if ok {
			sa := btc.NewAddrFromPubkey(pk, ad.Version)
			if ad.Hash160 != sa.Hash160 {
				fmt.Println("BAD signature for", ad.String())
				os.Exit(1)
			} else {
				fmt.Println("Good signature for", sa.String())
			}
		} else {
			println("BAD signature")
			os.Exit(1)
		}
	} else {
		println("BAD, BAD, BAD signature")
		os.Exit(1)
	}
}
Exemple #6
0
// this function signs either a message or a raw hash
func sign_message() {
	var hash []byte
	var signkey *btc.PrivateAddr

	signkey = address_to_key(*signaddr)
	if signkey == nil {
		println("You do not have a private key for", *signaddr)
		return
	}

	if *signhash != "" {
		hash, er := hex.DecodeString(*signhash)
		if er != nil {
			println("Incorrect content of -hash parameter")
			println(er.Error())
			return
		} else if len(hash) > 0 {
			txsig := new(btc.Signature)
			txsig.HashType = 0x01
			r, s, e := btc.EcdsaSign(signkey.Key, hash)
			if e != nil {
				println(e.Error())
				return
			}
			txsig.R.Set(r)
			txsig.S.Set(s)
			fmt.Println("PublicKey:", hex.EncodeToString(signkey.BtcAddr.Pubkey))
			fmt.Println(hex.EncodeToString(txsig.Bytes()))
			return
		}
	}

	var msg []byte
	if *message == "" {
		msg, _ = ioutil.ReadAll(os.Stdin)
	} else {
		msg = []byte(*message)
	}

	hash = make([]byte, 32)
	if litecoin {
		ltc.HashFromMessage(msg, hash)
	} else {
		btc.HashFromMessage(msg, hash)
	}

	btcsig := new(btc.Signature)
	var sb [65]byte
	sb[0] = 27
	if signkey.IsCompressed() {
		sb[0] += 4
	}

	r, s, e := btc.EcdsaSign(signkey.Key, hash)
	if e != nil {
		println(e.Error())
		return
	}
	btcsig.R.Set(r)
	btcsig.S.Set(s)

	rd := btcsig.R.Bytes()
	sd := btcsig.S.Bytes()
	copy(sb[1+32-len(rd):], rd)
	copy(sb[1+64-len(sd):], sd)

	rpk := btcsig.RecoverPublicKey(hash[:], 0)
	sa := btc.NewAddrFromPubkey(rpk.Bytes(signkey.IsCompressed()), signkey.BtcAddr.Version)
	if sa.Hash160 == signkey.BtcAddr.Hash160 {
		fmt.Println(base64.StdEncoding.EncodeToString(sb[:]))
		return
	}

	rpk = btcsig.RecoverPublicKey(hash[:], 1)
	sa = btc.NewAddrFromPubkey(rpk.Bytes(signkey.IsCompressed()), signkey.BtcAddr.Version)
	if sa.Hash160 == signkey.BtcAddr.Hash160 {
		sb[0]++
		fmt.Println(base64.StdEncoding.EncodeToString(sb[:]))
		return
	}
	println("Something went wrong. The message has not been signed.")
}
Exemple #7
0
// load the content of the "balance/" folder
func load_balance(showbalance bool) {
	var unknownInputs, multisigInputs int
	f, e := os.Open("balance/unspent.txt")
	if e != nil {
		println(e.Error())
		return
	}
	rd := bufio.NewReader(f)
	for {
		l, _, e := rd.ReadLine()
		if len(l) == 0 && e != nil {
			break
		}
		if l[64] == '-' {
			txid := btc.NewUint256FromString(string(l[:64]))
			rst := strings.SplitN(string(l[65:]), " ", 2)
			vout, _ := strconv.ParseUint(rst[0], 10, 32)
			uns := new(btc.TxPrevOut)
			copy(uns.Hash[:], txid.Hash[:])
			uns.Vout = uint32(vout)
			lab := ""
			if len(rst) > 1 {
				lab = rst[1]
			}

			str := string(l)
			if sti := strings.Index(str, "_StealthC:"); sti != -1 {
				c, e := hex.DecodeString(str[sti+10 : sti+10+64])
				if e != nil {
					fmt.Println("ERROR at stealth", txid.String(), vout, e.Error())
				} else {
					// add a new key to the wallet
					sec := btc.DeriveNextPrivate(first_seed[:], c)
					is_stealth[len(priv_keys)] = true
					priv_keys = append(priv_keys, sec)
					labels = append(labels, lab)
					pub_key := btc.PublicFromPrivate(sec, true)
					publ_addrs = append(publ_addrs, btc.NewAddrFromPubkey(pub_key, AddrVerPubkey()))
					compressed_key = append(compressed_key, true) // stealth keys are always compressed
				}
			}

			if _, ok := loadedTxs[txid.Hash]; !ok {
				tf, _ := os.Open("balance/" + txid.String() + ".tx")
				if tf != nil {
					siz, _ := tf.Seek(0, os.SEEK_END)
					tf.Seek(0, os.SEEK_SET)
					buf := make([]byte, siz)
					tf.Read(buf)
					tf.Close()
					th := btc.Sha2Sum(buf)
					if bytes.Equal(th[:], txid.Hash[:]) {
						tx, _ := btc.NewTx(buf)
						if tx != nil {
							loadedTxs[txid.Hash] = tx
						} else {
							println("transaction is corrupt:", txid.String())
						}
					} else {
						println("transaction file is corrupt:", txid.String())
						os.Exit(1)
					}
				} else {
					println("transaction file not found:", txid.String())
					os.Exit(1)
				}
			}

			// Sum up all the balance and check if we have private key for this input
			uo := UO(uns)

			add_it := true

			if !btc.IsP2SH(uo.Pk_script) {
				fnd := false
				for j := range publ_addrs {
					if publ_addrs[j].Owns(uo.Pk_script) {
						fnd = true
						break
					}
				}

				if !fnd {
					if *onlvalid {
						add_it = false
					}
					if showbalance {
						unknownInputs++
						if *verbose {
							ss := uns.String()
							ss = ss[:8] + "..." + ss[len(ss)-12:]
							fmt.Println(ss, "does not belong to your wallet (cannot sign it)")
						}
					}
				}
			} else {
				if *onlvalid {
					add_it = false
				}
				if *verbose {
					ss := uns.String()
					ss = ss[:8] + "..." + ss[len(ss)-12:]
					fmt.Println(ss, "belongs to a multisig address")
				}
				multisigInputs++
			}

			if add_it {
				unspentOuts = append(unspentOuts, uns)
				unspentOutsLabel = append(unspentOutsLabel, lab)
				totBtc += UO(uns).Value
			}
		}
	}
	f.Close()
	fmt.Printf("You have %.8f BTC in %d unspent outputs. %d inputs are multisig type\n",
		float64(totBtc)/1e8, len(unspentOuts), multisigInputs)
	if showbalance {
		if unknownInputs > 0 {
			fmt.Printf("WARNING: Some inputs (%d) cannot be spent with this password (-v to print them)\n", unknownInputs)
		}
	}
}
Exemple #8
0
func load_others() {
	f, e := os.Open(RawKeysFilename)
	if e == nil {
		defer f.Close()
		td := bufio.NewReader(f)
		for {
			li, _, _ := td.ReadLine()
			if li == nil {
				break
			}
			if len(li) == 0 {
				continue
			}
			pk := strings.SplitN(strings.Trim(string(li), " "), " ", 2)
			if pk[0][0] == '#' {
				continue // Just a comment-line
			}

			pkb := btc.Decodeb58(pk[0])

			if pkb == nil {
				println("Decodeb58 failed:", pk[0])
				continue
			}

			if len(pkb) < 6 {
				println("Syntax error in the raw keys file:", pk[0])
				continue
			}

			if len(pkb) != 37 && len(pkb) != 38 {
				println(pk[0][:6], "has wrong key", len(pkb))
				println(hex.EncodeToString(pkb))
				continue
			}

			if pkb[0] != AddrVerSecret() {
				println(pk[0][:6], "has version", pkb[0], "while we expect", AddrVerSecret())
				fmt.Println("You may want to play with -t or -ltc switch")
				continue
			}

			var sh [32]byte
			var compr bool

			if len(pkb) == 37 {
				// old/uncompressed key
				sh = btc.Sha2Sum(pkb[0:33])
				if !bytes.Equal(sh[:4], pkb[33:37]) {
					println(pk[0][:6], "checksum error")
					continue
				}
				compr = false
			} else {
				if pkb[33] != 1 {
					println(pk[0][:6], "a key of length 38 bytes must be compressed")
					continue
				}

				sh = btc.Sha2Sum(pkb[0:34])
				if !bytes.Equal(sh[:4], pkb[34:38]) {
					println(pk[0][:6], "checksum error")
					continue
				}
				compr = true
			}

			key := pkb[1:33]
			pub := btc.PublicFromPrivate(key, compr)
			if pub == nil {
				println("PublicFromPrivate failed")
				os.Exit(1)
			}

			priv_keys = append(priv_keys, key)
			compressed_key = append(compressed_key, compr)
			publ_addrs = append(publ_addrs, btc.NewAddrFromPubkey(pub, AddrVerPubkey()))
			if len(pk) > 1 {
				labels = append(labels, pk[1])
			} else {
				labels = append(labels, fmt.Sprint("Other ", len(priv_keys)))
			}
		}
		if *verbose {
			fmt.Println(len(priv_keys), "keys imported from", RawKeysFilename)
		}
	} else {
		if *verbose {
			fmt.Println("You can also have some dumped (b58 encoded) priv keys in file", RawKeysFilename)
		}
	}
}
Exemple #9
0
// Get the secret seed and generate "keycnt" key pairs (both private and public)
func make_wallet() {
	var lab string

	load_others()

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

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

	switch waltype {
	case 1:
		lab = "TypA"
		println("WARNING: Wallet Type 1 is obsolete")

	case 2:
		lab = "TypB"
		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)
		}

	case 3:
		lab = "TypC"

	default:
		println("ERROR: Unsupported wallet type", waltype)
		os.Exit(0)
	}

	if *verbose {
		fmt.Println("Generating", keycnt, "keys, version", AddrVerPubkey(), "...")
	}
	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, AddrVerPubkey())

			if *pubkey != "" && *pubkey == adr.String() {
				fmt.Println("Public address:", adr.String())
				fmt.Println("Public hexdump:", 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")
	}
}
Exemple #10
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)
}