@@ -103,27 +103,27 @@ | |||||
<artifactId>maven-plugin-plugin</artifactId> | <artifactId>maven-plugin-plugin</artifactId> | ||||
<version>3.5</version> | <version>3.5</version> | ||||
</plugin> | </plugin> | ||||
<plugin> | |||||
<groupId>org.apache.maven.plugins</groupId> | |||||
<artifactId>maven-compiler-plugin</artifactId> | |||||
<configuration> | |||||
<source>1.8</source> | |||||
<target>1.8</target> | |||||
<encoding>UTF-8</encoding> | |||||
<optimize>false</optimize> | |||||
<debug>true</debug> | |||||
<showDeprecation>false</showDeprecation> | |||||
<showWarnings>false</showWarnings> | |||||
</configuration> | |||||
</plugin> | |||||
<plugin> | |||||
<groupId>org.apache.maven.plugins</groupId> | |||||
<artifactId>maven-surefire-plugin</artifactId> | |||||
<configuration> | |||||
<skipTests>true</skipTests> | |||||
</configuration> | |||||
</plugin> | |||||
</plugins> | |||||
</build> | |||||
<!-- | |||||
<plugin> | |||||
<groupId>org.apache.maven.plugins</groupId> | |||||
<artifactId>maven-compiler-plugin</artifactId> | |||||
<configuration> | |||||
<source>1.8</source> | |||||
<target>1.8</target> | |||||
<encoding>UTF-8</encoding> | |||||
<optimize>false</optimize> | |||||
<debug>true</debug> | |||||
<showDeprecation>false</showDeprecation> | |||||
<showWarnings>false</showWarnings> | |||||
</configuration> | |||||
</plugin> | |||||
<plugin> | |||||
<groupId>org.apache.maven.plugins</groupId> | |||||
<artifactId>maven-surefire-plugin</artifactId> | |||||
<configuration> | |||||
<skipTests>true</skipTests> | |||||
</configuration> | |||||
</plugin>--> | |||||
</plugins> | |||||
</build> | |||||
</project> | </project> |
@@ -1,6 +1,5 @@ | |||||
package com.jd.blockchain; | package com.jd.blockchain; | ||||
import com.jd.blockchain.ledger.BlockchainKeyGenerator; | |||||
import org.apache.commons.io.FileUtils; | import org.apache.commons.io.FileUtils; | ||||
import org.apache.maven.model.Model; | import org.apache.maven.model.Model; | ||||
import org.apache.maven.model.Plugin; | import org.apache.maven.model.Plugin; | ||||
@@ -8,6 +7,7 @@ import org.apache.maven.model.PluginExecution; | |||||
import org.apache.maven.model.io.xpp3.MavenXpp3Reader; | import org.apache.maven.model.io.xpp3.MavenXpp3Reader; | ||||
import org.apache.maven.model.io.xpp3.MavenXpp3Writer; | import org.apache.maven.model.io.xpp3.MavenXpp3Writer; | ||||
import org.apache.maven.plugin.AbstractMojo; | import org.apache.maven.plugin.AbstractMojo; | ||||
import org.apache.maven.plugin.MojoFailureException; | |||||
import org.apache.maven.plugins.annotations.Mojo; | import org.apache.maven.plugins.annotations.Mojo; | ||||
import org.apache.maven.plugins.annotations.Parameter; | import org.apache.maven.plugins.annotations.Parameter; | ||||
import org.apache.maven.project.MavenProject; | import org.apache.maven.project.MavenProject; | ||||
@@ -22,11 +22,12 @@ import java.util.Collections; | |||||
import java.util.List; | import java.util.List; | ||||
@Mojo(name = "Contract.Check") | |||||
@Mojo(name = "contractCheck") | |||||
public class ContractCheckMojo extends AbstractMojo { | public class ContractCheckMojo extends AbstractMojo { | ||||
Logger LOG = LoggerFactory.getLogger(ContractCheckMojo.class); | Logger LOG = LoggerFactory.getLogger(ContractCheckMojo.class); | ||||
public static final String CONTRACT_VERIFY = "Contract.Verify"; | |||||
public static final String CONTRACT_VERIFY = "contractVerify"; | |||||
private static final String CONTRACT_MAVEN_PLUGIN = "contract-maven-plugin"; | private static final String CONTRACT_MAVEN_PLUGIN = "contract-maven-plugin"; | ||||
@@ -36,11 +37,11 @@ public class ContractCheckMojo extends AbstractMojo { | |||||
private static final String APACHE_MAVEN_PLUGINS = "org.apache.maven.plugins"; | private static final String APACHE_MAVEN_PLUGINS = "org.apache.maven.plugins"; | ||||
private static final String GOALS_VERIFY = "verify"; | |||||
private static final String GOALS_VERIFY = "package"; | |||||
private static final String GOALS_PACKAGE = "package"; | private static final String GOALS_PACKAGE = "package"; | ||||
private static final String OUT_POM_XML = "OutPom.xml"; | |||||
private static final String OUT_POM_XML = "ContractPom.xml"; | |||||
@Parameter(defaultValue = "${project}", required = true, readonly = true) | @Parameter(defaultValue = "${project}", required = true, readonly = true) | ||||
private MavenProject project; | private MavenProject project; | ||||
@@ -51,7 +52,6 @@ public class ContractCheckMojo extends AbstractMojo { | |||||
@Parameter | @Parameter | ||||
private String finalName; | private String finalName; | ||||
/** | /** | ||||
* mainClass; | * mainClass; | ||||
*/ | */ | ||||
@@ -73,11 +73,11 @@ public class ContractCheckMojo extends AbstractMojo { | |||||
* first compile the class, then parse it; | * first compile the class, then parse it; | ||||
*/ | */ | ||||
@Override | @Override | ||||
public void execute() { | |||||
public void execute() throws MojoFailureException { | |||||
compileFiles(); | compileFiles(); | ||||
} | } | ||||
private void compileFiles(){ | |||||
private void compileFiles() throws MojoFailureException { | |||||
try (FileInputStream fis = new FileInputStream(project.getFile())) { | try (FileInputStream fis = new FileInputStream(project.getFile())) { | ||||
MavenXpp3Reader reader = new MavenXpp3Reader(); | MavenXpp3Reader reader = new MavenXpp3Reader(); | ||||
@@ -107,7 +107,7 @@ public class ContractCheckMojo extends AbstractMojo { | |||||
} catch (Exception e) { | } catch (Exception e) { | ||||
LOG.error(e.getMessage()); | LOG.error(e.getMessage()); | ||||
throw new IllegalStateException(e); | |||||
throw new MojoFailureException(e.getMessage()); | |||||
} | } | ||||
} | } | ||||
@@ -185,7 +185,7 @@ public class ContractCheckMojo extends AbstractMojo { | |||||
PluginExecution pluginExecution = new PluginExecution(); | PluginExecution pluginExecution = new PluginExecution(); | ||||
pluginExecution.setId(id); | pluginExecution.setId(id); | ||||
pluginExecution.setPhase(phase); | pluginExecution.setPhase(phase); | ||||
List <String> goals = new ArrayList<>(); | |||||
List<String> goals = new ArrayList<>(); | |||||
goals.add(goal); | goals.add(goal); | ||||
pluginExecution.setGoals(goals); | pluginExecution.setGoals(goals); | ||||
List<PluginExecution> pluginExecutions = new ArrayList<>(); | List<PluginExecution> pluginExecutions = new ArrayList<>(); | ||||
@@ -3,37 +3,25 @@ package com.jd.blockchain; | |||||
import com.github.javaparser.JavaParser; | import com.github.javaparser.JavaParser; | ||||
import com.github.javaparser.ast.CompilationUnit; | import com.github.javaparser.ast.CompilationUnit; | ||||
import com.github.javaparser.ast.ImportDeclaration; | import com.github.javaparser.ast.ImportDeclaration; | ||||
import com.github.javaparser.ast.NodeList; | |||||
import com.github.javaparser.ast.PackageDeclaration; | |||||
import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration; | |||||
import com.github.javaparser.ast.body.MethodDeclaration; | |||||
import com.github.javaparser.ast.visitor.VoidVisitorAdapter; | import com.github.javaparser.ast.visitor.VoidVisitorAdapter; | ||||
import com.jd.blockchain.contract.ContractType; | import com.jd.blockchain.contract.ContractType; | ||||
import com.jd.blockchain.utils.IllegalDataException; | |||||
import org.apache.commons.codec.digest.DigestUtils; | |||||
import org.apache.commons.io.FileUtils; | import org.apache.commons.io.FileUtils; | ||||
import org.apache.commons.io.IOUtils; | |||||
import org.apache.maven.plugin.AbstractMojo; | import org.apache.maven.plugin.AbstractMojo; | ||||
import org.apache.maven.plugin.MojoFailureException; | |||||
import org.apache.maven.plugin.MojoExecutionException; | |||||
import org.apache.maven.plugins.annotations.Mojo; | import org.apache.maven.plugins.annotations.Mojo; | ||||
import org.apache.maven.plugins.annotations.Parameter; | import org.apache.maven.plugins.annotations.Parameter; | ||||
import org.apache.maven.project.MavenProject; | import org.apache.maven.project.MavenProject; | ||||
import org.slf4j.Logger; | import org.slf4j.Logger; | ||||
import org.slf4j.LoggerFactory; | import org.slf4j.LoggerFactory; | ||||
import org.springframework.util.ResourceUtils; | |||||
import java.io.*; | import java.io.*; | ||||
import java.net.URL; | import java.net.URL; | ||||
import java.net.URLClassLoader; | import java.net.URLClassLoader; | ||||
import java.nio.charset.StandardCharsets; | import java.nio.charset.StandardCharsets; | ||||
import java.nio.file.Files; | |||||
import java.nio.file.Path; | |||||
import java.util.*; | import java.util.*; | ||||
import java.util.jar.Attributes; | import java.util.jar.Attributes; | ||||
import java.util.jar.JarEntry; | import java.util.jar.JarEntry; | ||||
import java.util.jar.JarFile; | import java.util.jar.JarFile; | ||||
import java.util.jar.JarOutputStream; | |||||
import java.util.stream.Collectors; | |||||
import static com.jd.blockchain.ContractCheckMojo.CONTRACT_VERIFY; | import static com.jd.blockchain.ContractCheckMojo.CONTRACT_VERIFY; | ||||
import static com.jd.blockchain.utils.decompiler.utils.DecompilerUtils.decompileJarFile; | import static com.jd.blockchain.utils.decompiler.utils.DecompilerUtils.decompileJarFile; | ||||
@@ -78,12 +66,15 @@ public class ContractVerifyMojo extends AbstractMojo { | |||||
private static final String BLACK_NAME_LIST = "black.name.list"; | private static final String BLACK_NAME_LIST = "black.name.list"; | ||||
@Override | @Override | ||||
public void execute() throws MojoFailureException { | |||||
public void execute() throws MojoExecutionException { | |||||
try { | try { | ||||
File jarFile = copyAndManage(); | File jarFile = copyAndManage(); | ||||
// 首先校验MainClass | |||||
verifyMainClass(jarFile); | |||||
Properties config = loadConfig(); | Properties config = loadConfig(); | ||||
List<ContractPackage> blackNameList = blackNameList(config); | List<ContractPackage> blackNameList = blackNameList(config); | ||||
@@ -193,23 +184,25 @@ public class ContractVerifyMojo extends AbstractMojo { | |||||
if (!isOK) { | if (!isOK) { | ||||
throw new IllegalStateException("There are many Illegal information, please check !!!"); | throw new IllegalStateException("There are many Illegal information, please check !!!"); | ||||
} | } | ||||
// 加载main-class,开始校验类型 | |||||
URL jarURL = jarFile.toURI().toURL(); | |||||
ClassLoader classLoader = new URLClassLoader(new URL[]{jarURL}, this.getClass().getClassLoader()); | |||||
Attributes m = new JarFile(jarFile).getManifest().getMainAttributes(); | |||||
String contractMainClass = m.getValue(Attributes.Name.MAIN_CLASS); | |||||
Class mainClass = classLoader.loadClass(contractMainClass); | |||||
ContractType.resolve(mainClass); | |||||
} else { | } else { | ||||
throw new IllegalStateException("There is none class !!!"); | throw new IllegalStateException("There is none class !!!"); | ||||
} | } | ||||
} catch (Exception e) { | } catch (Exception e) { | ||||
LOG.error(e.getMessage()); | LOG.error(e.getMessage()); | ||||
throw new MojoFailureException(e.getMessage()); | |||||
throw new MojoExecutionException(e.getMessage()); | |||||
} | } | ||||
} | } | ||||
private void verifyMainClass(File jarFile) throws Exception { | |||||
// 加载main-class,开始校验类型 | |||||
URL jarURL = jarFile.toURI().toURL(); | |||||
ClassLoader classLoader = new URLClassLoader(new URL[]{jarURL}, this.getClass().getClassLoader()); | |||||
Attributes m = new JarFile(jarFile).getManifest().getMainAttributes(); | |||||
String contractMainClass = m.getValue(Attributes.Name.MAIN_CLASS); | |||||
Class mainClass = classLoader.loadClass(contractMainClass); | |||||
ContractType.resolve(mainClass); | |||||
} | |||||
private List<ContractPackage> blackNameList(Properties config) { | private List<ContractPackage> blackNameList(Properties config) { | ||||
return blackList(config, BLACK_NAME_LIST); | return blackList(config, BLACK_NAME_LIST); | ||||
} | } | ||||
@@ -320,14 +313,14 @@ public class ContractVerifyMojo extends AbstractMojo { | |||||
// 首先进行Copy处理 | // 首先进行Copy处理 | ||||
copy(srcJar, dstJar); | copy(srcJar, dstJar); | ||||
byte[] txtBytes = jdChainTxt(FileUtils.readFileToByteArray(dstJar)).getBytes(StandardCharsets.UTF_8); | |||||
byte[] txtBytes = contractMF(FileUtils.readFileToByteArray(dstJar)).getBytes(StandardCharsets.UTF_8); | |||||
String finalJarPath = project.getBuild().getDirectory() + | String finalJarPath = project.getBuild().getDirectory() + | ||||
File.separator + finalName + "-jdchain.jar"; | File.separator + finalName + "-jdchain.jar"; | ||||
File finalJar = new File(finalJarPath); | File finalJar = new File(finalJarPath); | ||||
copy(dstJar, finalJar, jdChainMetaTxtJarEntry(), txtBytes, null); | |||||
copy(dstJar, finalJar, contractMFJarEntry(), txtBytes, null); | |||||
// 删除临时文件 | // 删除临时文件 | ||||
FileUtils.forceDelete(dstJar); | FileUtils.forceDelete(dstJar); | ||||
@@ -423,8 +416,9 @@ public class ContractVerifyMojo extends AbstractMojo { | |||||
if (totalPackage.endsWith("*")) { | if (totalPackage.endsWith("*")) { | ||||
this.packageName = totalPackage.substring(0, totalPackage.length() - 2).trim(); | this.packageName = totalPackage.substring(0, totalPackage.length() - 2).trim(); | ||||
this.isTotal = true; | this.isTotal = true; | ||||
} else { | |||||
this.packageName = totalPackage; | |||||
} | } | ||||
this.packageName = totalPackage; | |||||
} | } | ||||
public String getPackageName() { | public String getPackageName() { | ||||
@@ -1,8 +1,8 @@ | |||||
#black.name.list:打包为合约Jar后,每个Class文件不允许使用的名称,默认不允许使用com.jd.blockchain.* | |||||
black.name.list=com.jd.blockchain.* | |||||
#black.name.list:打包为合约Jar后,每个Class文件不允许使用或包含的名称,默认不允许使用com.jd.blockchain.*及一些内部已经引用的包 | |||||
black.name.list=com.jd.blockchain.*, com.alibaba.fastjson.*, org.apache.commons.io.*, org.apache.commons.codec.*, io.netty.* | |||||
#black.package.list:打包为合约中的每个Class都不允许使用的包列表,某个包下面的所有包通过.*表示 | #black.package.list:打包为合约中的每个Class都不允许使用的包列表,某个包下面的所有包通过.*表示 | ||||
black.package.list=java.io.*, java.net.*, org.apache.commons.io.* | |||||
black.package.list=java.io.*, java.nio.*, java.net.*, org.apache.commons.io.* | |||||
#black.class.list:打包为合约中的每个Class都不允许使用的类列表 | #black.class.list:打包为合约中的每个Class都不允许使用的类列表 | ||||
black.class.list=java.util.Random, com.jd.blockchain.ledger.BlockchainKeyGenerator | black.class.list=java.util.Random, com.jd.blockchain.ledger.BlockchainKeyGenerator |
@@ -18,7 +18,7 @@ public class ContractVerifyTest { | |||||
@Before | @Before | ||||
public void testInit() { | public void testInit() { | ||||
project = mavenProjectInit(); | project = mavenProjectInit(); | ||||
finalName = "complex.jar"; | |||||
finalName = "complex"; | |||||
} | } | ||||
@Test | @Test | ||||
@@ -5,6 +5,7 @@ import com.jd.blockchain.ledger.ContractCodeDeployOperation; | |||||
import com.jd.blockchain.ledger.Operation; | import com.jd.blockchain.ledger.Operation; | ||||
import com.jd.blockchain.ledger.TransactionRequest; | import com.jd.blockchain.ledger.TransactionRequest; | ||||
import com.jd.blockchain.utils.IllegalDataException; | import com.jd.blockchain.utils.IllegalDataException; | ||||
import com.jd.blockchain.utils.jar.ContractJarUtils; | |||||
import org.springframework.beans.factory.annotation.Autowired; | import org.springframework.beans.factory.annotation.Autowired; | ||||
import org.springframework.stereotype.Service; | import org.springframework.stereotype.Service; | ||||
@@ -29,14 +30,7 @@ public class GatewayInterceptServiceHandler implements GatewayInterceptService { | |||||
} | } | ||||
private void contractCheck(final ContractCodeDeployOperation contractOP) { | private void contractCheck(final ContractCodeDeployOperation contractOP) { | ||||
// | |||||
byte[] chainCode = contractOP.getChainCode(); | |||||
if (chainCode == null || chainCode.length == 0) { | |||||
throw new IllegalDataException("Contract's content is empty !!!"); | |||||
} | |||||
// 校验chainCode | |||||
ContractJarUtils.verify(contractOP.getChainCode()); | |||||
} | } | ||||
} | } |
@@ -1,5 +1,6 @@ | |||||
package com.jd.blockchain.gateway.web; | package com.jd.blockchain.gateway.web; | ||||
import com.jd.blockchain.gateway.service.GatewayInterceptService; | |||||
import org.springframework.beans.factory.annotation.Autowired; | import org.springframework.beans.factory.annotation.Autowired; | ||||
import org.springframework.web.bind.annotation.RequestBody; | import org.springframework.web.bind.annotation.RequestBody; | ||||
import org.springframework.web.bind.annotation.RequestMapping; | import org.springframework.web.bind.annotation.RequestMapping; | ||||
@@ -30,9 +31,15 @@ public class TxProcessingController implements TransactionService { | |||||
@Autowired | @Autowired | ||||
private PeerService peerService; | private PeerService peerService; | ||||
@Autowired | |||||
private GatewayInterceptService interceptService; | |||||
@RequestMapping(path = "rpc/tx", method = RequestMethod.POST, consumes = BinaryMessageConverter.CONTENT_TYPE_VALUE, produces = BinaryMessageConverter.CONTENT_TYPE_VALUE) | @RequestMapping(path = "rpc/tx", method = RequestMethod.POST, consumes = BinaryMessageConverter.CONTENT_TYPE_VALUE, produces = BinaryMessageConverter.CONTENT_TYPE_VALUE) | ||||
@Override | @Override | ||||
public @ResponseBody TransactionResponse process(@RequestBody TransactionRequest txRequest) { | public @ResponseBody TransactionResponse process(@RequestBody TransactionRequest txRequest) { | ||||
// 拦截请求进行校验 | |||||
interceptService.intercept(txRequest); | |||||
// 检查交易请求的信息是否完整; | // 检查交易请求的信息是否完整; | ||||
HashDigest ledgerHash = txRequest.getTransactionContent().getLedgerHash(); | HashDigest ledgerHash = txRequest.getTransactionContent().getLedgerHash(); | ||||
if (ledgerHash == null) { | if (ledgerHash == null) { | ||||
@@ -1,5 +1,6 @@ | |||||
package com.jd.blockchain.ledger.core.impl.handles; | package com.jd.blockchain.ledger.core.impl.handles; | ||||
import com.jd.blockchain.utils.jar.ContractJarUtils; | |||||
import org.springframework.stereotype.Service; | import org.springframework.stereotype.Service; | ||||
import com.jd.blockchain.ledger.BytesValue; | import com.jd.blockchain.ledger.BytesValue; | ||||
@@ -22,8 +23,12 @@ public class ContractCodeDeployOperationHandle implements OperationHandle { | |||||
// TODO: 请求者应该提供合约账户的公钥签名,已确定注册的地址的唯一性; | // TODO: 请求者应该提供合约账户的公钥签名,已确定注册的地址的唯一性; | ||||
byte[] chainCode = contractOP.getChainCode(); | |||||
// 校验合约代码,不通过会抛出异常 | |||||
ContractJarUtils.verify(chainCode); | |||||
dataset.getContractAccountSet().deploy(contractOP.getContractID().getAddress(), | dataset.getContractAccountSet().deploy(contractOP.getContractID().getAddress(), | ||||
contractOP.getContractID().getPubKey(), contractOP.getAddressSignature(), contractOP.getChainCode()); | |||||
contractOP.getContractID().getPubKey(), contractOP.getAddressSignature(), chainCode); | |||||
return null; | return null; | ||||
} | } | ||||
@@ -37,5 +42,4 @@ public class ContractCodeDeployOperationHandle implements OperationHandle { | |||||
public boolean support(Class<?> operationType) { | public boolean support(Class<?> operationType) { | ||||
return ContractCodeDeployOperation.class.isAssignableFrom(operationType); | return ContractCodeDeployOperation.class.isAssignableFrom(operationType); | ||||
} | } | ||||
} | } |
@@ -260,8 +260,6 @@ public class BlockchainOperationFactory implements ClientOperator, LedgerInitOpe | |||||
private class ContractCodeDeployOperationBuilderFilter implements ContractCodeDeployOperationBuilder { | private class ContractCodeDeployOperationBuilderFilter implements ContractCodeDeployOperationBuilder { | ||||
@Override | @Override | ||||
public ContractCodeDeployOperation deploy(BlockchainIdentity id, byte[] chainCode) { | public ContractCodeDeployOperation deploy(BlockchainIdentity id, byte[] chainCode) { | ||||
// 校验chainCode | |||||
ContractJarUtils.verify(chainCode); | |||||
// 校验成功后发布 | // 校验成功后发布 | ||||
ContractCodeDeployOperation op = CONTRACT_CODE_DEPLOY_OP_BUILDER.deploy(id, chainCode); | ContractCodeDeployOperation op = CONTRACT_CODE_DEPLOY_OP_BUILDER.deploy(id, chainCode); | ||||
operationList.add(op); | operationList.add(op); | ||||
@@ -15,13 +15,16 @@ import java.util.jar.JarOutputStream; | |||||
public class ContractJarUtils { | public class ContractJarUtils { | ||||
private static final String JDCHAIN_META = "META-INF/CONTRACT.MF"; | |||||
private static final String CONTRACT_MF = "META-INF/CONTRACT.MF"; | |||||
private static final int JDCHAIN_HASH_LENGTH = 69; | private static final int JDCHAIN_HASH_LENGTH = 69; | ||||
private static final Random FILE_RANDOM = new Random(); | private static final Random FILE_RANDOM = new Random(); | ||||
public static void verify(byte[] chainCode) { | public static void verify(byte[] chainCode) { | ||||
if (chainCode == null || chainCode.length == 0) { | |||||
throw new IllegalStateException("ChainCode is empty !!!"); | |||||
} | |||||
// 首先生成合约文件 | // 首先生成合约文件 | ||||
File jarFile = newJarFile(); | File jarFile = newJarFile(); | ||||
try { | try { | ||||
@@ -42,14 +45,14 @@ public class ContractJarUtils { | |||||
private static void verify(File jarFile) throws Exception { | private static void verify(File jarFile) throws Exception { | ||||
// 首先判断jarFile中是否含有META-INF/JDCHAIN.TXT,并将其读出 | // 首先判断jarFile中是否含有META-INF/JDCHAIN.TXT,并将其读出 | ||||
URL jarUrl = new URL("jar:file:" + jarFile.getPath() + "!/" + JDCHAIN_META); | |||||
URL jarUrl = new URL("jar:file:" + jarFile.getPath() + "!/" + CONTRACT_MF); | |||||
InputStream inputStream = jarUrl.openStream(); | InputStream inputStream = jarUrl.openStream(); | ||||
if (inputStream == null) { | if (inputStream == null) { | ||||
throw new IllegalStateException(JDCHAIN_META + " IS NULL !!!"); | |||||
throw new IllegalStateException(CONTRACT_MF + " IS NULL !!!"); | |||||
} | } | ||||
byte[] bytes = IOUtils.toByteArray(inputStream); | byte[] bytes = IOUtils.toByteArray(inputStream); | ||||
if (bytes == null || bytes.length != JDCHAIN_HASH_LENGTH) { | if (bytes == null || bytes.length != JDCHAIN_HASH_LENGTH) { | ||||
throw new IllegalStateException(JDCHAIN_META + " IS Illegal !!!"); | |||||
throw new IllegalStateException(CONTRACT_MF + " IS Illegal !!!"); | |||||
} | } | ||||
// 获取对应的Hash内容 | // 获取对应的Hash内容 | ||||
String txt = new String(bytes, StandardCharsets.UTF_8); | String txt = new String(bytes, StandardCharsets.UTF_8); | ||||
@@ -58,10 +61,10 @@ public class ContractJarUtils { | |||||
File tempJar = newJarFile(); | File tempJar = newJarFile(); | ||||
// 复制除JDCHAIN.TXT之外的部分 | // 复制除JDCHAIN.TXT之外的部分 | ||||
copy(jarFile, tempJar, null, null, JDCHAIN_META); | |||||
copy(jarFile, tempJar, null, null, CONTRACT_MF); | |||||
// 生成新Jar包对应的Hash内容 | // 生成新Jar包对应的Hash内容 | ||||
String verifyTxt = jdChainTxt(FileUtils.readFileToByteArray(tempJar)); | |||||
String verifyTxt = contractMF(FileUtils.readFileToByteArray(tempJar)); | |||||
// 删除临时文件 | // 删除临时文件 | ||||
FileUtils.forceDelete(tempJar); | FileUtils.forceDelete(tempJar); | ||||
@@ -103,13 +106,13 @@ public class ContractJarUtils { | |||||
jarFile.close(); | jarFile.close(); | ||||
} | } | ||||
public static String jdChainTxt(byte[] content) { | |||||
public static String contractMF(byte[] content) { | |||||
// hash=Hex(hash(content)) | // hash=Hex(hash(content)) | ||||
return "hash:" + DigestUtils.sha256Hex(content); | return "hash:" + DigestUtils.sha256Hex(content); | ||||
} | } | ||||
public static JarEntry jdChainMetaTxtJarEntry() { | |||||
return new JarEntry(JDCHAIN_META); | |||||
public static JarEntry contractMFJarEntry() { | |||||
return new JarEntry(CONTRACT_MF); | |||||
} | } | ||||
private static byte[] readStream(InputStream inputStream) { | private static byte[] readStream(InputStream inputStream) { | ||||
@@ -34,14 +34,14 @@ public class ContractJarUtilsTest { | |||||
// 首先进行Copy处理 | // 首先进行Copy处理 | ||||
copy(srcJar, dstJar); | copy(srcJar, dstJar); | ||||
byte[] txtBytes = jdChainTxt(FileUtils.readFileToByteArray(dstJar)).getBytes(StandardCharsets.UTF_8); | |||||
byte[] txtBytes = contractMF(FileUtils.readFileToByteArray(dstJar)).getBytes(StandardCharsets.UTF_8); | |||||
String finalJarPath = classPath + | String finalJarPath = classPath + | ||||
File.separator + jarName + "-jdchain.jar"; | File.separator + jarName + "-jdchain.jar"; | ||||
File finalJar = new File(finalJarPath); | File finalJar = new File(finalJarPath); | ||||
copy(dstJar, finalJar, jdChainMetaTxtJarEntry(), txtBytes, null); | |||||
copy(dstJar, finalJar, contractMFJarEntry(), txtBytes, null); | |||||
// 删除临时文件 | // 删除临时文件 | ||||
FileUtils.forceDelete(dstJar); | FileUtils.forceDelete(dstJar); | ||||