func NewUnspRec(l []byte) (uns *unspRec) { if l[64] != '-' { return nil } txid := btc.NewUint256FromString(string(l[:64])) if txid == nil { return nil } rst := strings.SplitN(string(l[65:]), " ", 2) vout, e := strconv.ParseUint(rst[0], 10, 32) if e != nil { return nil } uns = new(unspRec) uns.TxPrevOut.Hash = txid.Hash uns.TxPrevOut.Vout = uint32(vout) if len(rst) > 1 { uns.label = rst[1] } if first_determ_idx < len(keys) { 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(keys[first_determ_idx].Key, c) rec := btc.NewPrivateAddr(sec, ver_secret(), true) // stealth keys are always compressed rec.BtcAddr.Extra.Label = uns.label keys = append(keys, rec) uns.stealth = true uns.key = rec } } } return }
// 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)) } }