func (self *Config) postProcess() { //var GenesisSignatureStr string //only set if passed in command line arg //var GenesisAddressStr string //only set if passed in command line arg //var BlockchainPubkeyStr string //only set if passed in command line arg //var BlockchainSeckeyStr string //only set if passed in command line arg var err error if GenesisSignatureStr != "" { self.GenesisSignature, err = cipher.SigFromHex(GenesisSignatureStr) if err != nil { log.Panic("Invalid Signature") } } if GenesisAddressStr != "" { self.GenesisAddress, err = cipher.DecodeBase58Address(GenesisAddressStr) if err != nil { log.Panic("Invalid Address") } } if BlockchainPubkeyStr != "" { self.BlockchainPubkey, err = cipher.PubKeyFromHex(BlockchainPubkeyStr) if err != nil { log.Panic("Invalid Pubkey") } } if BlockchainSeckeyStr != "" { self.BlockchainSeckey, err = cipher.SecKeyFromHex(BlockchainSeckeyStr) if err != nil { log.Panic("Invalid Seckey") } BlockchainSeckeyStr = "" } if BlockchainSeckeyStr != "" { self.BlockchainSeckey = cipher.SecKey{} } self.DataDirectory = util.InitDataDir(self.DataDirectory) if self.WebInterfaceCert == "" { self.WebInterfaceCert = filepath.Join(self.DataDirectory, "cert.pem") } if self.WebInterfaceKey == "" { self.WebInterfaceKey = filepath.Join(self.DataDirectory, "key.pem") } if self.BlockchainFile == "" { self.BlockchainFile = filepath.Join(self.DataDirectory, "blockchain.bin") } if self.BlockSigsFile == "" { self.BlockSigsFile = filepath.Join(self.DataDirectory, "blockchain.sigs") } if self.WalletDirectory == "" { self.WalletDirectory = filepath.Join(self.DataDirectory, "wallets/") } ll, err := logging.LogLevel(self.logLevel) if err != nil { log.Panic("Invalid -log-level %s: %v\n", self.logLevel, err) } self.LogLevel = ll }
func getAddrUxOutsHandler(req Request, gateway Gatewayer) Response { var addrs []string if err := req.DecodeParams(&addrs); err != nil { logger.Critical("decode params failed:%v", err) return makeErrorResponse(errCodeInvalidParams, errMsgInvalidParams) } if len(addrs) == 0 { logger.Error("empty request params") return makeErrorResponse(errCodeInvalidParams, errMsgInvalidParams) } results := make([]AddrUxoutResult, len(addrs)) for i, addr := range addrs { // decode address a, err := cipher.DecodeBase58Address(addr) if err != nil { logger.Error("%v", err) return makeErrorResponse(errCodeInvalidParams, fmt.Sprintf("%v", err)) } results[i].Address = addr uxouts, err := gateway.GetAddrUxOuts(a) if err != nil { logger.Error("%v", err) return makeErrorResponse(errCodeInternalError, errMsgInternalError) } results[i].UxOuts = append(results[i].UxOuts, uxouts...) } return makeSuccessResponse(req.ID, &results) }
func getChangeAddress(wltFile string, a string, c *gcli.Context) (string, error) { chgAddr := c.String("c") for { if chgAddr == "" { // get the default wallet's coin base address if a != "" { // use the from address as change address chgAddr = a break } if wltFile != "" { wlt, err := wallet.Load(wltFile) if err != nil { return "", err } if len(wlt.Entries) > 0 { chgAddr = wlt.Entries[0].Address.String() break } return "", errors.New("no change address was found") } return "", errors.New("both wallet file, from address and change address are empty") } break } // validate the address _, err := cipher.DecodeBase58Address(chgAddr) if err != nil { return "", fmt.Errorf("invalid change address: %s", chgAddr) } return chgAddr, nil }
func getAddrUxOuts(gateway *daemon.Gateway) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { if r.Method != "GET" { wh.Error405(w, "") return } addr := r.FormValue("address") if addr == "" { wh.Error400(w, "address is empty") return } cipherAddr, err := cipher.DecodeBase58Address(addr) if err != nil { wh.Error400(w, err.Error()) return } uxs, err := gateway.GetAddrUxOuts(cipherAddr) if err != nil { wh.Error400(w, err.Error()) return } wh.SendOr404(w, uxs) } }
// Creates and broadcasts a transaction sending money from one of our wallets // to destination address. func walletSpendHandler(gateway *daemon.Gateway) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { //log.Printf("Spend1") if r.FormValue("id") == "" { Error400(w, "Missing wallet_id") return } walletId := wallet.WalletID(r.FormValue("id")) if walletId == "" { Error400(w, "Invalid Wallet Id") return } sdst := r.FormValue("dst") if sdst == "" { Error400(w, "Missing destination address \"dst\"") return } dst, err := cipher.DecodeBase58Address(sdst) if err != nil { //Error400(w, "Invalid destination address: %v", err) Error400(w, "Invalid destination address: %v", err.Error()) return } //set fee automatically for now /* sfee := r.FormValue("fee") fee, err := strconv.ParseUint(sfee, 10, 64) if err != nil { Error400(w, "Invalid \"fee\" value") return } */ //var fee uint64 = 0 scoins := r.FormValue("coins") //shours := r.FormValue("hours") coins, err := strconv.ParseUint(scoins, 10, 64) if err != nil { Error400(w, "Invalid \"coins\" value") return } var hours uint64 = 0 var fee uint64 = 0 //doesnt work/do anything right now //MOVE THIS INTO HERE ret := Spend(gateway.D, gateway.D.Visor, Wg, walletId, wallet.NewBalance(coins, hours), fee, dst) if ret.Error != "" { Error400(w, "Spend Failed: %s", ret.Error) } SendOr404(w, ret) } }
func createRawTxFromAddress(addr string, chgAddr string, toAddr string, amt uint64) (string, error) { if (amt % 1e6) != 0 { return "", errors.New("skycoin coins must be multiple of 1e6") } // check if the address is in the default wallet. wlt, err := wallet.Load(filepath.Join(cfg.WalletDir, cfg.DefaultWalletName)) if err != nil { return "", err } srcAddr, err := cipher.DecodeBase58Address(addr) if err != nil { return "", errAddress } _, ok := wlt.GetEntry(srcAddr) if !ok { return "", fmt.Errorf("%v address is not in wallet", addr) } // validate change address cAddr, err := cipher.DecodeBase58Address(chgAddr) if err != nil { return "", errAddress } // validate to address _, err = cipher.DecodeBase58Address(toAddr) if err != nil { return "", errAddress } _, ok = wlt.GetEntry(cAddr) if !ok { return "", fmt.Errorf("change address %v is not in wallet", chgAddr) } return makeTx([]string{addr}, chgAddr, toAddr, amt, wlt) }
func getToAddress(c *gcli.Context) (string, error) { if c.NArg() < 2 { return "", errors.New("invalid argument") } toAddr := c.Args().First() // validate address if _, err := cipher.DecodeBase58Address(toAddr); err != nil { return "", err } return toAddr, nil }
func createRawTxFromWallet(wltPath string, chgAddr string, toAddr string, amt uint64) (string, error) { // validate the amt if (amt % 1e6) != 0 { return "", errors.New("skycoin coins must be multiple of 1e6") } // check if the change address is in wallet. wlt, err := wallet.Load(wltPath) if err != nil { return "", err } // check change address cAddr, err := cipher.DecodeBase58Address(chgAddr) if err != nil { return "", errAddress } // validate to address _, err = cipher.DecodeBase58Address(toAddr) if err != nil { return "", errAddress } _, ok := wlt.GetEntry(cAddr) if !ok { return "", fmt.Errorf("change address %v is not in wallet", chgAddr) } // get all address in the wallet totalAddrs := wlt.GetAddresses() addrStrArray := make([]string, len(totalAddrs)) for i, a := range totalAddrs { addrStrArray[i] = a.String() } return makeTx(addrStrArray, chgAddr, toAddr, amt, wlt) }
func gatherAddrs(c *gcli.Context) ([]string, error) { w := c.String("f") var a string if c.NArg() > 0 { a = c.Args().First() if _, err := cipher.DecodeBase58Address(a); err != nil { return []string{}, fmt.Errorf("invalid address: %v", a) } } addrs := []string{} if w == "" && a == "" { // use default wallet w = filepath.Join(cfg.WalletDir, cfg.DefaultWalletName) } if w != "" { if !strings.HasSuffix(w, walletExt) { return []string{}, fmt.Errorf("error wallet file name, must has %v extension", walletExt) } if filepath.Base(w) == w { w = filepath.Join(cfg.WalletDir, w) } else { var err error w, err = filepath.Abs(w) if err != nil { return []string{}, err } } wlt, err := wallet.Load(w) if err != nil { return []string{}, err } addresses := wlt.GetAddresses() for _, a := range addresses { addrs = append(addrs, a.String()) } } if a != "" { addrs = append(addrs, a) } return addrs, nil }
func getKeys(wlt *wallet.Wallet, outs []unspentOut) ([]cipher.SecKey, error) { keys := make([]cipher.SecKey, len(outs)) for i, o := range outs { addr, err := cipher.DecodeBase58Address(o.Address) if err != nil { return nil, errAddress } entry, ok := wlt.GetEntry(addr) if !ok { return nil, fmt.Errorf("%v is not in wallet", o.Address) } keys[i] = entry.Secret } return keys, nil }
func (c *Config) postProcess() { var err error if GenesisSignatureStr != "" { c.GenesisSignature, err = cipher.SigFromHex(GenesisSignatureStr) panicIfError(err, "Invalid Signature") } if GenesisAddressStr != "" { c.GenesisAddress, err = cipher.DecodeBase58Address(GenesisAddressStr) panicIfError(err, "Invalid Address") } if BlockchainPubkeyStr != "" { c.BlockchainPubkey, err = cipher.PubKeyFromHex(BlockchainPubkeyStr) panicIfError(err, "Invalid Pubkey") } if BlockchainSeckeyStr != "" { c.BlockchainSeckey, err = cipher.SecKeyFromHex(BlockchainSeckeyStr) panicIfError(err, "Invalid Seckey") BlockchainSeckeyStr = "" } if BlockchainSeckeyStr != "" { c.BlockchainSeckey = cipher.SecKey{} } c.DataDirectory = util.InitDataDir(c.DataDirectory) if c.WebInterfaceCert == "" { c.WebInterfaceCert = filepath.Join(c.DataDirectory, "cert.pem") } if c.WebInterfaceKey == "" { c.WebInterfaceKey = filepath.Join(c.DataDirectory, "key.pem") } if c.BlockchainFile == "" { c.BlockchainFile = filepath.Join(c.DataDirectory, "blockchain.bin") } if c.BlockSigsFile == "" { c.BlockSigsFile = filepath.Join(c.DataDirectory, "blockchain.sigs") } if c.WalletDirectory == "" { c.WalletDirectory = filepath.Join(c.DataDirectory, "wallets/") } ll, err := logging.LogLevel(c.logLevel) panicIfError(err, "Invalid -log-level %s", c.logLevel) c.LogLevel = ll }
func TransactionOutputFromJSON(in TransactionOutputJSON) (coin.TransactionOutput, error) { var tx coin.TransactionOutput //hash, err := cipher.SHA256FromHex(in.Hash) //if err != nil { // return coin.TransactionOutput{}, errors.New("Invalid hash") //} addr, err := cipher.DecodeBase58Address(in.Address) if err != nil { return coin.TransactionOutput{}, errors.New("Adress decode fail") } //tx.Hash = hash tx.Address = addr tx.Coins = in.Coins tx.Hours = in.Hours return tx, nil }
// Creates and broadcasts a transaction sending money from one of our wallets // to destination address. func walletSpendHandler(gateway *daemon.Gateway) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { walletId := wallet.WalletID(r.FormValue("id")) if walletId == "" { Error400(w, "Missing wallet_id") return } sdst := r.FormValue("dst") if sdst == "" { Error400(w, "Missing destination address \"dst\"") return } dst, err := cipher.DecodeBase58Address(sdst) if err != nil { Error400(w, "Invalid destination address") return } sfee := r.FormValue("fee") fee, err := strconv.ParseUint(sfee, 10, 64) if err != nil { Error400(w, "Invalid \"fee\" value") return } scoins := r.FormValue("coins") shours := r.FormValue("hours") coins, err := strconv.ParseUint(scoins, 10, 64) if err != nil { Error400(w, "Invalid \"coins\" value") return } hours, err := strconv.ParseUint(shours, 10, 64) if err != nil { Error400(w, "Invalid \"hours\" value") return } SendOr404(w, gateway.Spend(walletId, wallet.NewBalance(coins, hours), fee, dst)) } }
func fromWalletOrAddress(c *gcli.Context) (w string, a string, err error) { w = c.String("f") a = c.String("a") if a != "" && w != "" { // 1 1 err = errors.New("use either -f or -a flag") return } if a == "" { if w == "" { // 0 0 w = filepath.Join(cfg.WalletDir, cfg.DefaultWalletName) return } // 0 1 // validate wallet file name if !strings.HasSuffix(w, walletExt) { err = errWalletName return } if filepath.Base(w) != w { w, err = filepath.Abs(w) return } w = filepath.Join(cfg.WalletDir, w) return } // 1 0 if _, err = cipher.DecodeBase58Address(a); err != nil { err = fmt.Errorf("invalid from address: %s", a) } return }
func addBlock(bc historydb.Blockchainer, td testData, tm uint64) (*coin.Block, *coin.Transaction, error) { tx := coin.Transaction{} // get unspent output ux, err := getUx(bc, td.Vin.BlockSeq, td.Vin.TxID, td.Vin.Addr) if err != nil { return nil, nil, err } if ux == nil { return nil, nil, errors.New("no unspent output") } tx.PushInput(ux.Hash()) for _, o := range td.Vouts { addr, err := cipher.DecodeBase58Address(o.ToAddr) if err != nil { return nil, nil, err } tx.PushOutput(addr, o.Coins, o.Hours) } sigKey := cipher.MustSecKeyFromHex(td.Vin.SigKey) tx.SignInputs([]cipher.SecKey{sigKey}) tx.UpdateHeader() if err := bc.VerifyTransaction(tx); err != nil { return nil, nil, err } preBlock := bc.GetBlock(td.PreBlockHash) b := newBlock(*preBlock, tm, *bc.GetUnspent(), coin.Transactions{tx}, _feeCalc) // uxs, err := bc.ExecuteBlock(&b) _, err = bc.ExecuteBlock(&b) if err != nil { return nil, nil, err } return &b, &tx, nil }
func getOutputsHandler(req Request, gateway Gatewayer) Response { var addrs []string if err := req.DecodeParams(&addrs); err != nil { return makeErrorResponse(errCodeInvalidParams, errMsgInvalidParams) } if len(addrs) == 0 { return makeErrorResponse(errCodeInvalidParams, errMsgInvalidParams) } for i, a := range addrs { addrs[i] = strings.Trim(a, " ") } // validate those addresses for _, a := range addrs { if _, err := cipher.DecodeBase58Address(a); err != nil { return makeErrorResponse(errCodeInvalidParams, fmt.Sprintf("invalid address: %v", a)) } } outs := gateway.GetUnspentOutputs(daemon.FbyAddresses(addrs)) return makeSuccessResponse(req.ID, OutputsResult{outs}) }
func skyWithdrawl(nodeAddr string, rp *ReqParams) (*pp.WithdrawalRes, *pp.EmptyRes) { ee := rp.Values["engine"].(engine.Exchange) acnt := rp.Values["account"].(account.Accounter) amt := rp.Values["amt"].(uint64) ct := rp.Values["cointype"].(string) toAddr := rp.Values["toAddr"].(string) if err := skycoin.VerifyAmount(amt); err != nil { return nil, pp.MakeErrRes(err) } // verify the toAddr if _, err := cipher.DecodeBase58Address(toAddr); err != nil { return nil, pp.MakeErrRes(errors.New("invalid skycoin address")) } var success bool var skyTxRlt *SkyTxResult var err error if err := acnt.DecreaseBalance(ct, amt); err != nil { return nil, pp.MakeErrRes(err) } defer func() { if !success { go func() { if skyTxRlt != nil { ee.PutUtxos(skycoin.Type, skyTxRlt.UsingUtxos) } acnt.IncreaseBalance(ct, amt) }() } else { //TODO: handle the saving failure. ee.SaveAccount() } }() skyTxRlt, err = createSkyWithdrawTx(ee, amt, toAddr) if err != nil { return nil, pp.MakeErrRes(errors.New("failed to create withdrawal tx")) } rawtx, err := skyTxRlt.Tx.Serialize() if err != nil { return nil, pp.MakeErrRes(errors.New("skycoin tx serialize failed")) } newTxid, err := skycoin.BroadcastTx(nodeAddr, hex.EncodeToString(rawtx)) if err != nil { logger.Error(err.Error()) return nil, pp.MakeErrResWithCode(pp.ErrCode_BroadcastTxFail) } success = true if skyTxRlt.ChangeAddr != "" { logger.Debug("change address:%s", skyTxRlt.ChangeAddr) ee.WatchAddress(ct, skyTxRlt.ChangeAddr) } resp := pp.WithdrawalRes{ Result: pp.MakeResultWithCode(pp.ErrCode_Success), NewTxid: &newTxid, } return &resp, nil }
// CreateRawTx create raw tx base on some utxos. // mode: POST // url: /api/v1/create_rawtx?coin_type=[:coin_type] // request json: // different in bitcoin and skycoin. func CreateRawTx(se Servicer) httprouter.Handle { return func(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { var rlt *pp.EmptyRes loop: for { // get coin type cp := r.FormValue("coin_type") // get request body params := rawTxParams{} if err := json.NewDecoder(r.Body).Decode(¶ms); err != nil { logger.Error(err.Error()) rlt = pp.MakeErrRes(err) break } coin, err := se.GetCoin(cp) if err != nil { logger.Error(err.Error()) rlt = pp.MakeErrResWithCode(pp.ErrCode_ServerError) break } var rawtx string switch cp { case bitcoin.Type: outs := make([]bitcoin.TxOut, len(params.TxOuts)) for i, o := range params.TxOuts { outs[i].Addr = o.Addr outs[i].Value = o.Value } rawtx, err = coin.CreateRawTx(params.TxIns, outs) case skycoin.Type: outs := make([]skycoin.TxOut, len(params.TxOuts)) for i, o := range params.TxOuts { addr, err := cipher.DecodeBase58Address(o.Addr) if err != nil { logger.Error(err.Error()) rlt = pp.MakeErrRes(err) break loop } outs[i].Address = addr outs[i].Coins = o.Value outs[i].Hours = o.Hours } rawtx, err = coin.CreateRawTx(params.TxIns, outs) } if err != nil { logger.Error(err.Error()) rlt = pp.MakeErrRes(err) break } res := struct { Result *pp.Result `json:"result"` Rawtx string `json:"rawtx"` }{ Result: pp.MakeResultWithCode(pp.ErrCode_Success), Rawtx: rawtx, } sendJSON(w, &res) return } sendJSON(w, rlt) } }
// ValidateAddr check if the address is validated func (cn coinEx) ValidateAddr(address string) error { _, err := cipher.DecodeBase58Address(address) return err }