func load_wallet(fn string) { if fn == "." { fmt.Println("Default wallet from", common.GocoinHomeDir+"wallet/DEFAULT") wallet.LoadWallet(common.GocoinHomeDir + "wallet/DEFAULT") } else if fn == "-" { fmt.Println("Reloading wallet from", wallet.MyWallet.FileName) wallet.LoadWallet(wallet.MyWallet.FileName) fmt.Println("Dumping current wallet from", wallet.MyWallet.FileName) } else if fn != "" { fmt.Println("Switching to wallet from", fn) wallet.LoadWallet(fn) } if wallet.MyWallet == nil { fmt.Println("No wallet loaded") return } for i := range wallet.MyWallet.Addrs { fmt.Println(" ", wallet.MyWallet.Addrs[i].String(), wallet.MyWallet.Addrs[i].Label()) } }
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 }
func show_balance(p string) { if p == "sum" { fmt.Print(wallet.DumpBalance(wallet.MyBalance, nil, false, true)) return } if p != "" { fmt.Println("Using wallet from file", p, "...") wallet.LoadWallet(p) } if wallet.MyWallet == nil { println("You have no loaded wallet") return } if len(wallet.MyWallet.Addrs) == 0 { println("Your loaded wallet has no addresses") return } fmt.Print(wallet.UpdateBalanceFolder()) fmt.Println("Your balance data has been saved to the 'balance/' folder.") fmt.Println("You nend to move this folder to your wallet PC, to spend the coins.") }
func host_init() { var e error BtcRootDir := sys.BitcoinHome() if common.CFG.Datadir == "" { common.GocoinHomeDir = BtcRootDir + "gocoin" + string(os.PathSeparator) } else { common.GocoinHomeDir = common.CFG.Datadir + string(os.PathSeparator) } common.Testnet = common.CFG.Testnet // So chaging this value would will only affect the behaviour after restart if common.CFG.Testnet { // testnet3 common.GenesisBlock = btc.NewUint256FromString("000000000933ea01ad0ee984209779baaec3ced90fa3f408719526f8d77f4943") common.Magic = [4]byte{0x0B, 0x11, 0x09, 0x07} common.GocoinHomeDir += "tstnet" + string(os.PathSeparator) BtcRootDir += "testnet3" + string(os.PathSeparator) network.AlertPubKey, _ = hex.DecodeString("04302390343f91cc401d56d68b123028bf52e5fca1939df127f63c6467cdf9c8e2c14b61104cf817d0b780da337893ecc4aaff1309e536162dabbdb45200ca2b0a") common.MaxPeersNeeded = 100 } else { common.GenesisBlock = btc.NewUint256FromString("000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f") common.Magic = [4]byte{0xF9, 0xBE, 0xB4, 0xD9} common.GocoinHomeDir += "btcnet" + string(os.PathSeparator) network.AlertPubKey, _ = hex.DecodeString("04fc9702847840aaf195de8442ebecedf5b095cdbb9bc716bda9110971b28a49e0ead8564ff0db22209e0374782c093bb899692d524e9d6a6956e7c5ecbcd68284") common.MaxPeersNeeded = 1000 } // Lock the folder os.MkdirAll(common.GocoinHomeDir, 0770) os.MkdirAll(common.GocoinHomeDir+"wallet", 0770) sys.LockDatabaseDir(common.GocoinHomeDir) fi, e := os.Stat(common.GocoinHomeDir + "blockchain.dat") if e != nil { os.RemoveAll(common.GocoinHomeDir) fmt.Println("You seem to be running Gocoin for the fist time on this PC") fi, e = os.Stat(BtcRootDir + "blocks/blk00000.dat") if e == nil && fi.Size() > 1024*1024 { fmt.Println("There is a database from Satoshi client on your disk...") if textui.AskYesNo("Do you want to import this database into Gocoin?") { import_blockchain(BtcRootDir + "blocks") } } } // Create default wallet file if does not exist default_wallet_fn := common.GocoinHomeDir + "wallet" + string(os.PathSeparator) + wallet.DefaultFileName fi, _ = os.Stat(default_wallet_fn) if fi == nil || fi.IsDir() { fmt.Println(default_wallet_fn, "not found") old_wallet_location := common.GocoinHomeDir + "wallet.txt" // If there is wallet.txt rename it to default. fi, _ := os.Stat(old_wallet_location) if fi != nil && !fi.IsDir() { fmt.Println("Taking wallet.txt as", default_wallet_fn) os.Rename(old_wallet_location, default_wallet_fn) } else { fmt.Println("Creating empty default wallet at", default_wallet_fn) ioutil.WriteFile(default_wallet_fn, []byte(fmt.Sprintln("# Put your wallet's public addresses here")), 0660) } } // cache the current balance of all the addresses from the current wallet files wallet.LoadAllWallets() fmt.Println("Loading UTXO database while checking balance of", len(wallet.MyWallet.Addrs), "addresses... (press Ctrl-C to interrupt)") __exit := make(chan bool) __done := make(chan bool) go func() { for { select { case s := <-killchan: fmt.Println(s) chain.AbortNow = true case <-__exit: __done <- true return } } }() ext := &chain.NewChanOpts{NotifyTxAdd: wallet.TxNotifyAdd, NotifyTxDel: wallet.TxNotifyDel, LoadWalk: wallet.NewUTXO} sta := time.Now().UnixNano() common.BlockChain = chain.NewChainExt(common.GocoinHomeDir, common.GenesisBlock, common.FLAG.Rescan, ext) sto := time.Now().UnixNano() if chain.AbortNow { fmt.Printf("Blockchain opening aborted after %.3f seconds\n", float64(sto-sta)/1e9) common.BlockChain.Close() sys.UnlockDatabaseDir() os.Exit(1) } wallet.ChainInitDone() al, sy := sys.MemUsed() fmt.Printf("Blockchain open in %.3f seconds. %d + %d MB of RAM used (%d)\n", float64(sto-sta)/1e9, al>>20, qdb.ExtraMemoryConsumed>>20, sy>>20) common.StartTime = time.Now() __exit <- true _ = <-__done // ... and now load the dafault wallet wallet.LoadWallet(default_wallet_fn) if wallet.MyWallet != nil { wallet.UpdateBalance() fmt.Print(wallet.DumpBalance(wallet.MyBalance, nil, false, true)) } }
func p_wal(w http.ResponseWriter, r *http.Request) { if !ipchecker(r) { return } if checksid(r) { if len(r.Form["wal"]) > 0 { wallet.LoadWallet(common.GocoinHomeDir + "wallet" + string(os.PathSeparator) + r.Form["wal"][0]) http.Redirect(w, r, "/wal", http.StatusFound) return } if len(r.Form["setunused"]) > 0 { i, er := strconv.ParseUint(r.Form["setunused"][0], 10, 32) if er == nil && int(i) < len(wallet.MyWallet.Addrs) { if wallet.MoveToUnused(wallet.MyWallet.Addrs[i].Enc58str, wallet.MyWallet.Addrs[i].Extra.Wallet) { wallet.LoadWallet(wallet.MyWallet.FileName) } } http.Redirect(w, r, "/wal", http.StatusFound) return } if len(r.Form["setlabel"]) > 0 && len(r.Form["lab"]) > 0 { i, er := strconv.ParseUint(r.Form["setlabel"][0], 10, 32) if er == nil && int(i) < len(wallet.MyWallet.Addrs) { if wallet.SetLabel(int(i), r.Form["lab"][0]) { wallet.LoadWallet(wallet.MyWallet.FileName) } } http.Redirect(w, r, "/wal", http.StatusFound) return } } page := load_template("wallet.html") wal1 := load_template("wallet_qsw.html") addr := load_template("wallet_adr.html") page = strings.Replace(page, "{TOTAL_BTC}", fmt.Sprintf("%.8f", float64(wallet.LastBalance)/1e8), 1) page = strings.Replace(page, "{UNSPENT_OUTS}", fmt.Sprint(len(wallet.MyBalance)), 1) fis, er := ioutil.ReadDir(common.GocoinHomeDir + "wallet/") if er == nil { for i := range fis { if !fis[i].IsDir() && fis[i].Size() > 1 && fis[i].Name()[0] != '.' { s := strings.Replace(wal1, "{WALLET_NAME}", fis[i].Name(), -1) page = templ_add(page, "<!--ONEWALLET-->", s) } } } wallet.BalanceMutex.Lock() if wallet.MyWallet != nil { page = strings.Replace(page, "<!--WALLET_FILENAME-->", wallet.MyWallet.FileName, 1) wc, er := ioutil.ReadFile(wallet.MyWallet.FileName) if er == nil { page = strings.Replace(page, "{WALLET_DATA}", string(wc), 1) } for i := range wallet.MyWallet.Addrs { ad := addr lab := wallet.MyWallet.Addrs[i].Extra.Label if wallet.MyWallet.Addrs[i].Extra.Virgin { lab += " ***" } ad = strings.Replace(ad, "<!--WAL_ROW_IDX-->", fmt.Sprint(i), -1) ad = strings.Replace(ad, "<!--WAL_ADDR-->", wallet.MyWallet.Addrs[i].Enc58str, 1) if len(wallet.MyWallet.Addrs[i].Enc58str) > 80 { ad = strings.Replace(ad, "<!--WAL_ADDR_STYLE-->", "addr_long", 1) } else { ad = strings.Replace(ad, "<!--WAL_ADDR_STYLE-->", "addr_norm", 1) } ad = strings.Replace(ad, "<!--WAL_WALLET-->", html.EscapeString(wallet.MyWallet.Addrs[i].Extra.Wallet), 1) ad = strings.Replace(ad, "<!--WAL_LABEL-->", html.EscapeString(lab), 1) ms, msr := wallet.IsMultisig(wallet.MyWallet.Addrs[i]) if ms { if msr != nil { ad = strings.Replace(ad, "<!--WAL_MULTISIG-->", fmt.Sprintf("%d of %d", msr.KeysRequired, msr.KeysProvided), 1) } else { ad = strings.Replace(ad, "<!--WAL_MULTISIG-->", "Yes", 1) } } else { ad = strings.Replace(ad, "<!--WAL_MULTISIG-->", "No", 1) } rec := wallet.CachedAddrs[wallet.MyWallet.Addrs[i].Hash160] if rec == nil { ad = strings.Replace(ad, "<!--WAL_BALANCE-->", "?", 1) ad = strings.Replace(ad, "<!--WAL_OUTCNT-->", "?", 1) page = templ_add(page, "<!--ONE_WALLET_ADDR-->", ad) continue } if !rec.InWallet { ad = strings.Replace(ad, "<!--WAL_BALANCE-->", "WTF", 1) ad = strings.Replace(ad, "<!--WAL_OUTCNT-->", "-2", 1) page = templ_add(page, "<!--ONE_WALLET_ADDR-->", ad) continue } ucu := wallet.CacheUnspent[rec.CacheIndex] if ucu == nil { ad = strings.Replace(ad, "<!--WAL_BALANCE-->", "WTF", 1) ad = strings.Replace(ad, "<!--WAL_OUTCNT-->", "-3", 1) page = templ_add(page, "<!--ONE_WALLET_ADDR-->", ad) continue } if len(ucu.AllUnspentTx) > 0 { ad = strings.Replace(ad, "<!--WAL_BALANCE-->", fmt.Sprintf("%.8f", float64(rec.Value)/1e8), 1) ad = strings.Replace(ad, "<!--WAL_OUTCNT-->", fmt.Sprint(len(ucu.AllUnspentTx)), 1) } else if wallet.MyWallet.Addrs[i].Extra.Virgin { // Do not display virgin addresses with zero balance continue } else if wallet.MyWallet.Addrs[i].Extra.Wallet != wallet.UnusedFileName && wallet.MyWallet.Addrs[i].Extra.Wallet != wallet.AddrBookFileName { ad = strings.Replace(ad, "<!--WAL_OUTCNT-->", fmt.Sprint("<a href=\"javascript:setunused(", i, ")\" title=\"Move to "+ wallet.UnusedFileName+"\"><img src=\"webui/del.png\"></a>"), 1) } page = templ_add(page, "<!--ONE_WALLET_ADDR-->", ad) } page = strings.Replace(page, "{WALLET_NAME}", filepath.Base(wallet.MyWallet.FileName), 1) } else { strings.Replace(page, "<!--WALLET_FILENAME-->", "<i>no wallet loaded</i>", 1) page = strings.Replace(page, "{WALLET_NAME}", "", -1) } wallet.BalanceMutex.Unlock() write_html_head(w, r) w.Write([]byte(page)) write_html_tail(w) }
func write_html_head(w http.ResponseWriter, r *http.Request) { start_time = time.Now() sessid := sid(r) if sessid == "" { sessid = new_session_id(w) } // Quick switch wallet if checksid(r) && len(r.Form["qwalsel"]) > 0 { wallet.LoadWallet(common.GocoinHomeDir + "wallet" + string(os.PathSeparator) + r.Form["qwalsel"][0]) http.Redirect(w, r, r.URL.Path, http.StatusFound) return } // If currently selected wallet is address book and we are not on the wallet page - switch to default if r.URL.Path != "/wal" && wallet.MyWallet != nil && strings.HasSuffix(wallet.MyWallet.FileName, string(os.PathSeparator)+wallet.AddrBookFileName) { wallet.LoadWallet(common.GocoinHomeDir + "wallet" + string(os.PathSeparator) + wallet.DefaultFileName) http.Redirect(w, r, r.URL.Path, http.StatusFound) return } s := load_template("page_head.html") s = strings.Replace(s, "{VERSION}", lib.Version, 1) s = strings.Replace(s, "{SESSION_ID}", sessid, 1) if r.URL.Path != "/" { s = strings.Replace(s, "{HELPURL}", "help#"+r.URL.Path[1:], 1) } else { s = strings.Replace(s, "{HELPURL}", "help", 1) } if common.Testnet { s = strings.Replace(s, "{TESTNET}", "Testnet ", 1) } else { s = strings.Replace(s, "{TESTNET}", "", 1) } for i := range webuimenu { var x string if i > 0 && i < len(webuimenu)-1 { x = " | " } x += "<a " if r.URL.Path == webuimenu[i][0] { x += "class=\"menuat\" " } x += "href=\"" + webuimenu[i][0] + "\">" + webuimenu[i][1] + "</a>" if i == len(webuimenu)-1 { s = strings.Replace(s, "{MENU_LEFT}", "", 1) s = strings.Replace(s, "{MENU_RIGHT}", x, 1) } else { s = strings.Replace(s, "{MENU_LEFT}", x+"{MENU_LEFT}", 1) } } // Quick wallet switch fis, er := ioutil.ReadDir(common.GocoinHomeDir + "wallet/") if er == nil { for i := range fis { if !fis[i].IsDir() && fis[i].Size() > 1 && fis[i].Name()[0] != '.' && fis[i].Name() != wallet.AddrBookFileName { var ow string if wallet.MyWallet != nil && strings.HasSuffix(wallet.MyWallet.FileName, string(os.PathSeparator)+fis[i].Name()) { ow = "<option selected>" + fis[i].Name() + "</option>" } else { ow = "<option>" + fis[i].Name() + "</option>" } s = templ_add(s, "<!--QUICK_WALLET_SELECT-->", ow) } } } w.Write([]byte(s)) }
func p_cfg(w http.ResponseWriter, r *http.Request) { if !ipchecker(r) { return } common.LockCfg() defer common.UnlockCfg() if r.Method == "POST" { if len(r.Form["configjson"]) > 0 { e := json.Unmarshal([]byte(r.Form["configjson"][0]), &common.CFG) if e == nil { common.Reset() } if len(r.Form["save"]) > 0 { common.SaveConfig() } http.Redirect(w, r, "/", http.StatusFound) return } if len(r.Form["walletdata"]) > 0 && len(r.Form["walletfname"]) > 0 { fn := r.Form["walletfname"][0] if fn != "" { fn = common.GocoinHomeDir + "wallet" + string(os.PathSeparator) + fn ioutil.WriteFile(fn, []byte(r.Form["walletdata"][0]), 0660) wallet.LoadWallet(fn) } http.Redirect(w, r, "/wal", http.StatusFound) return } if len(r.Form["shutdown"]) > 0 { usif.Exit_now = true w.Write([]byte("Your node should shut down soon")) return } return } // for any other GET we need a matching session-id if !checksid(r) { new_session_id(w) return } if len(r.Form["txponoff"]) > 0 { common.CFG.TXPool.Enabled = !common.CFG.TXPool.Enabled http.Redirect(w, r, "txs", http.StatusFound) return } if len(r.Form["txronoff"]) > 0 { common.CFG.TXRoute.Enabled = !common.CFG.TXRoute.Enabled http.Redirect(w, r, "txs", http.StatusFound) return } if len(r.Form["lonoff"]) > 0 { common.SetListenTCP(common.IsListenTCP(), true) http.Redirect(w, r, "net", http.StatusFound) return } if len(r.Form["drop"]) > 0 { network.DropPeer(r.Form["drop"][0]) http.Redirect(w, r, "net", http.StatusFound) return } if len(r.Form["savecfg"]) > 0 { dat, _ := json.Marshal(&common.CFG) if dat != nil { ioutil.WriteFile(common.ConfigFile, dat, 0660) } http.Redirect(w, r, "/", http.StatusFound) return } if len(r.Form["beepblock"]) > 0 { common.CFG.Beeps.NewBlock = !common.CFG.Beeps.NewBlock http.Redirect(w, r, "/", http.StatusFound) return } if len(r.Form["freemem"]) > 0 { sys.FreeMem() http.Redirect(w, r, "/", http.StatusFound) return } if len(r.Form["mid"]) > 0 { v, e := strconv.ParseUint(r.Form["mid"][0], 10, 32) if e == nil && v < uint64(len(common.MinerIds)) { common.CFG.Beeps.MinerID = string(common.MinerIds[v].Tag) } else { common.CFG.Beeps.MinerID = "" } http.Redirect(w, r, "miners", http.StatusFound) return } }