123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286 |
- package helpers
- import (
- "context"
- "crypto/ecdsa"
- "encoding/json"
- "fmt"
- "log"
- "math/big"
- "strings"
- "github.com/ethereum/go-ethereum"
- "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/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"
- )
- func initEthClient() (*ethclient.Client, *ethclient.Client) {
- v := LoadEnvs()
- endPoint := v.GetString("rpc.endpoint")
- if strings.Compare(endPoint, "") == 0 {
- panic("env rpc endpoint doesn't exsit")
- }
- wss_endPoint := v.GetString("rpc.wss_endpoint")
- if strings.Compare(wss_endPoint, "") == 0 {
- panic("env rpc endpoint doesn't exsit")
- }
- client, err := ethclient.Dial(endPoint)
- if err != nil {
- log.Fatal(err)
- }
- wss_client, err := ethclient.Dial(wss_endPoint)
- if err != nil {
- log.Fatal(err)
- }
- Addr_metaFinance = v.GetString("rpc.metafinance")
- Addr_metaRare = v.GetString("rpc.metarare")
- Addr_CollectionFactory = v.GetString("rpc.collectionFactory")
- Addr_Operator = v.GetString("rpc.operator")
- return client, wss_client
- }
- func getClient() (*ethclient.Client, *ethclient.Client) {
- if clientSet.RpcClient != nil && clientSet.WssClient != nil {
- return clientSet.RpcClient, clientSet.WssClient
- } else {
- return initEthClient()
- }
- }
- func loadSigningKey(pkey string) (*ecdsa.PrivateKey, *ecdsa.PublicKey, common.Address) {
- // load the signing key
- privateKey, err := crypto.HexToECDSA(pkey)
- if err != nil {
- log.Fatal(err)
- }
- publicKey := privateKey.Public()
- publicKeyECDSA, ok := publicKey.(*ecdsa.PublicKey)
- if !ok {
- log.Fatal("cannot assert type: publicKey is not of type *ecdsa.PublicKey")
- }
- fromAddress := crypto.PubkeyToAddress(*publicKeyECDSA)
- return privateKey, publicKey.(*ecdsa.PublicKey), fromAddress
- }
- func obtainNonce(_client *ethclient.Client, _address common.Address) *big.Int {
- nonce, err := _client.PendingNonceAt(context.Background(), _address)
- if err != nil {
- log.Fatal(err)
- }
- return new(big.Int).SetUint64(nonce)
- }
- func obtainEstimatedGas(_client *ethclient.Client, _overFitting bool) *big.Int {
- gasPrice, err := _client.SuggestGasPrice(context.Background())
- if err != nil {
- log.Fatal(err)
- }
- // fmt.Println("gasPrice:", gasPrice)
- if _overFitting {
- return gasPrice.Mul(gasPrice, big.NewInt(15)).Div(gasPrice, big.NewInt(10))
- }
- return gasPrice
- }
- func UseContract() (ContractSet, ClientSet) {
- clientSet.RpcClient, clientSet.WssClient = getClient()
- //have to make smart contract instances
- //metarare
- address := common.HexToAddress(Addr_metaRare)
- _metaRare, err := metarare.NewMetaRare(address, clientSet.RpcClient)
- if err != nil {
- log.Fatal("Cannot make Metarare instance ", err)
- }
- //metafinance
- address = common.HexToAddress(Addr_metaFinance)
- _metaFinance, err := metafinance.NewMetafinance(address, clientSet.RpcClient)
- if err != nil {
- log.Fatal("Cannot make MetaFinance instance", err)
- }
- // some contracts
- address = common.HexToAddress(Addr_CollectionFactory)
- _factory, err := collectionFactory.NewMetaRareCollectionFactory(address, clientSet.RpcClient)
- if err != nil {
- log.Fatal("Cannot make MetaFinance instance", err)
- }
- address = common.HexToAddress(Addr_Operator)
- _operator, err := operator.NewMetaRareOperator(address, clientSet.RpcClient)
- if err != nil {
- log.Fatal("Cannot make MetaFinance instance", err)
- }
- contractSet.MetaFinance = _metaFinance
- contractSet.MetaRare = _metaRare
- contractSet.CollectionFactory = _factory
- contractSet.Operator = _operator
- contractSet.ChainID, err = clientSet.WssClient.ChainID(context.Background())
- return contractSet, clientSet
- }
- func makeAuth(_client *ethclient.Client, fromPrivateKey string, toAddress string, ethAmount *big.Int) (error, *bind.TransactOpts) {
- privateKey, err := crypto.HexToECDSA(fromPrivateKey)
- if err != nil {
- return err, nil
- }
- publicKey := privateKey.Public()
- publicKeyECDSA, ok := publicKey.(*ecdsa.PublicKey)
- if !ok {
- log.Fatal("cannot assert type: publicKey is not of type *ecdsa.PublicKey")
- }
- fromAddress := crypto.PubkeyToAddress(*publicKeyECDSA)
- auth := bind.NewKeyedTransactor(privateKey)
- auth.Nonce = obtainNonce(_client, fromAddress)
- if ethAmount != nil {
- auth.Value = ethAmount
- } else {
- auth.Value = big.NewInt(0)
- }
- // fmt.Println("value :", auth.Value)
- // auth.GasLimit = uint64(30000000)
- auth.GasPrice = obtainEstimatedGas(_client, true)
- // fmt.Println("gasPrice:", auth.GasPrice.String())
- return nil, auth
- }
- func GenerateWallet() (string, string) {
- privateKey, err := crypto.GenerateKey()
- if err != nil {
- log.Fatal(err)
- }
- privateKeyBytes := crypto.FromECDSA(privateKey)
- _privateKey := hexutil.Encode(privateKeyBytes)[2:]
- publicKey := privateKey.Public()
- publicKeyECDSA, ok := publicKey.(*ecdsa.PublicKey)
- if !ok {
- log.Fatal("error casting public key to ECDSA")
- }
- _address := crypto.PubkeyToAddress(*publicKeyECDSA).Hex()
- return _privateKey, _address
- }
- func WaitTxByHeader(tx *types.Transaction) error {
- _, _clientSet := UseContract()
- soc := make(chan *types.Header)
- sub, err := _clientSet.WssClient.SubscribeNewHead(context.Background(), soc)
- if err != nil {
- return err
- }
- for {
- select {
- case err := <-sub.Err():
- _ = err
- return err
- case header := <-soc:
- fmt.Println(header.TxHash.Hex())
- tx, err := _clientSet.RpcClient.TransactionReceipt(context.Background(), tx.Hash())
- if err != nil {
- return err
- }
- if tx.Status == 0 {
- sub.Unsubscribe()
- return nil
- } else if tx.Status == 1 {
- sub.Unsubscribe()
- return nil
- }
- }
- }
- }
- func WaitTxByLog(contractAddress string) (error, *types.Log) {
- _, _clientSet := UseContract()
- query := ethereum.FilterQuery{
- Addresses: []common.Address{common.HexToAddress(contractAddress)},
- }
- logs := make(chan types.Log)
- sub, err := _clientSet.WssClient.SubscribeFilterLogs(context.Background(), query, logs)
- if err != nil {
- log.Fatal(err)
- }
- for {
- select {
- case err := <-sub.Err():
- log.Fatal(err)
- return err, nil
- case vLog := <-logs:
- sub.Unsubscribe()
- return nil, &vLog
- }
- }
- }
- // for code verify
- func signHash(data []byte) common.Hash {
- msg := fmt.Sprintf("\x19Ethereum Signed Message:\n%d%s", len(data), data)
- return crypto.Keccak256Hash([]byte(msg))
- }
- func SignData(data []byte, strPrivKey string) ([]byte, error) {
- fmt.Println("Signing....")
- privKey, err := crypto.HexToECDSA(strPrivKey)
- if err != nil {
- return nil, err
- }
- hash := crypto.Keccak256Hash(data)
- fmt.Printf("hashed :%s\n", hash.String())
- signature, err := crypto.Sign(hash.Bytes(), privKey)
- fmt.Printf("signature :%s\n", hexutil.Encode(signature))
- if err != nil {
- return nil, err
- }
- return signature, nil
- }
- func Verify(data []byte, signature []byte) ([]byte, error) {
- fmt.Println("Verifing....")
- hash := crypto.Keccak256Hash(data)
- fmt.Printf("hashed :%s\n", hash.String())
- fmt.Printf("signature :%s\n", hexutil.Encode(signature))
- sigPublicKey, err := crypto.Ecrecover(hash.Bytes(), signature)
- if err != nil {
- return nil, err
- }
- fmt.Printf("sigPublickey: %s\n", hexutil.Encode(sigPublicKey))
- return sigPublicKey, nil
- }
- func Signing(voucher operator.MetaRareOperatorNFTVoucher, pirvateKey string) ([]byte, []byte, error) {
- _pk, err := crypto.HexToECDSA(pirvateKey)
- if err != nil {
- fmt.Println(err)
- return nil, nil, err
- }
- b, err := json.Marshal(voucher)
- if err != nil {
- fmt.Println(err)
- return nil, nil, err
- }
- hashRaw := crypto.Keccak256(b)
- signature, err := crypto.Sign(hashRaw, _pk)
- if err != nil {
- fmt.Println(err)
- return nil, nil, err
- }
- return signature, hashRaw, nil
- }
|