func (wlt *Wallet) GenerateAddresses(num int) []cipher.Address { var seckeys []cipher.SecKey var sd []byte var err error if len(wlt.Entries) == 0 { sd, seckeys = cipher.GenerateDeterministicKeyPairsSeed([]byte(wlt.getLastSeed()), num) } else { sd, err = hex.DecodeString(wlt.getLastSeed()) if err != nil { log.Panicf("decode hex seed failed,%v", err) } sd, seckeys = cipher.GenerateDeterministicKeyPairsSeed(sd, num) } wlt.setLastSeed(hex.EncodeToString(sd)) addrs := make([]cipher.Address, len(seckeys)) for i, s := range seckeys { p := cipher.PubKeyFromSecKey(s) a := cipher.AddressFromPubKey(p) addrs[i] = a wlt.Entries = append(wlt.Entries, WalletEntry{ Address: a, Secret: s, Public: p, }) } return addrs }
// GenerateAddresses generates bitcoin addresses. func GenerateAddresses(seed []byte, num int) (string, []coin.AddressEntry) { sd, seckeys := cipher.GenerateDeterministicKeyPairsSeed(seed, num) entries := make([]coin.AddressEntry, num) for i, sec := range seckeys { pub := cipher.PubKeyFromSecKey(sec) entries[i].Address = cipher.BitcoinAddressFromPubkey(pub) entries[i].Public = pub.Hex() if !HideSeckey { entries[i].Secret = cipher.BitcoinWalletImportFormatFromSeckey(sec) } } return fmt.Sprintf("%2x", sd), entries }
func mustUpdateWallet(wlt *Wallet, dir string, tm int64) { // update version meta data. wlt.Meta["version"] = version // update lastSeed meta data. lsd, seckeys := cipher.GenerateDeterministicKeyPairsSeed([]byte(wlt.Meta["seed"]), 1) if seckeys[0] != wlt.Entries[0].Secret { logger.Panic("update wallet failed, seckey not match") } wlt.Meta["lastSeed"] = hex.EncodeToString(lsd) // update tm meta data. wlt.Meta["tm"] = fmt.Sprintf("%v", tm) if err := wlt.Save(dir); err != nil { logger.Panic(err) } }
//////////////////////////////////////////////////////////////////////////////// // // main // //////////////////////////////////////////////////////////////////////////////// func main() { cmd_line_args_process() // PERFORMANCE: cipher.DebugLevel1 = false cipher.DebugLevel2 = false var X []*MinimalConnectionManager var hack_global_seqno uint64 = 0 seed := "hdhdhdkjashfy7273" _, SecKeyArray := cipher.GenerateDeterministicKeyPairsSeed([]byte(seed), Cfg_simu_num_node) for i := 0; i < Cfg_simu_num_node; i++ { cm := MinimalConnectionManager{} // Reason for mutual registration: (1) when conn man receives // messages, it needs to notify the node; (2) when node has // processed a mesage, it might need to use conn man to send // some data out. nodePtr := consensus.NewConsensusParticipantPtr(&cm) s := SecKeyArray[i] nodePtr.SetPubkeySeckey(cipher.PubKeyFromSecKey(s), s) cm.theNodePtr = nodePtr X = append(X, &cm) } if false { fmt.Printf("Got %d nodes\n", len(X)) } if Cfg_simu_topology_is_random { fmt.Printf("CONFIG Topology: connecting %d nodes randomly with approx"+ " %d nearest-neighbors in and approx %d nearest-neighbors out.\n", Cfg_simu_num_node, Cfg_simu_fanout_per_node, Cfg_simu_fanout_per_node) for i, _ := range X { cm := X[i] for g := 0; g < Cfg_simu_fanout_per_node; g++ { j := mathrand.Intn(Cfg_simu_num_node) if i != j { cm.RegisterPublisher(X[j]) } } } } else { fmt.Printf("CONFIG Topology: connecting %d nodes via one (thick)"+ " circle with approx %d nearest-neighbors in and approx %d "+ "nearest-neighbors out.\n", Cfg_simu_num_node, Cfg_simu_fanout_per_node, Cfg_simu_fanout_per_node) n := len(X) for i := 0; i < n; i++ { cm := X[i] c_left := int(Cfg_simu_fanout_per_node / 2) c_right := Cfg_simu_fanout_per_node - c_left for c := 0; c < c_left; c++ { j := (i - 1 - c + n) % n cm.RegisterPublisher(X[j]) } for c := 0; c < c_right; c++ { j := (i + 1 + c) % n cm.RegisterPublisher(X[j]) } } } // Connect. PROD: This should request connections. The // connections can be accepted, rejected or never answered. Such // replies are asynchronous. SIMU: we connect synchronously. for i, _ := range X { X[i].RequestConnectionToAllMyPublisher() } global_seqno2h := make(map[uint64]cipher.SHA256) global_seqno2h_alt := make(map[uint64]cipher.SHA256) iter := 0 block_round := 0 done_processing_messages := false for ; iter < Cfg_simu_num_iter; iter++ { if true { if block_round < Cfg_simu_num_block_round { // NOTE: Propagating blocks from here is a // simplification/HACK: it implies that we have // knowledge of when messaging due to previous // activity (blocks and connections) has // stopped. Again, we make blocks from here for // debugging and testing only. //x := secp256k1.RandByte(888) // Random data in SIMU. x := make([]byte, 888) mathrand.Read(x) h := cipher.SumSHA256(x) // Its hash. //x_alt := secp256k1.RandByte(888) // Random data in SIMU. x_alt := make([]byte, 888) mathrand.Read(x) h_alt := cipher.SumSHA256(x_alt) // Its hash. global_seqno2h[hack_global_seqno] = h global_seqno2h_alt[hack_global_seqno] = h_alt indices := get_random_index_subset(Cfg_simu_num_node, Cfg_simu_num_blockmaker) if Cfg_debug_show_block_maker { fmt.Printf("block_round=%d, Random indices of block-"+ "makers: %v\n", block_round, indices) } n_forkers := int(Cfg_simu_prob_malicious * float64(len(indices))) for i := 0; i < len(indices); i++ { // TODO: Have many nodes send same block, and a few nodes // send a different block. Research the conditions under // which the block published by the majority would // dominate the other one. index := indices[i] nodePtr := X[index].GetNode() malicious := (i < n_forkers) duplicate := (mathrand.Float64() < Cfg_simu_prob_duplicate) ph := &h if malicious { ph = &h_alt } rep := 1 if duplicate { rep = 2 } // // WARNING: In a reslistic simulation, one would // need to remove the assumption of knowing global // properties such as 'hack_global_seqno' // if malicious { fmt.Printf(">>>>>> NODE (index,pubkey)=(%d,%s) is"+ " publishing ALTERNATIVE block\n", index, nodePtr.Pubkey.Hex()[:8]) } for j := 0; j < rep; j++ { // Signing same hash multipe times produces different // signatures (for a good reason). We do it // here to test if malicious re-publishing is // detected properly. propagate_hash_from_node(*ph, nodePtr, true, hack_global_seqno) } } hack_global_seqno += 1 block_round += 1 } else { done_processing_messages = true break // <<<<<<<< } } } zzz := "done" if !done_processing_messages { zzz = "***NOT done***" } fmt.Printf("Done (i) making Blocks, %s (ii) processing responses."+ " See stats on the next few lines. Used iterations=%d, unused"+ " iterations=%d. Exiting the event loop now.\n", zzz, iter, Cfg_simu_num_iter-iter) print_stat(X, iter) if Cfg_debug_node_final_state { for i, _ := range X { fmt.Printf("FILE_FinalState.txt|NODE i=%d ", i) X[i].GetNode().Print() fmt.Printf("\n") } } if Cfg_debug_node_summary { Simulate_compare_node_StateQueue(X, global_seqno2h, global_seqno2h_alt) } }