scan.go 5.7 KB

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