Beispiel #1
0
func LocalAcceptBlock(bl *btc.Block, from *network.OneConnection) (e error) {
	sta := time.Now()
	e = common.BlockChain.AcceptBlock(bl)
	if e == nil {
		network.MutexRcv.Lock()
		network.ReceivedBlocks[bl.Hash.BIdx()].TmAccept = time.Now().Sub(sta)
		network.MutexRcv.Unlock()

		for i := 1; i < len(bl.Txs); i++ {
			network.TxMined(bl.Txs[i].Hash)
		}

		if int64(bl.BlockTime) > time.Now().Add(-10*time.Minute).Unix() {
			// Freshly mined block - do the inv and beeps...
			common.Busy("NetRouteInv")
			network.NetRouteInv(2, bl.Hash, from)

			if common.CFG.Beeps.NewBlock {
				fmt.Println("\007Received block", common.BlockChain.BlockTreeEnd.Height)
				textui.ShowPrompt()
			}

			if common.MinedByUs(bl.Raw) {
				fmt.Println("\007Mined by '"+common.CFG.Beeps.MinerID+"':", bl.Hash)
				textui.ShowPrompt()
			}

			if common.CFG.Beeps.ActiveFork && common.Last.Block == common.BlockChain.BlockTreeEnd {
				// Last block has not changed, so it must have been an orphaned block
				bln := common.BlockChain.BlockIndex[bl.Hash.BIdx()]
				commonNode := common.Last.Block.FirstCommonParent(bln)
				forkDepth := bln.Height - commonNode.Height
				fmt.Println("Orphaned block:", bln.Height, bl.Hash.String())
				if forkDepth > 1 {
					fmt.Println("\007\007\007WARNING: the fork is", forkDepth, "blocks deep")
				}
				textui.ShowPrompt()
			}

			if wallet.BalanceChanged && common.CFG.Beeps.NewBalance {
				fmt.Print("\007")
			}
		}

		common.Last.Mutex.Lock()
		common.Last.Time = time.Now()
		common.Last.Block = common.BlockChain.BlockTreeEnd
		common.Last.Mutex.Unlock()

		if wallet.BalanceChanged {
			wallet.BalanceChanged = false
			fmt.Println("Your balance has just changed")
			fmt.Print(wallet.DumpBalance(nil, false))
			textui.ShowPrompt()
		}
	} else {
		fmt.Println("Warning: AcceptBlock failed. If the block was valid, you may need to rebuild the unspent DB (-r)")
	}
	return
}
Beispiel #2
0
func do_scan_stealth(p string, ignore_prefix bool) {
	ad, _ := btc.NewAddrFromString(p)
	if ad == nil {
		fmt.Println("Specify base58 encoded bitcoin address")
		return
	}

	sa := ad.StealthAddr
	if sa == nil {
		fmt.Println("Specify base58 encoded stealth address")
		return
	}
	if sa.Version != btc.StealthAddressVersion(common.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:]))
	}

	wallet.FetchStealthKeys()
	d := wallet.FindStealthSecret(sa)
	if d == nil {
		fmt.Println("No matching secret found in your wallet/stealth folder")
		return
	}

	var unsp chain.AllUnspentTx

	common.BlockChain.Unspent.BrowseUTXO(true, func(db *qdb.DB, k qdb.KeyType, rec *chain.OneWalkRecord) uint32 {
		if !rec.IsStealthIdx() {
			return 0
		}
		fl, uo := wallet.CheckStealthRec(db, k, rec, ad, d, true)
		if uo != nil {
			unsp = append(unsp, uo)
		}
		return fl
	})

	sort.Sort(unsp)
	os.RemoveAll("balance")
	os.MkdirAll("balance/", 0770)
	utxt, _ := os.Create("balance/unspent.txt")
	fmt.Print(wallet.DumpBalance(unsp, utxt, true, false))
}
Beispiel #3
0
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.")
}
Beispiel #4
0
func main() {
	var ptr *byte
	if unsafe.Sizeof(ptr) < 8 {
		fmt.Println("WARNING: Gocoin client shall be build for 64-bit arch. It will likely crash now.")
	}

	fmt.Println("Gocoin client version", btc.SourcesTag)
	runtime.GOMAXPROCS(runtime.NumCPU()) // It seems that Go does not do it by default

	// Disable Ctrl+C
	signal.Notify(killchan, os.Interrupt, os.Kill)
	defer func() {
		if r := recover(); r != nil {
			err, ok := r.(error)
			if !ok {
				err = fmt.Errorf("pkg: %v", r)
			}
			fmt.Println("main panic recovered:", err.Error())
			fmt.Println(string(debug.Stack()))
			network.NetCloseAll()
			common.CloseBlockChain()
			network.ClosePeerDB()
			utils.UnlockDatabaseDir()
			os.Exit(1)
		}
	}()

	host_init() // This will create the DB lock file and keep it open

	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.FetchAllBalances()

	// ... 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))
	}

	peersTick := time.Tick(5 * time.Minute)
	txPoolTick := time.Tick(time.Minute)
	netTick := time.Tick(time.Second)

	network.InitPeers(common.GocoinHomeDir)

	common.Last.Block = common.BlockChain.BlockTreeEnd
	common.Last.Time = time.Unix(int64(common.Last.Block.Timestamp()), 0)
	if common.Last.Time.After(time.Now()) {
		common.Last.Time = time.Now()
	}

	for k, v := range common.BlockChain.BlockIndex {
		network.ReceivedBlocks[k] = &network.OneReceivedBlock{Time: time.Unix(int64(v.Timestamp()), 0)}
	}

	if common.CFG.TextUI.Enabled {
		go textui.MainThread()
	}

	if common.CFG.WebUI.Interface != "" {
		fmt.Println("Starting WebUI at", common.CFG.WebUI.Interface, "...")
		go webui.ServerThread(common.CFG.WebUI.Interface)
	}

	for !usif.Exit_now {
		common.CountSafe("MainThreadLoops")
		for retryCachedBlocks {
			retryCachedBlocks = retry_cached_blocks()
			// We have done one per loop - now do something else if pending...
			if len(network.NetBlocks) > 0 || len(usif.UiChannel) > 0 {
				break
			}
		}

		common.Busy("")

		select {
		case s := <-killchan:
			fmt.Println("Got signal:", s)
			usif.Exit_now = true
			continue

		case newbl := <-network.NetBlocks:
			HandleNetBlock(newbl)

		case newtx := <-network.NetTxs:
			network.HandleNetTx(newtx, false)

		case newal := <-network.NetAlerts:
			fmt.Println("\007" + newal)
			textui.ShowPrompt()

		case cmd := <-usif.UiChannel:
			common.Busy("UI command")
			cmd.Handler(cmd.Param)
			cmd.Done.Done()
			continue

		case <-peersTick:
			network.ExpirePeers()

		case <-txPoolTick:
			network.ExpireTxs()

		case <-netTick:
			network.NetworkTick()

		case <-time.After(time.Second / 2):
			common.CountSafe("MainThreadTouts")
			if !retryCachedBlocks {
				common.Busy("common.BlockChain.Idle()")
				common.BlockChain.Idle()
			}
			continue
		}

		common.CountSafe("NetMessagesGot")
	}

	network.NetCloseAll()
	network.ClosePeerDB()

	if usif.DefragBlocksDB {
		defrag_db()
	}

	common.CloseBlockChain()
	utils.UnlockDatabaseDir()
}
Beispiel #5
0
func main() {
	if btc.EC_Verify == nil {
		fmt.Println("WARNING: EC_Verify acceleration disabled. Enable EC_Verify wrapper if possible.")
	}
	var ptr *byte
	if unsafe.Sizeof(ptr) < 8 {
		fmt.Println("WARNING: Gocoin client shall be build for 64-bit arch. It will likely crash now.")
	}

	fmt.Println("Gocoin client version", btc.SourcesTag)
	runtime.GOMAXPROCS(runtime.NumCPU()) // It seems that Go does not do it by default

	// Disable Ctrl+C
	signal.Notify(killchan, os.Interrupt, os.Kill)
	defer func() {
		if r := recover(); r != nil {
			err, ok := r.(error)
			if !ok {
				err = fmt.Errorf("pkg: %v", r)
			}
			fmt.Println("main panic recovered:", err.Error())
			fmt.Println(string(debug.Stack()))
			network.NetCloseAll()
			common.CloseBlockChain()
			network.ClosePeerDB()
			utils.UnlockDatabaseDir()
			os.Exit(1)
		}
	}()

	host_init() // This will create the DB lock file and keep it open

	// Clean up the DB lock file on exit

	// cache the current balance of all the addresses from the current wallet files
	wallet.FetchAllBalances()
	// ... and now switch to the dafault wallet
	wallet.LoadWallet(common.GocoinHomeDir + "wallet" + string(os.PathSeparator) + "DEFAULT")
	if wallet.MyWallet == nil {
		wallet.LoadWallet(common.GocoinHomeDir + "wallet.txt")
	}
	if wallet.MyWallet != nil {
		wallet.UpdateBalance()
		fmt.Print(wallet.DumpBalance(nil, false))
	}

	peersTick := time.Tick(5 * time.Minute)
	txPoolTick := time.Tick(time.Minute)
	netTick := time.Tick(time.Second)

	network.InitPeers(common.GocoinHomeDir)

	common.Last.Block = common.BlockChain.BlockTreeEnd
	common.Last.Time = time.Unix(int64(common.Last.Block.Timestamp), 0)

	for k, v := range common.BlockChain.BlockIndex {
		network.ReceivedBlocks[k] = &network.OneReceivedBlock{Time: time.Unix(int64(v.Timestamp), 0)}
	}

	if common.CFG.TextUI.Enabled {
		go textui.MainThread()
	}

	if common.CFG.WebUI.Interface != "" {
		fmt.Println("Starting WebUI at", common.CFG.WebUI.Interface, "...")
		go webui.ServerThread(common.CFG.WebUI.Interface)
	}

	for !usif.Exit_now {
		common.CountSafe("MainThreadLoops")
		for retryCachedBlocks {
			retryCachedBlocks = retry_cached_blocks()
			// We have done one per loop - now do something else if pending...
			if len(network.NetBlocks) > 0 || len(usif.UiChannel) > 0 {
				break
			}
		}

		common.Busy("")

		select {
		case s := <-killchan:
			fmt.Println("Got signal:", s)
			usif.Exit_now = true
			continue

		case newbl := <-network.NetBlocks:
			HandleNetBlock(newbl)

		case newtx := <-network.NetTxs:
			network.HandleNetTx(newtx, false)

		case cmd := <-usif.UiChannel:
			common.Busy("UI command")
			cmd.Handler(cmd.Param)
			cmd.Done.Done()
			continue

		case <-peersTick:
			network.ExpirePeers()

		case <-txPoolTick:
			network.ExpireTxs()

		case <-netTick:
			network.NetworkTick()

		case <-time.After(time.Second / 2):
			common.CountSafe("MainThreadTouts")
			if !retryCachedBlocks {
				common.Busy("common.BlockChain.Idle()")
				common.BlockChain.Idle()
			}
			continue
		}

		common.CountSafe("NetMessagesGot")
	}

	network.NetCloseAll()
	network.ClosePeerDB()

	if usif.DefragBlocksDB {
		defrag_db()
	}

	common.CloseBlockChain()
	utils.UnlockDatabaseDir()
}
Beispiel #6
0
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))
}
Beispiel #7
0
func LocalAcceptBlock(bl *btc.Block, from *network.OneConnection) (e error) {
	sta := time.Now()
	e = common.BlockChain.AcceptBlock(bl)
	if e == nil {
		network.MutexRcv.Lock()
		network.ReceivedBlocks[bl.Hash.BIdx()].TmAccept = time.Now().Sub(sta)
		network.MutexRcv.Unlock()

		for i := 1; i < len(bl.Txs); i++ {
			network.TxMined(bl.Txs[i])
			/* dupa
			if msg:=contains_message(bl.Txs[i]); msg!=nil {
				for xx:=range msg {
					if msg[xx]<' ' || msg[xx]>127 {
						msg[xx] = '.'
					}
				}
				fmt.Println("TX", bl.Txs[i].Hash.String(), "says:", "'" + string(msg) + "'")
				textui.ShowPrompt()
			}
			*/
		}

		if int64(bl.BlockTime()) > time.Now().Add(-10*time.Minute).Unix() {
			// Freshly mined block - do the inv and beeps...
			common.Busy("NetRouteInv")
			network.NetRouteInv(2, bl.Hash, from)

			if common.CFG.Beeps.NewBlock {
				fmt.Println("\007Received block", common.BlockChain.BlockTreeEnd.Height)
				textui.ShowPrompt()
			}

			if common.CFG.Beeps.MinerID != "" {
				//_, rawtxlen := btc.NewTx(bl[bl.TxOffset:])
				if bytes.Contains(bl.Txs[0].Serialize(), []byte(common.CFG.Beeps.MinerID)) {
					fmt.Println("\007Mined by '"+common.CFG.Beeps.MinerID+"':", bl.Hash)
					textui.ShowPrompt()
				}
			}

			if common.CFG.Beeps.ActiveFork && common.Last.Block == common.BlockChain.BlockTreeEnd {
				// Last block has not changed, so it must have been an orphaned block
				bln := common.BlockChain.BlockIndex[bl.Hash.BIdx()]
				commonNode := common.Last.Block.FirstCommonParent(bln)
				forkDepth := bln.Height - commonNode.Height
				fmt.Println("Orphaned block:", bln.Height, bl.Hash.String(), bln.BlockSize>>10, "KB")
				if forkDepth > 1 {
					fmt.Println("\007\007\007WARNING: the fork is", forkDepth, "blocks deep")
				}
				textui.ShowPrompt()
			}

			if wallet.BalanceChanged && common.CFG.Beeps.NewBalance {
				fmt.Print("\007")
			}
		}

		common.Last.Mutex.Lock()
		common.Last.Time = time.Now()
		common.Last.Block = common.BlockChain.BlockTreeEnd
		common.Last.Mutex.Unlock()

		if wallet.BalanceChanged {
			wallet.BalanceChanged = false
			fmt.Println("Your balance has just changed")
			fmt.Print(wallet.DumpBalance(wallet.MyBalance, nil, false, true))
			textui.ShowPrompt()
		}
	} else {
		fmt.Println("Warning: AcceptBlock failed. If the block was valid, you may need to rebuild the unspent DB (-r)")
	}
	return
}
Beispiel #8
0
func do_scan_stealth(p string, ignore_prefix bool) {
	ad, _ := btc.NewAddrFromString(p)
	if ad == nil {
		fmt.Println("Specify base58 encoded bitcoin address")
		return
	}

	sa := ad.StealthAddr
	if sa == nil {
		fmt.Println("Specify base58 encoded stealth address")
		return
	}
	if sa.Version != btc.StealthAddressVersion(common.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:]))
	}

	wallet.FetchStealthKeys()
	d := wallet.FindStealthSecret(sa)
	if d == nil {
		fmt.Println("No matching secret found in your wallet/stealth folder")
		return
	}

	var unsp chain.AllUnspentTx
	var c, spen_exp []byte
	var rec, out *chain.QdbTxOut
	var h160 [20]byte

	common.BlockChain.Unspent.BrowseUTXO(true, func(tx *chain.QdbRec) {
		for i := 0; i < len(tx.Outs)-1; i++ {
			if rec = tx.Outs[i]; rec == nil {
				continue
			}
			if out = tx.Outs[i+1]; out == nil {
				continue
			}
			if !rec.IsStealthIdx() || !out.IsP2KH() || !ad.StealthAddr.CheckNonce(rec.PKScr[3:40]) {
				continue
			}
			c = btc.StealthDH(rec.PKScr[7:40], d)
			spen_exp = btc.DeriveNextPublic(sa.SpendKeys[0][:], c)
			btc.RimpHash(spen_exp, h160[:])
			if bytes.Equal(out.PKScr[3:23], h160[:]) {
				uo := new(chain.OneUnspentTx)
				uo.TxPrevOut.Hash = tx.TxID
				uo.TxPrevOut.Vout = uint32(i + 1)
				uo.Value = out.Value
				uo.MinedAt = tx.InBlock
				uo.BtcAddr = btc.NewAddrFromHash160(h160[:], btc.AddrVerPubkey(common.CFG.Testnet))
				uo.FixDestString()
				uo.BtcAddr.StealthAddr = sa
				uo.BtcAddr.Extra = ad.Extra
				uo.StealthC = c
				unsp = append(unsp, uo)
			}
		}
	})

	sort.Sort(unsp)
	os.RemoveAll("balance")
	os.MkdirAll("balance/", 0770)
	utxt, _ := os.Create("balance/unspent.txt")
	fmt.Print(wallet.DumpBalance(unsp, utxt, true, false))
}