예제 #1
0
func main() {
	var testnet bool

	if len(os.Args) < 3 {
		fmt.Println("Specify B_secret, A_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
	}
	A_public_key, er := hex.DecodeString(os.Args[2])
	if er != nil {
		println("Error parsing A_public_key:", er.Error())
		os.Exit(1)
	}

	pubk, er := btc.NewPublicKey(A_public_key)
	if er != nil {
		println("Invalid valid public key:", er.Error())
		os.Exit(1)
	}
	compressed := len(A_public_key) == 33

	B_secret, er := hex.DecodeString(os.Args[1])
	if er != nil {
		println("Error parsing B_secret:", er.Error())
		os.Exit(1)
	}
	sec := new(big.Int).SetBytes(B_secret)

	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(pubk.Bytes(compressed)))
	fmt.Println("#", hex.EncodeToString(sec.Bytes()))

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

		pubk.X, pubk.Y = btc.DeriveNextPublic(pubk.X, pubk.Y, sec)
	}
}
예제 #2
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)
	}
}
예제 #3
0
파일: type2next.go 프로젝트: raszzh/gocoin
func main() {
	if len(os.Args) < 3 {
		fmt.Println("Specify B_secret and A_public_key to get the next Type-2 deterministic address")
		fmt.Println("Add -t as the third argument to work with Testnet addresses.")
		return
	}
	A_public_key, er := hex.DecodeString(os.Args[2])
	if er != nil {
		println("Error parsing A_public_key:", er.Error())
		os.Exit(1)
	}

	pubk, er := btc.NewPublicKey(A_public_key)
	if er != nil {
		println("Invalid valid public key:", er.Error())
		os.Exit(1)
	}
	compressed := len(A_public_key) == 33

	B_secret, er := hex.DecodeString(os.Args[1])
	if er != nil {
		println("Error parsing B_secret:", er.Error())
		os.Exit(1)
	}
	sec := new(big.Int).SetBytes(B_secret)

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

	// Old address
	fmt.Print(btc.NewAddrFromPubkey(pubk.Bytes(compressed), btc.AddrVerPubkey(testnet)).String(), " => ")
	pubk.X, pubk.Y = btc.DeriveNextPublic(pubk.X, pubk.Y, sec)

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

}
예제 #4
0
파일: type2next.go 프로젝트: vipwzw/gocoin
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))

}
예제 #5
0
파일: textui.go 프로젝트: vipwzw/gocoin
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))
}
예제 #6
0
파일: unspent.go 프로젝트: vipwzw/gocoin
// 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, btc.AddrVerPubkey(*testnet)))
					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)
		}
	}
}
예제 #7
0
파일: mkmulti.go 프로젝트: vipwzw/gocoin
/*
{
"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)
}
예제 #8
0
파일: stealth.go 프로젝트: vipwzw/gocoin
// 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
}