印度包网
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

355 lines
8.1 KiB

package blockpay
import (
"fmt"
"server/call"
"server/common"
"server/config"
"server/db"
"server/pb"
"server/util"
"time"
"github.com/fbsobreira/gotron-sdk/pkg/account"
"github.com/fbsobreira/gotron-sdk/pkg/proto/core"
"github.com/fbsobreira/gotron-sdk/pkg/store"
"github.com/gogo/protobuf/proto"
"github.com/liangdas/mqant/log"
"gorm.io/gorm"
)
func Recharge(req *pb.InnerRechargeReq) (ret []byte, err error) {
log.Debug("player recharge:%+v", *req)
accountName := fmt.Sprintf("user%d", req.UID)
addr, _ := store.AddressFromAccountName(accountName)
if addr == "" {
account.CreateNewLocalAccount(&account.Creation{
Name: accountName,
})
addr, _ = store.AddressFromAccountName(accountName)
} else {
_, _, err := store.UnlockedKeystore(addr, "")
if err != nil {
log.Error("UnlockedKeystore err:%v", err)
account.RemoveAccount(accountName)
account.CreateNewLocalAccount(&account.Creation{
Name: accountName,
})
addr, _ = store.AddressFromAccountName(accountName)
}
}
util.Go(func() {
td := &common.TronData{UID: int(req.UID)}
db.Mysql().Get(td)
if td.Addr == addr {
return
}
if td.ID > 0 {
db.Mysql().Update(&common.TronData{UID: int(req.UID)}, map[string]interface{}{"addr": addr})
} else {
db.Mysql().Create(&common.TronData{UID: int(req.UID), Addr: addr})
}
})
mux.Lock()
one := &OneListen{OrderID: req.OrderID, Amount: req.Amount, Expire: time.Now().Unix() + ExpireTime}
listens, ok := listenMap[addr]
if !ok {
listenMap[addr] = []*OneListen{one}
} else {
listens = append(listens, one)
listenMap[addr] = listens
}
mux.Unlock()
pbResp := &pb.InnerRechargeResp{APIOrderID: req.OrderID, URL: addr}
ret, _ = proto.Marshal(pbResp)
return
}
func Withdraw(req *pb.InnerWithdrawReq) (ret []byte, err error) {
log.Debug("player withdraw:%+v", *req)
or := &common.WithdrawOrder{OrderID: req.OrderID}
db.Mysql().Get(or)
if or.Status > common.StatusROrderPay {
return
}
amount := req.Amount / 100
if config.GetBase().Release {
or.APIPayID, err = transferUSDT("", req.Address, or.OrderID, amount, 1)
} else {
or.APIPayID, err = transferTRX("", req.Address, or.OrderID, amount, 1)
}
success := err == nil
if success {
or.Status = common.StatusROrderFinish
} else {
or.Status = common.StatusROrderFail
}
call.WithdrawCallback(or)
return
}
func QueryOrder(req *pb.BlockPayQueryOrderReq) (ret []byte, err error) {
log.Debug("query order:%+v", req)
resp := new(pb.CommonResp)
defer func() {
ret, err = proto.Marshal(resp)
}()
or := &common.RechargeOrder{OrderID: req.OrderID}
db.Mysql().Get(or)
if or.Status == common.StatusROrderPay {
resp.Code = 2
resp.Msg = "该订单已完成"
return
}
or = &common.RechargeOrder{APIPayID: req.TxID, Status: common.StatusROrderPay}
db.Mysql().Get(or)
if len(or.OrderID) > 0 {
resp.Code = 2
resp.Msg = fmt.Sprintf("该交易单号已绑定订单%s", or.OrderID)
return
}
tx, err := tc.GetTransactionByID(req.TxID)
if err != nil {
log.Error("err:%e", err)
resp.Code = 2
resp.Msg = "查询交易出错"
return
}
if len(tx.Ret) == 0 {
resp.Code = 2
resp.Msg = "该交易存疑,请联系管理员"
return
}
if tx.Ret[0].ContractRet != core.Transaction_Result_SUCCESS {
resp.Code = 2
resp.Msg = "该交易已失败"
return
}
for _, v := range tx.RawData.Contract {
toAddr, amount := scanContracts(v)
if toAddr == "" || amount == 0 {
continue
}
if amount != or.Amount {
resp.Code = 2
resp.Msg = "交易金额与订单不符"
return
}
addr, err1 := store.AddressFromAccountName(fmt.Sprintf("user%d", or.UID))
if err1 != nil {
log.Error("err:%e", err)
resp.Code = 2
resp.Msg = "获取地址失败"
return
}
if addr != toAddr {
resp.Code = 2
resp.Msg = "交易地址有误"
return
}
_, _, err2 := store.UnlockedKeystore(addr, "")
if err2 != nil {
log.Error("err:%e", err2)
resp.Code = 2
resp.Msg = "获取私钥失败"
return
}
// ok
paySuccess(or.OrderID, toAddr, req.TxID, or.Amount)
break
}
return
}
func QueryLocalOfficialAddr(req *pb.CommonMsg) (ret []byte, err error) {
resp := &pb.BlockPayQueryLocalAddrResp{}
for _, v := range OfficialAddrs {
if v == "" {
continue
}
one := &pb.OneBlockAddr{
Addrres: v,
}
trx, err := tc.GetAccount(v)
if err != nil {
log.Error("err:%v")
}
var bal int64
if trx != nil {
bal = trx.Balance
}
one.TRX = util.FormatFloat(float64(bal)/1e6, 6)
usdt, err := tc.TRC20ContractBalance(v, TronUSDTAddr)
if err != nil {
log.Error("err:%v")
}
var usBal int64
if usdt != nil {
usBal = usdt.Int64()
}
one.USDT = util.FormatFloat(float64(usBal)/1e6, 6)
resp.Addrs = append(resp.Addrs, one)
}
log.Debug("get local addr:%v", OfficialAddrs)
ret, err = proto.Marshal(resp)
return
}
func AddLocalOfficialAddr(req *pb.BlockPayAddLocalAddrReq) (ret []byte, err error) {
log.Debug("add addr:%+v", *req)
resp := &pb.CommonResp{}
defer func() {
ret, err = proto.Marshal(resp)
}()
if req.Address == "" || req.Private == "" {
resp.Code = 2
resp.Msg = "请求参数有误"
return
}
if store.FromAddress(req.Address) != nil {
resp.Code = 2
resp.Msg = "该地址已添加"
return
}
for i := 1; i < MaxLocalAddress; i++ {
name := fmt.Sprintf("official%d", i)
addr, _ := store.AddressFromAccountName(name)
if addr == "" {
_, err = account.ImportFromPrivateKey(req.Private, name, "")
OfficialAddrs[i-1] = req.Address
if err != nil {
log.Error("err:%e", err)
resp.Code = 2
resp.Msg = "导入地址失败"
}
return
}
}
resp.Code = 2
resp.Msg = "本地地址过多"
return
}
func RemoveLocalOfficialAddr(req *pb.BlockPayAddLocalAddrReq) (ret []byte, err error) {
log.Debug("remove addr:%+v", *req)
resp := &pb.CommonResp{}
defer func() {
ret, err = proto.Marshal(resp)
}()
if req.Address == "" {
resp.Code = 2
resp.Msg = "请求参数有误"
return
}
for i, v := range OfficialAddrs {
if v == req.Address {
err1 := account.RemoveAccount(fmt.Sprintf("official%d", i+1))
if err1 != nil {
log.Error("err:%e", err1)
resp.Code = 2
resp.Msg = "移除地址失败"
}
return
}
}
resp.Code = 2
resp.Msg = "地址不存在"
return
}
func Transfer(req *pb.BlockPayTransferReq) (ret []byte, err error) {
log.Debug("transfer:%+v", *req)
resp := &pb.BlockPayTransferResp{}
defer func() {
ret, err = proto.Marshal(resp)
}()
if req.Amount <= 0 || req.FromAddr == "" || req.ToAddr == "" {
resp.Code = 2
resp.Msg = "请求参数有误"
return
}
var txid string
if req.Type == 1 {
txid, err = transferTRX(req.FromAddr, req.ToAddr, "", req.Amount, 3)
} else if req.Type == 2 {
txid, err = transferUSDT(req.FromAddr, req.ToAddr, "", req.Amount, 3)
} else {
resp.Code = 2
resp.Msg = "请求参数有误"
return
}
if err != nil {
resp.Code = 2
resp.Msg = "转账失败"
return
}
resp.TxID = txid
return
}
func GetFee(req *pb.CommonMsg) (ret []byte, err error) {
resp := &pb.BlockPayGetFeeResp{}
defer func() {
ret, err = proto.Marshal(resp)
}()
resp.Fee = getEnergyUse(0, "")
return
}
func ScanPlayerWallet(req *pb.BlockPayScanPlayerWalletReq) (ret []byte, err error) {
log.Debug("ScanPlayerWallet:%+v", *req)
resp := &pb.BlockPayScanPlayerWalletResp{}
defer func() {
ret, err = proto.Marshal(resp)
}()
sql := ""
if req.Down > 0 {
sql = fmt.Sprintf("usdt >= %v", req.Down)
} else {
sql = "usdt > 0"
}
if req.Up > 0 {
sql += fmt.Sprintf(" and usdt <= %v", req.Up)
}
list := []common.TronData{}
db.Mysql().QueryAll(sql, "", &common.TronData{}, &list)
fee := getEnergyUse(0, "")
needTotal := fee * int64(len(list))
toaddr := ""
for _, v := range OfficialAddrs {
if v == "" {
continue
}
trx, _ := tc.GetAccount(v)
if trx.Balance < needTotal {
continue
}
toaddr = v
break
}
if toaddr == "" {
resp.Code = 2
resp.Msg = "trx余额不足"
return
}
for _, v := range list {
_, err := transferUSDT(v.Addr, toaddr, "", v.Usdt, 2)
if err != nil {
log.Error("err:%v", err)
resp.Fail++
} else {
resp.Success++
db.Mysql().UpdateW(&common.TronData{}, map[string]interface{}{"usdt": gorm.Expr("usdt - ?", v.Usdt)}, fmt.Sprintf("uid = %v and usdt >=%v", v.UID, v.Usdt))
}
}
return
}