diff --git a/source/contract/contract-maven-plugin/pom.xml b/source/contract/contract-maven-plugin/pom.xml
index 7ba6a4f4..63f0e64c 100644
--- a/source/contract/contract-maven-plugin/pom.xml
+++ b/source/contract/contract-maven-plugin/pom.xml
@@ -103,27 +103,27 @@
maven-plugin-plugin
3.5
-
-
- org.apache.maven.plugins
- maven-compiler-plugin
-
-
- 1.8
- UTF-8
- false
- true
- false
- false
-
-
-
- org.apache.maven.plugins
- maven-surefire-plugin
-
- true
-
-
-
-
+
+
+
diff --git a/source/contract/contract-maven-plugin/src/main/java/com/jd/blockchain/ContractCheckMojo.java b/source/contract/contract-maven-plugin/src/main/java/com/jd/blockchain/ContractCheckMojo.java
index 1403e079..a57357e0 100644
--- a/source/contract/contract-maven-plugin/src/main/java/com/jd/blockchain/ContractCheckMojo.java
+++ b/source/contract/contract-maven-plugin/src/main/java/com/jd/blockchain/ContractCheckMojo.java
@@ -1,6 +1,5 @@
package com.jd.blockchain;
-import com.jd.blockchain.ledger.BlockchainKeyGenerator;
import org.apache.commons.io.FileUtils;
import org.apache.maven.model.Model;
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.MavenXpp3Writer;
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.Parameter;
import org.apache.maven.project.MavenProject;
@@ -22,11 +22,12 @@ import java.util.Collections;
import java.util.List;
-@Mojo(name = "Contract.Check")
+@Mojo(name = "contractCheck")
public class ContractCheckMojo extends AbstractMojo {
+
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";
@@ -36,11 +37,11 @@ public class ContractCheckMojo extends AbstractMojo {
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 OUT_POM_XML = "OutPom.xml";
+ private static final String OUT_POM_XML = "ContractPom.xml";
@Parameter(defaultValue = "${project}", required = true, readonly = true)
private MavenProject project;
@@ -51,7 +52,6 @@ public class ContractCheckMojo extends AbstractMojo {
@Parameter
private String finalName;
-
/**
* mainClass;
*/
@@ -73,11 +73,11 @@ public class ContractCheckMojo extends AbstractMojo {
* first compile the class, then parse it;
*/
@Override
- public void execute() {
+ public void execute() throws MojoFailureException {
compileFiles();
}
- private void compileFiles(){
+ private void compileFiles() throws MojoFailureException {
try (FileInputStream fis = new FileInputStream(project.getFile())) {
MavenXpp3Reader reader = new MavenXpp3Reader();
@@ -107,7 +107,7 @@ public class ContractCheckMojo extends AbstractMojo {
} catch (Exception e) {
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.setId(id);
pluginExecution.setPhase(phase);
- List goals = new ArrayList<>();
+ List goals = new ArrayList<>();
goals.add(goal);
pluginExecution.setGoals(goals);
List pluginExecutions = new ArrayList<>();
diff --git a/source/contract/contract-maven-plugin/src/main/java/com/jd/blockchain/ContractVerifyMojo.java b/source/contract/contract-maven-plugin/src/main/java/com/jd/blockchain/ContractVerifyMojo.java
index 28d5a1fb..950eb9bc 100644
--- a/source/contract/contract-maven-plugin/src/main/java/com/jd/blockchain/ContractVerifyMojo.java
+++ b/source/contract/contract-maven-plugin/src/main/java/com/jd/blockchain/ContractVerifyMojo.java
@@ -3,37 +3,25 @@ package com.jd.blockchain;
import com.github.javaparser.JavaParser;
import com.github.javaparser.ast.CompilationUnit;
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.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.IOUtils;
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.Parameter;
import org.apache.maven.project.MavenProject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.springframework.util.ResourceUtils;
import java.io.*;
import java.net.URL;
import java.net.URLClassLoader;
import java.nio.charset.StandardCharsets;
-import java.nio.file.Files;
-import java.nio.file.Path;
import java.util.*;
import java.util.jar.Attributes;
import java.util.jar.JarEntry;
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.utils.decompiler.utils.DecompilerUtils.decompileJarFile;
@@ -78,12 +66,15 @@ public class ContractVerifyMojo extends AbstractMojo {
private static final String BLACK_NAME_LIST = "black.name.list";
@Override
- public void execute() throws MojoFailureException {
+ public void execute() throws MojoExecutionException {
try {
File jarFile = copyAndManage();
+ // 首先校验MainClass
+ verifyMainClass(jarFile);
+
Properties config = loadConfig();
List blackNameList = blackNameList(config);
@@ -193,23 +184,25 @@ public class ContractVerifyMojo extends AbstractMojo {
if (!isOK) {
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 {
throw new IllegalStateException("There is none class !!!");
}
} catch (Exception e) {
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 blackNameList(Properties config) {
return blackList(config, BLACK_NAME_LIST);
}
@@ -320,14 +313,14 @@ public class ContractVerifyMojo extends AbstractMojo {
// 首先进行Copy处理
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() +
File.separator + finalName + "-jdchain.jar";
File finalJar = new File(finalJarPath);
- copy(dstJar, finalJar, jdChainMetaTxtJarEntry(), txtBytes, null);
+ copy(dstJar, finalJar, contractMFJarEntry(), txtBytes, null);
// 删除临时文件
FileUtils.forceDelete(dstJar);
@@ -423,8 +416,9 @@ public class ContractVerifyMojo extends AbstractMojo {
if (totalPackage.endsWith("*")) {
this.packageName = totalPackage.substring(0, totalPackage.length() - 2).trim();
this.isTotal = true;
+ } else {
+ this.packageName = totalPackage;
}
- this.packageName = totalPackage;
}
public String getPackageName() {
diff --git a/source/contract/contract-maven-plugin/src/main/resources/config.properties b/source/contract/contract-maven-plugin/src/main/resources/config.properties
index 4a176409..b54de2fb 100644
--- a/source/contract/contract-maven-plugin/src/main/resources/config.properties
+++ b/source/contract/contract-maven-plugin/src/main/resources/config.properties
@@ -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=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=java.util.Random, com.jd.blockchain.ledger.BlockchainKeyGenerator
\ No newline at end of file
diff --git a/source/contract/contract-maven-plugin/src/test/java/com/jd/blockchain/ledger/ContractVerifyTest.java b/source/contract/contract-maven-plugin/src/test/java/com/jd/blockchain/ledger/ContractVerifyTest.java
index dc5d2541..d57ab5d0 100644
--- a/source/contract/contract-maven-plugin/src/test/java/com/jd/blockchain/ledger/ContractVerifyTest.java
+++ b/source/contract/contract-maven-plugin/src/test/java/com/jd/blockchain/ledger/ContractVerifyTest.java
@@ -18,7 +18,7 @@ public class ContractVerifyTest {
@Before
public void testInit() {
project = mavenProjectInit();
- finalName = "complex.jar";
+ finalName = "complex";
}
@Test
diff --git a/source/gateway/src/main/java/com/jd/blockchain/gateway/service/GatewayInterceptServiceHandler.java b/source/gateway/src/main/java/com/jd/blockchain/gateway/service/GatewayInterceptServiceHandler.java
index b70bee5d..2f3d215e 100644
--- a/source/gateway/src/main/java/com/jd/blockchain/gateway/service/GatewayInterceptServiceHandler.java
+++ b/source/gateway/src/main/java/com/jd/blockchain/gateway/service/GatewayInterceptServiceHandler.java
@@ -5,6 +5,7 @@ import com.jd.blockchain.ledger.ContractCodeDeployOperation;
import com.jd.blockchain.ledger.Operation;
import com.jd.blockchain.ledger.TransactionRequest;
import com.jd.blockchain.utils.IllegalDataException;
+import com.jd.blockchain.utils.jar.ContractJarUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@@ -29,14 +30,7 @@ public class GatewayInterceptServiceHandler implements GatewayInterceptService {
}
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());
}
}
diff --git a/source/gateway/src/main/java/com/jd/blockchain/gateway/web/TxProcessingController.java b/source/gateway/src/main/java/com/jd/blockchain/gateway/web/TxProcessingController.java
index 3ee571d9..5405cc98 100644
--- a/source/gateway/src/main/java/com/jd/blockchain/gateway/web/TxProcessingController.java
+++ b/source/gateway/src/main/java/com/jd/blockchain/gateway/web/TxProcessingController.java
@@ -1,5 +1,6 @@
package com.jd.blockchain.gateway.web;
+import com.jd.blockchain.gateway.service.GatewayInterceptService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
@@ -30,9 +31,15 @@ public class TxProcessingController implements TransactionService {
@Autowired
private PeerService peerService;
+ @Autowired
+ private GatewayInterceptService interceptService;
+
@RequestMapping(path = "rpc/tx", method = RequestMethod.POST, consumes = BinaryMessageConverter.CONTENT_TYPE_VALUE, produces = BinaryMessageConverter.CONTENT_TYPE_VALUE)
@Override
public @ResponseBody TransactionResponse process(@RequestBody TransactionRequest txRequest) {
+ // 拦截请求进行校验
+ interceptService.intercept(txRequest);
+
// 检查交易请求的信息是否完整;
HashDigest ledgerHash = txRequest.getTransactionContent().getLedgerHash();
if (ledgerHash == null) {
diff --git a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/impl/handles/ContractCodeDeployOperationHandle.java b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/impl/handles/ContractCodeDeployOperationHandle.java
index e18c9304..fd4dc617 100644
--- a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/impl/handles/ContractCodeDeployOperationHandle.java
+++ b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/impl/handles/ContractCodeDeployOperationHandle.java
@@ -1,5 +1,6 @@
package com.jd.blockchain.ledger.core.impl.handles;
+import com.jd.blockchain.utils.jar.ContractJarUtils;
import org.springframework.stereotype.Service;
import com.jd.blockchain.ledger.BytesValue;
@@ -22,8 +23,12 @@ public class ContractCodeDeployOperationHandle implements OperationHandle {
// TODO: 请求者应该提供合约账户的公钥签名,已确定注册的地址的唯一性;
+ byte[] chainCode = contractOP.getChainCode();
+ // 校验合约代码,不通过会抛出异常
+ ContractJarUtils.verify(chainCode);
+
dataset.getContractAccountSet().deploy(contractOP.getContractID().getAddress(),
- contractOP.getContractID().getPubKey(), contractOP.getAddressSignature(), contractOP.getChainCode());
+ contractOP.getContractID().getPubKey(), contractOP.getAddressSignature(), chainCode);
return null;
}
@@ -37,5 +42,4 @@ public class ContractCodeDeployOperationHandle implements OperationHandle {
public boolean support(Class> operationType) {
return ContractCodeDeployOperation.class.isAssignableFrom(operationType);
}
-
}
diff --git a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/BlockchainOperationFactory.java b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/BlockchainOperationFactory.java
index a8f34045..93f0e3c7 100644
--- a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/BlockchainOperationFactory.java
+++ b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/BlockchainOperationFactory.java
@@ -260,8 +260,6 @@ public class BlockchainOperationFactory implements ClientOperator, LedgerInitOpe
private class ContractCodeDeployOperationBuilderFilter implements ContractCodeDeployOperationBuilder {
@Override
public ContractCodeDeployOperation deploy(BlockchainIdentity id, byte[] chainCode) {
- // 校验chainCode
- ContractJarUtils.verify(chainCode);
// 校验成功后发布
ContractCodeDeployOperation op = CONTRACT_CODE_DEPLOY_OP_BUILDER.deploy(id, chainCode);
operationList.add(op);
diff --git a/source/utils/utils-common/src/main/java/com/jd/blockchain/utils/jar/ContractJarUtils.java b/source/utils/utils-common/src/main/java/com/jd/blockchain/utils/jar/ContractJarUtils.java
index a59512db..5ec66dde 100644
--- a/source/utils/utils-common/src/main/java/com/jd/blockchain/utils/jar/ContractJarUtils.java
+++ b/source/utils/utils-common/src/main/java/com/jd/blockchain/utils/jar/ContractJarUtils.java
@@ -15,13 +15,16 @@ import java.util.jar.JarOutputStream;
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 Random FILE_RANDOM = new Random();
public static void verify(byte[] chainCode) {
+ if (chainCode == null || chainCode.length == 0) {
+ throw new IllegalStateException("ChainCode is empty !!!");
+ }
// 首先生成合约文件
File jarFile = newJarFile();
try {
@@ -42,14 +45,14 @@ public class ContractJarUtils {
private static void verify(File jarFile) throws Exception {
// 首先判断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();
if (inputStream == null) {
- throw new IllegalStateException(JDCHAIN_META + " IS NULL !!!");
+ throw new IllegalStateException(CONTRACT_MF + " IS NULL !!!");
}
byte[] bytes = IOUtils.toByteArray(inputStream);
if (bytes == null || bytes.length != JDCHAIN_HASH_LENGTH) {
- throw new IllegalStateException(JDCHAIN_META + " IS Illegal !!!");
+ throw new IllegalStateException(CONTRACT_MF + " IS Illegal !!!");
}
// 获取对应的Hash内容
String txt = new String(bytes, StandardCharsets.UTF_8);
@@ -58,10 +61,10 @@ public class ContractJarUtils {
File tempJar = newJarFile();
// 复制除JDCHAIN.TXT之外的部分
- copy(jarFile, tempJar, null, null, JDCHAIN_META);
+ copy(jarFile, tempJar, null, null, CONTRACT_MF);
// 生成新Jar包对应的Hash内容
- String verifyTxt = jdChainTxt(FileUtils.readFileToByteArray(tempJar));
+ String verifyTxt = contractMF(FileUtils.readFileToByteArray(tempJar));
// 删除临时文件
FileUtils.forceDelete(tempJar);
@@ -103,13 +106,13 @@ public class ContractJarUtils {
jarFile.close();
}
- public static String jdChainTxt(byte[] content) {
+ public static String contractMF(byte[] content) {
// hash=Hex(hash(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) {
diff --git a/source/utils/utils-common/src/test/java/test/my/utils/ContractJarUtilsTest.java b/source/utils/utils-common/src/test/java/test/my/utils/ContractJarUtilsTest.java
index 9caa6da2..02376434 100644
--- a/source/utils/utils-common/src/test/java/test/my/utils/ContractJarUtilsTest.java
+++ b/source/utils/utils-common/src/test/java/test/my/utils/ContractJarUtilsTest.java
@@ -34,14 +34,14 @@ public class ContractJarUtilsTest {
// 首先进行Copy处理
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 +
File.separator + jarName + "-jdchain.jar";
File finalJar = new File(finalJarPath);
- copy(dstJar, finalJar, jdChainMetaTxtJarEntry(), txtBytes, null);
+ copy(dstJar, finalJar, contractMFJarEntry(), txtBytes, null);
// 删除临时文件
FileUtils.forceDelete(dstJar);