func (p *Parser) AdminAddCurrencyFront() error { err := p.generalCheckAdmin() if err != nil { return p.ErrInfo(err) } verifyData := map[string]string{"currency_name": "currency_name", "currency_full_name": "currency_full_name", "max_promised_amount": "int", "max_other_currencies": "int"} err = p.CheckInputData(verifyData) if err != nil { return p.ErrInfo(err) } // проверим, нет ли уже такой валюты name, err := p.Single("SELECT name FROM currency WHERE name = ?", p.TxMaps.String["currency_name"]).String() if err != nil { return p.ErrInfo(err) } if len(name) > 0 { return p.ErrInfo("exists currency_name") } forSign := fmt.Sprintf("%s,%s,%s,%s,%s,%s,%s", p.TxMap["type"], p.TxMap["time"], p.TxMap["user_id"], p.TxMap["currency_name"], p.TxMap["currency_full_name"], p.TxMap["max_promised_amount"], p.TxMap["max_other_currencies"]) CheckSignResult, err := utils.CheckSign(p.PublicKeys, forSign, p.TxMap["sign"], false) if err != nil { return p.ErrInfo(err) } if !CheckSignResult { return p.ErrInfo("incorrect sign") } return nil }
func (p *Parser) DelCreditFront() error { err := p.generalCheck() if err != nil { return p.ErrInfo(err) } verifyData := map[string]string{"credit_id": "bigint"} err = p.CheckInputData(verifyData) if err != nil { return p.ErrInfo(err) } // явлется данный юзер кредитором id, err := p.Single("SELECT id FROM credits WHERE id = ? AND to_user_id = ? AND del_block_id = 0", p.TxMaps.Int64["credit_id"], p.TxUserID).Int64() if err != nil { return p.ErrInfo(err) } if id == 0 { return p.ErrInfo("not a creditor") } forSign := fmt.Sprintf("%s,%s,%s,%s", p.TxMap["type"], p.TxMap["time"], p.TxMap["user_id"], p.TxMap["credit_id"]) CheckSignResult, err := utils.CheckSign(p.PublicKeys, forSign, p.TxMap["sign"], false) if err != nil { return p.ErrInfo(err) } if !CheckSignResult { return p.ErrInfo("incorrect sign") } return nil }
func (p *Parser) AdminBlogFront() error { err := p.generalCheckAdmin() if err != nil { return p.ErrInfo(err) } if len(p.TxMaps.String["title"]) > 255 { return p.ErrInfo("len title>255") } if len(p.TxMaps.String["message"]) > 1048576 { return p.ErrInfo("len message>1048576") } forSign := fmt.Sprintf("%s,%s,%s,%s,%s,%s", p.TxMap["type"], p.TxMap["time"], p.TxMap["user_id"], p.TxMap["lng"], p.TxMap["title"], p.TxMap["message"]) CheckSignResult, err := utils.CheckSign(p.PublicKeys, forSign, p.TxMap["sign"], false) if err != nil { return p.ErrInfo(err) } if !CheckSignResult { return p.ErrInfo("incorrect sign") } return nil }
func (p *Parser) AdminAnswerFront() error { err := p.generalCheckAdmin() if err != nil { return p.ErrInfo(err) } if len(p.TxMaps.Bytes["encrypted_message"]) > 20480 { return p.ErrInfo("len encrypted_message>20480") } verifyData := map[string]string{"to_user_id": "user_id"} err = p.CheckInputData(verifyData) if err != nil { return p.ErrInfo(err) } forSign := fmt.Sprintf("%s,%s,%s,%s,%s", p.TxMap["type"], p.TxMap["time"], p.TxMap["user_id"], p.TxMap["to_user_id"], p.TxMap["encrypted_message"]) CheckSignResult, err := utils.CheckSign(p.PublicKeys, forSign, p.TxMap["sign"], false) if err != nil { return p.ErrInfo(err) } if !CheckSignResult { return p.ErrInfo("incorrect sign") } return nil }
func (p *Parser) AdminNewVersionFront() error { err := p.generalCheckAdmin() if err != nil { return p.ErrInfo(err) } verifyData := map[string]string{"version": "version", "soft_type": "soft_type"} err = p.CheckInputData(verifyData) if err != nil { return p.ErrInfo(err) } version, err := p.Single("SELECT version FROM new_version WHERE version = ?", p.TxMap["version"]).String() if err != nil { return p.ErrInfo(err) } if len(version) > 0 { return p.ErrInfo("exists version") } forSign := fmt.Sprintf("%s,%s,%s,%s,%s,%s,%s", p.TxMap["type"], p.TxMap["time"], p.TxMap["user_id"], p.TxMap["soft_type"], p.TxMap["version"], utils.Sha256(p.TxMap["file"]), p.TxMap["format"]) CheckSignResult, err := utils.CheckSign(p.PublicKeys, forSign, p.TxMap["sign"], false) if err != nil { return p.ErrInfo(err) } if !CheckSignResult { return p.ErrInfo("incorrect sign") } return nil }
func (p *Parser) ChangeSellerHoldBackFront() error { err := p.generalCheck() if err != nil { return p.ErrInfo(err) } verifyData := map[string]string{"arbitration_days_refund": "smallint", "hold_back_pct": "pct"} err = p.CheckInputData(verifyData) if err != nil { return p.ErrInfo(err) } if p.TxMaps.Money["hold_back_pct"] < 0.01 || p.TxMaps.Money["hold_back_pct"] > 100 { return p.ErrInfo("incorrect hold_back_pct") } forSign := fmt.Sprintf("%s,%s,%s,%s,%s", p.TxMap["type"], p.TxMap["time"], p.TxMap["user_id"], p.TxMap["arbitration_days_refund"], p.TxMap["hold_back_pct"]) CheckSignResult, err := utils.CheckSign(p.PublicKeys, forSign, p.TxMap["sign"], false) if err != nil { return p.ErrInfo(err) } if !CheckSignResult { return p.ErrInfo("incorrect sign") } err = p.limitRequest(consts.LIMIT_CHANGE_SELLER_HOLD_BACK, "change_seller_hold_back", consts.LIMIT_CHANGE_SELLER_HOLD_BACK_PERIOD) if err != nil { return p.ErrInfo(err) } return nil }
func (p *Parser) ChangePrimaryKeyFront() error { err := p.generalCheck() if err != nil { return p.ErrInfo(err) } if !utils.CheckInputData(p.newPublicKeysHex[0], "public_key") { return p.ErrInfo("public_key") } if len(p.newPublicKeysHex[1]) > 0 && !utils.CheckInputData(p.newPublicKeysHex[1], "public_key") { return p.ErrInfo("public_key 1") } if len(p.newPublicKeysHex[2]) > 0 && !utils.CheckInputData(p.newPublicKeysHex[2], "public_key") { return p.ErrInfo("public_key 2") } forSign := fmt.Sprintf("%s,%s,%s,%s,%s,%s", p.TxMap["type"], p.TxMap["time"], p.TxMap["user_id"], p.newPublicKeysHex[0], p.newPublicKeysHex[1], p.newPublicKeysHex[2]) CheckSignResult, err := utils.CheckSign(p.PublicKeys, forSign, p.TxMap["sign"], false) if err != nil { return p.ErrInfo(err) } if !CheckSignResult { return p.ErrInfo("incorrect sign") } err = p.limitRequest(p.Variables.Int64["limit_primary_key"], "primary_key", p.Variables.Int64["limit_primary_key_period"]) if err != nil { return p.ErrInfo(err) } return nil }
func (p *Parser) AdminNewVersionAlertFront() error { err := p.generalCheckAdmin() if err != nil { return p.ErrInfo(err) } verifyData := map[string]string{"version": "version", "soft_type": "soft_type"} err = p.CheckInputData(verifyData) if err != nil { return p.ErrInfo(err) } alert, err := p.Single("SELECT alert FROM new_version WHERE version = ?", p.TxMaps.String["version"]).Int64() if err != nil { return p.ErrInfo(err) } if alert == 1 { return p.ErrInfo("alert == 1") } forSign := fmt.Sprintf("%s,%s,%s,%s,%s", p.TxMap["type"], p.TxMap["time"], p.TxMap["user_id"], p.TxMap["soft_type"], p.TxMap["version"]) CheckSignResult, err := utils.CheckSign(p.PublicKeys, forSign, p.TxMap["sign"], false) if err != nil { return p.ErrInfo(err) } if !CheckSignResult { return p.ErrInfo("incorrect sign") } return nil }
func (p *Parser) ChangeCaFront() error { err := p.generalCheck() if err != nil { return p.ErrInfo(err) } if !utils.CheckInputData(p.TxMaps.String["ca1"], "ca_url") && p.TxMaps.String["ca1"] != "0" { return fmt.Errorf("incorrect ca1") } if !utils.CheckInputData(p.TxMaps.String["ca2"], "ca_url") && p.TxMaps.String["ca2"] != "0" { return fmt.Errorf("incorrect ca2") } if !utils.CheckInputData(p.TxMaps.String["ca3"], "ca_url") && p.TxMaps.String["ca3"] != "0" { return fmt.Errorf("incorrect ca3") } forSign := fmt.Sprintf("%s,%s,%s,%s,%s,%s", p.TxMap["type"], p.TxMap["time"], p.TxMap["user_id"], p.TxMap["ca1"], p.TxMap["ca2"], p.TxMap["ca3"]) CheckSignResult, err := utils.CheckSign(p.PublicKeys, forSign, p.TxMap["sign"], false) if err != nil { return p.ErrInfo(err) } if !CheckSignResult { return p.ErrInfo("incorrect sign") } err = p.limitRequest(consts.LIMIT_CHANGE_CA, "change_ca", consts.LIMIT_CHANGE_CA_PERIOD) if err != nil { return p.ErrInfo(err) } return nil }
func (p *Parser) UserAvatarFront() error { err := p.generalCheck() if err != nil { return p.ErrInfo(err) } verifyData := map[string]string{"name": "user_name"} err = p.CheckInputData(verifyData) if err != nil { return p.ErrInfo(err) } if !utils.CheckInputData(p.TxMaps.String["avatar"], "img_url") && p.TxMaps.String["avatar"] != "0" { return fmt.Errorf("incorrect avatar") } forSign := fmt.Sprintf("%s,%s,%s,%s,%s", p.TxMap["type"], p.TxMap["time"], p.TxMap["user_id"], p.TxMap["name"], p.TxMap["avatar"]) CheckSignResult, err := utils.CheckSign(p.PublicKeys, forSign, p.TxMap["sign"], false) if err != nil { return p.ErrInfo(err) } if !CheckSignResult { return p.ErrInfo("incorrect sign") } err = p.limitRequest(consts.LIMIT_USER_AVATAR, "user_avatar", consts.LIMIT_USER_AVATAR_PERIOD) if err != nil { return p.ErrInfo(err) } return nil }
func (p *Parser) ChangeKeyActiveFront() error { err := p.generalCheck() if err != nil { return p.ErrInfo(err) } if len(p.TxMaps.Bytes["secret"]) > 2048 { return p.ErrInfo("len secret > 2048") } // проверим, чтобы не было повторных смен changeKey, err := p.Single("SELECT change_key FROM users WHERE user_id = ?", p.TxUserID).Int64() if err != nil { return p.ErrInfo(err) } if changeKey == p.TxMaps.Int64["active"] { return p.ErrInfo("active") } forSign := fmt.Sprintf("%s,%s,%s,%s", p.TxMap["type"], p.TxMap["time"], p.TxMap["user_id"], p.TxMaps.String["secret_hex"]) CheckSignResult, err := utils.CheckSign(p.PublicKeys, forSign, p.TxMap["sign"], false) if err != nil { return p.ErrInfo(err) } if !CheckSignResult { return p.ErrInfo("incorrect sign") } err = p.limitRequest(consts.LIMIT_CHANGE_KEY_ACTIVE, "change_key_active", consts.LIMIT_CHANGE_KEY_ACTIVE_PERIOD) if err != nil { return p.ErrInfo(err) } return nil }
func (p *Parser) DelAutoPaymentFront() error { err := p.generalCheck() if err != nil { return p.ErrInfo(err) } verifyData := map[string]string{"auto_payment_id": "int"} err = p.CheckInputData(verifyData) if err != nil { return p.ErrInfo(err) } // проверим, есть ли такой автоплатеж, принадлежащий нашем юзеру autoPayment, err := p.Single("SELECT id FROM auto_payments WHERE id = ? and sender = ?", p.TxMaps.Int64["project_id"], p.TxUserID).Int64() if err != nil { return p.ErrInfo(err) } if autoPayment == 0 { return p.ErrInfo("incorrect auto_payment_id") } forSign := fmt.Sprintf("%s,%s,%s,%s", p.TxMap["type"], p.TxMap["time"], p.TxMap["user_id"], p.TxMap["auto_payment_id"]) CheckSignResult, err := utils.CheckSign(p.PublicKeys, forSign, p.TxMap["sign"], false) if err != nil { return p.ErrInfo(err) } if !CheckSignResult { return p.ErrInfo("incorrect sign") } return nil }
func (p *Parser) ChangeKeyCloseFront() error { err := p.generalCheck() if err != nil { return p.ErrInfo(err) } // проверим, не стоит ли уже close changeKeyClose, err := p.Single("SELECT change_key_close FROM users WHERE user_id = ?", p.TxUserID).Int64() if err != nil { return p.ErrInfo(err) } if changeKeyClose > 0 { return p.ErrInfo("change_key_close=1") } forSign := fmt.Sprintf("%s,%s,%s", p.TxMap["type"], p.TxMap["time"], p.TxMap["user_id"]) CheckSignResult, err := utils.CheckSign(p.PublicKeys, forSign, p.TxMap["sign"], false) if err != nil { return p.ErrInfo(err) } if !CheckSignResult { return p.ErrInfo("incorrect sign") } return nil }
func (p *Parser) MessageToAdminFront() error { err := p.generalCheck() if err != nil { return p.ErrInfo(err) } // в бинарном виде проверить можем только размер if len(p.TxMaps.Bytes["encrypted_message"]) > 20480 || len(p.TxMaps.Bytes["encrypted_message"]) == 0 { return p.ErrInfo("encrypted_message len") } forSign := fmt.Sprintf("%s,%s,%s,%s", p.TxMap["type"], p.TxMap["time"], p.TxMap["user_id"], p.TxMap["encrypted_message"]) CheckSignResult, err := utils.CheckSign(p.PublicKeys, forSign, p.TxMap["sign"], false) if err != nil { return p.ErrInfo(err) } if !CheckSignResult { return p.ErrInfo("incorrect sign") } err = p.limitRequest(p.Variables.Int64["limit_message_to_admin"], "message_to_admin", p.Variables.Int64["limit_message_to_admin_period"]) if err != nil { return p.ErrInfo(err) } return nil }
func (p *Parser) MoneyBackFront() error { err := p.generalCheck() if err != nil { return p.ErrInfo(err) } verifyData := map[string]string{"order_id": "bigint", "amount": "amount"} err = p.CheckInputData(verifyData) if err != nil { return p.ErrInfo(err) } var txTime int64 if p.BlockData != nil { txTime = p.BlockData.Time } else { txTime = time.Now().Unix() - 30 // просто на всякий случай небольшой запас } // проверим корректность ордера. тр-ия может быть как от продавца, так и от арбитра orderId, err := p.Single(` SELECT id FROM orders WHERE id = ? AND status = 'refund' AND ( ( (arbitrator0 = ? OR arbitrator1 = ? OR arbitrator2 = ? OR arbitrator3 = ? OR arbitrator4 = ?) AND refund = 0 AND (amount - voluntary_refund - ?) >= 0 AND end_time >= ? ) OR ( seller = ? AND voluntary_refund = 0 AND (amount - refund - ?) >= 0 AND end_time >= ? ) ) LIMIT 1 `, p.TxMaps.Int64["order_id"], p.TxUserID, p.TxUserID, p.TxUserID, p.TxUserID, p.TxUserID, string(p.TxMap["amount"]), txTime, p.TxUserID, string(p.TxMap["amount"]), txTime).Int64() if err != nil { return p.ErrInfo(err) } if orderId == 0 { return p.ErrInfo("orderId==0") } forSign := fmt.Sprintf("%s,%s,%s,%s,%s", p.TxMap["type"], p.TxMap["time"], p.TxMap["user_id"], p.TxMap["order_id"], p.TxMap["amount"]) CheckSignResult, err := utils.CheckSign(p.PublicKeys, forSign, p.TxMap["sign"], false) if err != nil { return p.ErrInfo(err) } if !CheckSignResult { return p.ErrInfo("incorrect sign") } return nil }
func (p *Parser) DelCfProjectFront() error { err := p.generalCheck() if err != nil { return p.ErrInfo(err) } verifyData := map[string]string{"project_id": "int"} err = p.CheckInputData(verifyData) if err != nil { return p.ErrInfo(err) } // проверим, есть ли такой проект projectActive, err := p.Single("SELECT id FROM cf_projects WHERE id = ? AND user_id = ? AND close_block_id = 0 AND del_block_id = 0", p.TxMaps.Int64["project_id"], p.TxUserID).Int64() if err != nil { return p.ErrInfo(err) } if projectActive == 0 { return p.ErrInfo("incorrect project_id") } forSign := fmt.Sprintf("%s,%s,%s,%s", p.TxMap["type"], p.TxMap["time"], p.TxMap["user_id"], p.TxMap["project_id"]) CheckSignResult, err := utils.CheckSign(p.PublicKeys, forSign, p.TxMap["sign"], false) if err != nil { return p.ErrInfo(err) } if !CheckSignResult { return p.ErrInfo("incorrect sign") } return nil }
func (p *Parser) NewUserFront() error { log.Debug("NewUserFront") err := p.generalCheck() if err != nil { return p.ErrInfo(err) } // является ли данный юзер майнером err = p.checkMiner(p.TxUserID) if err != nil { return p.ErrInfo(err) } // прошло ли 30 дней с момента регистрации майнера err = p.checkMinerNewbie() if err != nil { return p.ErrInfo(err) } // чтобы не записали слишком мелкий или слишком крупный ключ if !utils.CheckInputData(p.TxMap["public_key_hex"], "public_key") { return utils.ErrInfo(fmt.Errorf("incorrect public_key %s", p.TxMap["public_key_hex"])) } // публичный ключ должен быть без паролей if ok, _ := regexp.MatchString("DEK-Info: (.+),(.+)", string(p.TxMap["public_key"])); ok { return p.ErrInfo("incorrect public_key") } forSign := fmt.Sprintf("%s,%s,%s,%s", p.TxMap["type"], p.TxMap["time"], p.TxMap["user_id"], p.TxMap["public_key_hex"]) CheckSignResult, err := utils.CheckSign(p.PublicKeys, forSign, p.TxMap["sign"], false) if err != nil { return p.ErrInfo(err) } if !CheckSignResult { return p.ErrInfo("incorrect sign") } // один ключ не может быть у двух юзеров num, err := p.DCDB.Single("SELECT count(user_id) FROM users WHERE hex(public_key_0) = ? OR hex(public_key_1) = ? OR hex(public_key_2) = ?", p.TxMap["public_key_hex"], p.TxMap["public_key_hex"], p.TxMap["public_key_hex"]).Int() if num > 0 { return p.ErrInfo("exists public_key") } err = p.getAdminUserId() if err != nil { return p.ErrInfo(err) } if utils.BytesToInt64(p.TxMap["user_id"]) == p.AdminUserId { err = p.limitRequest(1000, "new_user", 86400) } else { err = p.limitRequest(p.Variables.Int64["limit_new_user"], "new_user", p.Variables.Int64["limit_new_user_period"]) } if err != nil { return p.ErrInfo(err) } return nil }
func (p *Parser) ActualizationPromisedAmountsFront() error { err := p.generalCheck() if err != nil { return p.ErrInfo(err) } // есть ли что актуализировать promisedAmountId, err := p.Single("SELECT id FROM promised_amount WHERE status = 'mining' AND user_id = ? AND currency_id > 1 AND del_block_id = 0 AND del_mining_block_id = 0 AND (cash_request_out_time > 0 AND cash_request_out_time < ? )", p.TxUserID, (p.TxTime - p.Variables.Int64["cash_request_time"])).Int64() if err != nil { return p.ErrInfo(err) } if promisedAmountId == 0 { return p.ErrInfo("incorrect promisedAmountId") } forSign := fmt.Sprintf("%s,%s,%s", p.TxMap["type"], p.TxMap["time"], p.TxMap["user_id"]) CheckSignResult, err := utils.CheckSign(p.PublicKeys, forSign, p.TxMap["sign"], false) if err != nil { return p.ErrInfo(err) } if !CheckSignResult { return p.ErrInfo("incorrect sign") } err = p.limitRequest(consts.LIMIT_ACTUALIZATION, "actualization", consts.LIMIT_ACTUALIZATION_PERIOD) if err != nil { return p.ErrInfo(err) } return nil }
/* не забываем, что cash_request_OUT_front проверяет формат amount, * можно ли делать запрос указанному юзеру, есть ли у юзера * обещанные суммы на сумму amount, есть ли нужное кол-во DC у отправителя, * является ли отправитель майнером * * */ func (p *Parser) CashRequestInFront() error { err := p.generalCheck() if err != nil { return p.ErrInfo(err) } // code может быть чем угодно, т.к. отправитель шлет в сеть лишь хэш // нигде, кроме cash_request_in_front, code не используется // if ( !check_input_data ($this->tx_data['code'], 'cash_code') ) // return 'cash_request_in_front code'; verifyData := map[string]string{"cash_request_id": "bigint"} err = p.CheckInputData(verifyData) if err != nil { return p.ErrInfo(err) } var to_user_id, cTime int64 var status string var hash_code []byte err = p.QueryRow(p.FormatQuery("SELECT to_user_id, status, hash_code, time FROM cash_requests WHERE id = ?"), p.TxMaps.Int64["cash_request_id"]).Scan(&to_user_id, &status, &hash_code, &cTime) if err != nil && err != sql.ErrNoRows { return p.ErrInfo(err) } // ID cash_requests юзер указал сам, значит это может быть случайное число. // проверим, является получателем наш юзер if to_user_id != p.TxUserID { return p.ErrInfo("to_user_id!=user_id") } // должно быть pending if status != "pending" { return p.ErrInfo("status!=pending") } // проверим код if !bytes.Equal(utils.DSha256(p.TxMaps.String["code"]), utils.BinToHex(hash_code)) { return p.ErrInfo("code!=hash_code") } var txTime int64 if p.BlockData != nil { // тр-ия пришла в блоке txTime = p.BlockData.Time } else { txTime = time.Now().Unix() // просто на всякий случай небольшой запас } // запрос может быть принят, только если он был отправлен не позднее чем через cash_request_time сек назад if cTime < txTime-p.Variables.Int64["cash_request_time"] { return p.ErrInfo(fmt.Sprintf("%d < %d - %d", cTime, txTime, p.Variables.Int64["cash_request_time"])) } forSign := fmt.Sprintf("%s,%s,%s,%s,%s", p.TxMap["type"], p.TxMap["time"], p.TxMap["user_id"], p.TxMap["cash_request_id"], p.TxMap["code"]) CheckSignResult, err := utils.CheckSign(p.PublicKeys, forSign, p.TxMap["sign"], false) if err != nil { return p.ErrInfo(err) } if !CheckSignResult { return p.ErrInfo("incorrect sign") } return nil }
func (p *Parser) DelForexOrderFront() error { err := p.generalCheck() if err != nil { return p.ErrInfo(err) } err = p.CheckInputData(map[string]string{"order_id": "int"}) if err != nil { return p.ErrInfo(err) } orderId, err := p.Single("SELECT id FROM forex_orders WHERE id = ? AND user_id = ? AND del_block_id = 0", p.TxMaps.Int64["order_id"], p.TxUserID).Int64() if err != nil { return p.ErrInfo(err) } if orderId == 0 { return p.ErrInfo("incorrect order_id") } // проверим, есть ли ордер для удаления forSign := fmt.Sprintf("%s,%s,%s,%s", p.TxMap["type"], p.TxMap["time"], p.TxMap["user_id"], p.TxMap["order_id"]) CheckSignResult, err := utils.CheckSign(p.PublicKeys, forSign, p.TxMap["sign"], false) if err != nil || !CheckSignResult { return p.ErrInfo("incorrect sign") } return nil }
func (p *Parser) VotesNodeNewMinerFront() error { err := p.generalCheck() if err != nil { return p.ErrInfo(err) } // является ли данный юзер майнером err = p.checkMiner(p.TxUserID) if err != nil { return err } if !utils.CheckInputData(p.TxMap["result"], "vote") { return utils.ErrInfoFmt("incorrect vote") } // получим public_key p.nodePublicKey, err = p.GetNodePublicKey(p.TxUserID) if len(p.nodePublicKey) == 0 { return utils.ErrInfoFmt("incorrect user_id len(nodePublicKey) = 0") } if !utils.CheckInputData(p.TxMap["vote_id"], "bigint") { return utils.ErrInfoFmt("incorrect bigint") } forSign := fmt.Sprintf("%s,%s,%s,%s,%s", p.TxMap["type"], p.TxMap["time"], p.TxMap["user_id"], p.TxMap["vote_id"], p.TxMap["result"]) CheckSignResult, err := utils.CheckSign([][]byte{p.nodePublicKey}, forSign, p.TxMap["sign"], true) if err != nil { return p.ErrInfo(err) } if !CheckSignResult { return utils.ErrInfoFmt("incorrect sign") } // проверим, верно ли указан ID и не закончилось ли голосование id, err := p.Single("SELECT id FROM votes_miners WHERE id = ? AND type = 'node_voting' AND votes_end = 0", p.TxMaps.Int64["vote_id"]).Int64() if err != nil { return p.ErrInfo(err) } if id == 0 { return p.ErrInfo(fmt.Errorf("voting is over")) } // проверим, не повторное ли это голосование данного юзера num, err := p.Single("SELECT count(user_id) FROM log_votes WHERE user_id = ? AND voting_id = ? AND type = 'votes_miners'", p.TxMaps.Int64["user_id"], p.TxMaps.Int64["vote_id"]).Int64() if err != nil { return p.ErrInfo(err) } if num > 0 { return utils.ErrInfoFmt("double voting") } // нод не должен голосовать более X раз за сутки, чтобы не было доса err = p.limitRequest(p.Variables.Int64["node_voting"], "votes_nodes", p.Variables.Int64["node_voting_period"]) if err != nil { return p.ErrInfo(err) } return nil }
func (p *Parser) MoneyBackRequestFront() error { err := p.generalCheck() if err != nil { return p.ErrInfo(err) } verifyData := map[string]string{"order_id": "bigint", "seller_enc_text": "comment", "arbitrator0_enc_text": "comment", "arbitrator1_enc_text": "comment", "arbitrator2_enc_text": "comment", "arbitrator3_enc_text": "comment", "arbitrator4_enc_text": "comment"} err = p.CheckInputData(verifyData) if err != nil { return p.ErrInfo(err) } var txTime int64 if p.BlockData != nil { // тр-ия пришла в блоке txTime = p.BlockData.Time } else { // голая тр-ия txTime = time.Now().Unix() - 30 // просто на всякий случай небольшой запас } // проверим, есть ли такой ордер, не был ли ранее запрос, точно ли покупатель наш юзер orderId, err := p.Single("SELECT id FROM orders WHERE id = ? AND status = 'normal' AND end_time > ? AND buyer = ?", p.TxMaps.Int64["order_id"], txTime, p.TxUserID).Int64() if err != nil { return p.ErrInfo(err) } if orderId == 0 { return p.ErrInfo("orderId==0") } forSign := "" if p.BlockData != nil && p.BlockData.BlockId < 197115 { forSign = fmt.Sprintf("%s,%s,%s,%s,%s,%s,%s,%s,%s,%s", p.TxMap["type"], p.TxMap["time"], p.TxMap["user_id"], p.TxMap["order_id"], p.TxMap["arbitrator0_enc_text"], p.TxMap["arbitrator1_enc_text"], p.TxMap["arbitrator2_enc_text"], p.TxMap["arbitrator3_enc_text"], p.TxMap["arbitrator4_enc_text"], p.TxMap["seller_enc_text"]) } else { encData := make(map[string]string) for i := 0; i < 5; i++ { iStr := utils.IntToStr(i) encData["arbitrator"+iStr+"_enc_text"] = string(utils.BinToHex(p.TxMap["arbitrator"+iStr+"_enc_text"])) if encData["arbitrator"+iStr+"_enc_text"] == "00" { encData["arbitrator"+iStr+"_enc_text"] = "0" } } forSign = fmt.Sprintf("%s,%s,%s,%s,%s,%s,%s,%s,%s,%s", p.TxMap["type"], p.TxMap["time"], p.TxMap["user_id"], p.TxMap["order_id"], encData["arbitrator0_enc_text"], encData["arbitrator1_enc_text"], encData["arbitrator2_enc_text"], encData["arbitrator3_enc_text"], encData["arbitrator4_enc_text"], utils.BinToHex(p.TxMap["seller_enc_text"])) } CheckSignResult, err := utils.CheckSign(p.PublicKeys, forSign, p.TxMap["sign"], false) if err != nil { return p.ErrInfo(err) } if !CheckSignResult { return p.ErrInfo("incorrect sign") } err = p.limitRequest(consts.LIMIT_MONEY_BACK_REQUEST, "money_back_request", consts.LIMIT_MONEY_BACK_REQUEST_PERIOD) if err != nil { return p.ErrInfo(err) } return nil }
func (p *Parser) AdminChangePrimaryKeyFront() error { err := p.generalCheckAdmin() if err != nil { return p.ErrInfo(err) } verifyData := map[string]string{"for_user_id": "user_id", "public_key_hex": "public_key"} err = p.CheckInputData(verifyData) if err != nil { return p.ErrInfo(err) } var txTime int64 if p.BlockData != nil { // тр-ия пришла в блоке txTime = p.BlockData.Time } else { txTime = time.Now().Unix() - 30 // просто на всякий случай небольшой запас } data, err := p.OneRow("SELECT user_id, change_key, change_key_time, change_key_close FROM users WHERE user_id = ?", p.TxMaps.Int64["for_user_id"]).Int64() if err != nil { return p.ErrInfo(err) } if len(data) == 0 { return p.ErrInfo("incorrect for_user_id") } // разрешил ли юзер смену ключа админом if data["change_key"] == 0 { return p.ErrInfo("change_key = 0") } // юзер отменил запрос на смену ключа if data["change_key_close"] == 1 { return p.ErrInfo("change_key_close = 1") } // прошел ли месяц с момента, когда кто-то запросил смену ключа if p.BlockData != nil && p.BlockData.BlockId > 170770 { if txTime-data["change_key_time"] < consts.CHANGE_KEY_PERIOD { return p.ErrInfo("CHANGE_KEY_PERIOD") } } else { if txTime-data["change_key_time"] < consts.CHANGE_KEY_PERIOD_170770 { return p.ErrInfo("CHANGE_KEY_PERIOD_170770") } } forSign := fmt.Sprintf("%s,%s,%s,%s,%s", p.TxMap["type"], p.TxMap["time"], p.TxMap["user_id"], p.TxMap["for_user_id"], p.TxMap["public_key_hex"]) CheckSignResult, err := utils.CheckSign(p.PublicKeys, forSign, p.TxMap["sign"], false) if err != nil { return p.ErrInfo(err) } if !CheckSignResult { return p.ErrInfo("incorrect sign") } return nil }
func (p *Parser) CfSendDcFront() error { err := p.generalCheck() if err != nil { return p.ErrInfo(err) } verifyData := map[string]string{"project_id": "int", "amount": "amount", "commission": "amount", "comment": "comment"} err = p.CheckInputData(verifyData) if err != nil { return p.ErrInfo(err) } if p.TxMaps.Money["amount"] < 0.01 { // 0.01 - минимальная сумма return p.ErrInfo("amount<0.01") } // не закончился ли сбор средств projectCurrencyId, err := p.Single("SELECT currency_id FROM cf_projects WHERE id = ? AND close_block_id = 0 AND del_block_id = 0", p.TxMaps.Int64["project_id"]).Int64() if err != nil { return p.ErrInfo(err) } if projectCurrencyId == 0 { return p.ErrInfo("projectCurrencyId==0") } nodeCommission, err := p.getMyNodeCommission(projectCurrencyId, p.TxUserID, p.TxMaps.Money["amount"]) if err != nil { return p.ErrInfo(err) } // проверим, удовлетворяет ли нас комиссия, которую предлагает юзер if p.TxMaps.Money["commission"] < nodeCommission { return p.ErrInfo("incorrect commission") } forSign := fmt.Sprintf("%s,%s,%s,%s,%s,%s,%s", p.TxMap["type"], p.TxMap["time"], p.TxMap["user_id"], p.TxMap["project_id"], p.TxMap["amount"], p.TxMap["commission"], utils.BinToHex(p.TxMap["comment"])) CheckSignResult, err := utils.CheckSign(p.PublicKeys, forSign, p.TxMap["sign"], false) if err != nil { return p.ErrInfo(err) } if !CheckSignResult { return p.ErrInfo("incorrect sign") } // Для защиты от несовместимости тр-ий cf_send_dc, new_forex_order, send_dc,cash_requests не могут быть в одном блоке (clear_incompatible_tx()). А cf_send_dc, new_forex_order,cash_requests могут быть только в единичном кол-ве в одном блоке от одного юзера. // есть ли нужная сумма в кошельке _, err = p.checkSenderMoney(projectCurrencyId, p.TxUserID, p.TxMaps.Money["amount"], p.TxMaps.Money["commission"], 0, 0, 0, 0, 0) if err != nil { return p.ErrInfo(err) } err = p.limitRequest(consts.LIMIT_CF_SEND_DC, "cf_send_dc", consts.LIMIT_CF_SEND_DC_PERIOD) if err != nil { return p.ErrInfo(err) } return nil }
func (p *Parser) VotesMinerFront() error { err := p.generalCheck() if err != nil { return p.ErrInfo(err) } if !utils.CheckInputData(p.TxMap["vote_id"], "bigint") { return p.ErrInfo("incorrect vote_id") } if !utils.CheckInputData(p.TxMap["result"], "vote") { return p.ErrInfo("incorrect vote_id") } if !utils.CheckInputData(p.TxMap["comment"], "votes_comment") { return p.ErrInfo("incorrect comment") } // является ли данный юзер майнером err = p.checkMiner(p.TxUserID) if err != nil { return p.ErrInfo(err) } // проверим, верно ли указан ID и не закончилось ли голосование id, err := p.Single("SELECT id FROM votes_miners WHERE id = ? AND type = 'user_voting' AND votes_end = 0", p.TxMaps.Int64["vote_id"]).Int() if err != nil { return p.ErrInfo(err) } if id == 0 { return p.ErrInfo("voting is over") } // проверим, не повторное ли это голосование данного юзера num, err := p.Single("SELECT count(user_id) FROM log_votes WHERE user_id = ? AND voting_id = ? AND type = 'votes_miners'", p.TxMaps.Int64["user_id"], p.TxMaps.Int64["vote_id"]).Int() if err != nil { return p.ErrInfo("double voting") } if num > 0 { return p.ErrInfo("double voting") } forSign := fmt.Sprintf("%s,%s,%s,%s,%s,%s", p.TxMap["type"], p.TxMap["time"], p.TxMap["user_id"], p.TxMap["vote_id"], p.TxMap["result"], p.TxMap["comment"]) CheckSignResult, err := utils.CheckSign(p.PublicKeys, forSign, p.TxMap["sign"], false) if err != nil { return p.ErrInfo(err) } if !CheckSignResult { return p.ErrInfo("incorrect sign") } // защита от доса err = p.maxDayVotes() if err != nil { return p.ErrInfo(err) } return nil }
func (p *Parser) VotesPromisedAmountFront() error { err := p.generalCheck() if err != nil { return p.ErrInfo(err) } verifyData := map[string]string{"promised_amount_id": "bigint", "result": "vote", "comment": "votes_comment"} err = p.CheckInputData(verifyData) if err != nil { return p.ErrInfo(err) } // является ли данный юзер майнером err = p.checkMiner(p.TxUserID) if err != nil { return p.ErrInfo(err) } // проверим, не закончилось ли уже голосование и верный ли статус (pending) status, err := p.Single("SELECT status FROM promised_amount WHERE id = ? AND del_block_id = 0 AND del_mining_block_id = 0", p.TxMaps.Int64["promised_amount_id"]).String() if err != nil { return p.ErrInfo(err) } if status != "pending" { return p.ErrInfo("voting is over") } // проверим, не повторное ли это голосование данного юзера num, err := p.Single("SELECT count(user_id) FROM log_votes WHERE user_id = ? AND voting_id = ? AND type = 'promised_amount'", p.TxMaps.Int64["user_id"], p.TxMaps.Int64["promised_amount_id"]).Int64() if err != nil { return p.ErrInfo(err) } p.getAdminUserId() if num > 0 && p.TxUserID != p.AdminUserId { // админу можно return p.ErrInfo("double voting") } forSign := fmt.Sprintf("%s,%s,%s,%s,%s,%s", p.TxMap["type"], p.TxMap["time"], p.TxMap["user_id"], p.TxMap["promised_amount_id"], p.TxMap["result"], p.TxMap["comment"]) CheckSignResult, err := utils.CheckSign(p.PublicKeys, forSign, p.TxMap["sign"], false) if err != nil { return p.ErrInfo(err) } if !CheckSignResult { return p.ErrInfo("incorrect sign") } // лимиты на голоса, чтобы не задосили голосами err = p.maxDayVotes() if err != nil { return p.ErrInfo(err) } return nil }
func (p *Parser) ChangeNodeKeyFront() error { err := p.generalCheck() if err != nil { return p.ErrInfo(err) } // является ли данный юзер майнером err = p.checkMiner(p.TxUserID) if err != nil { return p.ErrInfo(err) } verifyData := map[string]string{"new_node_public_key": "public_key"} err = p.CheckInputData(verifyData) if err != nil { return p.ErrInfo(err) } nodePublicKey, err := p.GetNodePublicKey(p.TxUserID) if err != nil || len(nodePublicKey) == 0 { return p.ErrInfo("incorrect user_id") } forSign := fmt.Sprintf("%s,%s,%s,%s", p.TxMap["type"], p.TxMap["time"], p.TxMap["user_id"], p.TxMap["new_node_public_key"]) CheckSignResult, err := utils.CheckSign([][]byte{nodePublicKey}, forSign, p.TxMap["sign"], true) if err != nil || !CheckSignResult { forSign := fmt.Sprintf("%s,%s,%s,%s", p.TxMap["type"], p.TxMap["time"], p.TxMap["user_id"], p.TxMap["new_node_public_key"]) CheckSignResult, err := utils.CheckSign(p.PublicKeys, forSign, p.TxMap["sign"], false) if err != nil || !CheckSignResult { return p.ErrInfo("incorrect sign") } } err = p.limitRequest(p.Variables.Int64["limit_node_key"], "node_key", p.Variables.Int64["limit_node_key_period"]) if err != nil { return p.ErrInfo(err) } return nil }
func (p *Parser) VotesExchangeFront() error { err := p.generalCheck() if err != nil { return p.ErrInfo(err) } verifyData := map[string]string{"e_owner_id": "bigint", "result": "vote"} err = p.CheckInputData(verifyData) if err != nil { return p.ErrInfo(err) } // является ли данный юзер майнером err = p.checkMiner(p.TxUserID) if err != nil { return p.ErrInfo(err) } // проверим, есть ли такой юзер userId, err := p.Single("SELECT user_id FROM users WHERE user_id = ?", p.TxMaps.Int64["e_owner_id"]).Int64() if err != nil { return p.ErrInfo(err) } if userId == 0 { return p.ErrInfo("userId == 0") } // не было ли уже такого же голоса от этого юзера num, err := p.Single("SELECT count(user_id) FROM votes_exchange WHERE user_id = ? AND e_owner_id = ? AND result = ?", p.TxMaps.Int64["user_id"], p.TxMaps.Int64["e_owner_id"], p.TxMaps.Int64["result"]).Int64() if err != nil { return p.ErrInfo(err) } if num > 0 { return p.ErrInfo("exists") } forSign := fmt.Sprintf("%s,%s,%s,%s,%s", p.TxMap["type"], p.TxMap["time"], p.TxMap["user_id"], p.TxMap["e_owner_id"], p.TxMap["result"]) CheckSignResult, err := utils.CheckSign(p.PublicKeys, forSign, p.TxMap["sign"], false) if err != nil { return p.ErrInfo(err) } if !CheckSignResult { return p.ErrInfo("incorrect sign") } // лимиты на голоса, чтобы не задосили голосами err = p.maxDayVotes() if err != nil { return p.ErrInfo(err) } return nil }
func (p *Parser) ChangeArbitratorListFront() error { err := p.generalCheck() if err != nil { return p.ErrInfo(err) } verifyData := map[string]string{"arbitration_trust_list": "arbitration_trust_list"} err = p.CheckInputData(verifyData) if err != nil { return p.ErrInfo(err) } if len(p.TxMaps.String["arbitration_trust_list"]) > 255 { return p.ErrInfo("len arbitration_trust_list > 255") } var arbitrationTrustList []int if p.TxMaps.String["arbitration_trust_list"] != "[0]" { err = json.Unmarshal(p.TxMap["arbitration_trust_list"], &arbitrationTrustList) if err != nil { return p.ErrInfo(err) } sort.Ints(arbitrationTrustList) } // юзер мог удалить весь список доверенных if len(arbitrationTrustList) > 0 { // указанные id должны быть ID юзеров. Являются ли эти юзеры арбитрами будет проверяться при отправке монет count, err := p.Single("SELECT count(user_id) FROM users WHERE user_id IN (" + strings.Join(utils.IntSliceToStr(arbitrationTrustList), ",") + ")").Int() if err != nil { return p.ErrInfo(err) } if count != len(arbitrationTrustList) { return p.ErrInfo("count != len(arbitrationTrustList)") } } forSign := fmt.Sprintf("%s,%s,%s,%s", p.TxMap["type"], p.TxMap["time"], p.TxMap["user_id"], p.TxMap["arbitration_trust_list"]) CheckSignResult, err := utils.CheckSign(p.PublicKeys, forSign, p.TxMap["sign"], false) if err != nil { return p.ErrInfo(err) } if !CheckSignResult { return p.ErrInfo("incorrect sign") } err = p.limitRequest(consts.LIMIT_CHANGE_ARBITRATION_TRUST_LIST, "change_arbitration_trust_list", consts.LIMIT_CHANGE_ARBITRATION_TRUST_LIST_PERIOD) if err != nil { return p.ErrInfo(err) } return nil }
func (p *Parser) MiningFront() error { err := p.generalCheck() if err != nil { return p.ErrInfo(err) } verifyData := map[string]string{"promised_amount_id": "bigint", "amount": "amount"} err = p.CheckInputData(verifyData) if err != nil { return p.ErrInfo(err) } forSign := fmt.Sprintf("%s,%s,%s,%s,%s", p.TxMap["type"], p.TxMap["time"], p.TxMap["user_id"], p.TxMap["promised_amount_id"], p.TxMap["amount"]) CheckSignResult, err := utils.CheckSign(p.PublicKeys, forSign, p.TxMap["sign"], false) if err != nil { return p.ErrInfo(err) } if !CheckSignResult { return p.ErrInfo("incorrect sign") } // статус может быть любым кроме pending, т.к. то, что набежало в tdc_amount доступо для перевода на кошелек всегда num, err := p.Single("SELECT id FROM promised_amount WHERE id = ? AND user_id = ? AND status != 'pending' AND del_block_id = 0 AND del_mining_block_id = 0", p.TxMaps.Int64["promised_amount_id"], p.TxMaps.Int64["user_id"]).Int64() if err != nil { return p.ErrInfo(err) } if num == 0 { return p.ErrInfo("0 promised_amount for mining") } newTdc, err := p.getTdc(p.TxMaps.Int64["promised_amount_id"], p.TxUserID) if err != nil { return p.ErrInfo(err) } log.Debug("newTdc", newTdc) log.Debug("p.TxMaps.Float64[amount]", p.TxMaps.Money["amount"]) if newTdc < p.TxMaps.Money["amount"]+0.01 { // запас 0.01 на всяк случай return p.ErrInfo(fmt.Sprintf("incorrect amount %d<%f+0.01", newTdc, p.TxMaps.Money["amount"])) } if p.TxMaps.Money["amount"] < 0.02 { return p.ErrInfo("incorrect amount") } err = p.limitRequest(p.Variables.Int64["limit_mining"], "mining", p.Variables.Int64["limit_mining_period"]) if err != nil { return p.ErrInfo(err) } return nil }