|
@@ -10,21 +10,26 @@ import com.antfinancial.mychain.baas.tool.restclient.model.CallRestBizParam;
|
|
|
import com.antfinancial.mychain.baas.tool.restclient.model.Method;
|
|
import com.antfinancial.mychain.baas.tool.restclient.model.Method;
|
|
|
import com.antfinancial.mychain.baas.tool.restclient.model.ReceiptDecoration;
|
|
import com.antfinancial.mychain.baas.tool.restclient.model.ReceiptDecoration;
|
|
|
import com.antfinancial.mychain.baas.tool.restclient.response.BaseResp;
|
|
import com.antfinancial.mychain.baas.tool.restclient.response.BaseResp;
|
|
|
-import com.izouma.nineth.config.GeneralProperties;
|
|
|
|
|
import com.izouma.nineth.config.Constants;
|
|
import com.izouma.nineth.config.Constants;
|
|
|
|
|
+import com.izouma.nineth.config.GeneralProperties;
|
|
|
import com.izouma.nineth.dto.NFT;
|
|
import com.izouma.nineth.dto.NFT;
|
|
|
import com.izouma.nineth.dto.NFTAccount;
|
|
import com.izouma.nineth.dto.NFTAccount;
|
|
|
|
|
+import com.izouma.nineth.event.AccountCreatedEvent;
|
|
|
import com.izouma.nineth.exception.BusinessException;
|
|
import com.izouma.nineth.exception.BusinessException;
|
|
|
import com.izouma.nineth.utils.HashUtils;
|
|
import com.izouma.nineth.utils.HashUtils;
|
|
|
import com.izouma.nineth.utils.SnowflakeIdWorker;
|
|
import com.izouma.nineth.utils.SnowflakeIdWorker;
|
|
|
import lombok.AllArgsConstructor;
|
|
import lombok.AllArgsConstructor;
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
|
|
+import org.springframework.context.ApplicationContext;
|
|
|
|
|
+import org.springframework.core.env.Environment;
|
|
|
import org.springframework.retry.annotation.Backoff;
|
|
import org.springframework.retry.annotation.Backoff;
|
|
|
import org.springframework.retry.annotation.Retryable;
|
|
import org.springframework.retry.annotation.Retryable;
|
|
|
|
|
+import org.springframework.scheduling.annotation.Async;
|
|
|
import org.springframework.stereotype.Service;
|
|
import org.springframework.stereotype.Service;
|
|
|
|
|
|
|
|
import java.math.BigInteger;
|
|
import java.math.BigInteger;
|
|
|
import java.util.ArrayList;
|
|
import java.util.ArrayList;
|
|
|
|
|
+import java.util.Arrays;
|
|
|
import java.util.List;
|
|
import java.util.List;
|
|
|
|
|
|
|
|
@Service
|
|
@Service
|
|
@@ -34,11 +39,30 @@ public class NFTService {
|
|
|
private final RestClient restClient;
|
|
private final RestClient restClient;
|
|
|
private final RestClientProperties restClientProperties;
|
|
private final RestClientProperties restClientProperties;
|
|
|
private final GeneralProperties generalProperties;
|
|
private final GeneralProperties generalProperties;
|
|
|
|
|
+ private final SnowflakeIdWorker snowflakeIdWorker;
|
|
|
|
|
+ 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)
|
|
@Retryable(maxAttempts = 10, backoff = @Backoff(delay = 5000), value = BusinessException.class)
|
|
|
public NFTAccount createAccount(String username) {
|
|
public NFTAccount createAccount(String username) {
|
|
|
CallRestBizParam callRestBizParam = CallRestBizParam.builder()
|
|
CallRestBizParam callRestBizParam = CallRestBizParam.builder()
|
|
|
- .orderId(String.valueOf(new SnowflakeIdWorker(0, 0).nextId()))
|
|
|
|
|
|
|
+ .orderId(String.valueOf(snowflakeIdWorker.nextId()))
|
|
|
.bizid(Constants.bizId)
|
|
.bizid(Constants.bizId)
|
|
|
.account(restClientProperties.getAccount())
|
|
.account(restClientProperties.getAccount())
|
|
|
.mykmsKeyId(restClientProperties.getKmsId())
|
|
.mykmsKeyId(restClientProperties.getKmsId())
|
|
@@ -64,11 +88,17 @@ public class NFTService {
|
|
|
|
|
|
|
|
@Retryable(maxAttempts = 10, backoff = @Backoff(delay = 5000), value = BusinessException.class)
|
|
@Retryable(maxAttempts = 10, backoff = @Backoff(delay = 5000), value = BusinessException.class)
|
|
|
public synchronized NFT createToken(String toAccount, String tokenId) throws Exception {
|
|
public synchronized NFT createToken(String toAccount, String tokenId) throws Exception {
|
|
|
|
|
+ log.info("开始执行EVM合约mint, toAccount: {}, tokenId: {}", toAccount, tokenId);
|
|
|
|
|
+ if (Arrays.asList(env.getActiveProfiles()).contains("test")) {
|
|
|
|
|
+ NFT nft = new NFT("1", tokenId, new BigInteger("1"), new BigInteger("1"));
|
|
|
|
|
+ log.info("测试服生成假token {}", tokenId);
|
|
|
|
|
+ return nft;
|
|
|
|
|
+ }
|
|
|
JSONArray jsonArray = new JSONArray();
|
|
JSONArray jsonArray = new JSONArray();
|
|
|
jsonArray.add(Utils.getIdentityByName(toAccount));
|
|
jsonArray.add(Utils.getIdentityByName(toAccount));
|
|
|
jsonArray.add(new BigInteger(tokenId, 16));
|
|
jsonArray.add(new BigInteger(tokenId, 16));
|
|
|
CallRestBizParam callRestBizParam = CallRestBizParam.builder()
|
|
CallRestBizParam callRestBizParam = CallRestBizParam.builder()
|
|
|
- .orderId(String.valueOf(new SnowflakeIdWorker(0, 0).nextId()))
|
|
|
|
|
|
|
+ .orderId(String.valueOf(snowflakeIdWorker.nextId()))
|
|
|
.bizid(restClientProperties.getBizid())
|
|
.bizid(restClientProperties.getBizid())
|
|
|
.account(restClientProperties.getAccount())
|
|
.account(restClientProperties.getAccount())
|
|
|
.contractName(generalProperties.getContractName())
|
|
.contractName(generalProperties.getContractName())
|
|
@@ -82,7 +112,7 @@ public class NFTService {
|
|
|
.build();
|
|
.build();
|
|
|
BaseResp resp = restClient.bizChainCallWithReceipt(callRestBizParam);
|
|
BaseResp resp = restClient.bizChainCallWithReceipt(callRestBizParam);
|
|
|
if (!resp.isSuccess()) {
|
|
if (!resp.isSuccess()) {
|
|
|
- log.info("EVM合约执行失败: " + resp.getCode() + ", " + resp.getData());
|
|
|
|
|
|
|
+ log.info("EVM合约执行失败: code: {}, data: {}, toAccount: {}, tokenId: {}", resp.getCode(), resp.getData(), toAccount, tokenId);
|
|
|
}
|
|
}
|
|
|
if ("200".equals(resp.getCode())) {
|
|
if ("200".equals(resp.getCode())) {
|
|
|
log.info("EVM合约执行成功");
|
|
log.info("EVM合约执行成功");
|
|
@@ -95,18 +125,18 @@ public class NFTService {
|
|
|
log.info("NFT生成成功 {}", nft);
|
|
log.info("NFT生成成功 {}", nft);
|
|
|
return nft;
|
|
return nft;
|
|
|
} else if ("211".equals(resp.getCode())) {
|
|
} else if ("211".equals(resp.getCode())) {
|
|
|
-
|
|
|
|
|
|
|
+ log.error("EVM合约执行限流");
|
|
|
} else if ("10201".equals(resp.getCode())) {
|
|
} else if ("10201".equals(resp.getCode())) {
|
|
|
// 异步交易未成功需要根据状态码判断交易状态
|
|
// 异步交易未成功需要根据状态码判断交易状态
|
|
|
ReceiptDecoration txReceipt = JSON.parseObject(resp.getData(), ReceiptDecoration.class);
|
|
ReceiptDecoration txReceipt = JSON.parseObject(resp.getData(), ReceiptDecoration.class);
|
|
|
String out = new String(matchAndReplaceNonEnglishChar(txReceipt.getOutput()));
|
|
String out = new String(matchAndReplaceNonEnglishChar(txReceipt.getOutput()));
|
|
|
// 异步交易未成功需要根据状态码判断交易状态
|
|
// 异步交易未成功需要根据状态码判断交易状态
|
|
|
- log.error("EVM合约执行未成功: {}, {}", resp.getCode(), out);
|
|
|
|
|
|
|
+ log.error("EVM合约执行未成功: code: {}, out: {}, tokenId: {}", resp.getCode(), out, tokenId);
|
|
|
if (out.endsWith("ERC721: token already minted")) {
|
|
if (out.endsWith("ERC721: token already minted")) {
|
|
|
return new NFT(txReceipt.getHash(), tokenId, txReceipt.getBlockNumber(), txReceipt.getGasUsed());
|
|
return new NFT(txReceipt.getHash(), tokenId, txReceipt.getBlockNumber(), txReceipt.getGasUsed());
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
- throw new BusinessException("创建nft失败");
|
|
|
|
|
|
|
+ throw new BusinessException("执行EVM合约mint失败");
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
public static byte[] matchAndReplaceNonEnglishChar(byte[] data) {
|
|
public static byte[] matchAndReplaceNonEnglishChar(byte[] data) {
|