NFTService.java 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. package com.izouma.nineth.service;
  2. import com.alibaba.fastjson.JSON;
  3. import com.alibaba.fastjson.JSONArray;
  4. import com.alipay.mychain.sdk.api.utils.Utils;
  5. import com.alipay.mychain.sdk.domain.transaction.LogEntry;
  6. import com.antfinancial.mychain.baas.tool.restclient.RestClient;
  7. import com.antfinancial.mychain.baas.tool.restclient.RestClientProperties;
  8. import com.antfinancial.mychain.baas.tool.restclient.model.CallRestBizParam;
  9. import com.antfinancial.mychain.baas.tool.restclient.model.ClientParam;
  10. import com.antfinancial.mychain.baas.tool.restclient.model.Method;
  11. import com.antfinancial.mychain.baas.tool.restclient.model.ReceiptDecoration;
  12. import com.antfinancial.mychain.baas.tool.restclient.response.BaseResp;
  13. import com.izouma.nineth.config.Constants;
  14. import com.izouma.nineth.dto.NFT;
  15. import com.izouma.nineth.dto.NFTAccount;
  16. import com.izouma.nineth.exception.BusinessException;
  17. import com.izouma.nineth.utils.HashUtils;
  18. import com.izouma.nineth.utils.SnowflakeIdWorker;
  19. import lombok.AllArgsConstructor;
  20. import lombok.extern.slf4j.Slf4j;
  21. import org.springframework.retry.annotation.Backoff;
  22. import org.springframework.retry.annotation.Retryable;
  23. import org.springframework.stereotype.Service;
  24. import java.math.BigInteger;
  25. @Service
  26. @Slf4j
  27. @AllArgsConstructor
  28. public class NFTService {
  29. private final RestClient restClient;
  30. private final RestClientProperties restClientProperties;
  31. public NFTAccount createAccount(String username) {
  32. CallRestBizParam callRestBizParam = CallRestBizParam.builder()
  33. .orderId(String.valueOf(new SnowflakeIdWorker(0, 0).nextId()))
  34. .bizid(Constants.bizId)
  35. .account(restClientProperties.getAccount())
  36. .mykmsKeyId(restClientProperties.getKmsId())
  37. .newAccountId(username)
  38. .newAccountKmsId(Constants.kmsKey)
  39. .method(Method.TENANTCREATEACCUNT)
  40. .gas(100000L).build();
  41. try {
  42. BaseResp baseResp = restClient.chainCallForBiz(callRestBizParam);
  43. NFTAccount account = new NFTAccount(username, Constants.kmsKey, baseResp.getData());
  44. if (baseResp.isSuccess()) {
  45. log.info("创建账户成功 {}", account);
  46. return account;
  47. } else {
  48. throw new RuntimeException(baseResp.getCode());
  49. }
  50. } catch (Exception e) {
  51. e.printStackTrace();
  52. log.error("创建账户失败", e);
  53. throw new BusinessException("创建账户失败");
  54. }
  55. }
  56. @Retryable(maxAttempts = 10, backoff = @Backoff(delay = 5000), value = BusinessException.class)
  57. public NFT createToken(String toAccount) throws Exception {
  58. JSONArray jsonArray = new JSONArray();
  59. jsonArray.add(Utils.getIdentityByName(toAccount));
  60. CallRestBizParam callRestBizParam = CallRestBizParam.builder()
  61. .orderId(String.valueOf(new SnowflakeIdWorker(0, 0).nextId()))
  62. .bizid(restClientProperties.getBizid())
  63. .account(restClientProperties.getAccount())
  64. .contractName(Constants.CONTRACT_NAME)
  65. .methodSignature("mint(identity)")
  66. .inputParamListStr(jsonArray.toJSONString())
  67. .outTypes("[]")//合约返回值类型
  68. .mykmsKeyId(restClientProperties.getKmsId())
  69. .method(Method.CALLCONTRACTBIZASYNC)
  70. .tenantid(restClientProperties.getTenantid())
  71. .gas(500000L)
  72. .build();
  73. BaseResp resp = restClient.bizChainCallWithReceipt(callRestBizParam);
  74. if (!resp.isSuccess()) {
  75. log.info("EVM合约执行失败: " + resp.getCode() + ", " + resp.getData());
  76. }
  77. if ("200".equals(resp.getCode())) {
  78. log.info("EVM合约执行成功");
  79. // 合约调用交易回执内容
  80. ReceiptDecoration txReceipt = JSON.parseObject(resp.getData(), ReceiptDecoration.class);
  81. BigInteger gasUsed = txReceipt.getGasUsed();
  82. long result = txReceipt.getResult();
  83. log.info("EVM合约交易内容: 哈希 " + txReceipt.getHash() + ", 消耗燃料 " + gasUsed + ", 结果 " + result);
  84. for (LogEntry logEntry : txReceipt.getLogs()) {
  85. if (logEntry.getTopics().get(0).equals(HashUtils.Keccak256("Transfer(identity,identity,uint256)"))) {
  86. String tokenId = logEntry.getTopics().get(3);
  87. txReceipt.getBlockNumber();
  88. NFT nft = new NFT(txReceipt.getHash(), tokenId, txReceipt.getBlockNumber(), txReceipt.getGasUsed());
  89. log.info("NFT生成成功 {}", nft);
  90. return nft;
  91. }
  92. }
  93. } else {
  94. // 异步交易未成功需要根据状态码判断交易状态
  95. log.error("EVM合约执行未成功: " + resp.getCode());
  96. }
  97. throw new BusinessException("创建nft失败");
  98. }
  99. }