Example #1
0
func addTxOuts(msgtx *wire.MsgTx, b balance, hash []byte, blockHeight uint32) error {
	anchorHash, err := prependBlockHeight(blockHeight, hash)
	if err != nil {
		anchorLog.Errorf("ScriptBuilder error: %v\n", err)
	}

	builder := txscript.NewScriptBuilder()
	builder.AddOp(txscript.OP_RETURN)
	builder.AddData(anchorHash)

	// latest routine from Conformal btcsuite returns 2 parameters, not 1... not sure what to do for people with the old conformal libraries :(
	opReturn, err := builder.Script()
	msgtx.AddTxOut(wire.NewTxOut(0, opReturn))
	if err != nil {
		anchorLog.Errorf("ScriptBuilder error: %v\n", err)
	}

	amount, _ := btcutil.NewAmount(b.unspentResult.Amount)
	change := amount - fee

	// Check if there are leftover unspent outputs, and return coins back to
	// a new address we own.
	if change > 0 {

		// Spend change.
		pkScript, err := txscript.PayToAddrScript(b.address)
		if err != nil {
			return fmt.Errorf("cannot create txout script: %s", err)
		}
		msgtx.AddTxOut(wire.NewTxOut(int64(change), pkScript))
	}
	return nil
}
Example #2
0
func initWallet() error {
	balances = make([]balance, 0, 200)
	fee, _ = btcutil.NewAmount(cfg.Btc.BtcTransFee)
	walletLocked = true
	err := updateUTXO()
	if err == nil && len(balances) > 0 {
		defaultAddress = balances[0].address
	}
	return err
}
Example #3
0
// InitAnchor inits rpc clients for factom
// and load up unconfirmed DirBlockInfo from leveldb
func InitAnchor(s interfaces.IState) (*Anchor, error) {
	anchorLog.Debug("InitAnchor")
	a := NewAnchor()
	a.state = s
	a.db = s.GetDB()
	a.minBalance, _ = btcutil.NewAmount(0.01)

	var err error
	a.dirBlockInfoSlice, err = a.db.FetchAllUnconfirmedDirBlockInfos()
	if err != nil {
		anchorLog.Error("InitAnchor error - " + err.Error())
		return nil, err
	}
	anchorLog.Debug("init dirBlockInfoSlice.len=", len(a.dirBlockInfoSlice))
	// this might take a while to check missing DirBlockInfo for existing DirBlocks in database

	//TODO: handle concurrance better
	go a.checkMissingDirBlockInfo()

	a.readConfig()
	if err = a.InitRPCClient(); err != nil {
		anchorLog.Error(err.Error())
	} else {
		a.updateUTXO(a.minBalance)
	}

	ticker0 := time.NewTicker(time.Minute * time.Duration(1))
	go func() {
		for _ = range ticker0.C {
			a.checkForAnchor()
		}
	}()

	ticker := time.NewTicker(time.Minute * time.Duration(a.tenMinutes))
	go func() {
		for _ = range ticker.C {
			anchorLog.Info("In 10 minutes ticker...")
			a.readConfig()
			if a.dclient == nil || a.wclient == nil {
				if err = a.InitRPCClient(); err != nil {
					anchorLog.Error(err.Error())
				}
			}
			if a.wclient != nil {
				a.checkTxConfirmations()
			}
		}
	}()
	return a, nil
}
Example #4
0
func initWallet() error {
	balances = make([]balance, 0, 100)
	fee, _ = btcutil.NewAmount(cfg.Btc.BtcTransFee)
	err := unlockWallet(int64(600))
	if err != nil {
		return fmt.Errorf("%s", err)
	}

	unspentResults, err := wclient.ListUnspent() //minConf=1
	if err != nil {
		return fmt.Errorf("cannot list unspent. %s", err)
	}
	anchorLog.Info("unspentResults.len=", len(unspentResults))

	if len(unspentResults) > 0 {
		var i int
		for _, b := range unspentResults {
			if b.Amount > fee.ToBTC() {
				balances = append(balances, balance{unspentResult: b})
				i++
			}
		}
	}
	anchorLog.Info("balances.len=", len(balances))

	for i, b := range balances {
		addr, err := btcutil.DecodeAddress(b.unspentResult.Address, &chaincfg.TestNet3Params)
		if err != nil {
			return fmt.Errorf("cannot decode address: %s", err)
		}
		balances[i].address = addr

		wif, err := wclient.DumpPrivKey(addr)
		if err != nil {
			return fmt.Errorf("cannot get WIF: %s", err)
		}
		balances[i].wif = wif
		anchorLog.Info("balance[%d]=%s", i, spew.Sdump(balances[i]))
	}

	time.Sleep(1 * time.Second)
	return nil
}
Example #5
0
func (a *Anchor) readConfig() {
	anchorLog.Info("readConfig")
	a.cfg = util.ReadConfig("")
	a.confirmationsNeeded = a.cfg.Anchor.ConfirmationsNeeded
	a.fee, _ = btcutil.NewAmount(a.cfg.Btc.BtcTransFee)

	var err error
	a.serverPrivKey, err = primitives.NewPrivateKeyFromHex(a.cfg.App.LocalServerPrivKey)
	if err != nil {
		panic("Cannot parse Server Private Key from configuration file: " + err.Error())
	}
	a.serverECKey, err = primitives.NewPrivateKeyFromHex(a.cfg.Anchor.ServerECPrivKey)
	if err != nil {
		panic("Cannot parse Server EC Key from configuration file: " + err.Error())
	}
	a.anchorChainID, err = primitives.HexToHash(a.cfg.Anchor.AnchorChainID)
	anchorLog.Debug("anchorChainID: ", a.anchorChainID)
	if err != nil || a.anchorChainID == nil {
		panic("Cannot parse Server AnchorChainID from configuration file: " + err.Error())
	}
}
Example #6
0
func selectInputs(eligible []btcjson.ListUnspentResult, minconf int) (selected []btcjson.ListUnspentResult, out btcutil.Amount, err error) {
	// Iterate throguh eligible transactions, appending to outputs and
	// increasing out.  This is finished when out is greater than the
	// requested amt to spend.
	selected = make([]btcjson.ListUnspentResult, 0, len(eligible))
	for _, e := range eligible {
		amount, err := btcutil.NewAmount(e.Amount)
		if err != nil {
			anchorLog.Error("err in creating NewAmount")
			continue
		}
		selected = append(selected, e)
		out += amount
		if out >= fee {
			return selected, out, nil
		}
	}
	if out < fee {
		return nil, 0, fmt.Errorf("insufficient funds: transaction requires %v fee, but only %v spendable", fee, out)
	}

	return selected, out, nil
}