eth.go 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627
  1. package helpers
  2. import (
  3. "context"
  4. "crypto/ecdsa"
  5. "errors"
  6. "fmt"
  7. "log"
  8. "math/big"
  9. "strconv"
  10. "strings"
  11. "github.com/ethereum/go-ethereum/accounts/abi/bind"
  12. "github.com/ethereum/go-ethereum/common"
  13. "github.com/ethereum/go-ethereum/common/hexutil"
  14. "github.com/ethereum/go-ethereum/core/types"
  15. "github.com/ethereum/go-ethereum/crypto"
  16. "github.com/ethereum/go-ethereum/ethclient"
  17. "github.com/guregu/null"
  18. "github.com/metarare/metarare_api/contracts/collectionFactory"
  19. "github.com/metarare/metarare_api/contracts/metafinance"
  20. "github.com/metarare/metarare_api/contracts/metarare"
  21. "github.com/metarare/metarare_api/contracts/operator"
  22. "github.com/metarare/metarare_api/models"
  23. "gorm.io/gorm"
  24. )
  25. const _DECIMAL = 1000000000000000000
  26. var Addr_metaRare = ""
  27. var Addr_metaFinance = ""
  28. var Addr_CollectionFactory = ""
  29. var Addr_Operator = ""
  30. var Decimal = big.NewInt(1).Exp(big.NewInt(10), big.NewInt(18), nil)
  31. type ContractSet struct {
  32. Client *ethclient.Client
  33. MetaFinance *metafinance.Metafinance
  34. MetaRare *metarare.MetaRare
  35. CollectionFactory *collectionFactory.MetaRareCollectionFactory
  36. Operator *operator.MetaRareOperator
  37. ChainID *big.Int
  38. }
  39. type ClientSet struct {
  40. RpcClient *ethclient.Client
  41. WssClient *ethclient.Client
  42. }
  43. var contractSet ContractSet
  44. var clientSet ClientSet
  45. type NFTBasic struct {
  46. Name string
  47. Symbol string
  48. OwnerAddress string
  49. }
  50. type CollectionInfo struct {
  51. Tx *types.Transaction
  52. CollectionAddress string
  53. }
  54. type EIP721 struct {
  55. *NFTBasic
  56. *CollectionInfo
  57. BaseURI string
  58. }
  59. type EIP1155 struct {
  60. *NFTBasic
  61. *CollectionInfo
  62. CustomURI string
  63. }
  64. func TypeCastingToFloat64(target *big.Int) float64 {
  65. _f := new(big.Float).SetInt(target)
  66. f, _ := _f.Float64()
  67. _div := f / _DECIMAL
  68. split := strings.Split(fmt.Sprintf("%f", _div), ".")
  69. var _c string
  70. if len(split[1]) > 5 {
  71. _c = split[0] + "." + split[1][:5]
  72. } else {
  73. _c = split[0] + "." + split[1]
  74. }
  75. result, _ := strconv.ParseFloat(_c, 64)
  76. return result
  77. }
  78. func GetBalance(address string) (float64, float64, float64) {
  79. _contracts, clientSet := UseContract()
  80. _address := common.HexToAddress(address)
  81. mf1_balance, err := _contracts.MetaFinance.BalanceOf(nil, _address)
  82. if err != nil {
  83. fmt.Printf("balance(mf1) :%s", mf1_balance.String())
  84. }
  85. mr_balance, err := _contracts.MetaRare.BalanceOf(nil, _address)
  86. if err != nil {
  87. fmt.Printf("balance(mr) :%s", mr_balance.String())
  88. }
  89. eth_balance, _ := clientSet.RpcClient.BalanceAt(context.Background(), _address, nil)
  90. return TypeCastingToFloat64(mf1_balance), TypeCastingToFloat64(mr_balance), TypeCastingToFloat64(eth_balance)
  91. }
  92. func GetSelectedBalance(db *gorm.DB, userID uint64, kind string, address string) (float64, float64) {
  93. _contracts, clientSet := UseContract()
  94. _address := common.HexToAddress(address)
  95. if kind == "mf" {
  96. mf1_balance, err := _contracts.MetaFinance.BalanceOf(nil, _address)
  97. if err != nil {
  98. fmt.Printf("balance(mf1) :%s", mf1_balance.String())
  99. return 0, 0
  100. }
  101. return TypeCastingToFloat64(mf1_balance), GetAvailableBalance(db, userID, kind, TypeCastingToFloat64(mf1_balance))
  102. } else if kind == "mr" {
  103. mr_balance, err := _contracts.MetaRare.BalanceOf(nil, _address)
  104. if err != nil {
  105. fmt.Printf("balance(mr) :%s", mr_balance.String())
  106. return 0, 0
  107. }
  108. return TypeCastingToFloat64(mr_balance), GetAvailableBalance(db, userID, kind, TypeCastingToFloat64(mr_balance))
  109. } else {
  110. eth_balance, _ := clientSet.RpcClient.BalanceAt(context.Background(), _address, nil)
  111. return TypeCastingToFloat64(eth_balance), GetAvailableBalance(db, userID, kind, TypeCastingToFloat64(eth_balance))
  112. }
  113. }
  114. func GetAvailableBalance(db *gorm.DB, userID uint64, kind string, totalBalance float64) float64 {
  115. var _available float64
  116. deposit := []models.Deposit{}
  117. err := db.Where("user_id = ? AND status = 'deposit'", userID).Find(&deposit).Error
  118. if errors.Is(err, gorm.ErrRecordNotFound) {
  119. return 0
  120. }
  121. if kind == "mf" {
  122. for _, item := range deposit {
  123. if item.Mf1Price != null.FloatFrom(0) {
  124. _available += item.Mf1Price.Float64
  125. }
  126. }
  127. } else if kind == "mr" {
  128. for _, item := range deposit {
  129. if item.MrPrice != null.FloatFrom(0) {
  130. _available += item.MrPrice.Float64
  131. }
  132. }
  133. } else {
  134. for _, item := range deposit {
  135. if item.EthPrice != null.FloatFrom(0) {
  136. _available += item.EthPrice.Float64
  137. }
  138. }
  139. }
  140. return (totalBalance - _available)
  141. }
  142. func TransferETH(_fromPrivateKey string, _toAddress string, amount *big.Int) (error, *types.Transaction) {
  143. _, _clientSet := UseContract()
  144. privateKey, err := crypto.HexToECDSA(_fromPrivateKey)
  145. if err != nil {
  146. log.Fatal(err)
  147. }
  148. publicKey := privateKey.Public()
  149. publicKeyECDSA, ok := publicKey.(*ecdsa.PublicKey)
  150. if !ok {
  151. log.Fatal("error casting public key to ECDSA")
  152. }
  153. fromAddress := crypto.PubkeyToAddress(*publicKeyECDSA)
  154. nonce, err := _clientSet.RpcClient.PendingNonceAt(context.Background(), fromAddress)
  155. if err != nil {
  156. log.Fatal(err)
  157. }
  158. value := amount
  159. gasLimit := uint64(21000)
  160. gasPrice := obtainEstimatedGas(_clientSet.RpcClient, true)
  161. toAddress := common.HexToAddress(_toAddress)
  162. var data []byte
  163. tx := types.NewTransaction(nonce, toAddress, value, gasLimit, gasPrice, data)
  164. chainID, err := _clientSet.RpcClient.NetworkID(context.Background())
  165. if err != nil {
  166. log.Fatal(err)
  167. }
  168. signedTx, err := types.SignTx(tx, types.NewEIP155Signer(chainID), privateKey)
  169. if err != nil {
  170. log.Fatal(err)
  171. }
  172. err = _clientSet.RpcClient.SendTransaction(context.Background(), signedTx)
  173. if err != nil {
  174. log.Fatal(err)
  175. }
  176. return nil, signedTx
  177. }
  178. func TransferMetaRare(fromPrivateKey string, toAddress string, amount *big.Int) (error, *types.Transaction) {
  179. _contracts, _clientSet := UseContract()
  180. c := make(chan types.Log)
  181. go func() {
  182. err, log := WaitTxByLog(Addr_metaRare)
  183. if err != nil {
  184. fmt.Print(err)
  185. }
  186. c <- *log
  187. }()
  188. err, auth := makeAuth(_clientSet.RpcClient, fromPrivateKey, toAddress, nil)
  189. if err != nil {
  190. return err, nil
  191. }
  192. tx, err := _contracts.MetaRare.Transfer(auth, common.HexToAddress(toAddress), amount)
  193. if err != nil {
  194. log.Fatal(err)
  195. return err, nil
  196. }
  197. <-c
  198. return nil, tx
  199. }
  200. func TransferMetaFinance(fromPrivateKey string, toAddress string, amount *big.Int) (error, *types.Transaction) {
  201. _contracts, _clientSet := UseContract()
  202. c := make(chan types.Log)
  203. go func() {
  204. err, log := WaitTxByLog(Addr_metaFinance)
  205. if err != nil {
  206. fmt.Print(err)
  207. }
  208. c <- *log
  209. }()
  210. err, auth := makeAuth(_clientSet.RpcClient, fromPrivateKey, toAddress, nil)
  211. if err != nil {
  212. return err, nil
  213. }
  214. tx, err := _contracts.MetaFinance.Transfer(auth, common.HexToAddress(toAddress), amount)
  215. if err != nil {
  216. log.Fatal(err)
  217. return err, nil
  218. }
  219. <-c
  220. return nil, tx
  221. }
  222. func CreateCollection721(info EIP721, fromPrivateKey string) (error, EIP721) {
  223. _contracts, _clientSet := UseContract()
  224. _factory := _contracts.CollectionFactory
  225. c := make(chan types.Log)
  226. go func() {
  227. err, log := WaitTxByLog(Addr_CollectionFactory)
  228. if err != nil {
  229. fmt.Print(err)
  230. }
  231. c <- *log
  232. }()
  233. err, auth := makeAuth(_clientSet.RpcClient, fromPrivateKey, Addr_CollectionFactory, nil)
  234. if err != nil {
  235. return err, EIP721{}
  236. }
  237. _operator := common.HexToAddress(Addr_Operator)
  238. tx, err := _factory.CreateMetaRareERC721Collection(auth, info.Name, info.Symbol, info.BaseURI, _operator)
  239. if err != nil {
  240. return err, EIP721{}
  241. }
  242. vLog := <-c
  243. // fmt.Println(vLog)
  244. info.CollectionInfo = &CollectionInfo{CollectionAddress: hexutil.Encode(vLog.Data[12:32])}
  245. info.Tx = tx
  246. return nil, info
  247. }
  248. func CreateCollection1155(info EIP1155, fromPrivateKey string) (error, EIP1155) {
  249. _contracts, _clientSet := UseContract()
  250. _factory := _contracts.CollectionFactory
  251. c := make(chan types.Log)
  252. go func() {
  253. err, log := WaitTxByLog(Addr_CollectionFactory)
  254. if err != nil {
  255. fmt.Print(err)
  256. }
  257. c <- *log
  258. }()
  259. err, auth := makeAuth(_clientSet.RpcClient, fromPrivateKey, Addr_CollectionFactory, nil)
  260. if err != nil {
  261. return err, EIP1155{}
  262. }
  263. _operator := common.HexToAddress(Addr_Operator)
  264. tx, err := _factory.CreateMetaRareERC1155Collection(auth, info.Name, info.Symbol, info.CustomURI, _operator)
  265. if err != nil {
  266. return err, EIP1155{}
  267. }
  268. vLog := <-c
  269. info.CollectionInfo = &CollectionInfo{CollectionAddress: hexutil.Encode(vLog.Data[12:32])}
  270. info.Tx = tx
  271. // approve
  272. _collection, err := collectionFactory.NewMetaRareERC1155Collection(common.HexToAddress(info.CollectionAddress), _clientSet.RpcClient)
  273. if err != nil {
  274. return err, EIP1155{}
  275. }
  276. go func() {
  277. err, log := WaitTxByLog(info.CollectionAddress)
  278. if err != nil {
  279. fmt.Print(err)
  280. }
  281. c <- *log
  282. }()
  283. auth.Nonce = auth.Nonce.Add(auth.Nonce, big.NewInt(1))
  284. _, err = _collection.SetApprovalForAll(auth, common.HexToAddress(Addr_Operator), true)
  285. if err != nil {
  286. return err, EIP1155{}
  287. }
  288. <-c
  289. /// end of approve
  290. return nil, info
  291. }
  292. func RecoverAddress(hashedData [32]byte, signature [65]byte) (common.Address, error) {
  293. _contracts, _ := UseContract()
  294. var r32 [32]byte
  295. var s32 [32]byte
  296. copy(r32[:], signature[:32])
  297. copy(s32[:], signature[32:64])
  298. call := bind.CallOpts{}
  299. return _contracts.Operator.RecoverAddress(&call, hashedData, (signature[64] + 27), r32, s32)
  300. }
  301. type ContractType int
  302. const (
  303. MetaRare ContractType = iota
  304. MetaFinance
  305. )
  306. func GetAllowance(contractType ContractType, address string) (*big.Int, error) {
  307. _contractSet, _ := UseContract()
  308. options := bind.CallOpts{}
  309. if contractType == MetaRare {
  310. return _contractSet.MetaRare.Allowance(&options, common.HexToAddress(address), common.HexToAddress(Addr_Operator))
  311. } else if contractType == MetaFinance {
  312. return _contractSet.MetaFinance.Allowance(&options, common.HexToAddress(address), common.HexToAddress(Addr_Operator))
  313. }
  314. return nil, fmt.Errorf("Invalid contract Type")
  315. }
  316. func ApproveForERC20(contractType ContractType, fromPrivateKey string, amount *big.Int) (*types.Transaction, string, string, error) {
  317. var _tx *types.Transaction
  318. _contracts, _clientSet := UseContract()
  319. err, auth := makeAuth(_clientSet.RpcClient, fromPrivateKey, Addr_Operator, nil)
  320. if err != nil {
  321. return nil, "", "", err
  322. }
  323. if contractType == MetaRare {
  324. _tc, err := metarare.NewMetaRare(common.HexToAddress(Addr_metaRare), _clientSet.WssClient)
  325. if err != nil {
  326. return nil, "", "", err
  327. }
  328. done := make(chan *metarare.MetaRareApproval)
  329. spender := make([]common.Address, 0)
  330. address := make([]common.Address, 0)
  331. // Registor watch
  332. sub, err := _tc.WatchApproval(nil, done, spender, address)
  333. if err != nil {
  334. return nil, "", "", err
  335. }
  336. // send Transaction
  337. _tx, err = _contracts.MetaRare.Approve(auth, common.HexToAddress(Addr_Operator), amount)
  338. if err != nil {
  339. return nil, "", "", err
  340. }
  341. //detect watch
  342. for {
  343. select {
  344. case err := <-sub.Err():
  345. fmt.Println(err)
  346. return nil, "", "", err
  347. case t := <-done:
  348. // fmt.Printf("\tMetaRare Approve spender(%s) , vlaue (%s)\n ", t.Spender.Hash().String(), t.Value.String())
  349. return _tx, t.Spender.Hex(), t.Value.String(), nil
  350. }
  351. }
  352. } else if contractType == MetaFinance {
  353. _tc, err := metafinance.NewMetafinance(common.HexToAddress(Addr_metaFinance), _clientSet.WssClient)
  354. if err != nil {
  355. return nil, "", "", err
  356. }
  357. done := make(chan *metafinance.MetafinanceApproval)
  358. spender := make([]common.Address, 0)
  359. address := make([]common.Address, 0)
  360. // Registor watch
  361. sub, err := _tc.WatchApproval(nil, done, spender, address)
  362. if err != nil {
  363. return nil, "", "", err
  364. }
  365. // send Transaction
  366. _tx, err = _contracts.MetaFinance.Approve(auth, common.HexToAddress(Addr_Operator), amount)
  367. if err != nil {
  368. return nil, "", "", err
  369. }
  370. //detect watch
  371. for {
  372. select {
  373. case err := <-sub.Err():
  374. fmt.Println(err)
  375. return nil, "", "", err
  376. case t := <-done:
  377. // fmt.Printf("\tMetaFinance Approve spender(%s) , vlaue (%s)\n ", t.Spender.Hash().String(), t.Value.String())
  378. return _tx, t.Spender.Hex(), t.Value.String(), nil
  379. }
  380. }
  381. }
  382. return _tx, "", "", nil
  383. }
  384. func Order721WithMinting(_v operator.MetaRareOperatorNFTVoucher, hashedData [32]byte, fromPrivateKey string, signature [65]byte, isGenenalCollection bool) (*types.Transaction, *types.Log, error) {
  385. _contracts, _clientSet := UseContract()
  386. c := make(chan types.Log)
  387. go func() {
  388. err, log := WaitTxByLog(_v.TokenAddress.String())
  389. if err != nil {
  390. fmt.Print(err)
  391. }
  392. c <- *log
  393. }()
  394. _operator := _contracts.Operator
  395. err, auth := makeAuth(_clientSet.RpcClient, fromPrivateKey, Addr_Operator, nil)
  396. if err != nil {
  397. return nil, nil, err
  398. }
  399. var r32 [32]byte
  400. var s32 [32]byte
  401. copy(r32[:], signature[:32])
  402. copy(s32[:], signature[32:64])
  403. if _v.AssetAddress.Hex() == "0x0000000000000000000000000000000000000000" {
  404. auth.Value = _v.Price
  405. }
  406. var tx *types.Transaction
  407. if isGenenalCollection {
  408. tx, err = _operator.ExcuteMintingOrderWithERC721MetaRareCollection(auth, _v, hashedData, (signature[64] + 27), r32, s32)
  409. if err != nil {
  410. return nil, nil, err
  411. }
  412. } else {
  413. tx, err = _operator.ExcuteMintingOrderWithERC721Collection(auth, _v, hashedData, (signature[64] + 27), r32, s32)
  414. if err != nil {
  415. return nil, nil, err
  416. }
  417. }
  418. vLog := <-c
  419. return tx, &vLog, nil
  420. }
  421. func Order721OnlyTransfer(_v operator.MetaRareOperatorNFTVoucher, hashedData [32]byte, fromPrivateKey string, signature [65]byte) (*types.Transaction, *types.Log, error) {
  422. _contracts, _clientSet := UseContract()
  423. c := make(chan types.Log)
  424. _operator := _contracts.Operator
  425. err, auth := makeAuth(_clientSet.RpcClient, fromPrivateKey, Addr_Operator, nil)
  426. if err != nil {
  427. return nil, nil, err
  428. }
  429. go func() {
  430. err, log := WaitTxByLog(_v.TokenAddress.String())
  431. if err != nil {
  432. fmt.Print(err)
  433. }
  434. c <- *log
  435. }()
  436. var r32 [32]byte
  437. var s32 [32]byte
  438. copy(r32[:], signature[:32])
  439. copy(s32[:], signature[32:64])
  440. fmt.Println(_v.AssetAddress.Hex())
  441. if _v.AssetAddress.Hex() == "0x0000000000000000000000000000000000000000" {
  442. auth.Value = _v.Price
  443. }
  444. tx, err := _operator.ExcuteTransferOrderWithERC721Collection(auth, _v, hashedData, (signature[64] + 27), r32, s32)
  445. if err != nil {
  446. return nil, nil, err
  447. }
  448. vLog := <-c
  449. return tx, &vLog, nil
  450. }
  451. func Order1155WithMinting(_v operator.MetaRareOperatorNFTVoucher, hashedData [32]byte, fromPrivateKey string, signature [65]byte, isGenenalCollection bool) (*types.Transaction, *types.Log, error) {
  452. _contracts, _clientSet := UseContract()
  453. c := make(chan types.Log)
  454. go func() {
  455. err, log := WaitTxByLog(_v.TokenAddress.String())
  456. if err != nil {
  457. fmt.Print(err)
  458. }
  459. c <- *log
  460. }()
  461. _operator := _contracts.Operator
  462. err, auth := makeAuth(_clientSet.RpcClient, fromPrivateKey, Addr_Operator, nil)
  463. if err != nil {
  464. return nil, nil, err
  465. }
  466. var r32 [32]byte
  467. var s32 [32]byte
  468. copy(r32[:], signature[:32])
  469. copy(s32[:], signature[32:64])
  470. fmt.Println(_v.AssetAddress.Hex())
  471. if _v.AssetAddress.Hex() == "0x0000000000000000000000000000000000000000" {
  472. auth.Value = _v.Price
  473. }
  474. var tx *types.Transaction
  475. if isGenenalCollection {
  476. // approve
  477. // d := make(chan types.Log)
  478. // go func() {
  479. // err, log := WaitTxByLog(_v.TokenAddress.Hex())
  480. // if err != nil {
  481. // fmt.Print(err)
  482. // }
  483. // d <- *log
  484. // }()
  485. // _collection, err := collectionFactory.NewMetaRareERC1155Collection(_v.TokenAddress, _clientSet.RpcClient)
  486. // if err != nil {
  487. // return nil, nil, err
  488. // }
  489. // _, err = _collection.SetApprovalForAll(auth, common.HexToAddress(Addr_Operator), true)
  490. // if err != nil {
  491. // return nil, nil, err
  492. // }
  493. // <-d
  494. // Mint
  495. tx, err = _operator.ExcuteMintingOrderWithERC1155MetaRareCollection(auth, _v, hashedData, (signature[64] + 27), r32, s32)
  496. if err != nil {
  497. return nil, nil, err
  498. }
  499. } else {
  500. tx, err = _operator.ExcuteMintingOrderWithERC1155Collection(auth, _v, hashedData, (signature[64] + 27), r32, s32)
  501. if err != nil {
  502. return nil, nil, err
  503. }
  504. }
  505. vLog := <-c
  506. return tx, &vLog, nil
  507. // return tx, err
  508. }
  509. func Order1155OnlyTransfer(_v operator.MetaRareOperatorNFTVoucher, hashedData [32]byte, fromPrivateKey string, signature [65]byte) (*types.Transaction, *types.Log, error) {
  510. _contracts, _clientSet := UseContract()
  511. c := make(chan types.Log)
  512. _operator := _contracts.Operator
  513. err, auth := makeAuth(_clientSet.RpcClient, fromPrivateKey, Addr_Operator, nil)
  514. if err != nil {
  515. return nil, nil, err
  516. }
  517. go func() {
  518. err, log := WaitTxByLog(_v.TokenAddress.String())
  519. if err != nil {
  520. fmt.Print(err)
  521. }
  522. c <- *log
  523. }()
  524. var r32 [32]byte
  525. var s32 [32]byte
  526. copy(r32[:], signature[:32])
  527. copy(s32[:], signature[32:64])
  528. if _v.AssetAddress.Hex() == "0x0000000000000000000000000000000000000000" {
  529. auth.Value = _v.Price
  530. }
  531. tx, err := _operator.ExcuteTransferOrderWithERC1155Collection(auth, _v, hashedData, (signature[64] + 27), r32, s32)
  532. if err != nil {
  533. return nil, nil, err
  534. }
  535. vLog := <-c
  536. return tx, &vLog, nil
  537. }