scan.go 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. package blockchain
  2. import (
  3. "context"
  4. "encoding/hex"
  5. "fmt"
  6. "ktogame/contractgo/Collect"
  7. "ktogame/controller"
  8. "ktogame/dbUtil"
  9. "ktogame/models"
  10. "os"
  11. "strings"
  12. "time"
  13. "github.com/astaxie/beego"
  14. "github.com/astaxie/beego/logs"
  15. "github.com/ethereum/go-ethereum/accounts/abi"
  16. utilAddress "github.com/korthochain/korthochain/pkg/address"
  17. "github.com/korthochain/korthochain/pkg/block"
  18. pb "github.com/korthochain/korthochain/pkg/server/grpcserver/message"
  19. "github.com/korthochain/korthochain/pkg/transaction"
  20. "google.golang.org/grpc"
  21. )
  22. var ktoClient pb.GreeterClient
  23. var ktoRpc = beego.AppConfig.String("hostHttp_mit_kto")
  24. var currentBlock uint64
  25. var TopsMap map[string]string
  26. func init() {
  27. kc, err := grpc.Dial(ktoRpc, grpc.WithInsecure(), grpc.WithBlock())
  28. if err != nil {
  29. logs.Info(err)
  30. os.Exit(1)
  31. }
  32. ktoClient = pb.NewGreeterClient(kc)
  33. utilAddress.SetNetWork("mainnet")
  34. tm := make(map[string]string, 0)
  35. tm[TopicParticipate] = COLLECT_PARTICIPATE
  36. TopsMap = tm
  37. go scanBlock()
  38. go confirmClaimedTxs()
  39. }
  40. func scanBlock() {
  41. var bi models.BlockInfo
  42. ok, err := dbUtil.Engine.Id(1).Get(&bi)
  43. if err != nil {
  44. fmt.Println("获取最新快高错误=", err)
  45. return
  46. }
  47. if !ok {
  48. fmt.Println("获取最新快高失败!")
  49. return
  50. }
  51. currentBlock = uint64(bi.BlockNumber) + 1
  52. //currentBlock =62203394
  53. for {
  54. time.Sleep(time.Second * 3)
  55. res, err := ktoClient.GetMaxBlockHeight(context.Background(), &pb.ReqMaxBlockHeight{})
  56. if err != nil {
  57. fmt.Println("获取交易block number错误=", err)
  58. continue
  59. }
  60. if res.MaxHeight < currentBlock {
  61. currentBlock = res.MaxHeight
  62. }
  63. bl, err := ktoClient.GetBlockByNum(context.Background(), &pb.ReqBlockByNumber{Height: currentBlock})
  64. if err != nil || bl.Code != 0 {
  65. fmt.Println("获取交易block错误=", err)
  66. continue
  67. }
  68. blc, errs := block.Deserialize(bl.Data)
  69. if errs != nil {
  70. fmt.Println("解析blcock错误=", errs)
  71. continue
  72. }
  73. var ERR error
  74. for _, v := range blc.Transactions {
  75. evm, err := transaction.DecodeEvmData(v.Input)
  76. if err != nil {
  77. ERR = err
  78. break
  79. }
  80. if len(evm.Logs) == 0 {
  81. continue
  82. }
  83. for _, l := range evm.Logs {
  84. th := l.Topics[0].Hex()
  85. method := TopsMap[th]
  86. contract := l.Address.String()
  87. if contract == COLLECTCONTRACT {
  88. if method == COLLECT_PARTICIPATE {
  89. var ev EventParticipate
  90. abi, err := abi.JSON(strings.NewReader(Collect.CollectMetaData.ABI))
  91. if err != nil {
  92. ERR = err
  93. break
  94. }
  95. err = abi.UnpackIntoInterface(&ev, method, l.Data)
  96. if err != nil {
  97. ERR = err
  98. break
  99. }
  100. fmt.Printf("participate event data=%+v\n ", ev)
  101. //handle user participate
  102. err = participate(dbUtil.Engine, ev.User.String(), ev.Inviter.String(), v.HashToString(), float64(ev.Amount.Uint64()/controller.Decimals))
  103. if err != nil {
  104. ERR = err
  105. break
  106. }
  107. } else if method == COLLECT_CLAIMREWARDS {
  108. var evt EventClaim
  109. abi, err := abi.JSON(strings.NewReader(Collect.CollectMetaData.ABI))
  110. if err != nil {
  111. ERR = err
  112. break
  113. }
  114. err = abi.UnpackIntoInterface(&evt, method, l.Data)
  115. if err != nil {
  116. ERR = err
  117. break
  118. }
  119. fmt.Printf("claim event data=%+v\n ", evt)
  120. err = checkClaim(dbUtil.Engine, evt.User.String(), v.HashToString(), hex.EncodeToString(evt.Signature), float64(evt.Amount.Uint64()/controller.Decimals))
  121. if err != nil {
  122. ERR = err
  123. break
  124. }
  125. }
  126. }
  127. }
  128. if ERR != nil {
  129. break
  130. }
  131. }
  132. if ERR != nil {
  133. fmt.Println("处理错误=", ERR)
  134. continue
  135. }
  136. bi.BlockNumber = int64(currentBlock)
  137. _, err = dbUtil.Engine.ID(1).Update(&bi)
  138. if err != nil {
  139. fmt.Println("更新最新快高错误=", err)
  140. return
  141. }
  142. currentBlock++
  143. }
  144. }
  145. func confirmClaimedTxs() {
  146. var mark int64 = 0
  147. for {
  148. time.Sleep(time.Second * 5)
  149. var txs []models.ClaimedTxs
  150. ok, err := dbUtil.Engine.Where("state = ?", 0).Where("droped = ?", 0).Where("id > ?", mark).Get(&txs)
  151. if err != nil {
  152. continue
  153. }
  154. if !ok {
  155. continue
  156. }
  157. if len(txs) > 0 {
  158. mark = txs[len(txs)-1].Id
  159. }
  160. for _, t := range txs {
  161. go func(tx models.ClaimedTxs) {
  162. interval := 0
  163. for {
  164. time.Sleep(time.Second * 5)
  165. if interval > (CONFIRMINTERVAL / 5) {
  166. var ui models.UserInfo
  167. _, err := dbUtil.Engine.Id(tx.Hash).Get(&ui)
  168. if err != nil {
  169. mark = tx.Id - 1
  170. return
  171. }
  172. ui.AvailableClaim += tx.Amount
  173. ui.TotalClaimed -= tx.Amount
  174. _, err = dbUtil.Engine.ID(tx.Addr).Cols("total_claimed,available_claim").Update(&ui)
  175. if err != nil {
  176. mark = tx.Id - 1
  177. return
  178. }
  179. tx.Droped = 1
  180. _, err = dbUtil.Engine.ID(tx.Hash).Cols("droped").Update(&tx)
  181. if err != nil {
  182. mark = tx.Id - 1
  183. return
  184. }
  185. return
  186. }
  187. ptx, err := ktoClient.GetTxByHash(context.Background(), &pb.ReqTxByHash{Hash: tx.Hash})
  188. if err != nil {
  189. interval++
  190. continue
  191. }
  192. if ptx.Code != 0 {
  193. interval++
  194. continue
  195. }
  196. ftx, err := transaction.DeserializeFinishedTransaction(ptx.Data)
  197. if err != nil {
  198. interval++
  199. continue
  200. }
  201. //pending tx
  202. if ftx.BlockNum == 0 {
  203. interval++
  204. continue
  205. }
  206. tx.State = 1
  207. _, err = dbUtil.Engine.ID(tx.Hash).Cols("state").Update(&tx)
  208. if err != nil {
  209. mark = tx.Id - 1
  210. }
  211. return
  212. }
  213. }(t)
  214. }
  215. }
  216. }