From 52ad61c4e62a70ce5720555d6d61d3e3b7597a25 Mon Sep 17 00:00:00 2001 From: zhaoguangwei Date: Fri, 31 May 2019 11:40:42 +0800 Subject: [PATCH] IntegrationTest4Contract.java can run OK. for String[]; --- .../contract/ContractSerializeUtils.java | 25 +++--- .../blockchain/ledger/ContractBizContent.java | 25 +----- .../transaction/ContractInvocationProxy.java | 1 - .../sdk/test/SDK_Contract_Test.java | 71 ++++++++++++------ .../src/test/resources/contract.jar | Bin 7914 -> 7937 bytes 5 files changed, 63 insertions(+), 59 deletions(-) diff --git a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/contract/ContractSerializeUtils.java b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/contract/ContractSerializeUtils.java index 2a09cd1b..da3297bf 100644 --- a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/contract/ContractSerializeUtils.java +++ b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/contract/ContractSerializeUtils.java @@ -7,7 +7,7 @@ import com.jd.blockchain.ledger.*; import com.jd.blockchain.utils.Bytes; import com.jd.blockchain.utils.IllegalDataException; import org.springframework.util.ReflectionUtils; -import java.math.BigDecimal; + import java.nio.ByteBuffer; import java.util.Arrays; import java.util.HashMap; @@ -110,6 +110,11 @@ public class ContractSerializeUtils { } + /** + * the param types that we can support; + * @param + * @return + */ public static Map > getDataIntf(){ DATA_CONTRACT_MAP.put(DataCodes.CONTRACT_INT8, CONTRACT_INT8.class); DATA_CONTRACT_MAP.put(DataCodes.CONTRACT_INT16, CONTRACT_INT16.class); @@ -128,6 +133,7 @@ public class ContractSerializeUtils { private static Object regenObj(DataContract dataContract, Object object){ if(getDataIntf().get(dataContract.code()).equals(CONTRACT_INT8.class)){ + return (CONTRACT_INT8) () -> Byte.parseByte(object.toString()); }else if(getDataIntf().get(dataContract.code()).equals(CONTRACT_INT16.class)){ return (CONTRACT_INT16) () -> Short.parseShort(object.toString()); @@ -139,8 +145,6 @@ public class ContractSerializeUtils { return (CONTRACT_TEXT) () -> object.toString(); }else if(getDataIntf().get(dataContract.code()).equals(CONTRACT_BINARY.class)){ return (CONTRACT_BINARY) () -> (Bytes) object; - }else if(getDataIntf().get(dataContract.code()).equals(CONTRACT_BIG_INT.class)){ - return (CONTRACT_BIG_INT) () -> new BigDecimal(object.toString()); }else if(getDataIntf().get(dataContract.code()).equals(ContractBizContent.class)){ ContractBizContent contractBizContent = (ContractBizContent)object; return contractBizContent; @@ -169,26 +173,19 @@ public class ContractSerializeUtils { return CONTRACT_TEXT.class; }else if(classType.equals(Bytes.class)){ return CONTRACT_BINARY.class; - }else if(classType.equals(BigDecimal.class)){ - return CONTRACT_BIG_INT.class; + }else { + throw new IllegalDataException(String.format("no support the classType=%s, please check @DataContract.",classType.toString())); } - return null; } public static DataContract parseDataContract(Class classType){ - DataContract dataContract = classType.getDeclaredAnnotation(DataContract.class); + DataContract dataContract = classType.getAnnotation(DataContract.class); //if the param's class Type don't contain @DataContract, then check parameterAnnotations of this method. if(dataContract == null){ boolean canPass = false; //if parameterAnnotations don't contain @DataContract, is it primitive type? Class contractType = getContractTypeByPrimitiveType(classType); - dataContract = contractType.getDeclaredAnnotation(DataContract.class); - if(dataContract != null){ - canPass = true; - } - if(!canPass){ - throw new IllegalArgumentException("must set @DataContract for each param of contract."); - } + dataContract = contractType.getAnnotation(DataContract.class); } if(!getDataIntf().containsKey(dataContract.code())){ throw new IllegalArgumentException(String.format( diff --git a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/ContractBizContent.java b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/ContractBizContent.java index ab2ff4c3..56e6bc24 100644 --- a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/ContractBizContent.java +++ b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/ContractBizContent.java @@ -4,34 +4,17 @@ import com.jd.blockchain.binaryproto.DataContract; import com.jd.blockchain.binaryproto.DataField; import com.jd.blockchain.binaryproto.PrimitiveType; import com.jd.blockchain.consts.DataCodes; -import com.jd.blockchain.crypto.HashDigest; /** - * build complex param Object; + * build complex param Object, provide more String attributes; */ @DataContract(code = DataCodes.CONTRACT_BIZ_CONTENT) public interface ContractBizContent { - - /** - * 执行交易的账本地址; - * 注:除了账本的创世交易之外,任何交易的账本地址都不允许为 null; - * - * @return - */ - @DataField(order = 1, primitiveType = PrimitiveType.BYTES) - HashDigest getLedgerHash(); - /** - * 地址; + * param lists; * @return */ - @DataField(order = 2, primitiveType = PrimitiveType.TEXT) - String getAddr(); + @DataField(order = 1, list = true, primitiveType = PrimitiveType.TEXT, genericContract = true) + String[] getAttrs(); - /** - * 年龄; - * @return - */ - @DataField(order = 3, primitiveType = PrimitiveType.INT32) - int getAge(); } diff --git a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/ContractInvocationProxy.java b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/ContractInvocationProxy.java index acabd5b4..f5f83708 100644 --- a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/ContractInvocationProxy.java +++ b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/ContractInvocationProxy.java @@ -46,7 +46,6 @@ public class ContractInvocationProxy implements InvocationHandler { } private byte[] serializeArgs(Object[] args, Method method) { - // TODO 根据方法参数的定义序列化参数; if(args == null || args.length==0){ return null; } 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 12954711..76bdceed 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 @@ -1,12 +1,11 @@ package test.com.jd.blockchain.sdk.test; +import com.jd.blockchain.binaryproto.BinaryProtocol; import com.jd.blockchain.contract.samples.AssetContract; import com.jd.blockchain.contract.samples.AssetContract2; import com.jd.blockchain.crypto.*; -import com.jd.blockchain.crypto.service.classic.ClassicAlgorithm; import com.jd.blockchain.ledger.*; import com.jd.blockchain.sdk.BlockchainService; -import com.jd.blockchain.sdk.BlockchainServiceFactory; import com.jd.blockchain.sdk.client.GatewayServiceFactory; import com.jd.blockchain.sdk.samples.SDKDemo_Contract; import com.jd.blockchain.utils.Bytes; @@ -23,7 +22,6 @@ import org.springframework.core.io.ClassPathResource; import java.io.File; import java.io.FileInputStream; import java.io.IOException; -import java.math.BigDecimal; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; @@ -66,36 +64,20 @@ public class SDK_Contract_Test { /** * 演示合约执行的过程; */ -// @Test + @Test public void demoContract1() { String dataAddress = registerData4Contract(); // 发起交易; TransactionTemplate txTemp = bcsrv.newTransaction(ledgerHash); String contractAddress = "LdeNg8JHFCKABJt6AaRNVCZPgY4ofGPd8MgcR"; AssetContract2 assetContract = txTemp.contract(contractAddress, AssetContract2.class); - ContractBizContent contractBizContent = new ContractBizContent() { - @Override - public HashDigest getLedgerHash() { - return new HashDigest(ClassicAlgorithm.SHA256, "zhaogw".getBytes()); - } - - @Override - public String getAddr() { - return "jinghailu street."; - } - - @Override - public int getAge() { - return 100; - } - }; // assetContract.issue(transactionContentBody,contractAddress); // assetContract.issue(transactionContentBody,contractAddress,888888); // assetContract.issue(Bytes.fromString("zhaogw, contract based interface is OK!"),contractAddress,77777); // assetContract.issue(Bytes.fromString("zhaogw, contract based interface is OK!"),contractAddress,77777); Byte byteObj = Byte.parseByte("127"); assetContract.issue(byteObj,dataAddress,321123); - assetContract.issue(contractBizContent,dataAddress); +// assetContract.issue(contractBizContent,dataAddress); assetContract.issue(Byte.parseByte("126"),dataAddress,Bytes.fromString("100.234")); // TX 准备就绪; @@ -109,6 +91,34 @@ public class SDK_Contract_Test { assertEquals("100",dataEntries[0].getValue().toString()); } + /** + * 演示合约执行的过程; + */ + @Test + public void demoContract2() throws IOException { + String contractAddress = deploy(); + String dataAddress = registerData4Contract(); + System.out.println("dataAddress="+dataAddress); + // 发起交易; + TransactionTemplate txTemp = bcsrv.newTransaction(ledgerHash); + + AssetContract2 assetContract = txTemp.contract(contractAddress, AssetContract2.class); + ContractBizContent contractBizContent = () -> new String[]{"param1","param2"}; + assetContract.issue(contractBizContent,dataAddress,123456); + + // TX 准备就绪; + PreparedTransaction prepTx = txTemp.prepare(); + prepTx.sign(signKeyPair); + // 提交交易; + TransactionResponse transactionResponse = prepTx.commit(); + + //check; + assertTrue(transactionResponse.isSuccess()); + KVDataEntry[] dataEntries = bcsrv.getDataEntries(ledgerHash,dataAddress,contractBizContent.getAttrs()[0],contractBizContent.getAttrs()[1]); + assertEquals("value1",dataEntries[0].getValue().toString()); + assertEquals(888,dataEntries[1].getValue()); + } + @Test public void registerData(){ // 在本地定义 TX 模板 @@ -146,6 +156,8 @@ public class SDK_Contract_Test { BlockchainKeypair dataAccount = BlockchainKeyGenerator.getInstance().generate(); txTemp.dataAccounts().register(dataAccount.getIdentity()); txTemp.dataAccount(dataAccount.getAddress()).set("total", 200, -1); + txTemp.dataAccount(dataAccount.getAddress()).set("param1", "v", -1); + txTemp.dataAccount(dataAccount.getAddress()).set("param2", 123, -1); // TX 准备就绪; PreparedTransaction prepTx = txTemp.prepare(); prepTx.sign(signKeyPair); @@ -173,8 +185,7 @@ public class SDK_Contract_Test { assertTrue(transactionResponse.isSuccess()); } - @Test - public void deploy() throws IOException { + private String deploy() throws IOException { ClassPathResource classPathResource = new ClassPathResource("contract.jar"); byte[] chainCode = this.getChainCode(classPathResource.getURL().getPath()); TransactionTemplate txTpl = this.bcsrv.newTransaction(ledgerHash); @@ -186,6 +197,7 @@ public class SDK_Contract_Test { System.out.println("contract's address=" + contractIdentity.getAddress()); String contractAddr = contractIdentity.getAddress().toBase58(); log.info("contractAddr="+contractAddr); + return contractAddr; } public byte[] getChainCode(String path) { @@ -333,4 +345,17 @@ public class SDK_Contract_Test { } + @Test + public void testStringArr(){ + String[] strArr = {"1","2","you are welcome!"}; + ContractBizContent contractBizContent = new ContractBizContent() { + @Override + public String[] getAttrs() { + return strArr; + } + }; + byte[] bizBytes = BinaryProtocol.encode(contractBizContent,ContractBizContent.class); + ContractBizContent actualObj = BinaryProtocol.decodeAs(bizBytes,ContractBizContent.class); + assertEquals(contractBizContent,actualObj); + } } diff --git a/source/sdk/sdk-samples/src/test/resources/contract.jar b/source/sdk/sdk-samples/src/test/resources/contract.jar index 3f21f9b388229093ba00383b91e01b4389f40378..3ff8a821d9f4980f3a642b3b392901b723979a78 100644 GIT binary patch delta 2113 zcmV-H2)_5~J%K(AP)h>@3IG5A002izzmW|j14c`~u{1pa14T=}lXL+#14T=}v#kL? z0Ru%#zq9WGgaHFZOTV*r1WgDHMN7X<>RoA0ZwCMXjg!y}Jbwv$8`Tv(W6K^{9s)Q{ zXj&5NBm&8nqr@ZyvbdG)fVbilyGmTQg^@IICXqB^W@KWz&;`0Lbl*2hTe>#^l$bP> z;{MMzVRR?-FOmq1Psec$#vt~_)Zw#Rq;I)-&gSi1zpo87apIVoqtcwDCn6vuP^J#yk1;N&bhW( zTso#eGnS2_J7yJKn8nbeSg4<`zqVZ_CkTL9eJ(D+teJiWy)4FYncYiVDo--W<$<6Gh9LI3i zjZYRz`F~+r?JymuOn}i?fNI{zEg5!|@TmE;q+4{4HOD}3?#VVuDj3=lFhO*|bHd8! z3_F#}*@i>Mc0E=ux@N&hn~q6`Q^lg?>aJ-O`E8)(U=ux5)C+X?HtF_|G&OWk!Pu?3 zKPCK+WOe79mn;R!l!ER$GYXCb87aGF-bs$GxPOLoBiN3N_^RNZo2WOqHLT#?SRJGg zx{(Q0n3&C+S8zw8Mg!{o3dUPNy$Mxev+Kh0Nk-NbuHCnIaf$8}d1qAMg5&X(3a8O=0Z&%5`WI3)6k=Z&#O9~gWMoE;pG}vL- zwtvOSI!-p3VCMDKcl3?X2;zDJIQb&12+%$i9MTD@KlKID+@8_@Ra$ z;m3q)tenxZDLP;DPO(&W`*eSkpQ`wohM(gXDt@Wq1^h}}UR3dG4Zp!}ndABq zOpW_-Sj9^keuv+y_=AQ&;zhc$WVk8UwSS$XeN13N_vXt94)8>+ccr;MDM-k^I}vpf z%_B*y)@ej@?3|h_Ug2$6^1M^=XAOVBUquuyskp4+WxS%{Ra97pvPfg`b+frv%&NGe z;VM>Dye6=&{eLj*!0qfSn*r>bksUO_uZ+Xra9zV846Aru!{6}+v)oe8iM@b$vVT$g zmJQosSrP6Zc$2dxv8?CI24C0kPYwUVzg4`Y;cfhfCGL8yJ+!5Lj2qu3^0Mnr*;ba0 zGX<%qOq+EaZ`H!^#x$-tu2JA7ZI$Wd4sY<8R`L|H>oUiNUJ!e^UMd+y*2GXOV5e+a z@@t-ogIm~z*rV&!OeV4TV$i|Fqkk?&Z!%@u`U*wEuH}8^1dY`z`Qx&gA8~qPfy>(i z{AY$s;w@hkw1Q6xo8>ELT9N>L9rH@GR-wX!c+l9fS4ysx6e8p1lHrIwU|$PjGB~5U zV;p%eKVs1uR+p)z_;rq54=8Pq>pvr!jJdE%T@aA!?ol0jb*LwILwvL4M}CtMfP;pKsIGB^k8 z`SiqU2i;h!vLsC_>zltkCpdvSSyQ$*57T-bwtVIgyGGg@Vlr4$UhDbM+t?b_Ge>uh z2&rt=DvMT~4;%!|_8Eqv!+%K7RC2rqFrA(=+}V<0%R_Ii2uE%Wf!@fIX*z)2)YL8W zLqC6d^`Z?)9OSi2>?Hh!)h704-n*fQ!vL=j@GZ%^!h6TS6)2aa*n_-w%EcXch*!-M zz)>9IUBPjjpp;O~@h4(C?|Uz!?Hbw_t{~LYQ9R> z9*N%PA^7OxX$0?+7Wd-)B;JOUPkNO9#vF`G3MYLEFChf+8}dvYg>IT1cm>)jZc|Xf zwknG{ncEv^_T0fsLOk5bOMeADjl{P}qWiF)e@`PS$q&#vZCA;ksgghAlNV19;}PmM zxG^E!nDpH!BP`vBlYe5*_Rj0*U1-0C9SegM?7V`z<`zPUxrL7Yt9aMkRqP4~=m26E ztm71~a*AUL(~?uX$|)YqX-0DTfY0eksFG7uaC*1LiG1F36?fm9&p}4%P#vFWl}{9p zVpj5rR{2DO`J9q`KIrjL9w47i3akk}yMy=)Rj|kBQoG<3tRP1$@}YnxIU( z#8LvV1eJ7M&o^UB0 rPHzVQ0F9G19#jKGOTUwh9vcFA6q7F<9g~|B4wKX#5C*Xu00000NF@Z+ delta 2116 zcmZXWX*kq-8^=dunfWs*yOAwR#@>uWw&|oNJC)^xEE%#S*$16r4lfpD)|tD5X9pJ`m_Mc}&0vzw5zZ zNyl>YLMi1MPXFQ*5=w#{C`bD`z+-4qCGZVGZ z$?4G1bRq}Zp;C{oTD14X!Aqb^w4Fi%oj<>jpam({0!FkVmR{^6CpX;KagiWyM8Mu2 zTMYs-^*I|?r8n@63p=`9l*M+{u1e;fYHVp~0BhtKZ8L0>LIZB&eYD_erYC(xa)d1C zRKThi2oLL5k6Oa^ptODmWb#MncKiBoo-CrFa*;0xj^^GwW2cesn2ykp3fshEMU}Pj zD`_fz=>v9v$r5(PA$YddQM*KQWwHVlR329GD9AU}bvRf(#KT!2`bAES9JOfS^6W32 zHcR%qm|J&$GgQaVY8=0&4lgZ0(X1-$m5h8k<=A2!i!2GqOXGZH3!VhSBg%K>qikQd z*0NK5Xe9Oo^*cQaD9+Zi&j}b`95?CtOMu?UkJB9seUv1lDiPh*Zq;V2Vgp0hUfZ`_ zC=vTXL=oE8Pg%tw>q^^Srp61OGqo(v4iomODQ3R`n(+!6#i~*7bU(mu!4PMJ>Jmgu zT99Rca2PuU_;hQ^@7EZIp8xPaY$;Q{iFI?)?|ts_>@iU+Nctdu>dvC1NqDw*ll4%( z@0T!#wxXlbNR&H;Z!kZ%DY^%1?JNS2_*Sm(VYByBn%5lVCJc#w7K@<+>dDAlUPJ3a zsDrmsOPN$tp2CF!T#qM}-BJ4)`DmuqIo z<1+mrqE9C{Kx`dT&mcBM?L^y=AKtQLNxgk%d{{xRk^7pL|F=kh*~oX%Y(8o;N~k6R zp0O@g5qrFPr;~K{U3xsb#9`lg&|~9@^p%jbty489IHM^eu%D28C8C2c>zKte^ZJ0V zcZShR2$iVna(-n%##vT2c)1NKNZ4@*B&i*#NroLQ$>xu!#`Al>Sr1+}KK@Dh&GNk@ ze1k-5<`CoQl7{p_H$zo7d|&tg6Zm`VMZr&g;3ZN^TF1>68mXvkNj+zLRfEWLB4GO2 z*i8J@2xAm|;g#n2kUO5~jAg2?jd}f2VCsI8X-f4Ia{?ud|Dn<7UuC!MVAPiIk(l9% zG|srp^E+kq;hi-YQmgGX?Ykk%xEp*DFW&D~|0u>gffwF-Z~BRc^7#W=^Ss%>|;o*BQ$>7=g5vV6`V5NAVDw3u_q5_l@uanm80eQ4$ zNRFynR(=dR1CT|FU%F^Q5aar%k`&rM}Kwcg^T&gS=#CzK&8k$-kzL? z8O!Y}oEI;uHmj)>u1{faY<6=*3lm0h-!P9O$Ng#=6>Ze+@6qOm7rI9)5DW&)h;OG~T}y^3)+ytsYddz*n1Jp?fa{OF|1Qt*1afb{3QO z)e1;Btvb=g=SA{kQoCRBfNOX?=Gh-qJLl}es#h{mNx zLW@O<4S8ouU9&Oin{x>9?RQX_2oKPy(<8Ka`!hC(vW}5yY;n5lc?PUWt5$w$^0MhF z>>| z4T5bei<@wkP0SAP5giKA(tF?sk}E;AB>UQ71i^pA+?J|Z>7-rhJjCu4wWV_mU4xS$ zwx7T1XV7D2L*D&`Bb~NQGC*gjmOzRJ3YUeez9eyP>Z|Q`&{ru&rsyJ(xnsCbf=rat zKo3yTW^^{V#$`i%x7sNNF1X-5#%L%z+e+d)e@61P>~wC{&z-eO76guJ$plr7yN@#7~r z3-zYK6nIbC4Q@S&9!U;fyl@a@j$|oWj?%svz$pbxw$U4pe2{{JIH(A0<}p}5po6}! zWnqCS!D~4xjU!f*@?`jTe&q?sM1B;qf_7U91$5Of-lz6WpG2Gc$9*dUK0uQaSi4P^ z%&e>85kk*SHS4oT!&{)cg0pE)Y#?bh_mlZnge|uPx{`m?*i~0_<~q?W`_iAwr8t6j zWdCby$WLS2UMZG%%i#rq$S@EHLCX?B@Ew}FTT17r$;sPNti$~7gy|s>($0rWly*5J hQ`+r+G;S^9Ap3ud4-bTYOL-iI{8Yw>w?OJ={u^eO?9TuI