diff --git a/source/base/src/main/java/com/jd/blockchain/consts/DataCodes.java b/source/base/src/main/java/com/jd/blockchain/consts/DataCodes.java index a7382d0a..48cffbc7 100644 --- a/source/base/src/main/java/com/jd/blockchain/consts/DataCodes.java +++ b/source/base/src/main/java/com/jd/blockchain/consts/DataCodes.java @@ -90,6 +90,7 @@ public interface DataCodes { public static final int CONTRACT_BIG_INT = 0xA07; //...0xA19 public static final int CONTRACT_BIZ_CONTENT = 0xA20; + public static final int CONTRACT_ARGS = 0xA21; public static final int HASH = 0xB00; diff --git a/source/contract/contract-maven-plugin/pom.xml b/source/contract/contract-maven-plugin/pom.xml index 0a357e52..626790d1 100644 --- a/source/contract/contract-maven-plugin/pom.xml +++ b/source/contract/contract-maven-plugin/pom.xml @@ -10,6 +10,10 @@ contract-maven-plugin maven-plugin + + 3.3.9 + + com.jd.blockchain @@ -35,32 +39,54 @@ ${project.version} - - - org.apache.maven.plugin-tools - maven-plugin-annotations - 3.6.0 - provided + com.github.javaparser + javaparser-core + ${javaparser.version} + org.apache.maven maven-plugin-api - 2.0 + 3.3.9 org.apache.maven - maven-project - 2.0.6 + maven-core + 3.3.9 - - com.github.javaparser - javaparser-core - ${javaparser.version} + org.apache.maven + maven-artifact + 3.3.9 + provided + + + org.apache.maven + maven-compat + 3.3.9 + + + junit + junit + 4.12 + test + + + org.apache.maven.plugin-testing + maven-plugin-testing-harness + test + 3.3.0 + + + org.apache.maven.plugin-tools + maven-plugin-annotations + 3.6.0 + provided + diff --git a/source/contract/contract-maven-plugin/src/main/java/com/jd/blockchain/CheckImportsMojo.java b/source/contract/contract-maven-plugin/src/main/java/com/jd/blockchain/CheckImportsMojo.java index 7c62b31c..4f9279a7 100644 --- a/source/contract/contract-maven-plugin/src/main/java/com/jd/blockchain/CheckImportsMojo.java +++ b/source/contract/contract-maven-plugin/src/main/java/com/jd/blockchain/CheckImportsMojo.java @@ -49,6 +49,7 @@ public class CheckImportsMojo extends AbstractMojo { } } } + } } catch (IOException exception) { logger.error(exception.getMessage()); diff --git a/source/contract/contract-maven-plugin/src/test/java/com/jd/blockchain/ledger/CheckImportsMojoTest.java b/source/contract/contract-maven-plugin/src/test/java/com/jd/blockchain/ledger/CheckImportsMojoTest.java index 9a91e4f6..8cdce97a 100644 --- a/source/contract/contract-maven-plugin/src/test/java/com/jd/blockchain/ledger/CheckImportsMojoTest.java +++ b/source/contract/contract-maven-plugin/src/test/java/com/jd/blockchain/ledger/CheckImportsMojoTest.java @@ -1,32 +1,28 @@ package com.jd.blockchain.ledger; import com.jd.blockchain.CheckImportsMojo; +import org.apache.maven.plugin.testing.AbstractMojoTestCase; import org.junit.Test; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.io.IOException; -import java.io.InputStream; -import java.util.Arrays; -import java.util.Properties; +import java.io.File; /** * @Author zhaogw * @Date 2019/3/1 21:27 */ -public class CheckImportsMojoTest { +public class CheckImportsMojoTest extends AbstractMojoTestCase { Logger logger = LoggerFactory.getLogger(CheckImportsMojo.class); @Test - public void test1() { - try { - InputStream inputStream = CheckImportsMojo.class.getClassLoader().getResourceAsStream("config.properties"); - Properties properties = new Properties(); - properties.load(inputStream); - String result[] = properties.getProperty("blacklist").split(","); - logger.info(Arrays.toString(result).toString()); - } catch (IOException e) { - logger.error(e.getMessage()); - } + public void test1() throws Exception { + File pom = getTestFile( "src/test/resources/project-to-test/pom.xml" ); + assertNotNull( pom ); + assertTrue( pom.exists() ); + + CheckImportsMojo myMojo = (CheckImportsMojo) lookupMojo( "checkImports", pom ); + assertNotNull( myMojo ); + myMojo.execute(); } } diff --git a/source/contract/contract-maven-plugin/src/test/java/com/jd/blockchain/ledger/MyProjectStub.java b/source/contract/contract-maven-plugin/src/test/java/com/jd/blockchain/ledger/MyProjectStub.java new file mode 100644 index 00000000..473115af --- /dev/null +++ b/source/contract/contract-maven-plugin/src/test/java/com/jd/blockchain/ledger/MyProjectStub.java @@ -0,0 +1,67 @@ +package com.jd.blockchain.ledger; + +import org.apache.maven.model.Build; +import org.apache.maven.model.Model; +import org.apache.maven.model.io.xpp3.MavenXpp3Reader; +import org.apache.maven.plugin.testing.stubs.MavenProjectStub; +import org.codehaus.plexus.util.ReaderFactory; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; + +/** + * @author zhaogw + * date 2019/6/4 18:33 + */ + +public class MyProjectStub extends MavenProjectStub +{ + /** + * Default constructor + */ + public MyProjectStub() + { + MavenXpp3Reader pomReader = new MavenXpp3Reader(); + Model model; + try + { + model = pomReader.read( ReaderFactory.newXmlReader( new File( getBasedir(), "pom.xml" ) ) ); + setModel( model ); + } + catch ( Exception e ) + { + throw new RuntimeException( e ); + } + + setGroupId( model.getGroupId() ); + setArtifactId( model.getArtifactId() ); + setVersion( model.getVersion() ); + setName( model.getName() ); + setUrl( model.getUrl() ); + setPackaging( model.getPackaging() ); + + Build build = new Build(); + build.setFinalName( model.getArtifactId() ); + build.setDirectory( getBasedir() + "/target" ); + build.setSourceDirectory( getBasedir() + "/src/main/java" ); + build.setOutputDirectory( getBasedir() + "/target/classes" ); + build.setTestSourceDirectory( getBasedir() + "/src/test/java" ); + build.setTestOutputDirectory( getBasedir() + "/target/test-classes" ); + setBuild( build ); + + List compileSourceRoots = new ArrayList(); + compileSourceRoots.add( getBasedir() + "/src/main/java" ); + setCompileSourceRoots( compileSourceRoots ); + + List testCompileSourceRoots = new ArrayList(); + testCompileSourceRoots.add( getBasedir() + "/src/test/java" ); + setTestCompileSourceRoots( testCompileSourceRoots ); + } + + /** {@inheritDoc} */ + public File getBasedir() + { + return new File( super.getBasedir() + "/src/test/resources/project-to-test/" ); + } +} diff --git a/source/contract/contract-maven-plugin/src/test/resources/project-to-test/AssetContract2.java b/source/contract/contract-maven-plugin/src/test/resources/project-to-test/AssetContract2.java new file mode 100644 index 00000000..b597558e --- /dev/null +++ b/source/contract/contract-maven-plugin/src/test/resources/project-to-test/AssetContract2.java @@ -0,0 +1,40 @@ +package com.jd.blockchain.contract; + +import com.jd.blockchain.ledger.ContractBizContent; +import com.jd.blockchain.utils.Bytes; + +/** + * 示例:一个“资产管理”智能合约; + * + * @author zhaogw + */ +@Contract +public interface AssetContract2 { + + /** + * 发行资产; + * 新发行的资产数量; + * @param assetHolderAddress + * 新发行的资产的持有账户; + */ + @ContractEvent(name = "issue-asset-0") + void issue(ContractBizContent contractBizContent, String assetHolderAddress); + + /** + * 发行资产; + * 新发行的资产数量; + * @param assetHolderAddress + * 新发行的资产的持有账户; + */ + @ContractEvent(name = "issue-asset") + void issue(ContractBizContent contractBizContent, String assetHolderAddress, long cashNumber); + + @ContractEvent(name = "issue-asset-2") + void issue(Bytes bytes, String assetHolderAddress, long cashNumber); + + @ContractEvent(name = "issue-asset-3") + void issue(Byte byteObj, String assetHolderAddress, long cashNumber); + + @ContractEvent(name = "issue-asset-4") + void issue(Byte byteObj, String assetHolderAddress, Bytes cashNumber); +} \ No newline at end of file diff --git a/source/contract/contract-maven-plugin/src/test/resources/project-to-test/AssetContractImpl2.java b/source/contract/contract-maven-plugin/src/test/resources/project-to-test/AssetContractImpl2.java new file mode 100644 index 00000000..06af2632 --- /dev/null +++ b/source/contract/contract-maven-plugin/src/test/resources/project-to-test/AssetContractImpl2.java @@ -0,0 +1,99 @@ +package com.jd.blockchain.contract; + +import com.jd.blockchain.ledger.ContractBizContent; +import com.jd.blockchain.ledger.KVDataEntry; +import com.jd.blockchain.ledger.KVDataObject; +import com.jd.blockchain.utils.Bytes; + +import java.util.Arrays; + +/** + * 示例:一个“资产管理”智能合约的实现; + * + * 注: 1、实现 EventProcessingAwire 接口以便合约实例在运行时可以从上下文获得合约生命周期事件的通知; 2、实现 + * AssetContract 接口定义的合约方法; + * + * @author huanghaiquan + * + */ +@Contract +public class AssetContractImpl2 implements EventProcessingAwire, AssetContract2 { + public static String KEY_TOTAL = "total"; + // 合约事件上下文; + private ContractEventContext eventContext; + + @Override + @ContractEvent(name = "issue-asset-0") + public void issue(ContractBizContent contractBizContent, String assetHolderAddress) { + System.out.println("input addr="+ Arrays.toString(contractBizContent.getAttrs())); + } + + @Override + @ContractEvent(name = "issue-asset") + public void issue(ContractBizContent contractBizContent, String assetHolderAddress, long cashNumber) { + System.out.println("eventContext="+eventContext.getCurrentLedgerHash().toBase58()); + System.out.println("getAttrs: "+Arrays.toString(contractBizContent.getAttrs())+",address="+assetHolderAddress+",cashNumber="+cashNumber); + + eventContext.getLedger().dataAccount(assetHolderAddress).set(contractBizContent.getAttrs()[0], "value1",-1); + eventContext.getLedger().dataAccount(assetHolderAddress).set(contractBizContent.getAttrs()[1], 888,-1); + } + + @Override + @ContractEvent(name = "issue-asset-2") + public void issue(Bytes bytes, String assetHolderAddress, long cashNumber){ + System.out.println(String.format("bytes=%s,assetHolderAddress=%s,cashNumber=%d",new String(bytes.toBytes()),assetHolderAddress,cashNumber)); + } + + @ContractEvent(name = "issue-asset-3") + @Override + public void issue(Byte byteObj, String assetHolderAddress, long cashNumber) { + System.out.println(String.format("issue(),bytes=%d,assetHolderAddress=%s,cashNumber=%d",byteObj.intValue(),assetHolderAddress,cashNumber)); + } + + @ContractEvent(name = "issue-asset-4") + @Override + public void issue(Byte byteObj, String assetHolderAddress, Bytes cashNumber) { + System.out.println(String.format("issue(),bytes=%d,assetHolderAddress=%s,cashNumber=%s",byteObj.intValue(),assetHolderAddress,cashNumber.toString())); + System.out.println("current LedgerHash="+eventContext.getCurrentLedgerHash().toBase58()); + // 查询当前值; + KVDataEntry[] kvEntries = eventContext.getLedger().getDataEntries(eventContext.getCurrentLedgerHash(), assetHolderAddress, KEY_TOTAL); +// 计算资产的发行总数; + KVDataObject curTotal = (KVDataObject) kvEntries[0]; + System.out.println("currTotal version="+curTotal.getVersion()+",value="+curTotal.getValue().toString()); + eventContext.getLedger().dataAccount(assetHolderAddress).set(KEY_TOTAL, 100,curTotal.getVersion()); + } + + /* + * (non-Javadoc) + * + * @see + * com.jd.blockchain.contract.model.EventProcessingAwire#beforeEvent(com.jd. + * blockchain.contract.model.ContractEventContext) + */ + @Override + public void beforeEvent(ContractEventContext eventContext) { + this.eventContext = eventContext; + } + + /* + * (non-Javadoc) + * + * @see com.jd.blockchain.contract.model.EventProcessingAwire#postEvent(com.jd. + * blockchain.contract.model.ContractEventContext, + * com.jd.blockchain.contract.model.ContractError) + */ + @Override + public void postEvent(ContractEventContext eventContext, ContractException error) { + this.eventContext = null; + } + + @Override + public void postEvent(ContractException error) { + + } + + @Override + public void postEvent() { + + } +} diff --git a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/ContractArgs.java b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/ContractArgs.java new file mode 100644 index 00000000..9cce0cee --- /dev/null +++ b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/ContractArgs.java @@ -0,0 +1,14 @@ +package com.jd.blockchain.ledger; +import com.jd.blockchain.binaryproto.DataContract; +import com.jd.blockchain.consts.DataCodes; + +import java.lang.reflect.Method; + +/** + * contract's args; + */ +@DataContract(code = DataCodes.CONTRACT_ARGS) +public interface ContractArgs { + Method getMethod(); + Object[] getArgs(); +} diff --git a/source/sdk/sdk-samples/src/test/java/test/com/jd/blockchain/sdk/test/SDK_Contract_Test.java b/source/sdk/sdk-samples/src/test/java/test/com/jd/blockchain/sdk/test/SDK_Contract_Test.java index 359b4dd4..9a1ff31d 100644 --- a/source/sdk/sdk-samples/src/test/java/test/com/jd/blockchain/sdk/test/SDK_Contract_Test.java +++ b/source/sdk/sdk-samples/src/test/java/test/com/jd/blockchain/sdk/test/SDK_Contract_Test.java @@ -18,10 +18,12 @@ import org.junit.Test; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.core.io.ClassPathResource; +import org.springframework.util.ReflectionUtils; import java.io.File; import java.io.FileInputStream; import java.io.IOException; +import java.lang.reflect.Method; import static org.junit.Assert.*; @@ -351,4 +353,24 @@ public class SDK_Contract_Test { ContractBizContent actualObj = BinaryProtocol.decodeAs(bizBytes,ContractBizContent.class); assertArrayEquals(contractBizContent.getAttrs(),actualObj.getAttrs()); } + + @Test + public void testContractArgs(){ + ContractBizContent contractBizContent = () -> new String[]{"param1"}; + Method method = ReflectionUtils.findMethod(AssetContract2.class,"issue",ContractBizContent.class,String.class); + ContractArgs contractArgs = new ContractArgs() { + @Override + public Method getMethod() { + return method; + } + + @Override + public Object[] getArgs() { + return new Object[]{contractBizContent,"hello"}; + } + }; + + //add the annotation; + + } }