package com.izouma.nineth.service; import com.github.kevinsawicki.http.HttpRequest; import com.izouma.nineth.domain.Asset; 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.exception.BusinessException; import com.izouma.nineth.repo.AssetRepo; import com.izouma.nineth.repo.UserRepo; import io.ipfs.api.IPFS; import io.ipfs.api.MerkleNode; import io.ipfs.api.NamedStreamable; import io.ipfs.multihash.Multihash; import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.springframework.context.ApplicationContext; import org.springframework.retry.annotation.Backoff; import org.springframework.retry.annotation.Retryable; import org.springframework.stereotype.Service; import java.io.File; @Service @Slf4j @AllArgsConstructor public class AssetMintService { private AssetRepo assetRepo; private UserRepo userRepo; private NFTService nftService; private ApplicationContext applicationContext; @Retryable(maxAttempts = 10, backoff = @Backoff(delay = 1000)) public void mint(Long assetId) { Asset asset = assetRepo.findById(assetId).orElseThrow(new BusinessException("asset不存在")); User user = userRepo.findById(asset.getUserId()).orElseThrow(new BusinessException("用户不存在")); if (StringUtils.isEmpty(user.getNftAccount())) { NFTAccount account = nftService.createAccount(user.getUsername() + "_"); user.setNftAccount(account.getAccountId()); user.setKmsId(account.getAccountKmsId()); user.setPublicKey(account.getPublicKey()); userRepo.save(user); } try { NFT nft = nftService.createToken(user.getNftAccount(), asset.getTokenId()); if (nft != null) { asset.setTokenId(nft.getTokenId()); asset.setBlockNumber(nft.getBlockNumber()); asset.setTxHash(nft.getTxHash()); asset.setGasUsed(nft.getGasUsed()); if (asset.getIpfsUrl() == null) { asset.setIpfsUrl(ipfsUpload(asset.getPic().get(0).getUrl())); } assetRepo.save(asset); applicationContext.publishEvent(new CreateAssetEvent(this, true, asset)); } else { log.error("铸造失败"); } } catch (Exception e) { log.error("铸造失败", e); } } // @Async // public void mint(Asset asset) { // User user = userRepo.findById(asset.getUserId()).orElseThrow(new BusinessException("用户不存在")); // if (StringUtils.isEmpty(user.getPublicKey())) { // NFTAccount account = nftService.createAccount(user.getUsername() + "_"); // user.setNftAccount(account.getAccountId()); // user.setKmsId(account.getAccountKmsId()); // user.setPublicKey(account.getPublicKey()); // userRepo.save(user); // } // try { // NFT nft = nftService.createToken(user.getNftAccount(), asset.getTokenId()); // if (nft != null) { // asset.setTokenId(nft.getTokenId()); // asset.setBlockNumber(nft.getBlockNumber()); // asset.setTxHash(nft.getTxHash()); // asset.setGasUsed(nft.getGasUsed()); // if (asset.getIpfsUrl() == null) { // asset.setIpfsUrl(ipfsUpload(asset.getPic().get(0).getUrl())); // } // assetRepo.save(asset); // } // } catch (Exception e) { // log.error("铸造失败", e); // } // applicationContext.publishEvent(new CreateAssetEvent(this, true, asset)); // } public String ipfsUpload(String url) { try { IPFS ipfs = new IPFS("120.24.204.226", 5001); HttpRequest request = HttpRequest.get(url); File file = File.createTempFile("ipfs", ".tmp"); request.receive(file); NamedStreamable.FileWrapper file1 = new NamedStreamable.FileWrapper(file); MerkleNode put = ipfs.add(file1).get(0); Multihash multihash = ipfs.pin.add(put.hash).get(0); log.info("上传ipfs成功 {}", multihash.toBase58()); file.delete(); return multihash.toBase58(); } catch (Exception e) { } return null; } }