package blockchain import ( "context" "encoding/hex" "fmt" "ktogame/contractgo/Collect" "ktogame/dbUtil" "ktogame/models" "os" "strings" "time" "github.com/astaxie/beego" "github.com/astaxie/beego/logs" "github.com/ethereum/go-ethereum/accounts/abi" utilAddress "github.com/korthochain/korthochain/pkg/address" "github.com/korthochain/korthochain/pkg/block" pb "github.com/korthochain/korthochain/pkg/server/grpcserver/message" "github.com/korthochain/korthochain/pkg/transaction" "google.golang.org/grpc" ) var ktoClient pb.GreeterClient var ktoRpc = beego.AppConfig.String("hostHttp_mit_kto") var currentBlock uint64 var TopsMap map[string]string func init() { kc, err := grpc.Dial(ktoRpc, grpc.WithInsecure(), grpc.WithBlock()) if err != nil { logs.Info(err) os.Exit(1) } ktoClient = pb.NewGreeterClient(kc) utilAddress.SetNetWork("mainnet") tm := make(map[string]string, 0) tm[TopicParticipate] = COLLECT_PARTICIPATE TopsMap = tm go scanBlock() go modifyClaimTxs() } func scanBlock() { var bi models.BlockInfo ok, err := dbUtil.Engine.Id(1).Get(&bi) if err != nil { fmt.Println("获取最新快高错误=", err) return } if !ok { fmt.Println("获取最新快高失败!") return } currentBlock = uint64(bi.BlockNumber) + 1 //currentBlock =62203394 for { time.Sleep(time.Second * 3) res, err := ktoClient.GetMaxBlockHeight(context.Background(), &pb.ReqMaxBlockHeight{}) if err != nil { fmt.Println("获取交易block number错误=", err) continue } if res.MaxHeight < currentBlock { currentBlock = res.MaxHeight } bl, err := ktoClient.GetBlockByNum(context.Background(), &pb.ReqBlockByNumber{Height: currentBlock}) if err != nil || bl.Code != 0 { fmt.Println("获取交易block错误=", err) continue } blc, errs := block.Deserialize(bl.Data) if errs != nil { fmt.Println("解析blcock错误=", errs) continue } var ERR error for _, v := range blc.Transactions { evm, err := transaction.DecodeEvmData(v.Input) if err != nil { ERR = err break } if len(evm.Logs) == 0 { continue } for _, l := range evm.Logs { th := l.Topics[0].Hex() method := TopsMap[th] contract := l.Address.String() if contract == COLLECTCONTRACT { if method == COLLECT_PARTICIPATE { var ev EventParticipate abi, err := abi.JSON(strings.NewReader(Collect.CollectMetaData.ABI)) if err != nil { ERR = err break } err = abi.UnpackIntoInterface(&ev, method, l.Data) if err != nil { ERR = err break } fmt.Printf("participate event data=%+v\n ", ev) //handle user participate err = participate(dbUtil.Engine, ev.User.String(), ev.Inviter.String(), v.HashToString(), float64(ev.Amount.Uint64())) if err != nil { ERR = err break } } else if method == COLLECT_CLAIMREWARDS { var evt EventClaim abi, err := abi.JSON(strings.NewReader(Collect.CollectMetaData.ABI)) if err != nil { ERR = err break } err = abi.UnpackIntoInterface(&evt, method, l.Data) if err != nil { ERR = err break } fmt.Printf("claim event data=%+v\n ", evt) err = checkClaim(dbUtil.Engine, evt.User.String(), v.HashToString(), hex.EncodeToString(evt.Signature), float64(evt.Amount.Uint64())) if err != nil { ERR = err break } } } } if ERR != nil { break } } if ERR != nil { fmt.Println("处理错误=", ERR) continue } bi.BlockNumber = int64(currentBlock) _, err = dbUtil.Engine.ID(1).Update(&bi) if err != nil { fmt.Println("更新最新快高错误=", err) return } currentBlock++ } } func modifyClaimTxs() { for { time.Sleep(time.Second) mark := 0 var tx models.ClaimedTxs ok, err := dbUtil.Engine.Where("state = ?", 0).Where("droped = ?", 0).Get(&tx) if err != nil { continue } if !ok { continue } for { time.Sleep(time.Second * 5) if mark > 200 { var ui models.UserInfo _, err := dbUtil.Engine.Id(tx.Hash).Get(&ui) if err != nil { break } ui.AvailableClaim += tx.Amount ui.TotalClaimed -= tx.Amount _, err = dbUtil.Engine.ID(tx.Addr).Cols("total_claimed,available_claim").Update(&ui) if err != nil { break } tx.Droped = 1 _, err = dbUtil.Engine.ID(tx.Hash).Cols("droped").Update(&tx) if err != nil { break } break } _, err = ktoClient.GetTxByHash(context.Background(), &pb.ReqTxByHash{Hash: tx.Hash}) if err != nil { mark++ continue } tx.State = 1 _, err = dbUtil.Engine.ID(tx.Hash).Cols("droped").Update(&tx) if err != nil { break } } } }