Commit 0d1ff723 authored by 贾浩@五瓣科技's avatar 贾浩@五瓣科技

update call login on server

parent 6bdc2243
...@@ -41,11 +41,11 @@ func main() { ...@@ -41,11 +41,11 @@ func main() {
} }
func runGasSender(cfg *config.Config) *gassender.GasSender { func runGasSender(cfg *config.Config) *gassender.GasSender {
gs, err := gassender.NewGasSender(cfg.GasSender.RPC, cfg.GasSender.PrivateKey) gs, err := gassender.NewGasSender(cfg.GasSender.RPC, cfg.GasSender.PrivateKey, cfg.GasSender.UserContract)
if err != nil { if err != nil {
panic(err) panic(err)
} }
gs.Run() gs.Run()
// gs.SendAONGas("0x0000000077024042e797Ae28A163C27E389CC5b2", 1) // gs.AonLogin(common.HexToAddress("aaaa"), "1", "1")
return gs return gs
} }
...@@ -29,8 +29,9 @@ type ServerConfig struct { ...@@ -29,8 +29,9 @@ type ServerConfig struct {
} }
type GasSenderConfig struct { type GasSenderConfig struct {
PrivateKey string `toml:"private_key"` PrivateKey string `toml:"private_key"`
RPC string `toml:"rpc"` UserContract string `toml:"user_contract"`
RPC string `toml:"rpc"`
} }
type TGBotConfig struct { type TGBotConfig struct {
......
This diff is collapsed.
This diff is collapsed.
...@@ -4,11 +4,12 @@ import ( ...@@ -4,11 +4,12 @@ import (
"context" "context"
"crypto/ecdsa" "crypto/ecdsa"
"math/big" "math/big"
"sdk_api/contract/aonUser"
"time" "time"
"github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/ethclient" "github.com/ethereum/go-ethereum/ethclient"
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
...@@ -19,21 +20,23 @@ type GasSender struct { ...@@ -19,21 +20,23 @@ type GasSender struct {
client *ethclient.Client client *ethclient.Client
taskCh chan *gasTask taskCh chan *gasTask
chainId *big.Int chainId *big.Int
nonce uint64
aonUser *aonUser.AonUser
} }
type gasTask struct { type gasTask struct {
dest common.Address user common.Address
value *big.Int userId string
inviter string
nonce uint64
} }
func NewGasSender(rpc, privateKey string) (*GasSender, error) { func NewGasSender(rpc, privateKey, aonUserContract string) (*GasSender, error) {
ecdsaKey, err := crypto.HexToECDSA(common.Bytes2Hex(common.FromHex(privateKey))) ecdsaKey, err := crypto.HexToECDSA(common.Bytes2Hex(common.FromHex(privateKey)))
if err != nil { if err != nil {
return nil, err return nil, err
} }
log.WithField("address", crypto.PubkeyToAddress(ecdsaKey.PublicKey)).Info("aon gas sender address")
client, err := ethclient.Dial(rpc) client, err := ethclient.Dial(rpc)
if err != nil { if err != nil {
return nil, err return nil, err
...@@ -44,11 +47,29 @@ func NewGasSender(rpc, privateKey string) (*GasSender, error) { ...@@ -44,11 +47,29 @@ func NewGasSender(rpc, privateKey string) (*GasSender, error) {
return nil, err return nil, err
} }
nonce, err := client.NonceAt(context.Background(), crypto.PubkeyToAddress(ecdsaKey.PublicKey), nil)
if err != nil {
return nil, err
}
ca, err := aonUser.NewAonUser(common.HexToAddress(aonUserContract), client)
if err != nil {
return nil, err
}
log.WithFields(log.Fields{
"caller": crypto.PubkeyToAddress(ecdsaKey.PublicKey),
"userContract": common.HexToAddress(aonUserContract),
"nonce": nonce,
}).Info("init gas sender")
return &GasSender{ return &GasSender{
privateKey: ecdsaKey, privateKey: ecdsaKey,
client: client, client: client,
taskCh: make(chan *gasTask, 32), taskCh: make(chan *gasTask, 64),
chainId: chainId, chainId: chainId,
nonce: nonce,
aonUser: ca,
}, nil }, nil
} }
...@@ -58,53 +79,54 @@ func (gs *GasSender) Run() { ...@@ -58,53 +79,54 @@ func (gs *GasSender) Run() {
for { for {
select { select {
case task := <-gs.taskCh: case task := <-gs.taskCh:
gs.sendTx(task) task.nonce = gs.nonce
gs.nonce++
go gs.sendTx(task)
} }
} }
}() }()
} }
func (gs *GasSender) SendAONGas(dest string, amount int) { // func (gs *GasSender) SendAONGas(dest string, amount int) {
addr := common.HexToAddress(dest) // addr := common.HexToAddress(dest)
value := new(big.Int).Mul(big.NewInt(int64(amount)), big.NewInt(1000000000000000000)) // value := new(big.Int).Mul(big.NewInt(int64(amount)), big.NewInt(1000000000000000000))
// gs.taskCh <- &gasTask{
// dest: addr,
// value: value,
// }
// }
func (gs *GasSender) AonLogin(user common.Address, userId, inviter string) {
gs.taskCh <- &gasTask{ gs.taskCh <- &gasTask{
dest: addr, user: user,
value: value, userId: userId,
inviter: inviter,
} }
} }
func (gs *GasSender) sendTx(task *gasTask) { func (gs *GasSender) sendTx(task *gasTask) {
log.WithFields(log.Fields{ log.WithFields(log.Fields{
"address": task.dest, "address": task.user.Hex(),
"value": task.value, "userId": task.userId,
}).Info("new send gas task") "inviterId": task.inviter,
nonce, err := gs.client.NonceAt(context.Background(), crypto.PubkeyToAddress(gs.privateKey.PublicKey), nil) "nonce": task.nonce,
if err != nil { }).Info("new login task")
log.WithError(err).Error("get nonce failed")
return
}
tx := &types.LegacyTx{ opts, err := bind.NewKeyedTransactorWithChainID(gs.privateKey, gs.chainId)
Nonce: nonce,
GasPrice: big.NewInt(1000000000),
Gas: 21000,
To: &task.dest,
Value: task.value,
}
signer := types.NewEIP155Signer(gs.chainId)
signedTx, err := types.SignNewTx(gs.privateKey, signer, tx)
if err != nil { if err != nil {
log.WithError(err).Error("sign tx failed") log.WithError(err).Error("create transactor failed")
return return
} }
err = gs.client.SendTransaction(context.Background(), signedTx) opts.GasPrice = big.NewInt(1000000000)
opts.GasLimit = 2000000
opts.Nonce = big.NewInt(int64(task.nonce))
signedTx, err := gs.aonUser.LoginByServer(opts, task.user, task.userId, task.inviter)
if err != nil { if err != nil {
log.WithError(err).Error("send tx failed") log.WithError(err).Error("send tx failed")
return return
} }
txLog := log.WithField("txHash", signedTx.Hash().Hex()) txLog := log.WithField("txHash", signedTx.Hash().Hex())
txLog.Info("tx broadcasted") txLog.Info("tx broadcasted")
for i := 0; i < 5; i++ { for i := 0; i < 5; i++ {
......
...@@ -31,6 +31,7 @@ require ( ...@@ -31,6 +31,7 @@ require (
github.com/deckarep/golang-set/v2 v2.1.0 // indirect github.com/deckarep/golang-set/v2 v2.1.0 // indirect
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 // indirect github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 // indirect
github.com/ethereum/c-kzg-4844/bindings/go v0.0.0-20230126171313-363c7d7593b4 // indirect github.com/ethereum/c-kzg-4844/bindings/go v0.0.0-20230126171313-363c7d7593b4 // indirect
github.com/fsnotify/fsnotify v1.6.0 // indirect
github.com/gabriel-vasile/mimetype v1.4.3 // indirect github.com/gabriel-vasile/mimetype v1.4.3 // indirect
github.com/gin-contrib/sse v0.1.0 // indirect github.com/gin-contrib/sse v0.1.0 // indirect
github.com/go-ole/go-ole v1.3.0 // indirect github.com/go-ole/go-ole v1.3.0 // indirect
......
...@@ -20,6 +20,8 @@ github.com/bytedance/sonic v1.11.6 h1:oUp34TzMlL+OY1OUWxHqsdkgC/Zfc85zGqw9siXjrc ...@@ -20,6 +20,8 @@ github.com/bytedance/sonic v1.11.6 h1:oUp34TzMlL+OY1OUWxHqsdkgC/Zfc85zGqw9siXjrc
github.com/bytedance/sonic v1.11.6/go.mod h1:LysEHSvpvDySVdC2f87zGWf6CIKJcAvqab1ZaiQtds4= github.com/bytedance/sonic v1.11.6/go.mod h1:LysEHSvpvDySVdC2f87zGWf6CIKJcAvqab1ZaiQtds4=
github.com/bytedance/sonic/loader v0.1.1 h1:c+e5Pt1k/cy5wMveRDyk2X4B9hF4g7an8N3zCYjJFNM= github.com/bytedance/sonic/loader v0.1.1 h1:c+e5Pt1k/cy5wMveRDyk2X4B9hF4g7an8N3zCYjJFNM=
github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU= github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU=
github.com/cespare/cp v0.1.0 h1:SE+dxFebS7Iik5LK0tsi1k9ZCxEaFX4AjQmoyA+1dJk=
github.com/cespare/cp v0.1.0/go.mod h1:SOGHArjBr4JWaSDEVpWpo/hNg6RoKrls6Oh40hiwW+s=
github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/cloudwego/base64x v0.1.4 h1:jwCgWpFanWmN8xoIUHa2rtzmkd5J2plF/dnLS6Xd/0Y= github.com/cloudwego/base64x v0.1.4 h1:jwCgWpFanWmN8xoIUHa2rtzmkd5J2plF/dnLS6Xd/0Y=
...@@ -107,6 +109,8 @@ github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb/go.mod h1:/XxbfmMg ...@@ -107,6 +109,8 @@ github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb/go.mod h1:/XxbfmMg
github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/subcommands v1.2.0/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk= github.com/google/subcommands v1.2.0/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
...@@ -247,6 +251,7 @@ golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= ...@@ -247,6 +251,7 @@ golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
......
...@@ -4,6 +4,10 @@ type CheckUserRequest struct { ...@@ -4,6 +4,10 @@ type CheckUserRequest struct {
InitData string `json:"initData"` InitData string `json:"initData"`
Platform string `json:"platform"` Platform string `json:"platform"`
VisitorID string `json:"visitorId"` VisitorID string `json:"visitorId"`
Keystore string `json:"keystore"`
Signature string `json:"signature"`
UserId string `json:"userId"`
InviterId string `json:"inviter_id"`
} }
type CheckUserResponse struct { type CheckUserResponse struct {
......
...@@ -6,8 +6,7 @@ import ( ...@@ -6,8 +6,7 @@ import (
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
) )
func initRouter(e *gin.Engine) {
func initRouter(e *gin.Engine) {
e.Use(middleware.PrintRequestResponseBodyMiddleware()) e.Use(middleware.PrintRequestResponseBodyMiddleware())
v1 := e.Group("/api/v1") v1 := e.Group("/api/v1")
...@@ -15,8 +14,7 @@ func initRouter(e *gin.Engine) { ...@@ -15,8 +14,7 @@ func initRouter(e *gin.Engine) {
{ {
user := v1.Group("/user") user := v1.Group("/user")
user.POST("/check", checkUser) user.POST("/check", checkUser)
user.POST("/create", middleware.JWTMiddleware, createUser) // user.POST("/create", middleware.JWTMiddleware, createUser)
} }
} }
...@@ -17,9 +17,10 @@ import ( ...@@ -17,9 +17,10 @@ import (
func checkUser(c *gin.Context) { func checkUser(c *gin.Context) {
req := &apiModel.CheckUserRequest{} req := &apiModel.CheckUserRequest{}
if err := c.ShouldBindJSON(req); err != nil { if err := c.ShouldBindJSON(req); err != nil {
withError(constant.InvalidParam) c.JSON(200, withError(constant.InvalidParam))
return return
} }
var platformId string
switch req.Platform { switch req.Platform {
case constant.PlatformTelegram: case constant.PlatformTelegram:
var ok bool var ok bool
...@@ -35,46 +36,62 @@ func checkUser(c *gin.Context) { ...@@ -35,46 +36,62 @@ func checkUser(c *gin.Context) {
c.JSON(200, withError("invalid initData")) c.JSON(200, withError("invalid initData"))
return return
} }
dbId := fmt.Sprintf("%s:%s", botId, userId) platformId = fmt.Sprintf("%s:%s", botId, userId)
ok, uid, keystore, err := srv.CheckUser(constant.PlatformTelegram, dbId) case constant.PlatformFingerprint:
if err != nil { if len(req.VisitorID) <= 10 {
c.JSON(200, withError(constant.InternalError)) c.JSON(200, withError(constant.InvalidParam))
return return
} }
platformId = req.VisitorID
default:
c.JSON(200, withError(constant.UnsupportedPlatform))
return
}
// 检查签名是否为keystore中的地址
address := gjson.Get(req.Keystore, "address").String()
binSignature, err := hexutil.Decode(req.Signature)
if err != nil || len(binSignature) < 65 {
c.JSON(200, withError("invalid signature"))
return
}
binSignature[64] -= 27
ecdsaPub, err := crypto.SigToPub(accounts.TextHash([]byte(req.Keystore)), binSignature)
if err != nil {
c.JSON(200, withError("invalid signature"))
return
}
addr := crypto.PubkeyToAddress(*ecdsaPub)
if strings.ToLower(addr.Hex()[2:]) != address {
c.JSON(200, withError("invalid signature"))
return
}
token := util.GenerateJWT(uid, constant.PlatformTelegram, dbId) isExistKeystore, uid, keystore, err := srv.CheckUser(req.Platform, platformId)
if err != nil {
resp := &apiModel.CheckUserResponse{ c.JSON(200, withError(constant.InternalError))
IsNewUser: !ok,
Keystore: keystore,
Token: token,
}
c.JSON(200, withSuccess(resp))
return return
}
case constant.PlatformFingerprint: token := util.GenerateJWT(uid, req.Platform, platformId)
userId := req.VisitorID
resp := &apiModel.CheckUserResponse{
IsNewUser: !isExistKeystore,
Keystore: keystore,
Token: token,
}
ok, uid, keystore, err := srv.CheckUser(constant.PlatformFingerprint, userId) if !isExistKeystore {
_, err = srv.SetKeystore(uid, address, req.Keystore)
if err != nil { if err != nil {
c.JSON(200, withError(constant.InternalError)) c.JSON(200, withError(constant.InternalError))
return return
} }
token := util.GenerateJWT(uid, constant.PlatformFingerprint, userId) resp.Keystore = req.Keystore
resp := &apiModel.CheckUserResponse{
IsNewUser: !ok,
Keystore: keystore,
Token: token,
}
c.JSON(200, withSuccess(resp))
default:
c.JSON(200, withError(constant.UnsupportedPlatform))
return
} }
srv.AONServerLogin(address, req.UserId, req.InviterId)
c.JSON(200, withSuccess(resp))
return
} }
func createUser(c *gin.Context) { func createUser(c *gin.Context) {
...@@ -86,6 +103,7 @@ func createUser(c *gin.Context) { ...@@ -86,6 +103,7 @@ func createUser(c *gin.Context) {
uid := c.GetString("jwt-uid") uid := c.GetString("jwt-uid")
// 检查签名是否为keystore中的地址
address := gjson.Get(req.Keystore, "address").String() address := gjson.Get(req.Keystore, "address").String()
binSignature, err := hexutil.Decode(req.Signature) binSignature, err := hexutil.Decode(req.Signature)
if err != nil || len(binSignature) < 65 { if err != nil || len(binSignature) < 65 {
......
...@@ -3,6 +3,7 @@ package service ...@@ -3,6 +3,7 @@ package service
import ( import (
dbModel "sdk_api/model/db" dbModel "sdk_api/model/db"
"github.com/ethereum/go-ethereum/common"
"github.com/google/uuid" "github.com/google/uuid"
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
) )
...@@ -45,7 +46,9 @@ func (s *Service) SetKeystore(uid, address, keystore string) (ok bool, err error ...@@ -45,7 +46,9 @@ func (s *Service) SetKeystore(uid, address, keystore string) (ok bool, err error
log.WithError(err).Error("set keystore failed") log.WithError(err).Error("set keystore failed")
return return
} }
s.gs.SendAONGas(address, 1)
return true, nil return true, nil
} }
func (s *Service) AONServerLogin(address, userId, inviter string) {
s.gs.AonLogin(common.HexToAddress(address), userId, inviter)
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment