xiongzhu 4 éve
szülő
commit
89c325d947

+ 5 - 0
src/main/java/com/izouma/nineth/domain/Asset.java

@@ -200,6 +200,11 @@ public class Asset extends CollectionBaseEntity {
     @JsonView(View.Detail.class)
     private Set<Tag> tags = new HashSet<>();
 
+    private String     hcTxHash;
+    private BigInteger hcBlockNumber;
+    private BigInteger hcGasUsed;
+    private String     hcTokenId;
+
     public static Asset create(Collection collection, User user) {
         return Asset.builder()
                 .userId(user.getId())

+ 6 - 0
src/main/java/com/izouma/nineth/domain/Collection.java

@@ -22,6 +22,7 @@ import org.hibernate.annotations.Formula;
 
 import javax.persistence.*;
 import java.math.BigDecimal;
+import java.math.BigInteger;
 import java.time.LocalDateTime;
 import java.util.HashSet;
 import java.util.List;
@@ -257,4 +258,9 @@ public class Collection extends CollectionBaseEntity {
     @ApiModelProperty("活动规则")
     @Column(columnDefinition = "TEXT")
     private String rule;
+
+    private String     hcTxHash;
+    private BigInteger hcBlockNumber;
+    private BigInteger hcGasUsed;
+    private String     hcTokenId;
 }

+ 4 - 0
src/main/java/com/izouma/nineth/domain/Order.java

@@ -209,4 +209,8 @@ public class Order extends BaseEntityNoID {
 
     @ApiModelProperty("vip积分购买")
     private Integer vipPoint;
+
+    private String     hcTxHash;
+    private BigInteger hcBlockNumber;
+    private BigInteger hcGasUsed;
 }

+ 2 - 0
src/main/java/com/izouma/nineth/domain/User.java

@@ -176,4 +176,6 @@ public class User extends UserBaseEntity implements Serializable {
 
     @Column(columnDefinition = "tinyint unsigned default 0")
     private boolean walletEnabled = false;
+
+    private String hcChainAddress;
 }

+ 25 - 0
src/main/java/com/izouma/nineth/event/MintedEvent.java

@@ -0,0 +1,25 @@
+package com.izouma.nineth.event;
+
+import com.izouma.nineth.dto.NFT;
+import org.springframework.context.ApplicationEvent;
+
+public class MintedEvent extends ApplicationEvent {
+
+    private final Long assetId;
+    private final NFT  nft;
+
+
+    public MintedEvent(Object source, Long assetId, NFT nft) {
+        super(source);
+        this.assetId = assetId;
+        this.nft = nft;
+    }
+
+    public Long getAssetId() {
+        return assetId;
+    }
+
+    public NFT getNft() {
+        return nft;
+    }
+}

+ 5 - 0
src/main/java/com/izouma/nineth/listener/MintListener.java

@@ -27,5 +27,10 @@ public class MintListener implements RocketMQListener<Long> {
         } catch (Exception e) {
             log.error("铸造失败 " + assetId, e);
         }
+        try {
+            assetMintService.hcMint(assetId);
+        } catch (Exception e) {
+            log.error("铸造失败 " + assetId, e);
+        }
     }
 }

+ 25 - 0
src/main/java/com/izouma/nineth/service/AssetMintService.java

@@ -6,6 +6,7 @@ import com.izouma.nineth.domain.User;
 import com.izouma.nineth.dto.NFT;
 import com.izouma.nineth.dto.NFTAccount;
 import com.izouma.nineth.event.CreateAssetEvent;
+import com.izouma.nineth.event.MintedEvent;
 import com.izouma.nineth.exception.BusinessException;
 import com.izouma.nineth.repo.AssetRepo;
 import com.izouma.nineth.repo.UserRepo;
@@ -35,6 +36,7 @@ public class AssetMintService {
     private ApplicationContext applicationContext;
     private Environment        env;
     private UserService        userService;
+    private HCChainService     hcChainService;
 
     @Retryable(maxAttempts = 10, backoff = @Backoff(delay = 1000))
     public void mint(Long assetId) {
@@ -67,6 +69,29 @@ public class AssetMintService {
         }
     }
 
+    @Retryable(maxAttempts = 10, backoff = @Backoff(delay = 1000))
+    public void hcMint(Long assetId) {
+        Asset asset = assetRepo.findById(assetId).orElseThrow(new BusinessException("asset不存在"));
+        User user = userRepo.findById(asset.getUserId()).orElseThrow(new BusinessException("用户不存在"));
+        if (StringUtils.isEmpty(user.getHcChainAddress())) {
+            user.setHcChainAddress(hcChainService.createAccount(user.getId()));
+            userService.save(user);
+        }
+        try {
+            NFT nft = hcChainService.mint(user.getHcChainAddress(), asset.getTokenId());
+            asset.setHcTokenId(nft.getTokenId());
+            asset.setHcBlockNumber(nft.getBlockNumber());
+            asset.setHcTxHash(nft.getTxHash());
+            asset.setHcGasUsed(nft.getGasUsed());
+            if (asset.getIpfsUrl() == null) {
+                asset.setIpfsUrl(ipfsUpload(asset.getPic().get(0).getUrl()));
+            }
+            assetRepo.save(asset);
+            applicationContext.publishEvent(new MintedEvent(this, assetId, nft));
+        } catch (Exception e) {
+            log.error("铸造失败", e);
+        }
+    }
 //    @Async
 //    public void mint(Asset asset) {
 //        User user = userRepo.findById(asset.getUserId()).orElseThrow(new BusinessException("用户不存在"));

+ 85 - 0
src/main/java/com/izouma/nineth/service/HCChainService.java

@@ -0,0 +1,85 @@
+package com.izouma.nineth.service;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.github.kevinsawicki.http.HttpRequest;
+import com.izouma.nineth.dto.NFT;
+import com.izouma.nineth.exception.BusinessException;
+import lombok.AllArgsConstructor;
+import lombok.NoArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.RandomStringUtils;
+import org.springframework.retry.annotation.Backoff;
+import org.springframework.retry.annotation.Retryable;
+import org.springframework.stereotype.Service;
+
+import java.math.BigInteger;
+import java.util.UUID;
+
+@Service
+@Slf4j
+@AllArgsConstructor
+public class HCChainService {
+
+    private static final String baseUrl         = "http://47.107.77.154:10000";
+    private static final String adminAddress    = "0x7c3eb0db638057af2cfbb0e7758ae37ff8dcca27";
+    private static final String contractAddress = "0xce50d8fb56f8f0d90daa8e11ca1ba125a17ce9a8";
+
+    @Retryable(maxAttempts = 10, backoff = @Backoff(delay = 5000), value = BusinessException.class)
+    public String createAccount(Long userId) {
+        String body = HttpRequest.get(baseUrl + "/api/privateKey?type=2&userName=" + UUID.randomUUID() + "&signUserId="
+                + userId + RandomStringUtils.randomAlphabetic(8) + "&appId=1&returnPrivateKey=true").body();
+        JSONObject res = JSON.parseObject(body);
+        log.info("create account result: {}", JSON.toJSONString(res, true));
+        return res.getString("address");
+    }
+
+    @Retryable(maxAttempts = 10, backoff = @Backoff(delay = 5000), value = BusinessException.class)
+    public NFT mint(String address, String tokenId) {
+        String body = HttpRequest.post(baseUrl + "/api/trans/handle").contentType("application/json")
+                .send("{\n" +
+                        "    \"groupId\": \"1\",\n" +
+                        "    \"user\": \"" + adminAddress + "\",\n" +
+                        "    \"funcName\": \"mint\",\n" +
+                        "    \"funcParam\": [\n" +
+                        "        \"" + address + "\",\n" +
+                        "        \"" + new BigInteger(tokenId.replaceAll("^0x", ""), 16).toString(10) + "\"\n" +
+                        "    ],\n" +
+                        "    \"contractAddress\": \"" + contractAddress + "\",\n" +
+                        "    \"contractAbi\": [\n" +
+                        "        {\n" +
+                        "            \"inputs\": [\n" +
+                        "                {\n" +
+                        "                    \"internalType\": \"address\",\n" +
+                        "                    \"name\": \"to\",\n" +
+                        "                    \"type\": \"address\"\n" +
+                        "                },\n" +
+                        "                {\n" +
+                        "                    \"internalType\": \"uint256\",\n" +
+                        "                    \"name\": \"tokenId\",\n" +
+                        "                    \"type\": \"uint256\"\n" +
+                        "                }\n" +
+                        "            ],\n" +
+                        "            \"name\": \"mint\",\n" +
+                        "            \"outputs\": [],\n" +
+                        "            \"stateMutability\": \"nonpayable\",\n" +
+                        "            \"type\": \"function\"\n" +
+                        "        }\n" +
+                        "    ],\n" +
+                        "    \"useAes\": false,\n" +
+                        "    \"useCns\": false,\n" +
+                        "    \"cnsName\": \"\"\n" +
+                        "}").body();
+        JSONObject res = JSON.parseObject(body);
+        log.info("mint result: {}", JSON.toJSONString(res, true));
+        if ("0x0".equals(res.getString("status"))) {
+            BigInteger gas = new BigInteger(res.getString("gasUsed"));
+            String txHash = res.getString("transactionHash");
+            BigInteger blockNumber = new BigInteger(res.getString("blockNumber"));
+            return new NFT(txHash, tokenId, blockNumber, gas);
+        } else {
+            String msg = res.getString("message");
+            throw new BusinessException(msg);
+        }
+    }
+}

+ 0 - 16
src/main/java/com/izouma/nineth/service/NFTService.java

@@ -42,22 +42,6 @@ public class NFTService {
     private final ApplicationContext   context;
     private final Environment          env;
 
-    @Async
-    public void createAccount(Long userId) {
-        NFTAccount account = null;
-        for (int i = 0; i < 10; i++) {
-            try {
-                Thread.sleep(5000);
-                account = createAccount("account_" + userId);
-                break;
-            } catch (Exception e) {
-            }
-        }
-        if (account != null) {
-            context.publishEvent(new AccountCreatedEvent(this, userId, account));
-        }
-    }
-
     @Retryable(maxAttempts = 10, backoff = @Backoff(delay = 5000), value = BusinessException.class)
     public NFTAccount createAccount(String username) {
         CallRestBizParam callRestBizParam = CallRestBizParam.builder()

+ 14 - 4
src/main/java/com/izouma/nineth/service/OrderService.java

@@ -23,10 +23,7 @@ import com.izouma.nineth.dto.MarketSettlement;
 import com.izouma.nineth.dto.PageQuery;
 import com.izouma.nineth.dto.UserBankCard;
 import com.izouma.nineth.enums.*;
-import com.izouma.nineth.event.CreateAssetEvent;
-import com.izouma.nineth.event.CreateOrderEvent;
-import com.izouma.nineth.event.OrderNotifyEvent;
-import com.izouma.nineth.event.TransferAssetEvent;
+import com.izouma.nineth.event.*;
 import com.izouma.nineth.exception.BusinessException;
 import com.izouma.nineth.repo.*;
 import com.izouma.nineth.security.Authority;
@@ -770,6 +767,19 @@ public class OrderService {
         }
     }
 
+    @EventListener
+    public void onHcMinted(MintedEvent event) {
+        Asset asset = assetRepo.findById(event.getAssetId()).orElse(null);
+        if (asset != null && asset.getOrderId() != null) {
+            orderRepo.findById(asset.getOrderId()).ifPresent(order -> {
+                order.setHcTxHash(asset.getTxHash());
+                order.setHcGasUsed(asset.getGasUsed());
+                order.setHcBlockNumber(asset.getBlockNumber());
+                orderRepo.save(order);
+            });
+        }
+    }
+
     @EventListener
     public void onTransferAsset(TransferAssetEvent event) {
         Asset asset = event.getAsset();

+ 0 - 10
src/main/java/com/izouma/nineth/service/UserService.java

@@ -224,16 +224,6 @@ public class UserService {
         return save(user);
     }
 
-    @EventListener
-    public void accountCreated(AccountCreatedEvent event) {
-        userRepo.findById(event.getUserId()).ifPresent(user -> {
-            user.setNftAccount(event.getAccount().getAccountId());
-            user.setKmsId(event.getAccount().getAccountKmsId());
-            user.setPublicKey(event.getAccount().getPublicKey());
-            save(user);
-        });
-    }
-
     public User phoneRegister(String phone, String code, String password, String inviteCode, Long invitor, Long collectionId) {
         String name = "9th_" + RandomStringUtils.randomAlphabetic(8);
         Invite invite = null;

+ 7 - 0
src/test/java/com/izouma/nineth/CommonTest.java

@@ -724,4 +724,11 @@ public class CommonTest {
             System.out.println(m.group(1));
         }
     }
+
+    @Test
+    public void createaccount() {
+        JSONObject jsonObject = JSON.parseObject(HttpRequest.get("http://47.107.77.154:10000/api/privateKey?type=2&userName=" + UUID.randomUUID() + "&signUserId="
+                + RandomStringUtils.randomAlphabetic(8) + "&appId=1&returnPrivateKey=true").body());
+        System.out.println(JSON.toJSONString(jsonObject, true));
+    }
 }

+ 16 - 0
src/test/java/com/izouma/nineth/service/HCChainServiceTest.java

@@ -0,0 +1,16 @@
+package com.izouma.nineth.service;
+
+import org.junit.jupiter.api.Test;
+
+class HCChainServiceTest {
+    HCChainService hcChainService = new HCChainService();
+
+    @Test
+    public void createAccount() {
+    }
+
+    @Test
+    public void mint() {
+        hcChainService.mint("0x62e5d2ae45f9f056e71ac34c49430976b96a81b0", "0x3ce288795a3b7799c3e65345301a0e9");
+    }
+}