123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627 |
- package helpers
- import (
- "context"
- "crypto/ecdsa"
- "errors"
- "fmt"
- "log"
- "math/big"
- "strconv"
- "strings"
- "github.com/ethereum/go-ethereum/accounts/abi/bind"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/hexutil"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/crypto"
- "github.com/ethereum/go-ethereum/ethclient"
- "github.com/guregu/null"
- "github.com/metarare/metarare_api/contracts/collectionFactory"
- "github.com/metarare/metarare_api/contracts/metafinance"
- "github.com/metarare/metarare_api/contracts/metarare"
- "github.com/metarare/metarare_api/contracts/operator"
- "github.com/metarare/metarare_api/models"
- "gorm.io/gorm"
- )
- const _DECIMAL = 1000000000000000000
- var Addr_metaRare = ""
- var Addr_metaFinance = ""
- var Addr_CollectionFactory = ""
- var Addr_Operator = ""
- var Decimal = big.NewInt(1).Exp(big.NewInt(10), big.NewInt(18), nil)
- type ContractSet struct {
- Client *ethclient.Client
- MetaFinance *metafinance.Metafinance
- MetaRare *metarare.MetaRare
- CollectionFactory *collectionFactory.MetaRareCollectionFactory
- Operator *operator.MetaRareOperator
- ChainID *big.Int
- }
- type ClientSet struct {
- RpcClient *ethclient.Client
- WssClient *ethclient.Client
- }
- var contractSet ContractSet
- var clientSet ClientSet
- type NFTBasic struct {
- Name string
- Symbol string
- OwnerAddress string
- }
- type CollectionInfo struct {
- Tx *types.Transaction
- CollectionAddress string
- }
- type EIP721 struct {
- *NFTBasic
- *CollectionInfo
- BaseURI string
- }
- type EIP1155 struct {
- *NFTBasic
- *CollectionInfo
- CustomURI string
- }
- func TypeCastingToFloat64(target *big.Int) float64 {
- _f := new(big.Float).SetInt(target)
- f, _ := _f.Float64()
- _div := f / _DECIMAL
- split := strings.Split(fmt.Sprintf("%f", _div), ".")
- var _c string
- if len(split[1]) > 5 {
- _c = split[0] + "." + split[1][:5]
- } else {
- _c = split[0] + "." + split[1]
- }
- result, _ := strconv.ParseFloat(_c, 64)
- return result
- }
- func GetBalance(address string) (float64, float64, float64) {
- _contracts, clientSet := UseContract()
- _address := common.HexToAddress(address)
- mf1_balance, err := _contracts.MetaFinance.BalanceOf(nil, _address)
- if err != nil {
- fmt.Printf("balance(mf1) :%s", mf1_balance.String())
- }
- mr_balance, err := _contracts.MetaRare.BalanceOf(nil, _address)
- if err != nil {
- fmt.Printf("balance(mr) :%s", mr_balance.String())
- }
- eth_balance, _ := clientSet.RpcClient.BalanceAt(context.Background(), _address, nil)
- return TypeCastingToFloat64(mf1_balance), TypeCastingToFloat64(mr_balance), TypeCastingToFloat64(eth_balance)
- }
- func GetSelectedBalance(db *gorm.DB, userID uint64, kind string, address string) (float64, float64) {
- _contracts, clientSet := UseContract()
- _address := common.HexToAddress(address)
- if kind == "mf" {
- mf1_balance, err := _contracts.MetaFinance.BalanceOf(nil, _address)
- if err != nil {
- fmt.Printf("balance(mf1) :%s", mf1_balance.String())
- return 0, 0
- }
- return TypeCastingToFloat64(mf1_balance), GetAvailableBalance(db, userID, kind, TypeCastingToFloat64(mf1_balance))
- } else if kind == "mr" {
- mr_balance, err := _contracts.MetaRare.BalanceOf(nil, _address)
- if err != nil {
- fmt.Printf("balance(mr) :%s", mr_balance.String())
- return 0, 0
- }
- return TypeCastingToFloat64(mr_balance), GetAvailableBalance(db, userID, kind, TypeCastingToFloat64(mr_balance))
- } else {
- eth_balance, _ := clientSet.RpcClient.BalanceAt(context.Background(), _address, nil)
- return TypeCastingToFloat64(eth_balance), GetAvailableBalance(db, userID, kind, TypeCastingToFloat64(eth_balance))
- }
- }
- func GetAvailableBalance(db *gorm.DB, userID uint64, kind string, totalBalance float64) float64 {
- var _available float64
- deposit := []models.Deposit{}
- err := db.Where("user_id = ? AND status = 'deposit'", userID).Find(&deposit).Error
- if errors.Is(err, gorm.ErrRecordNotFound) {
- return 0
- }
- if kind == "mf" {
- for _, item := range deposit {
- if item.Mf1Price != null.FloatFrom(0) {
- _available += item.Mf1Price.Float64
- }
- }
- } else if kind == "mr" {
- for _, item := range deposit {
- if item.MrPrice != null.FloatFrom(0) {
- _available += item.MrPrice.Float64
- }
- }
- } else {
- for _, item := range deposit {
- if item.EthPrice != null.FloatFrom(0) {
- _available += item.EthPrice.Float64
- }
- }
- }
- return (totalBalance - _available)
- }
- func TransferETH(_fromPrivateKey string, _toAddress string, amount *big.Int) (error, *types.Transaction) {
- _, _clientSet := UseContract()
- privateKey, err := crypto.HexToECDSA(_fromPrivateKey)
- if err != nil {
- log.Fatal(err)
- }
- publicKey := privateKey.Public()
- publicKeyECDSA, ok := publicKey.(*ecdsa.PublicKey)
- if !ok {
- log.Fatal("error casting public key to ECDSA")
- }
- fromAddress := crypto.PubkeyToAddress(*publicKeyECDSA)
- nonce, err := _clientSet.RpcClient.PendingNonceAt(context.Background(), fromAddress)
- if err != nil {
- log.Fatal(err)
- }
- value := amount
- gasLimit := uint64(21000)
- gasPrice := obtainEstimatedGas(_clientSet.RpcClient, true)
- toAddress := common.HexToAddress(_toAddress)
- var data []byte
- tx := types.NewTransaction(nonce, toAddress, value, gasLimit, gasPrice, data)
- chainID, err := _clientSet.RpcClient.NetworkID(context.Background())
- if err != nil {
- log.Fatal(err)
- }
- signedTx, err := types.SignTx(tx, types.NewEIP155Signer(chainID), privateKey)
- if err != nil {
- log.Fatal(err)
- }
- err = _clientSet.RpcClient.SendTransaction(context.Background(), signedTx)
- if err != nil {
- log.Fatal(err)
- }
- return nil, signedTx
- }
- func TransferMetaRare(fromPrivateKey string, toAddress string, amount *big.Int) (error, *types.Transaction) {
- _contracts, _clientSet := UseContract()
- c := make(chan types.Log)
- go func() {
- err, log := WaitTxByLog(Addr_metaRare)
- if err != nil {
- fmt.Print(err)
- }
- c <- *log
- }()
- err, auth := makeAuth(_clientSet.RpcClient, fromPrivateKey, toAddress, nil)
- if err != nil {
- return err, nil
- }
- tx, err := _contracts.MetaRare.Transfer(auth, common.HexToAddress(toAddress), amount)
- if err != nil {
- log.Fatal(err)
- return err, nil
- }
- <-c
- return nil, tx
- }
- func TransferMetaFinance(fromPrivateKey string, toAddress string, amount *big.Int) (error, *types.Transaction) {
- _contracts, _clientSet := UseContract()
- c := make(chan types.Log)
- go func() {
- err, log := WaitTxByLog(Addr_metaFinance)
- if err != nil {
- fmt.Print(err)
- }
- c <- *log
- }()
- err, auth := makeAuth(_clientSet.RpcClient, fromPrivateKey, toAddress, nil)
- if err != nil {
- return err, nil
- }
- tx, err := _contracts.MetaFinance.Transfer(auth, common.HexToAddress(toAddress), amount)
- if err != nil {
- log.Fatal(err)
- return err, nil
- }
- <-c
- return nil, tx
- }
- func CreateCollection721(info EIP721, fromPrivateKey string) (error, EIP721) {
- _contracts, _clientSet := UseContract()
- _factory := _contracts.CollectionFactory
- c := make(chan types.Log)
- go func() {
- err, log := WaitTxByLog(Addr_CollectionFactory)
- if err != nil {
- fmt.Print(err)
- }
- c <- *log
- }()
- err, auth := makeAuth(_clientSet.RpcClient, fromPrivateKey, Addr_CollectionFactory, nil)
- if err != nil {
- return err, EIP721{}
- }
- _operator := common.HexToAddress(Addr_Operator)
- tx, err := _factory.CreateMetaRareERC721Collection(auth, info.Name, info.Symbol, info.BaseURI, _operator)
- if err != nil {
- return err, EIP721{}
- }
- vLog := <-c
- // fmt.Println(vLog)
- info.CollectionInfo = &CollectionInfo{CollectionAddress: hexutil.Encode(vLog.Data[12:32])}
- info.Tx = tx
- return nil, info
- }
- func CreateCollection1155(info EIP1155, fromPrivateKey string) (error, EIP1155) {
- _contracts, _clientSet := UseContract()
- _factory := _contracts.CollectionFactory
- c := make(chan types.Log)
- go func() {
- err, log := WaitTxByLog(Addr_CollectionFactory)
- if err != nil {
- fmt.Print(err)
- }
- c <- *log
- }()
- err, auth := makeAuth(_clientSet.RpcClient, fromPrivateKey, Addr_CollectionFactory, nil)
- if err != nil {
- return err, EIP1155{}
- }
- _operator := common.HexToAddress(Addr_Operator)
- tx, err := _factory.CreateMetaRareERC1155Collection(auth, info.Name, info.Symbol, info.CustomURI, _operator)
- if err != nil {
- return err, EIP1155{}
- }
- vLog := <-c
- info.CollectionInfo = &CollectionInfo{CollectionAddress: hexutil.Encode(vLog.Data[12:32])}
- info.Tx = tx
- // approve
- _collection, err := collectionFactory.NewMetaRareERC1155Collection(common.HexToAddress(info.CollectionAddress), _clientSet.RpcClient)
- if err != nil {
- return err, EIP1155{}
- }
- go func() {
- err, log := WaitTxByLog(info.CollectionAddress)
- if err != nil {
- fmt.Print(err)
- }
- c <- *log
- }()
- auth.Nonce = auth.Nonce.Add(auth.Nonce, big.NewInt(1))
- _, err = _collection.SetApprovalForAll(auth, common.HexToAddress(Addr_Operator), true)
- if err != nil {
- return err, EIP1155{}
- }
- <-c
- /// end of approve
- return nil, info
- }
- func RecoverAddress(hashedData [32]byte, signature [65]byte) (common.Address, error) {
- _contracts, _ := UseContract()
- var r32 [32]byte
- var s32 [32]byte
- copy(r32[:], signature[:32])
- copy(s32[:], signature[32:64])
- call := bind.CallOpts{}
- return _contracts.Operator.RecoverAddress(&call, hashedData, (signature[64] + 27), r32, s32)
- }
- type ContractType int
- const (
- MetaRare ContractType = iota
- MetaFinance
- )
- func GetAllowance(contractType ContractType, address string) (*big.Int, error) {
- _contractSet, _ := UseContract()
- options := bind.CallOpts{}
- if contractType == MetaRare {
- return _contractSet.MetaRare.Allowance(&options, common.HexToAddress(address), common.HexToAddress(Addr_Operator))
- } else if contractType == MetaFinance {
- return _contractSet.MetaFinance.Allowance(&options, common.HexToAddress(address), common.HexToAddress(Addr_Operator))
- }
- return nil, fmt.Errorf("Invalid contract Type")
- }
- func ApproveForERC20(contractType ContractType, fromPrivateKey string, amount *big.Int) (*types.Transaction, string, string, error) {
- var _tx *types.Transaction
- _contracts, _clientSet := UseContract()
- err, auth := makeAuth(_clientSet.RpcClient, fromPrivateKey, Addr_Operator, nil)
- if err != nil {
- return nil, "", "", err
- }
- if contractType == MetaRare {
- _tc, err := metarare.NewMetaRare(common.HexToAddress(Addr_metaRare), _clientSet.WssClient)
- if err != nil {
- return nil, "", "", err
- }
- done := make(chan *metarare.MetaRareApproval)
- spender := make([]common.Address, 0)
- address := make([]common.Address, 0)
- // Registor watch
- sub, err := _tc.WatchApproval(nil, done, spender, address)
- if err != nil {
- return nil, "", "", err
- }
- // send Transaction
- _tx, err = _contracts.MetaRare.Approve(auth, common.HexToAddress(Addr_Operator), amount)
- if err != nil {
- return nil, "", "", err
- }
- //detect watch
- for {
- select {
- case err := <-sub.Err():
- fmt.Println(err)
- return nil, "", "", err
- case t := <-done:
- // fmt.Printf("\tMetaRare Approve spender(%s) , vlaue (%s)\n ", t.Spender.Hash().String(), t.Value.String())
- return _tx, t.Spender.Hex(), t.Value.String(), nil
- }
- }
- } else if contractType == MetaFinance {
- _tc, err := metafinance.NewMetafinance(common.HexToAddress(Addr_metaFinance), _clientSet.WssClient)
- if err != nil {
- return nil, "", "", err
- }
- done := make(chan *metafinance.MetafinanceApproval)
- spender := make([]common.Address, 0)
- address := make([]common.Address, 0)
- // Registor watch
- sub, err := _tc.WatchApproval(nil, done, spender, address)
- if err != nil {
- return nil, "", "", err
- }
- // send Transaction
- _tx, err = _contracts.MetaFinance.Approve(auth, common.HexToAddress(Addr_Operator), amount)
- if err != nil {
- return nil, "", "", err
- }
- //detect watch
- for {
- select {
- case err := <-sub.Err():
- fmt.Println(err)
- return nil, "", "", err
- case t := <-done:
- // fmt.Printf("\tMetaFinance Approve spender(%s) , vlaue (%s)\n ", t.Spender.Hash().String(), t.Value.String())
- return _tx, t.Spender.Hex(), t.Value.String(), nil
- }
- }
- }
- return _tx, "", "", nil
- }
- func Order721WithMinting(_v operator.MetaRareOperatorNFTVoucher, hashedData [32]byte, fromPrivateKey string, signature [65]byte, isGenenalCollection bool) (*types.Transaction, *types.Log, error) {
- _contracts, _clientSet := UseContract()
- c := make(chan types.Log)
- go func() {
- err, log := WaitTxByLog(_v.TokenAddress.String())
- if err != nil {
- fmt.Print(err)
- }
- c <- *log
- }()
- _operator := _contracts.Operator
- err, auth := makeAuth(_clientSet.RpcClient, fromPrivateKey, Addr_Operator, nil)
- if err != nil {
- return nil, nil, err
- }
- var r32 [32]byte
- var s32 [32]byte
- copy(r32[:], signature[:32])
- copy(s32[:], signature[32:64])
- if _v.AssetAddress.Hex() == "0x0000000000000000000000000000000000000000" {
- auth.Value = _v.Price
- }
- var tx *types.Transaction
- if isGenenalCollection {
- tx, err = _operator.ExcuteMintingOrderWithERC721MetaRareCollection(auth, _v, hashedData, (signature[64] + 27), r32, s32)
- if err != nil {
- return nil, nil, err
- }
- } else {
- tx, err = _operator.ExcuteMintingOrderWithERC721Collection(auth, _v, hashedData, (signature[64] + 27), r32, s32)
- if err != nil {
- return nil, nil, err
- }
- }
- vLog := <-c
- return tx, &vLog, nil
- }
- func Order721OnlyTransfer(_v operator.MetaRareOperatorNFTVoucher, hashedData [32]byte, fromPrivateKey string, signature [65]byte) (*types.Transaction, *types.Log, error) {
- _contracts, _clientSet := UseContract()
- c := make(chan types.Log)
- _operator := _contracts.Operator
- err, auth := makeAuth(_clientSet.RpcClient, fromPrivateKey, Addr_Operator, nil)
- if err != nil {
- return nil, nil, err
- }
- go func() {
- err, log := WaitTxByLog(_v.TokenAddress.String())
- if err != nil {
- fmt.Print(err)
- }
- c <- *log
- }()
- var r32 [32]byte
- var s32 [32]byte
- copy(r32[:], signature[:32])
- copy(s32[:], signature[32:64])
- fmt.Println(_v.AssetAddress.Hex())
- if _v.AssetAddress.Hex() == "0x0000000000000000000000000000000000000000" {
- auth.Value = _v.Price
- }
- tx, err := _operator.ExcuteTransferOrderWithERC721Collection(auth, _v, hashedData, (signature[64] + 27), r32, s32)
- if err != nil {
- return nil, nil, err
- }
- vLog := <-c
- return tx, &vLog, nil
- }
- func Order1155WithMinting(_v operator.MetaRareOperatorNFTVoucher, hashedData [32]byte, fromPrivateKey string, signature [65]byte, isGenenalCollection bool) (*types.Transaction, *types.Log, error) {
- _contracts, _clientSet := UseContract()
- c := make(chan types.Log)
- go func() {
- err, log := WaitTxByLog(_v.TokenAddress.String())
- if err != nil {
- fmt.Print(err)
- }
- c <- *log
- }()
- _operator := _contracts.Operator
- err, auth := makeAuth(_clientSet.RpcClient, fromPrivateKey, Addr_Operator, nil)
- if err != nil {
- return nil, nil, err
- }
- var r32 [32]byte
- var s32 [32]byte
- copy(r32[:], signature[:32])
- copy(s32[:], signature[32:64])
- fmt.Println(_v.AssetAddress.Hex())
- if _v.AssetAddress.Hex() == "0x0000000000000000000000000000000000000000" {
- auth.Value = _v.Price
- }
- var tx *types.Transaction
- if isGenenalCollection {
- // approve
- // d := make(chan types.Log)
- // go func() {
- // err, log := WaitTxByLog(_v.TokenAddress.Hex())
- // if err != nil {
- // fmt.Print(err)
- // }
- // d <- *log
- // }()
- // _collection, err := collectionFactory.NewMetaRareERC1155Collection(_v.TokenAddress, _clientSet.RpcClient)
- // if err != nil {
- // return nil, nil, err
- // }
- // _, err = _collection.SetApprovalForAll(auth, common.HexToAddress(Addr_Operator), true)
- // if err != nil {
- // return nil, nil, err
- // }
- // <-d
- // Mint
- tx, err = _operator.ExcuteMintingOrderWithERC1155MetaRareCollection(auth, _v, hashedData, (signature[64] + 27), r32, s32)
- if err != nil {
- return nil, nil, err
- }
- } else {
- tx, err = _operator.ExcuteMintingOrderWithERC1155Collection(auth, _v, hashedData, (signature[64] + 27), r32, s32)
- if err != nil {
- return nil, nil, err
- }
- }
- vLog := <-c
- return tx, &vLog, nil
- // return tx, err
- }
- func Order1155OnlyTransfer(_v operator.MetaRareOperatorNFTVoucher, hashedData [32]byte, fromPrivateKey string, signature [65]byte) (*types.Transaction, *types.Log, error) {
- _contracts, _clientSet := UseContract()
- c := make(chan types.Log)
- _operator := _contracts.Operator
- err, auth := makeAuth(_clientSet.RpcClient, fromPrivateKey, Addr_Operator, nil)
- if err != nil {
- return nil, nil, err
- }
- go func() {
- err, log := WaitTxByLog(_v.TokenAddress.String())
- if err != nil {
- fmt.Print(err)
- }
- c <- *log
- }()
- var r32 [32]byte
- var s32 [32]byte
- copy(r32[:], signature[:32])
- copy(s32[:], signature[32:64])
- if _v.AssetAddress.Hex() == "0x0000000000000000000000000000000000000000" {
- auth.Value = _v.Price
- }
- tx, err := _operator.ExcuteTransferOrderWithERC1155Collection(auth, _v, hashedData, (signature[64] + 27), r32, s32)
- if err != nil {
- return nil, nil, err
- }
- vLog := <-c
- return tx, &vLog, nil
- }
|