eth_backend.go 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286
  1. package helpers
  2. import (
  3. "context"
  4. "crypto/ecdsa"
  5. "encoding/json"
  6. "fmt"
  7. "log"
  8. "math/big"
  9. "strings"
  10. "github.com/ethereum/go-ethereum"
  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/metarare/metarare_api/contracts/collectionFactory"
  18. "github.com/metarare/metarare_api/contracts/metafinance"
  19. "github.com/metarare/metarare_api/contracts/metarare"
  20. "github.com/metarare/metarare_api/contracts/operator"
  21. )
  22. func initEthClient() (*ethclient.Client, *ethclient.Client) {
  23. v := LoadEnvs()
  24. endPoint := v.GetString("rpc.endpoint")
  25. if strings.Compare(endPoint, "") == 0 {
  26. panic("env rpc endpoint doesn't exsit")
  27. }
  28. wss_endPoint := v.GetString("rpc.wss_endpoint")
  29. if strings.Compare(wss_endPoint, "") == 0 {
  30. panic("env rpc endpoint doesn't exsit")
  31. }
  32. client, err := ethclient.Dial(endPoint)
  33. if err != nil {
  34. log.Fatal(err)
  35. }
  36. wss_client, err := ethclient.Dial(wss_endPoint)
  37. if err != nil {
  38. log.Fatal(err)
  39. }
  40. Addr_metaFinance = v.GetString("rpc.metafinance")
  41. Addr_metaRare = v.GetString("rpc.metarare")
  42. Addr_CollectionFactory = v.GetString("rpc.collectionFactory")
  43. Addr_Operator = v.GetString("rpc.operator")
  44. return client, wss_client
  45. }
  46. func getClient() (*ethclient.Client, *ethclient.Client) {
  47. if clientSet.RpcClient != nil && clientSet.WssClient != nil {
  48. return clientSet.RpcClient, clientSet.WssClient
  49. } else {
  50. return initEthClient()
  51. }
  52. }
  53. func loadSigningKey(pkey string) (*ecdsa.PrivateKey, *ecdsa.PublicKey, common.Address) {
  54. // load the signing key
  55. privateKey, err := crypto.HexToECDSA(pkey)
  56. if err != nil {
  57. log.Fatal(err)
  58. }
  59. publicKey := privateKey.Public()
  60. publicKeyECDSA, ok := publicKey.(*ecdsa.PublicKey)
  61. if !ok {
  62. log.Fatal("cannot assert type: publicKey is not of type *ecdsa.PublicKey")
  63. }
  64. fromAddress := crypto.PubkeyToAddress(*publicKeyECDSA)
  65. return privateKey, publicKey.(*ecdsa.PublicKey), fromAddress
  66. }
  67. func obtainNonce(_client *ethclient.Client, _address common.Address) *big.Int {
  68. nonce, err := _client.PendingNonceAt(context.Background(), _address)
  69. if err != nil {
  70. log.Fatal(err)
  71. }
  72. return new(big.Int).SetUint64(nonce)
  73. }
  74. func obtainEstimatedGas(_client *ethclient.Client, _overFitting bool) *big.Int {
  75. gasPrice, err := _client.SuggestGasPrice(context.Background())
  76. if err != nil {
  77. log.Fatal(err)
  78. }
  79. // fmt.Println("gasPrice:", gasPrice)
  80. if _overFitting {
  81. return gasPrice.Mul(gasPrice, big.NewInt(15)).Div(gasPrice, big.NewInt(10))
  82. }
  83. return gasPrice
  84. }
  85. func UseContract() (ContractSet, ClientSet) {
  86. clientSet.RpcClient, clientSet.WssClient = getClient()
  87. //have to make smart contract instances
  88. //metarare
  89. address := common.HexToAddress(Addr_metaRare)
  90. _metaRare, err := metarare.NewMetaRare(address, clientSet.RpcClient)
  91. if err != nil {
  92. log.Fatal("Cannot make Metarare instance ", err)
  93. }
  94. //metafinance
  95. address = common.HexToAddress(Addr_metaFinance)
  96. _metaFinance, err := metafinance.NewMetafinance(address, clientSet.RpcClient)
  97. if err != nil {
  98. log.Fatal("Cannot make MetaFinance instance", err)
  99. }
  100. // some contracts
  101. address = common.HexToAddress(Addr_CollectionFactory)
  102. _factory, err := collectionFactory.NewMetaRareCollectionFactory(address, clientSet.RpcClient)
  103. if err != nil {
  104. log.Fatal("Cannot make MetaFinance instance", err)
  105. }
  106. address = common.HexToAddress(Addr_Operator)
  107. _operator, err := operator.NewMetaRareOperator(address, clientSet.RpcClient)
  108. if err != nil {
  109. log.Fatal("Cannot make MetaFinance instance", err)
  110. }
  111. contractSet.MetaFinance = _metaFinance
  112. contractSet.MetaRare = _metaRare
  113. contractSet.CollectionFactory = _factory
  114. contractSet.Operator = _operator
  115. contractSet.ChainID, err = clientSet.WssClient.ChainID(context.Background())
  116. return contractSet, clientSet
  117. }
  118. func makeAuth(_client *ethclient.Client, fromPrivateKey string, toAddress string, ethAmount *big.Int) (error, *bind.TransactOpts) {
  119. privateKey, err := crypto.HexToECDSA(fromPrivateKey)
  120. if err != nil {
  121. return err, nil
  122. }
  123. publicKey := privateKey.Public()
  124. publicKeyECDSA, ok := publicKey.(*ecdsa.PublicKey)
  125. if !ok {
  126. log.Fatal("cannot assert type: publicKey is not of type *ecdsa.PublicKey")
  127. }
  128. fromAddress := crypto.PubkeyToAddress(*publicKeyECDSA)
  129. auth := bind.NewKeyedTransactor(privateKey)
  130. auth.Nonce = obtainNonce(_client, fromAddress)
  131. if ethAmount != nil {
  132. auth.Value = ethAmount
  133. } else {
  134. auth.Value = big.NewInt(0)
  135. }
  136. // fmt.Println("value :", auth.Value)
  137. // auth.GasLimit = uint64(30000000)
  138. auth.GasPrice = obtainEstimatedGas(_client, true)
  139. // fmt.Println("gasPrice:", auth.GasPrice.String())
  140. return nil, auth
  141. }
  142. func GenerateWallet() (string, string) {
  143. privateKey, err := crypto.GenerateKey()
  144. if err != nil {
  145. log.Fatal(err)
  146. }
  147. privateKeyBytes := crypto.FromECDSA(privateKey)
  148. _privateKey := hexutil.Encode(privateKeyBytes)[2:]
  149. publicKey := privateKey.Public()
  150. publicKeyECDSA, ok := publicKey.(*ecdsa.PublicKey)
  151. if !ok {
  152. log.Fatal("error casting public key to ECDSA")
  153. }
  154. _address := crypto.PubkeyToAddress(*publicKeyECDSA).Hex()
  155. return _privateKey, _address
  156. }
  157. func WaitTxByHeader(tx *types.Transaction) error {
  158. _, _clientSet := UseContract()
  159. soc := make(chan *types.Header)
  160. sub, err := _clientSet.WssClient.SubscribeNewHead(context.Background(), soc)
  161. if err != nil {
  162. return err
  163. }
  164. for {
  165. select {
  166. case err := <-sub.Err():
  167. _ = err
  168. return err
  169. case header := <-soc:
  170. fmt.Println(header.TxHash.Hex())
  171. tx, err := _clientSet.RpcClient.TransactionReceipt(context.Background(), tx.Hash())
  172. if err != nil {
  173. return err
  174. }
  175. if tx.Status == 0 {
  176. sub.Unsubscribe()
  177. return nil
  178. } else if tx.Status == 1 {
  179. sub.Unsubscribe()
  180. return nil
  181. }
  182. }
  183. }
  184. }
  185. func WaitTxByLog(contractAddress string) (error, *types.Log) {
  186. _, _clientSet := UseContract()
  187. query := ethereum.FilterQuery{
  188. Addresses: []common.Address{common.HexToAddress(contractAddress)},
  189. }
  190. logs := make(chan types.Log)
  191. sub, err := _clientSet.WssClient.SubscribeFilterLogs(context.Background(), query, logs)
  192. if err != nil {
  193. log.Fatal(err)
  194. }
  195. for {
  196. select {
  197. case err := <-sub.Err():
  198. log.Fatal(err)
  199. return err, nil
  200. case vLog := <-logs:
  201. sub.Unsubscribe()
  202. return nil, &vLog
  203. }
  204. }
  205. }
  206. // for code verify
  207. func signHash(data []byte) common.Hash {
  208. msg := fmt.Sprintf("\x19Ethereum Signed Message:\n%d%s", len(data), data)
  209. return crypto.Keccak256Hash([]byte(msg))
  210. }
  211. func SignData(data []byte, strPrivKey string) ([]byte, error) {
  212. fmt.Println("Signing....")
  213. privKey, err := crypto.HexToECDSA(strPrivKey)
  214. if err != nil {
  215. return nil, err
  216. }
  217. hash := crypto.Keccak256Hash(data)
  218. fmt.Printf("hashed :%s\n", hash.String())
  219. signature, err := crypto.Sign(hash.Bytes(), privKey)
  220. fmt.Printf("signature :%s\n", hexutil.Encode(signature))
  221. if err != nil {
  222. return nil, err
  223. }
  224. return signature, nil
  225. }
  226. func Verify(data []byte, signature []byte) ([]byte, error) {
  227. fmt.Println("Verifing....")
  228. hash := crypto.Keccak256Hash(data)
  229. fmt.Printf("hashed :%s\n", hash.String())
  230. fmt.Printf("signature :%s\n", hexutil.Encode(signature))
  231. sigPublicKey, err := crypto.Ecrecover(hash.Bytes(), signature)
  232. if err != nil {
  233. return nil, err
  234. }
  235. fmt.Printf("sigPublickey: %s\n", hexutil.Encode(sigPublicKey))
  236. return sigPublicKey, nil
  237. }
  238. func Signing(voucher operator.MetaRareOperatorNFTVoucher, pirvateKey string) ([]byte, []byte, error) {
  239. _pk, err := crypto.HexToECDSA(pirvateKey)
  240. if err != nil {
  241. fmt.Println(err)
  242. return nil, nil, err
  243. }
  244. b, err := json.Marshal(voucher)
  245. if err != nil {
  246. fmt.Println(err)
  247. return nil, nil, err
  248. }
  249. hashRaw := crypto.Keccak256(b)
  250. signature, err := crypto.Sign(hashRaw, _pk)
  251. if err != nil {
  252. fmt.Println(err)
  253. return nil, nil, err
  254. }
  255. return signature, hashRaw, nil
  256. }