// Get tx with given id from the balance folder, of from cache func tx_from_balance(txid *btc.Uint256, error_is_fatal bool) (tx *btc.Tx) { if tx = loadedTxs[txid.Hash]; tx != nil { return // we have it in cache already } fn := "balance/" + txid.String() + ".tx" buf, er := ioutil.ReadFile(fn) if er == nil && buf != nil { var th [32]byte btc.ShaHash(buf, th[:]) if txid.Hash == th { tx, _ = btc.NewTx(buf) if error_is_fatal && tx == nil { println("Transaction is corrupt:", txid.String()) cleanExit(1) } } else if error_is_fatal { println("Transaction file is corrupt:", txid.String()) cleanExit(1) } } else if error_is_fatal { println("Error reading transaction file:", fn) if er != nil { println(er.Error()) } cleanExit(1) } loadedTxs[txid.Hash] = tx // store it in the cache return }
// LTC signing uses different seed string func HashFromMessage(msg []byte, out []byte) { const MessageMagic = "Litecoin Signed Message:\n" b := new(bytes.Buffer) btc.WriteVlen(b, uint32(len(MessageMagic))) b.Write([]byte(MessageMagic)) btc.WriteVlen(b, uint32(len(msg))) b.Write(msg) btc.ShaHash(b.Bytes(), out) }
func arm_stealth(p string) { var buf, b2 [256]byte create := p != "" fmt.Print("Enter seed password of the stealth key (empty line to abort) : ") le := sys.ReadPassword(buf[:]) if le <= 0 { fmt.Println("Aborted") return } if create { fmt.Print("Re-enter the seed password : "******"The passwords you entered do not match") return } } nw := make([]byte, 32) btc.ShaHash(buf[:le], nw) // seed sys.ClearBuffer(buf[:le]) btc.ShaHash(nw, nw) // 1st key wallet.ArmedStealthSecrets = append(wallet.ArmedStealthSecrets, nw) if create { fmt.Println("You have created a new stealth scan-key. Make sure to not forget this password!") pk := btc.PublicFromPrivate(nw, true) fmt.Println("Public hexdump:", hex.EncodeToString(pk)) fmt.Println(" Go to your wallet machine and execute:") fmt.Println(" wallet -scankey", hex.EncodeToString(pk), "-prefix 0") fmt.Println(" (change the prefix to a different value if you want)") } fmt.Println("Stealth key number", len(wallet.ArmedStealthSecrets)-1, "has been stored in memory") fmt.Println("Reloading the current wallet...") usif.ExecUiReq(&usif.OneUiReq{Handler: func(p string) { wallet.LoadWallet(wallet.MyWallet.FileName) }}) show_prompt = false }
// 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: "******"" { if !*singleask { fmt.Print("Re-enter the seed password (to be sure): ") var pass2 [1024]byte p2len := sys.ReadPassword(pass2[:]) if p2len != n || !bytes.Equal(pass[:n], pass2[:p2len]) { sys.ClearBuffer(pass2[:p2len]) println("The two passwords you entered do not match") return false } sys.ClearBuffer(pass2[:p2len]) } if *dump { // 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()) } else { fmt.Println("The seed password has been stored in", PassSeedFilename) } } } } calc_seed: for i := 0; i < n; i++ { if pass[i] < ' ' || pass[i] > 126 { fmt.Println("WARNING: Your secret contains non-printable characters") break } } if len(secret_seed) > 0 { x := append(secret_seed, pass[:n]...) sys.ClearBuffer(secret_seed) btc.ShaHash(x, seed) sys.ClearBuffer(x) } else { btc.ShaHash(pass[:n], seed) } sys.ClearBuffer(pass[:n]) return true }
// Get the secret seed and generate "keycnt" key pairs (both private and public) func make_wallet() { var lab string load_others() var seed_key []byte var hdwal *btc.HDWallet defer func() { sys.ClearBuffer(seed_key) if hdwal != nil { sys.ClearBuffer(hdwal.Key) sys.ClearBuffer(hdwal.ChCode) } }() pass := getpass() if pass == nil { cleanExit(0) } if waltype >= 1 && waltype <= 3 { seed_key = make([]byte, 32) btc.ShaHash(pass, seed_key) sys.ClearBuffer(pass) lab = fmt.Sprintf("Typ%c", 'A'+waltype-1) if waltype == 1 { println("WARNING: Wallet Type 1 is obsolete") } else if waltype == 2 { if type2sec != "" { d, e := hex.DecodeString(type2sec) if e != nil { println("t2sec error:", e.Error()) cleanExit(1) } type2_secret = d } else { type2_secret = make([]byte, 20) btc.RimpHash(seed_key, type2_secret) } } } else if waltype == 4 { lab = "TypHD" hdwal = btc.MasterKey(pass, testnet) sys.ClearBuffer(pass) } else { sys.ClearBuffer(pass) println("ERROR: Unsupported wallet type", waltype) cleanExit(1) } if *verbose { fmt.Println("Generating", keycnt, "keys, version", ver_pubkey(), "...") } first_determ_idx = len(keys) 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 if waltype == 1 { btc.ShaHash(seed_key, prv_key) copy(seed_key, prv_key) } else /*if waltype==4*/ { // HD wallet _hd := hdwal.Child(uint32(0x80000000 | i)) copy(prv_key, _hd.Key[1:]) sys.ClearBuffer(_hd.Key) sys.ClearBuffer(_hd.ChCode) } if *scankey != "" { new_stealth_address(prv_key) return } rec := btc.NewPrivateAddr(prv_key, ver_secret(), !uncompressed) if *pubkey != "" && *pubkey == rec.BtcAddr.String() { fmt.Println("Public address:", rec.BtcAddr.String()) fmt.Println("Public hexdump:", hex.EncodeToString(rec.BtcAddr.Pubkey)) return } rec.BtcAddr.Extra.Label = fmt.Sprint(lab, " ", i+1) keys = append(keys, rec) i++ } if *verbose { fmt.Println("Private keys re-generated") } // Calculate SegWit addresses segwit = make([]*btc.BtcAddr, len(keys)) for i, pk := range keys { if len(pk.Pubkey) != 33 { continue } h160 := btc.Rimp160AfterSha256(append([]byte{0, 20}, pk.Hash160[:]...)) segwit[i] = btc.NewAddrFromHash160(h160[:], btc.AddrVerScript(testnet)) } }
// 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") } }