From a99f88244f3a789602946b01b31a55d2bd839027 Mon Sep 17 00:00:00 2001 From: imuge Date: Wed, 22 Sep 2021 10:58:25 +0800 Subject: [PATCH] new version 1.6.0-SNAPSHOT --- core | 2 +- deploy/deploy-gateway/pom.xml | 2 +- .../src/main/resources/config/gateway.conf | 6 +- deploy/deploy-peer/pom.xml | 2 +- .../src/main/resources/config/init/ledger.init | 16 +- .../src/main/resources/config/init/local.conf | 8 +- deploy/docker/docker-demo/pom.xml | 135 ----------- .../docker/docker-demo/src/main/docker/Dockerfile | 37 --- .../docker-demo/src/main/docker/script/shutdown.sh | 4 - .../docker-demo/src/main/docker/script/start.sh | 34 --- .../docker-demo/src/main/docker/zip/conf.zip | Bin 91179 -> 0 bytes .../src/main/resources/docker-compose-all.yaml | 36 --- .../docker-demo/src/main/resources/start-net.sh | 5 - .../docker/docker-demo/src/main/resources/zip.sh | 9 - deploy/docker/docker-sdk/pom.xml | 66 ------ .../java/com/jd/blockchain/ContractParams.java | 107 --------- .../src/main/java/com/jd/blockchain/SDKDemo.java | 68 ------ .../java/com/jd/blockchain/SDKDemo_Constant.java | 46 ---- .../main/java/com/jd/blockchain/SDK_Base_Demo.java | 192 ---------------- .../com/jd/chain/contract/TransferContract.java | 32 --- .../resources/contract-compile-1.3.0.RELEASE.car | Bin 5129 -> 0 bytes deploy/docker/pom.xml | 24 -- deploy/docker/readme.md | 44 ---- deploy/pom.xml | 7 +- docs/ca.md | 150 +++++++++++++ docs/cli/ca.md | 248 +++++++++++++++++++++ docs/cli/keys.md | 2 + docs/cli/participant.md | 36 +-- docs/cli/tx.md | 242 ++++++++++++++++++-- docs/jdchain_cli.md | 4 +- explorer | 2 +- feature/ledger-database/.gitkeep | 0 framework | 2 +- libs/bft-smart | 2 +- libs/binary-proto | 2 +- libs/httpservice | 2 +- libs/kvdb | 2 +- libs/utils | 2 +- pom.xml | 2 +- project | 2 +- samples/contract-samples/pom.xml | 2 +- samples/pom.xml | 6 +- samples/sdk-samples/pom.xml | 2 +- test | 2 +- 44 files changed, 695 insertions(+), 899 deletions(-) delete mode 100644 deploy/docker/docker-demo/pom.xml delete mode 100644 deploy/docker/docker-demo/src/main/docker/Dockerfile delete mode 100644 deploy/docker/docker-demo/src/main/docker/script/shutdown.sh delete mode 100644 deploy/docker/docker-demo/src/main/docker/script/start.sh delete mode 100644 deploy/docker/docker-demo/src/main/docker/zip/conf.zip delete mode 100644 deploy/docker/docker-demo/src/main/resources/docker-compose-all.yaml delete mode 100644 deploy/docker/docker-demo/src/main/resources/start-net.sh delete mode 100644 deploy/docker/docker-demo/src/main/resources/zip.sh delete mode 100644 deploy/docker/docker-sdk/pom.xml delete mode 100644 deploy/docker/docker-sdk/src/main/java/com/jd/blockchain/ContractParams.java delete mode 100644 deploy/docker/docker-sdk/src/main/java/com/jd/blockchain/SDKDemo.java delete mode 100644 deploy/docker/docker-sdk/src/main/java/com/jd/blockchain/SDKDemo_Constant.java delete mode 100644 deploy/docker/docker-sdk/src/main/java/com/jd/blockchain/SDK_Base_Demo.java delete mode 100644 deploy/docker/docker-sdk/src/main/java/com/jd/chain/contract/TransferContract.java delete mode 100644 deploy/docker/docker-sdk/src/main/resources/contract-compile-1.3.0.RELEASE.car delete mode 100644 deploy/docker/pom.xml delete mode 100644 deploy/docker/readme.md create mode 100644 docs/ca.md create mode 100644 docs/cli/ca.md delete mode 100644 feature/ledger-database/.gitkeep diff --git a/core b/core index c7160adc..c6d05f98 160000 --- a/core +++ b/core @@ -1 +1 @@ -Subproject commit c7160adc704c53766427ecdf70f130e43f6cac43 +Subproject commit c6d05f98420213bf7ab1b4f431f6dcee2654bf5c diff --git a/deploy/deploy-gateway/pom.xml b/deploy/deploy-gateway/pom.xml index 31de50bf..f13dbf16 100644 --- a/deploy/deploy-gateway/pom.xml +++ b/deploy/deploy-gateway/pom.xml @@ -5,7 +5,7 @@ com.jd.blockchain deploy-root - 1.5.0.RELEASE + 1.6.0-SNAPSHOT deploy-gateway diff --git a/deploy/deploy-gateway/src/main/resources/config/gateway.conf b/deploy/deploy-gateway/src/main/resources/config/gateway.conf index a5cd04fd..529f99a5 100644 --- a/deploy/deploy-gateway/src/main/resources/config/gateway.conf +++ b/deploy/deploy-gateway/src/main/resources/config/gateway.conf @@ -25,11 +25,13 @@ peer.providers=com.jd.blockchain.consensus.bftsmart.BftsmartConsensusProvider data.retrieval.url= schema.retrieval.url= -#默认公钥的内容(Base58编码数据); +#默认公钥的内容(Base58编码数据),非CA模式下必填; keys.default.pubkey= +#默认网关证书路径(X509,PEM),CA模式下必填; +keys.default.ca-path= #默认私钥的路径;在 pk-path 和 pk 之间必须设置其一; keys.default.privkey-path= -#默认私钥的内容(加密的Base58编码数据);在 pk-path 和 pk 之间必须设置其一; +#默认私钥的内容;在 pk-path 和 pk 之间必须设置其一; keys.default.privkey= #默认私钥的解码密码; keys.default.privkey-password= diff --git a/deploy/deploy-peer/pom.xml b/deploy/deploy-peer/pom.xml index 42cbdf9f..129a1c82 100644 --- a/deploy/deploy-peer/pom.xml +++ b/deploy/deploy-peer/pom.xml @@ -5,7 +5,7 @@ com.jd.blockchain deploy-root - 1.5.0.RELEASE + 1.6.0-SNAPSHOT deploy-peer diff --git a/deploy/deploy-peer/src/main/resources/config/init/ledger.init b/deploy/deploy-peer/src/main/resources/config/init/ledger.init index f475f0e9..82ae9016 100644 --- a/deploy/deploy-peer/src/main/resources/config/init/ledger.init +++ b/deploy/deploy-peer/src/main/resources/config/init/ledger.init @@ -4,6 +4,12 @@ ledger.seed=932dfe23-fe23232f-283f32fa-dd32aa76-8322ca2f-56236cda-7136b322-cb323 #账本的描述名称;此属性不参与共识,仅仅在当前参与方的本地节点用于描述用途; ledger.name= +#身份认证模式:KEYPAIR/CA,默认KEYPAIR即公私钥对模式 +identity-mode=KEYPAIR + +#账本根证书路径,identity-mode 为 CA 时,此选项不能为空,支持多个,半角逗号相隔 +root-ca-path= + #声明的账本创建时间;格式为 “yyyy-MM-dd HH:mm:ss.SSSZ”,表示”年-月-日 时:分:秒:毫秒时区“;例如:“2019-08-01 14:26:58.069+0800”,其中,+0800 表示时区是东8区 created-time=2019-08-01 14:26:58.069+0800 @@ -76,6 +82,8 @@ cons_parti.0.name= cons_parti.0.pubkey-path= #第0个参与方的公钥内容(由keygen工具生成);此参数优先于 pubkey-path 参数; cons_parti.0.pubkey= +#第1个参与方的证书路径,identity-mode 为 CA 时,此选项不能为空 +cons_parti.0.ca-path= #第0个参与方的角色清单;可选项; #cons_parti.0.roles=ADMIN, MANAGER @@ -96,6 +104,8 @@ cons_parti.1.name= cons_parti.1.pubkey-path= #第1个参与方的公钥内容(由keygen工具生成);此参数优先于 pubkey-path 参数; cons_parti.1.pubkey= +#第1个参与方的证书路径,identity-mode 为 CA 时,此选项不能为空 +cons_parti.1.ca-path= #第1个参与方的角色清单;可选项; #cons_parti.1.roles=MANAGER @@ -116,6 +126,8 @@ cons_parti.2.name= cons_parti.2.pubkey-path= #第2个参与方的公钥内容(由keygen工具生成);此参数优先于 pubkey-path 参数; cons_parti.2.pubkey= +#第1个参与方的证书路径,identity-mode 为 CA 时,此选项不能为空 +cons_parti.2.ca-path= #第2个参与方的角色清单;可选项; #cons_parti.2.roles=MANAGER @@ -136,6 +148,8 @@ cons_parti.3.name= cons_parti.3.pubkey-path= #第3个参与方的公钥内容(由keygen工具生成);此参数优先于 pubkey-path 参数; cons_parti.3.pubkey= +#第1个参与方的证书路径,identity-mode 为 CA 时,此选项不能为空 +cons_parti.3.ca-path= #第3个参与方的角色清单;可选项; #cons_parti.3.roles=GUEST @@ -147,4 +161,4 @@ cons_parti.3.initializer.host=127.0.0.1 #第3个参与方的账本初始服务的端口; cons_parti.3.initializer.port=8830 #第3个参与方的账本初始服务是否开启安全连接; -cons_parti.3.initializer.secure=false +cons_parti.3.initializer.secure=false \ No newline at end of file diff --git a/deploy/deploy-peer/src/main/resources/config/init/local.conf b/deploy/deploy-peer/src/main/resources/config/init/local.conf index 46ae5b35..17615351 100644 --- a/deploy/deploy-peer/src/main/resources/config/init/local.conf +++ b/deploy/deploy-peer/src/main/resources/config/init/local.conf @@ -1,13 +1,17 @@ #当前参与方的 id,与ledger.init文件中cons_parti.id一致,默认从0开始 local.parti.id=0 -#当前参与方的公钥 +#当前参与方的公钥,用于非证书模式 local.parti.pubkey= +#当前参与方的证书信息,用于证书模式 +local.parti.ca-path= #当前参与方的私钥(密文编码) local.parti.privkey= +#当前参与方的私钥文件,PEM格式,用于证书模式 +local.parti.privkey-path= -#当前参与方的私钥解密密钥(原始口令的一次哈希,Base58格式),如果不设置,则启动过程中需要从控制台输入 +#当前参与方的私钥解密密钥(原始口令的一次哈希,Base58格式),如果不设置,则启动过程中需要从控制台输入; local.parti.pwd= #账本初始化完成后生成的"账本绑定配置文件"的输出目录 diff --git a/deploy/docker/docker-demo/pom.xml b/deploy/docker/docker-demo/pom.xml deleted file mode 100644 index 6eb80655..00000000 --- a/deploy/docker/docker-demo/pom.xml +++ /dev/null @@ -1,135 +0,0 @@ - - - - docker - com.jd.blockchain - 1.5.0.RELEASE - - 4.0.0 - docker-demo - - - - com.jd.blockchain - docker-sdk - ${project.version} - - - - - jdchain-demo - - - org.apache.maven.plugins - maven-compiler-plugin - - 1.8 - 1.8 - UTF-8 - false - true - false - false - - - - - - - - - - - - - - - - - - - - - - - - - maven-resources-plugin - 3.0.2 - - - copy-resources - validate - - copy-resources - - - - UTF-8 - ${project.basedir}/src/main/docker/zip - false - - - ${project.basedir}/../../deploy-peer/target/ - false - - jdchain-peer-${project.version}.zip - - - - - ${project.basedir}/../../deploy-gateway/target/ - false - - jdchain-gateway-${project.version}.zip - - - - - - ${project.basedir}/../docker-sdk/target/ - false - - docker-sdk-${project.version}.jar - - - - - - - - - - - com.spotify - docker-maven-plugin - 1.2.2 - - - - - build-image - - package - - build - - - - - - - jdchain-demo - - ${project.version} - - - ${project.basedir}/target - - - - - - \ No newline at end of file diff --git a/deploy/docker/docker-demo/src/main/docker/Dockerfile b/deploy/docker/docker-demo/src/main/docker/Dockerfile deleted file mode 100644 index c6d8edde..00000000 --- a/deploy/docker/docker-demo/src/main/docker/Dockerfile +++ /dev/null @@ -1,37 +0,0 @@ -FROM centos:8.2.2004 - -# install tools -RUN yum install wget -y \ - && wget -O /etc/yum.repos.d/epel-7.repo http://mirrors.aliyun.com/repo/epel-7.repo \ - && yum install java net-tools nc crontabs expect unzip -y \ - && yum install langpacks-zh_CN.noarch -y \ - && yum install dos2unix -y \ - && echo "LANG=zh_CN.utf8" >> /etc/locale.conf \ - && source /etc/locale.conf \ - && yum clean all - -WORKDIR /export/jdchain -COPY zip/* /export/jdchain/ - -# env -ENV RELEASE_DIR=/export/jdchain -ENV RELEASE_VERSION=1.3.0 -#ENV DATA_DIR=/shared -ENV NAME=conf -ENV SERVER_NAME_PEER=deploy-peer -ENV SERVER_NAME_GW=deploy-gateway - -COPY script/* /export/jdchain/ -RUN dos2unix /export/jdchain/*.sh -RUN chmod +x /export/jdchain/*.sh - -# ports -EXPOSE 8080 -#EXPOSE 16000 -#EXPOSE 16010 -#EXPOSE 16020 -#EXPOSE 16030 - -#ENTRYPOINT ["/bin/sh","-c","/export/jdchain/start.sh"] -ENTRYPOINT sh /export/jdchain/start.sh - diff --git a/deploy/docker/docker-demo/src/main/docker/script/shutdown.sh b/deploy/docker/docker-demo/src/main/docker/script/shutdown.sh deleted file mode 100644 index 8cf6d207..00000000 --- a/deploy/docker/docker-demo/src/main/docker/script/shutdown.sh +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/bash - -ps -ef|grep 'jdchain'|grep -v grep|cut -c 9-15|xargs kill -9 - diff --git a/deploy/docker/docker-demo/src/main/docker/script/start.sh b/deploy/docker/docker-demo/src/main/docker/script/start.sh deleted file mode 100644 index c55380b6..00000000 --- a/deploy/docker/docker-demo/src/main/docker/script/start.sh +++ /dev/null @@ -1,34 +0,0 @@ -#!/bin/bash - -cd $RELEASE_DIR - -# check the files; -peer_file="./jdchain-peer-$RELEASE_VERSION.RELEASE.zip" -gw_file="./jdchain-gateway-$RELEASE_VERSION.RELEASE.zip" -sdk_file="./docker-sdk-$RELEASE_VERSION.RELEASE.jar" -if [[ ! -f $peer_file ]] || [[ ! -f $gw_file ]] || [[ ! -f $sdk_file ]] ; then -echo "not find $peer_file or $gw_file or $sdk_file in the $RELEASE_DIR, please check the image of jdchain-demo:$RELEASE_VERSION." -exit 1 -fi - - unzip -o conf.zip - - for i in `seq 0 3` - do - unzip -n -d ./peer$i jdchain-peer-$RELEASE_VERSION.RELEASE.zip - chmod +x ./peer$i/bin/* - done - - unzip -n -d ./gw jdchain-gateway-$RELEASE_VERSION.RELEASE.zip - chmod +x ./gw/bin/* - -sh ./peer0/bin/peer-startup.sh -sh ./peer1/bin/peer-startup.sh -sh ./peer2/bin/peer-startup.sh -sh ./peer3/bin/peer-startup.sh -sleep 30 -sh ./gw/bin/startup.sh -sleep 10 -java -jar docker-sdk-1.3.0.RELEASE.jar > sdk.log - -tail -f /dev/null diff --git a/deploy/docker/docker-demo/src/main/docker/zip/conf.zip b/deploy/docker/docker-demo/src/main/docker/zip/conf.zip deleted file mode 100644 index dc8dffb12ecef03f0a8dfecc4da7f9fb539a07a9..0000000000000000000000000000000000000000 GIT binary patch literal 0 KcmV+b0RR6000031 literal 91179 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 mbijtlV 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 z0000000RId000000000G000000001IcP|P6AOHXW000317yz(D{LeD1)&Y=ECD1ag z)&X3sSz;lm)&WpU0Rle&6aWAK005bLTTuW20000000000000L7Bme*a000005C8xG zApigXXLm1RX>KnH03ZMW0000102lz$lKjsytkwaLP$keZtkwarMEuV(tkwZgO928u z02BZK00;o+f?H81-&;F_0RR9_0ssIJ03-ka0000003ZMW07d`+0B3hEVrgzKb97;H zbaikpb7%?xAOHXW000317yzR*vuZl5)&Zk5vuZl5)&bIz{LeD1)&WpU0Rle&6aWAK z002i>Tu}f30000000000000UABme*a000005C8xG_yGU_XLm1SZ*FF3XDAOHXW z000317yv%Rw%OOL)&ZQ4TiVyG)&a}pT4Eun)&WpU0Rle&6aWAK2mpdbR#6*js-T1e z005{5000&MBme*a00000AOHXWAOZjYXLm1SZ*FF3XD?@AbY*v8c`jpbZe|JqAOHXW z000317ytmG({K!^)&T&b({K!^)&T&b({K!^)&WpU0Rle&6aWAK2mnV}Tu}rBCghg| z007Jr000*NBme*a00000AOHXW*aZLpXLm1SZ*FF3XD@7TXEbUuEoXNwcx`M703ZMW z0000102ly1#J1VjtkwZO#J1VjtkwZO#J1VjtkwZgO928u02BZK0002MSyoX100000 z000000000603-ka0000001yBG0Hg~50B~hxaxgCn03ZMW0000102lzwJ$qsysMZ0@ zJ$qsysMZ0(pI>4jsMY~cO928u02BZK0001)ds|Te00000000000000A03-ka00000 z01yBG0LTjf0B~hxaxgDqX>KnH03ZMW0000102ly|^Zm~KoYWo2?Lb97;Hbaikpb7%?xAOHXW000317y!>Szim3K)&b8nzim3K)&Y<6 z{m(M2)&WpU0Rle&6aWAK002i>Tu}f30000000000000dDBme*a000005C8xGy$t{W zaAjq3FfU_oZf0p`FA4x4000000096P0DL*O+1ISr0ju<++Sjbs0YKqpVj-y30Z>Z; z0zUv0000000BKTIQ2+n{000000000001^Ns000000000G0002!4FCXeWo2?OFJo_R zW@%?HX>MtBFA4x4000000096P007sbz8R?20al=BVj-y30al=BVj-y30Z>Z;0zUv0 z000080D?tUQHU--YnTB507eD?03iS*000000000W0000O4gdgfWo2?OFJo_RW@%?H zX>MtBFJfkNb8TUAbS`6WZf0p`3IHGg000000RR{P0HV`y45-!t0HV`y45-!t0HV`y z45-!tP)h*>1aZ)0I>E@N+QW(oix000000096P002mFZVaf_ z0RTvGZVaf_0RTvGZVaf_0Z>Z;0zUv0000000BKTIQ2+n{000000000001^Ns00000 z0000G0001S6#xKmWo2?OFJo_RW@%?HYh`(JFA4x4000000096P007sbz8R?20o77* zVj-y30o77*Vj-y30Z>Z;0zUu>000000DwhSQAFnvR!0B;07n1-02u%z000000000W z0001?6#xKmWo2?OFJo_RW@%?HYh`(JFKT2iaB^vO3IHGg000000RR{P07!9e45-!t z07!9e45-!t07!9e45-!tP)h*tG{{;X5AOIu) z00000001BW008Y4003}hWpXetV{dL|X=g8NWn^b%axG$MZe(e0XD(xJZe|JqAOHXW z000317yyw>O^HFM)&Y@BO^HFM)&T(gHFFH8)&WpU0Rle&6aWAK2mnV}Tv4L#mo?c0 z002S{000~SBme*a00000AOHXW;~4+|aAjq3FfU_oZf0p`FKlmTG-@&}aAjq3E_iKh z3IHGg000000RR{Pd^xw-*R0k7d^xw-*R0k7d^xw-*R0k7P)h*}nHkBWnpH>}nH%sqQzA*j{?P)h*W~ls z000mG000#LBme*a00000AOHXW);0hDaAjq3FfVd%V{3C{VlP8gQc^`uR0;qf00000 z0096P0Dxtkatx@}0mDl%l{c)`0iz@_l{c)`0Z>Z;0zUu>000000E9(WQMD@UBqaa< z03`qb02Tlw000000000W0000PHvj-|Wo2?OFLG~VYjb2`FG)m2PE<)$SqcCk00000 z0096P0Dxtkatx@}0SgZ@l{c)`0SgZ@l{c)`0Z>Z;0zUu>000000E9(WQ2+n{00000 z0000001^Ns000000000W0001THvj-|Wo2?OFLG~VYjb2`FHBEEO9}uW000000096P z0Dxtkatx@}0b+Z;0zUv0000080E9(WQPo^f6k!hl0Mt?d z01*Hr000000000W0001@Hvj-|Wo2?OFLG~VYjb2`FHBEI3IHGg000000RR{PfMuO> z45-!t>L@RjH>}nH)B!J*H>}nHP)h*Z;0zUv0000000Ki#RQ2+n{ z000000000000sag000000000G0001zPXGXLWo2?PFA4x4000000096P04=ehVj-y3 z0WGniVj-y30mdkWVj-y30Z>Z;0zUv0000000GWGRQ2+n{0000000000015yk00000 z0000G0002CPXGXLWo2?PFJftKFA4x4000000096P09B6%&@!yn0TYQP&@!yn0W>;> zVj-y30Z>Z;0zUv0000080PTWXQN7pgY?c840CoZZ02u%z000000000W0002qPXGXL zWo2?PFJftKFK}gLaxHUoVRCeJa4vIb3IHGg000000RR{PcZ=6>I;_?KcZ=6>I;_?K zRgVYIGOX4CP)h*QOUtkwbASc+mHsMY~c zO928u02BZK0001KQdUs_00000000000000I03-ka0000001yBG0M=0e0B~hxaxpJs zZ*FF3XD?}PX>>0N03ZMW0000102lxO*P^}|sMY}lKaFA`sMY}lKaFA`sMY~cO928u z02BZK00;nrMOIOWE>1QW^{9HVRCdXV{dL|X=e%mAOHXW000317ytmG({K!^)&T&b({K!^)&T&b z({K!^)&WpU0Rle&6aWAK2mpdbR#8DEJT@Bw001Hd0012TBme*a00000AOHXW-BSPn zaAjq3F)w3pZf0p`FKKRRbT4dWWM^e^E@^IQbP50<000000096P005%Xa15x{0RW=Y za15x{0RW=Ya15x{0Z>Z;0zUv0000080DwhSQP};l3iJX10F(p(02}}$000000000W z0000pRsaBSWo2?PFJo_RW@%?HX>MtBFKlmPVQemAZ*FD^03ZMW0000102lxONO5iq zsMY}hNO5iqsMY}hNO5iqsMY~cO928u02BZK0001KQdUs_00000000000000L03-ka z0000001yBG0AX1G0B~hxaxpJsZ*FF3XD?}PX>>1baW4u0AOHXW000317ytm*qP`iZ z)&Z^clVTyL)&Z^clVTyL)&WpU0Rle&6aWAK2mn=o2T`(DqoTe9004ar001BWBme*a z00000AOHXWlvw}(aAjq3F)w3pZf0p`FKKRRbT4gjFKlIGXJv9OX>MtB3IHGg00000 z0RR{P0Hq<3kZjfg0Hq<3kZjfg0Hq<3kZjfgP)h*E@N+Q zW(oix000000096P005;Sk&tZG0RW{Tk&tZG0RW{Tk&tZG0Z>Z;0zUv00000809Ahn zQG!iY7BB(;0G|T@03HA&000000000W0002PU;qGcWo2?PFJo_RW@%?HX>MtBFKuxz zZE-GRZ*FF3X9@ry000000096P005;Sk&tZG0RW{Tk&tZG0RW{Tk&tZG0Z>Z;0zUv0 z000000BKTIQ2+n{000000000001^Ns000000000G0000lV*mhfWo2?PFJo_RW@%?H zYh`(JFA4x4000000096P007sbz8R?20X;XGVj-y30X;XGVj-y30Z>Z;0zUu>00000 z0DwhSQ7gE0fJXoT07n1-02u%z000000000W0001AV*mhfWo2?PFJo_RW@%?HYh`(J zFKT2iaB^vO3IHGg000000RR{P07!9e45-!t07!9e45-!t07!9e45-!tP)h*HUIzsHUIzs7yu*y00000001BW007-%003}hWpXhuV{dL|X=g8M zWqETiYGf{Obz%wtAOHXW000317ytlBac&H#)&T%Wac&H#)&T%Wac&H#)&WpU0Rle& z3IG5A004kRR#D`R5fv-|001li000;OBme*a00000AOHXWNn`*3aAjq3F)w3pZf0p` zFKcCab1!OSE^v2b3IHGg000000RR{P07!9e45-!t07!9e45-!t07!9e45-!tP)h*< zKL8W}000O8n0QuEXm?!@w*mkF{{;X5AOIu)00000001BW0066G003}hWpXhuV{dL| zX=g8NWn^b%axG$MZe(e0XD(xJZe|JqAOHXW000317y#r{T%bXy)&b;HT%bXy)&T(g zHFFH8)&WpU0Rle&6aWAK2mnV}Tv4L#mo?c0002S{000~SBme*a00000AOHXWpl1L8 zaAjq3F)w3pZf0p`FKlmTG-@&}aAjq3E_iKh3IHGg000000RR{PpRTvr*R0k7pRTvr z*R0k7pRTvr*R0k7P)h*}nHm9c}BH>}nHEwQ0u zA*j{?P)h*W~ls000mG000#LBme*a00000AOHXWlY{^O zaAjq3F)wm&V{3C{VlP8gQc^`uR0;qf000000096P0Dxtkatx@}0shH0l{c)`0shH0 zl{c)`0Z>Z;0zUu>000000E9(WQ3~${?Ii#J03`qb02Tlw000000000W0002iga80= zWo2?PFLG~VYjb2`FG)m2PE<)$SqcCk000000096P0Dxtkatx@}0X>a3l{c)`0X>a3 zl{c)`0Z>Z;0zUu>000000E9(WQ2+n{000000000001^Ns000000000W0000lg#Z9> zWo2?PFLG~VYjb2`FHBEEO9}uW000000096P0Dxtkatx@}0kj4-l{c)`0kj4-l{c)` z0Z>Z;0zUv0000080E9(WQ9@>VN@x!N0Mt?d01*Hr000000000W0001Ag#Z9>Wo2?P zFLG~VYjb2`FHBEI3IHGg000000RR{PfMuO>45-!tY-%-?H>}nHY-%-?H>}nHP)h*< zKL82<00000ghf_SOBu-j4FCWD4FCWD9RMT%00000001BW008!s003}hWpXhua&Kd6 zb7W#KO+ijcMnzLpEif=JFfcI+03ZMW0000102ly(Wu0;isMY~N*Ey9ptkwZR*Ey9p ztkwZgO928u02BZK00;ntMOIPCRsM$F2LJ&56951l03-ka0000003ZMW06vuf0B~hx zaxpJ*Z)0n7WMVH*P*h1zPE#!~FfcGMH3|SA000000096P0Dxtkatx@}0q7Gsl{c)` z0ov?1l{c)`0Z>Z;0zUv0000000Ki#RQ2+n{000000000000sag000000000G00011 zod5uEWo2?QFA4x4000000096P00%b7Vj-y30S7k8Vj-y30m_Q1Vj-y30Z>Z;0zUv0 z000000GWGRQ2+n{0000000000015yk000000000G0001bod5uEWo2?QFJftKFA4x4 z000000096P01&PV&@!yn0TYQP&@!yn0XM^|Vj-y30Z>Z;0zUv0000080P%ubQ6RUf z0+s;)0CoZZ02u%z000000000W0001@od5uEWo2?QFJftKFK}gLaxHUoVRCeJa4vIb z3IHGg000000RR{PZ|cr;I;_?KZ|cr;I;_?K5UvZ*GOX4CP)h*butkwa*8>QOUtkwbN;jdyLsMY~cO928u02BZK0001KQdUs_0000000000 z0000I03-ka0000001yBG0Ggiw0B~hxaxyPtZ*FF3XD?}PX>>0N03ZMW0000102lxO z*P^}|sMY}p$g*M~sMY}p$g*M~sMY~cO928u02BZK00;nrMOIOWE>1QW^{9HVRCdXV{dL|X=e%m zAOHXW000317ytmG({K!^)&T&b({K!^)&T&b({K!^)&WpU0Rle&6aWAK2mpdbR#7!w zC^;Jf001Hd0012TBme*a00000AOHXWp`ic(aAjq3GB0CqZf0p`FKKRRbT4dWWM^e^ zE@^IQbP50<000000096P005%Xa15x{0RW=Ya15x{0RW=Ya15x{0Z>Z;0zUv000008 z0D(nTQ4D(Gp7a6$0F(p(02}}$000000000W0002@qW}PKWo2?QFJo_RW@%?HX>MtB zFKlmPVQemAZ*FD^03ZMW0000102lxOb)s(!sMY}hb)s(!sMY}hb)s(!sMY~cO928u z02BZK0001KQdUs_00000000000000L03-ka0000001yBG041jY0B~hxaxyPtZ*FF3 zXD?}PX>>1baW4u0AOHXW000317ytm*qP`iZ)&T$;x?&-y)&T$;x?&-y)&WpU0Rle& z6aWAK2mn=o2T`(DqoTe9004ar001BWBme*a00000AOHXWSf>C0aAjq3GB0CqZf0p` zFKKRRbT4gjFKlIGXJv9OX>MtB3IHGg000000RR{P0Hq<3kZjfg0Hq<3kZjfg0Hq<3 zkZjfgP)h*E@N+QW(oix000000096P005;Sk&tZG0RW{T zk&tZG0RW{Tk&tZG0Z>Z;0zUv00000809AhnQG!iY7BB(;0G|T@03HA&000000000W z0001ot^fdVWo2?QFJo_RW@%?HX>MtBFKuxzZE-GRZ*FF3X9@ry000000096P005;S zk&tZG0RW{Tk&tZG0RW{Tk&tZG0Z>Z;0zUv0000000BKTIQ2+n{000000000001^Ns z000000000G0002Z;0zUu>000000D(nTQP5!_Lq`Ar07n1-02u%z00000 z0000W0000Zu>b&YWo2?QFJo_RW@%?HYh`(JFKT2iaB^vO3IHGg000000RR{P0Cl2o z45-!t0Cl2o45-!t0Cl2o45-!tP)h*tG{{;X5 zAOIu)00000001BW003{Y003}hWpXkvV{dL|X=g8NWn^b%axG$MZe(e0XD(xJZe|Jq zAOHXW000317ywz;R-i$s)&W`8R-i$s)&T(gHFFH8)&WpU0Rle&6aWAK2mnV}Tv4L# zmo?c0002S{000~SBme*a00000AOHXWWwihRaAjq3GB0CqZf0p`FKlmTG-@&}aAjq3 zE_iKh3IHGg000000RR{P$0NAe*R0k7$0NAe*R0k7$0NAe*R0k7P)h*}nHsMv#*H>}nH2R6xKA*j{?P)h*W~ls000mG000#LBme*a00000AOHXWSkeFhaAjq3GB0v(V{3C{VlP8gQc^`uR0;qf z000000096P0Dxtkatx@}0alhgl{c)`0alhgl{c)`0Z>Z;0zUu>000000E9(WQS|pO zDZ;0zUu>000000E9(WQ2+n{ z000000000001^Ns000000000W0002=(f|N(Wo2?QFLG~VYjb2`FHBEEO9}uW00000 z0096P0Dxtkatx@}0Tk0al{c)`0Tk0al{c)`0Z>Z;0zUv0000080E9(WQE;$Yrf3fU z0Mt?d01*Hr000000000W0000a(*OW)Wo2?QFLG~VYjb2`FHBEI3IHGg000000RR{P zfMuO>45-!t%QiceH>}nHxeq&)H>}nHP)h*Z;0zUv0000000Kr*S zQ2+n{000000000000sag000000000G0000R>i__7Wo2?RFA4x4000000096P03N&o zVpVZ;0zUv0000000GWGRQ2+n{0000000000015yk z000000000G0000#>i__7Wo2?RFJftKFA4x4000000096P0AJz`&@!yn0UNL;&@!yn z0lL@OVj-y30Z>Z;0zUv0000080Q7=eQLAWZCzb&K0CoZZ02u%z000000000W0001I z>i__7Wo2?RFJftKFK}gLaxHUoVRCeJa4vIb3IHGg000000RR{PYX}#4I;_?KYX}#4 zI;_?KU*ZnXGOX4CP)h*>0N03ZMW0000102lxO*P^}|sMZ1I#^GWisMZ1I#^GWisMY~c zO928u02BZK00;nrMOIOWE>1QW^{9HVRCdXV{dL|X=e%mAOHXW000317ytmG({K!^)&T&b({K!^ z)&T&b({K!^)&WpU0Rle&6aWAK2mpdbR#6#sBs?1e001Hd0012TBme*a00000AOHXW zX72z1aAjq3GcRLrZf0p`FKKRRbT4dWWM^e^E@^IQbP50<000000096P005%Xa15x{ z0RW=Ya15x{0RW=Ya15x{0Z>Z;0zUv0000080D?tUQJ|JO3-ba10F(p(02}}$00000 z0000W0002I@c;mDWo2?RFJo_RW@%?HX>MtBFKlmPVQemAZ*FD^03ZMW0000102lxO zqSJ5;sMY}hqSJ5;sMY}hqSJ5;sMY~cO928u02BZK0001KQdUs_00000000000000L z03-ka0000001yBG0O|Aq0B~hxax*VuZ*FF3XD?}PX>>1baW4u0AOHXW000317ytm* zqP`iZ)&bJ{?P4LQ)&bJ{?P4LQ)&WpU0Rle&6aWAK2mn=o2T`(DqoTe9004ar001BW zBme*a00000AOHXW9Q6PIaAjq3GcRLrZf0p`FKKRRbT4gjFKlIGXJv9OX>MtB3IHGg z000000RR{P0Hq<3kZjfg0Hq<3kZjfg0Hq<3kZjfgP)h*J003}hWpXnwV{dL|X=g8KZfSHcZE-JbZ)0I> zE@N+QW(oix000000096P005;Sk&tZG0RW{Tk&tZG0RW{Tk&tZG0Z>Z;0zUv000008 z09AhnQG!iY7BB(;0G|T@03HA&000000000W0000>`~U!OWo2?RFJo_RW@%?HX>MtB zFKuxzZE-GRZ*FF3X9@ry000000096P005;Sk&tZG0RW{Tk&tZG0RW{Tk&tZG0Z>Z; z0zUv0000000BKTIQ2+n{000000000001^Ns000000000G0002D{r~`QWo2?RFJo_R zW@%?HYh`(JFA4x4000000096P007sbz8R?20kkmsVj-y30kkmsVj-y30Z>Z;0zUu> z000000D?tUQJU9FT}J=_07n1-02u%z000000000W0002z{r~`QWo2?RFJo_RW@%?H zYh`(JFKT2iaB^vO3IHGg000000RR{P0HV`y45-!t0HV`y45-!t0HV`y45-!tP)h*< zKL82<00000f<;zQXN{L%HUIzsHUIzs7yu*y00000001BW003qG003}hWpXnwV{dL| zX=g8MWqETiYGf{Obz%wtAOHXW000317ytmG({K!^)&T&b({K!^)&T&b({K!^)&WpU z0Rle&3IG5A004qTR#D`R5fv-|001li000;OBme*a00000AOHXW(ftG{{;X5AOIu)00000001BW001)p0RV7iWpXnw zV{dL|X=g8NWn^b%axG$MZe(e0XD(xJZe|JqAOHXW000317yt}JTcAOx)&UGeTcAOx z)&T(gHFFH8)&WpU0Rle&6aWAK2mnV}Tv4L#mo?c0002S{000~SBme*a00000AOHXW zDFXojaAjq3GcRLrZf0p`FKlmTG-@&}aAjq3E_iKh3IHGg000000RR{P7MZx&*R0k7 z7MZx&*R0k75OTQL*R0k7P)h*;p=bH>}nHsMv#*H>}nH z9=rl$A*j{?P)h*CN z)&WCN)&WpU0Rle&3IG5A004wVR#Cok>W~ls000mG000#LBme*a00000AOHXW z93TMzaAjq3GcR&)V{3C{VlP8gQc^`uR0;qf000000096P0Dxtkatx@}0k1?yl{c)` z0k1?yl{c)`0Z>Z;0zUu>000000E9(WQGT)010?_e03`qb02Tlw000000000W0001A zAOQeyWo2?RFLG~VYjb2`FG)m2PE<)$SqcCk000000096P0Dxtkatx@}0U8KMl{c)` z0U8KMl{c)`0Z>Z;0zUu>000000E9(WQ2+n{000000000001^Ns000000000W0002E zAOQeyWo2?RFLG~VYjb2`FHBEEO9}uW000000096P0Dxtkatx@}0cxm5l{c)`0cxm5 zl{c)`0Z>Z;0zUv0000080E9(WQ3f5CXlf4t0Mt?d01*Hr000000000W0002!AOQey zWo2?RFLG~VYjb2`FHBEI3IHGg000000RR{PfMuO>45-!tDCI?!H>}nHDCI?!H>}nH zP)h*Z?1^@s60BQhg05mHA0O2?R0000=VwVH} diff --git a/deploy/docker/docker-demo/src/main/resources/docker-compose-all.yaml b/deploy/docker/docker-demo/src/main/resources/docker-compose-all.yaml deleted file mode 100644 index b42268f9..00000000 --- a/deploy/docker/docker-demo/src/main/resources/docker-compose-all.yaml +++ /dev/null @@ -1,36 +0,0 @@ -version: '2' - -services: - demo: - image: "jdchain-demo:1.3.0" - container_name: jdchain-demo - networks: - jdchain_default: - aliases: - - demo - hostname: demo - restart: always - ports: - - "11010:11010" - - "7080:7080" - - "10080:10080" - - "10081:10081" - - "11011:11011" - - "7081:7081" - - "10082:10082" - - "10083:10083" - - "11012:11012" - - "7082:7082" - - "10084:10084" - - "10085:10085" - - "11013:11013" - - "7083:7083" - - "10086:10086" - - "10087:10087" - - "8080:8080" -# volumes: -# - "./logs:/export/jdchain/peer0/logs" - -networks: - jdchain_default: - driver: bridge diff --git a/deploy/docker/docker-demo/src/main/resources/start-net.sh b/deploy/docker/docker-demo/src/main/resources/start-net.sh deleted file mode 100644 index 7eafc55d..00000000 --- a/deploy/docker/docker-demo/src/main/resources/start-net.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/bash -echo "停止network" -docker-compose -f docker-compose-all.yaml down -echo "启动jdchain" -docker-compose -f docker-compose-all.yaml up -d diff --git a/deploy/docker/docker-demo/src/main/resources/zip.sh b/deploy/docker/docker-demo/src/main/resources/zip.sh deleted file mode 100644 index 3305c646..00000000 --- a/deploy/docker/docker-demo/src/main/resources/zip.sh +++ /dev/null @@ -1,9 +0,0 @@ -#/bin/bash - -# all in one; -allIn1_file="./jdchain-demo_1.3.0.tar.gz" -if [ -f $allIn1_file ] ; then - rm -rf $allIn1_file -fi -docker save jdchain-demo:1.3.0 -o jdchain-demo_1.3.0.tar -gzip jdchain-demo_1.3.0.tar diff --git a/deploy/docker/docker-sdk/pom.xml b/deploy/docker/docker-sdk/pom.xml deleted file mode 100644 index 974edb25..00000000 --- a/deploy/docker/docker-sdk/pom.xml +++ /dev/null @@ -1,66 +0,0 @@ - - - - com.jd.blockchain - docker - 1.5.0.RELEASE - - 4.0.0 - - docker-sdk - - - - com.jd.blockchain - crypto-classic - ${framework.version} - - - com.jd.blockchain - crypto-sm - ${framework.version} - - - com.jd.blockchain - ledger-model - ${framework.version} - - - com.jd.blockchain - sdk-client - ${framework.version} - - - - - - - maven-assembly-plugin - - false - - jar-with-dependencies - - - - - com.jd.blockchain.SDKDemo - - - - - - make-assembly - package - - single - - - - - - - - \ No newline at end of file diff --git a/deploy/docker/docker-sdk/src/main/java/com/jd/blockchain/ContractParams.java b/deploy/docker/docker-sdk/src/main/java/com/jd/blockchain/ContractParams.java deleted file mode 100644 index b1464b4e..00000000 --- a/deploy/docker/docker-sdk/src/main/java/com/jd/blockchain/ContractParams.java +++ /dev/null @@ -1,107 +0,0 @@ -package com.jd.blockchain; - -import com.jd.blockchain.ledger.BlockchainIdentity; -import com.jd.blockchain.ledger.BlockchainKeypair; - -public class ContractParams { - String contractZipName; - BlockchainKeypair signAdminKey; - BlockchainIdentity contractIdentity; - boolean isDeploy; - boolean isExecute; - boolean hasVersion; //contract's version; - long version; - BlockchainIdentity dataAccount; - String key; - String value; - - public String getContractZipName() { - return contractZipName; - } - - public ContractParams setContractZipName(String contractZipName) { - this.contractZipName = contractZipName; - return this; - } - - public BlockchainKeypair getSignAdminKey() { - return signAdminKey; - } - - public ContractParams setSignAdminKey(BlockchainKeypair signAdminKey) { - this.signAdminKey = signAdminKey; - return this; - } - - public BlockchainIdentity getContractIdentity() { - return contractIdentity; - } - - public ContractParams setContractIdentity(BlockchainIdentity contractIdentity) { - this.contractIdentity = contractIdentity; - return this; - } - - public boolean isDeploy() { - return isDeploy; - } - - public ContractParams setDeploy(boolean deploy) { - isDeploy = deploy; - return this; - } - - public boolean isExecute() { - return isExecute; - } - - public ContractParams setExecute(boolean execute) { - isExecute = execute; - return this; - } - - public boolean isHasVersion() { - return hasVersion; - } - - public ContractParams setHasVersion(boolean hasVersion) { - this.hasVersion = hasVersion; - return this; - } - - public long getVersion() { - return version; - } - - public ContractParams setVersion(long version) { - this.version = version; - return this; - } - - public BlockchainIdentity getDataAccount() { - return dataAccount; - } - - public ContractParams setDataAccount(BlockchainIdentity dataAccount) { - this.dataAccount = dataAccount; - return this; - } - - public String getKey() { - return key; - } - - public ContractParams setKey(String key) { - this.key = key; - return this; - } - - public String getValue() { - return value; - } - - public ContractParams setValue(String value) { - this.value = value; - return this; - } -} diff --git a/deploy/docker/docker-sdk/src/main/java/com/jd/blockchain/SDKDemo.java b/deploy/docker/docker-sdk/src/main/java/com/jd/blockchain/SDKDemo.java deleted file mode 100644 index 5e02ccf1..00000000 --- a/deploy/docker/docker-sdk/src/main/java/com/jd/blockchain/SDKDemo.java +++ /dev/null @@ -1,68 +0,0 @@ -package com.jd.blockchain; - -import com.jd.blockchain.ledger.*; -import org.apache.commons.codec.binary.Base64; - -import java.util.Random; -import java.util.UUID; - -public class SDKDemo extends SDK_Base_Demo{ - public static void main(String[] args) { - SDKDemo sdkDemo = new SDKDemo(); - //注册用户; - sdkDemo.registerUsers(); - //构建数据账户; - sdkDemo.genDataAccount(); - //发布和执行合约; - sdkDemo.deployContract(); - } - - //注册用户; - public void registerUsers(){ - this.registerUser(); - } - - //构建数据账户; - public void genDataAccount(){ - byte[] arr = new byte[1024]; - new Random().nextBytes(arr); - String value = Base64.encodeBase64String(arr); - this.insertData(null,null,"key1",value,-1); - } - - public BlockchainKeypair insertData(BlockchainKeypair dataAccount, BlockchainKeypair signAdminKey, - String key, String value, long version) { - // 在本地定义注册账号的 TX; - TransactionTemplate txTemp = blockchainService.newTransaction(ledgerHash); - //采用KeyGenerator来生成BlockchainKeypair; - if(dataAccount == null){ - dataAccount = BlockchainKeyGenerator.getInstance().generate(); - txTemp.dataAccounts().register(dataAccount.getIdentity()); - } - - System.out.println("current dataAccount=" + dataAccount.getAddress()); - txTemp.dataAccount(dataAccount.getAddress()).setText(key, value, version); - txTemp.dataAccount(dataAccount.getAddress()).setTimestamp(UUID.randomUUID().toString(),System.currentTimeMillis(),-1); - - // TX 准备就绪 - commit(txTemp,signAdminKey); - - //get the version - TypedKVEntry[] kvData = blockchainService.getDataEntries(ledgerHash, - dataAccount.getAddress().toBase58(), key); - System.out.println(String.format("key1 info:key=%s,value=%s,version=%d", - kvData[0].getKey(),kvData[0].getValue().toString(),kvData[0].getVersion())); - - return dataAccount; - } - - public void deployContract(){ - ContractParams contractParams = new ContractParams(); - contractParams.setContractZipName("contract-compile-1.3.0.RELEASE.car").setDeploy(true).setExecute(false); - BlockchainIdentity contractAddress = - this.contractHandle(contractParams); - contractParams.setContractIdentity(contractAddress); - this.contractHandle(contractParams); - this.contractHandle(contractParams.setExecute(true)); - } -} diff --git a/deploy/docker/docker-sdk/src/main/java/com/jd/blockchain/SDKDemo_Constant.java b/deploy/docker/docker-sdk/src/main/java/com/jd/blockchain/SDKDemo_Constant.java deleted file mode 100644 index cfdd0140..00000000 --- a/deploy/docker/docker-sdk/src/main/java/com/jd/blockchain/SDKDemo_Constant.java +++ /dev/null @@ -1,46 +0,0 @@ -package com.jd.blockchain; - -import com.jd.blockchain.crypto.KeyGenUtils; -import com.jd.blockchain.crypto.PrivKey; -import com.jd.blockchain.crypto.PubKey; -import com.jd.blockchain.ledger.BlockchainKeypair; -import org.apache.commons.io.FileUtils; -import org.springframework.core.io.ClassPathResource; - -import java.io.File; -import java.io.InputStream; - -public class SDKDemo_Constant { - - public static String GW_IPADDR = "localhost"; - public static int GW_PORT = 8080; - public static String GW_PUB_KEY = "7VeRL1kWpYpvawkgFbM9N9ao1YiAE9HW65QpwLvpw6oPjCnZ"; - public static String GW_PRIV_KEY = "177gk2PbxhHeEdfAAqGfShJQyeV4XvGsJ9CvJFUbToBqwW1YJd5obicySE1St6SvPPaRrUP"; - public static String GW_PASSWORD = "8EjkXVSTxMFjCvNNsTo8RBMDEVQmk7gYkW4SCDuvdsBG"; - - public static PrivKey gwPrivkey0 = KeyGenUtils.decodePrivKey(GW_PRIV_KEY, GW_PASSWORD); - public static PubKey gwPubKey0 = KeyGenUtils.decodePubKey(GW_PUB_KEY); - public static BlockchainKeypair adminKey = new BlockchainKeypair(gwPubKey0, gwPrivkey0); - - public static final byte[] readChainCodes(String contractZip) { - // 构建合约的字节数组; - try { - ClassPathResource contractPath = new ClassPathResource(contractZip); -// File contractFile = new File(contractPath.getURI()); - - InputStream in = contractPath.getInputStream(); - // 将文件写入至config目录下 - File directory = new File("."); - String configPath = directory.getAbsolutePath() + File.separator + "contract.jar"; - File targetFile = new File(configPath); - // 先将原来文件删除再Copy - if (targetFile.exists()) { - FileUtils.forceDelete(targetFile); - } - FileUtils.copyInputStreamToFile(in, targetFile); - return FileUtils.readFileToByteArray(targetFile); - } catch (Exception e) { - throw new IllegalStateException(e); - } - } -} diff --git a/deploy/docker/docker-sdk/src/main/java/com/jd/blockchain/SDK_Base_Demo.java b/deploy/docker/docker-sdk/src/main/java/com/jd/blockchain/SDK_Base_Demo.java deleted file mode 100644 index 4f321b13..00000000 --- a/deploy/docker/docker-sdk/src/main/java/com/jd/blockchain/SDK_Base_Demo.java +++ /dev/null @@ -1,192 +0,0 @@ -package com.jd.blockchain; - -import static com.jd.blockchain.SDKDemo_Constant.readChainCodes; -import static com.jd.blockchain.transaction.ContractReturnValue.decode; - -import com.jd.blockchain.crypto.HashDigest; -import com.jd.blockchain.ledger.BlockchainIdentity; -import com.jd.blockchain.ledger.BlockchainKeyGenerator; -import com.jd.blockchain.ledger.BlockchainKeypair; -import com.jd.blockchain.ledger.PreparedTransaction; -import com.jd.blockchain.ledger.TransactionResponse; -import com.jd.blockchain.ledger.TransactionTemplate; -import com.jd.blockchain.sdk.BlockchainService; -import com.jd.blockchain.sdk.client.GatewayServiceFactory; -import com.jd.blockchain.transaction.GenericValueHolder; -import com.jd.chain.contract.TransferContract; - -import utils.Bytes; - -public abstract class SDK_Base_Demo { - protected BlockchainKeypair adminKey; - - protected HashDigest ledgerHash; - - protected BlockchainService blockchainService; - - public SDK_Base_Demo() { - init(); - } - - public void init() { - // 生成连接网关的账号 - adminKey = SDKDemo_Constant.adminKey; - - // 连接网关 - GatewayServiceFactory serviceFactory = GatewayServiceFactory.connect(SDKDemo_Constant.GW_IPADDR, - SDKDemo_Constant.GW_PORT, false, adminKey); - - // 获取网关对应的Service处理类 - blockchainService = serviceFactory.getBlockchainService(); - - HashDigest[] ledgerHashs = blockchainService.getLedgerHashs(); - // 获取当前账本Hash - ledgerHash = ledgerHashs[0]; - } - - public TransactionResponse commit(TransactionTemplate txTpl){ - return this.commitA(txTpl,null); - } - - /** - * 默认使用A方式commit; - * @param txTpl - * @param signAdminKey - * @return - */ - public TransactionResponse commit(TransactionTemplate txTpl, BlockchainKeypair signAdminKey){ - return commitA(txTpl, signAdminKey); - } - - /** - * 采用A方式提交; - * @param txTpl - * @param signAdminKey - * @return - */ - public TransactionResponse commitA(TransactionTemplate txTpl, BlockchainKeypair signAdminKey) { - PreparedTransaction ptx = txTpl.prepare(); - - if(signAdminKey != null){ - System.out.println("signAdminKey's pubKey = "+signAdminKey.getIdentity().getPubKey()); - ptx.sign(signAdminKey); - }else { - System.out.println("adminKey's pubKey = "+adminKey.getIdentity().getPubKey()); - ptx.sign(adminKey); - } - TransactionResponse transactionResponse = ptx.commit(); - - if (transactionResponse.isSuccess()) { - System.out.println(String.format("height=%d, ###OK#, contentHash=%s, executionState=%s", - transactionResponse.getBlockHeight(), - transactionResponse.getContentHash(), transactionResponse.getExecutionState().toString())); - } else { - System.out.println(String.format("height=%d, ###exception#, contentHash=%s, executionState=%s", - transactionResponse.getBlockHeight(), - transactionResponse.getContentHash(), transactionResponse.getExecutionState().toString())); - } - return transactionResponse; - } - - /** - * 生成一个区块链用户,并注册到区块链; - */ - public BlockchainKeypair registerUser() { - return this.registerUser(null,null,null); - } - - public BlockchainKeypair registerUser(String cryptoType, BlockchainKeypair signAdminKey, BlockchainKeypair userKeypair) { - // 在本地定义注册账号的 TX; - TransactionTemplate txTemp = blockchainService.newTransaction(ledgerHash); - if(userKeypair == null){ - if("SM2".equals(cryptoType)){ - userKeypair = BlockchainKeyGenerator.getInstance().generate(cryptoType); - }else { - userKeypair = BlockchainKeyGenerator.getInstance().generate(); - } - } - System.out.println("user'address="+userKeypair.getAddress()); - txTemp.users().register(userKeypair.getIdentity()); - // TX 准备就绪; - commit(txTemp,signAdminKey); - return userKeypair; - } - - public BlockchainKeypair registerUser(BlockchainKeypair signAdminKey, BlockchainKeypair userKeypair) { - return registerUser(null,signAdminKey,userKeypair); - } - - /** - * 生成一个区块链用户,并注册到区块链; - */ - public BlockchainKeypair registerUserByNewSigner(BlockchainKeypair signer) { - return this.registerUser(signer,null); - } - - public BlockchainIdentity createDataAccount() { - // 首先注册一个数据账户 - BlockchainKeypair newDataAccount = BlockchainKeyGenerator.getInstance().generate(); - - TransactionTemplate txTpl = blockchainService.newTransaction(ledgerHash); - txTpl.dataAccounts().register(newDataAccount.getIdentity()); - commit(txTpl); - return newDataAccount.getIdentity(); - } - - public String create1(Bytes contractAddress, String address, String account, String content) { - System.out.println(String.format("params,String address=%s, String account=%s, String content=%s, Bytes contractAddress=%s", - address,account,content,contractAddress.toBase58())); - TransactionTemplate txTpl = blockchainService.newTransaction(ledgerHash); - // 使用合约创建 - TransferContract guanghu = txTpl.contract(contractAddress, TransferContract.class); - GenericValueHolder result = decode(guanghu.putval(address, account, content, System.currentTimeMillis())); - commit(txTpl); - return result.get(); - } - - public BlockchainIdentity contractHandle(ContractParams contractParams) { - if(contractParams.getContractZipName() == null){ - contractParams.setContractZipName("contract-JDChain-Contract.jar"); - } - // 发布jar包 - // 定义交易模板 - TransactionTemplate txTpl = blockchainService.newTransaction(ledgerHash); - Bytes contractAddress = null; - if(contractParams.getContractIdentity() != null){ - contractAddress = contractParams.getContractIdentity().getAddress(); - } - - if(contractParams.isDeploy){ - // 将jar包转换为二进制数据 - byte[] contractCode = readChainCodes(contractParams.getContractZipName()); - - // 生成一个合约账号 - if(contractParams.getContractIdentity() == null){ - contractParams.setContractIdentity(BlockchainKeyGenerator.getInstance().generate().getIdentity()); - } - contractAddress = contractParams.getContractIdentity().getAddress(); - System.out.println("contract's address=" + contractAddress); - - // 生成发布合约操作 - txTpl.contracts().deploy(contractParams.contractIdentity, contractCode); - - // 生成预发布交易; - commit(txTpl,contractParams.getSignAdminKey()); - } - - if(contractParams.isExecute){ - // 注册一个数据账户 - if(contractParams.dataAccount == null){ - contractParams.dataAccount = createDataAccount(); - contractParams.key = "jd_zhangsan"; - contractParams.value = "{\"dest\":\"KA006\",\"id\":\"cc-fin08-01\",\"items\":\"FIN001|3030\",\"source\":\"FIN001\"}"; - } - // 获取数据账户地址x - String dataAddress = contractParams.dataAccount.getAddress().toBase58(); - // 打印数据账户地址 - System.out.printf("DataAccountAddress = %s \r\n", dataAddress); - System.out.println("return value = "+create1(contractAddress, dataAddress, contractParams.key, contractParams.value)); - } - return contractParams.contractIdentity; - } -} diff --git a/deploy/docker/docker-sdk/src/main/java/com/jd/chain/contract/TransferContract.java b/deploy/docker/docker-sdk/src/main/java/com/jd/chain/contract/TransferContract.java deleted file mode 100644 index a3a41529..00000000 --- a/deploy/docker/docker-sdk/src/main/java/com/jd/chain/contract/TransferContract.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.jd.chain.contract; - -import com.jd.blockchain.contract.Contract; -import com.jd.blockchain.contract.ContractEvent; - -@Contract -public interface TransferContract { - - @ContractEvent(name = "create") - String create(String address, String account, long money); - - @ContractEvent(name = "transfer") - String transfer(String address, String from, String to, long money); - - @ContractEvent(name = "read") - long read(String address, String account); - - @ContractEvent(name = "readAll") - String readAll(String address, String account); - - @ContractEvent(name = "putval1") - String putval(String address, String account, String content, Long time); - - @ContractEvent(name = "putvalBif") - String putvalBifurcation(String address, String account, String content, String isHalf); - - @ContractEvent(name = "getTxSigners") - String getTxSigners(String input); - - @ContractEvent(name = "test") - String test(String input); -} diff --git a/deploy/docker/docker-sdk/src/main/resources/contract-compile-1.3.0.RELEASE.car b/deploy/docker/docker-sdk/src/main/resources/contract-compile-1.3.0.RELEASE.car deleted file mode 100644 index cd7c3c825ef6c2d305a0a7e3c1ea974825205a86..0000000000000000000000000000000000000000 GIT binary patch literal 0 KcmV+b0RR6000031 literal 5129 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 diff --git a/deploy/docker/pom.xml b/deploy/docker/pom.xml deleted file mode 100644 index c2041624..00000000 --- a/deploy/docker/pom.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - com.jd.blockchain - deploy-root - 1.5.0.RELEASE - - 4.0.0 - pom - - docker - - - 1.4.3.RELEASE - - - - docker-sdk - docker-demo - - - \ No newline at end of file diff --git a/deploy/docker/readme.md b/deploy/docker/readme.md deleted file mode 100644 index 72f9c804..00000000 --- a/deploy/docker/readme.md +++ /dev/null @@ -1,44 +0,0 @@ -# jdchain-demo镜像使用说明 -本镜像主要为快速构建JDChain测试环境使用,内嵌固定的公私钥,不可用于生产正式环境。 -JDChain在docker中的安装路径:/export/jdchain,网关对外端口为:8080。可通过docker-compose-all文件来修改端口。 -demo环境构建完成后执行sdk加载部分测试数据,区块高度:7,交易总数:8,用户总数:5,数据账户总数:2,合约总数:1。 - -## 如何生成镜像 -1. 如果构建的docker镜像为当前开发版本,将docker模块中的跟主版本对齐,然后在deploy模块执行:mvn clean package即可。 -如果镜像版本与所在开发版本不一致(举例说明:构建1.3.0的镜像版本,但当前开发版本是1.4.0),需要预先在deploy-peer和deploy-gateway的 -target文件夹下放置相应版本zip安装包(jdchain-peer-xxx.zip,jdchain-gateway-xxx.zip),然后在docker模块执行:mvn clean package。 -2. 在maven构建过程中,两个zip安装包和docker-sdk-xxx.jar,会放至docker-demo模块src/main/docker/zip文件夹下。 -3. maven构建完成后,控制台执行:docker images,可看到构建的jdchain-peer镜像。 -4. 生成镜像文件。执行docker-demo模块中src/main/resources/zip.sh,可生成镜像的tar.gz压缩包; - -## 镜像快速使用 -1.在已经安装docker工具的环境中,装入jdchain-demo镜像: -```` -docker load -i jdchain-demo_1.3.0.tar.gz -```` -2.启动脚本 -每次执行启动脚本时,会删除原有的容器,然后重新构建全新的容器。 -所以每次执行之后,会清除原先链上新增的区块。 -```` -sh start-net.sh -```` -3.卸载容器 -如果不再使用容器,在start-net.sh脚本所在路径下执行: -```` -docker-compose -f docker-compose-all.yaml down -```` - -## SDK连接网关参数 -```` -ip=localhost -port=8080 -#默认公钥的内容(Base58编码数据); -keys.default.pubkey=7VeRL1kWpYpvawkgFbM9N9ao1YiAE9HW65QpwLvpw6oPjCnZ -#默认私钥的内容(加密的Base58编码数据);在 pk-path 和 pk 之间必须设置其一; -keys.default.privkey=177gk2PbxhHeEdfAAqGfShJQyeV4XvGsJ9CvJFUbToBqwW1YJd5obicySE1St6SvPPaRrUP -#默认私钥的解码密码; -keys.default.privkey-password=8EjkXVSTxMFjCvNNsTo8RBMDEVQmk7gYkW4SCDuvdsBG -```` - - - diff --git a/deploy/pom.xml b/deploy/pom.xml index f5491a8e..92566af0 100644 --- a/deploy/pom.xml +++ b/deploy/pom.xml @@ -5,22 +5,21 @@ com.jd.blockchain jdchain-parent - 1.1.5.RELEASE + 1.1.6-SNAPSHOT ../project/parent deploy-root - 1.5.0.RELEASE + 1.6.0-SNAPSHOT pom - 1.5.0.RELEASE + 1.6.0-SNAPSHOT ../core deploy-gateway deploy-peer - docker diff --git a/docs/ca.md b/docs/ca.md new file mode 100644 index 00000000..75ac8f97 --- /dev/null +++ b/docs/ca.md @@ -0,0 +1,150 @@ +## 证书 + +`JD Chain`身份认证支持两种模式:`KEYPAIR`(默认)/`CA`,即公私钥对和证书。 + +证书模式采用`X.509`标准的数字证书作为用户标识,证书字段中,附加组织和角色等信息。 + +`JD Chain`使用`jdchain-cli`/`openssl`生成的自签名证书,也支持使用`CFCA`等国家认可的第三方`CA`颁发的外部证书。 + +`JD Chain` `CA`支持`RSA 2048`/`ECDSA P-256`/`SM2 SM3WithSM2`/`ED25519`四种签名算法。 + + +### 类别 + +`JD Chain`证书体系分`ROOT`,`CA`,`PEER`,`GW`,`USER`几个类别。 + +使用证书`Subject`中`OU`字段区分。 + +#### ROOT + +根证书,可用于签发证书及账本初始化时作为账本证书。 + +#### CA + +中间证书,可用于签发证书及账本初始化时作为账本证书。 + +#### PEER + +共识节点证书,注册参与方时需要提供`PEER`类型证书。 + +#### GW + +网关证书,网关所配置公私钥对应账户信息在链上必须存储有`GW`类型的证书。 + +#### USER + +普通用户证书 + +### 实现 + +`JD Chain`证书使用链上存储方式。主要存储于两个地方: +- 元数据区,存储账本初始化时配置的根证书列表 +- 用户账户头部,存储用户注册时提供的证书 + +> 根证书支持列表,即支持多个参与机构使用不同的证书链,且根证书可使用`ROOT`证书,也可使用`CA`(中间)证书,但节点/网关/用户证书必须由配置在`JD Chain`根证书列表中的证书直接签出。 + +#### 账本初始化 + +*`ledger.init`* +较`KEYPAIR`模式有如下修改: + +1. `identity-mode` +```properties +identity-mode=CA +``` +`identity-mode`身份认证模式,`KEYPAIR`(默认)/`CA` + +2. `root-ca-path` +```properties +root-ca-path=/**/ledger1.crt,/**/ledger2.crt +``` +`root-ca-path`根证书列表,使用`ROOT`或者`CA`类型证书,多个根证书使用半角逗号分割。初始化完成后,证书信息会上链存储,通过[2.7 获取账本初始化配置信息](api.md#27-获取账本初始化配置信息)可查。 + +3. `cons_parti.*.ca-path` + +**CA 模式参与方需要增加配置网关信息,网关节点IP和端口不需要填写** + +节点公钥配置改为证书地址: + +```properties +// KEYPAIR +// cons_parti.0.pubkey-path= +// cons_parti.0.pubkey= + +// CA +cons_parti.0.ca-path=/**/peer0.crt +``` + +*`local.conf`* +较`KEYPAIR`模式有如下修改: +```properties +#当前参与方的公钥,用于非证书模式 +# local.parti.pubkey= +#当前参与方的证书信息,用于证书模式 +local.parti.ca-path= + +#当前参与方的私钥文件,PEM格式,用于证书模式 +local.parti.privkey-path= +``` + +#### 节点运行 + +节点启动和运行时会校验证书类型,时间有效性以及是否由某个根证书签出等,一旦校验失败会阻止网关接入,不再对外服务。 + +#### 网关接入 + +*gateway.conf* +```properties +#默认公钥的内容(Base58编码数据),非CA模式下必填; +keys.default.pubkey= +#默认网关证书路径(X509,PEM),CA模式下必填; +keys.default.ca-path=/home/imuge/jd/nodes/peer0/config/keys/gw1.crt +#默认私钥的路径;在 pk-path 和 pk 之间必须设置其一; +keys.default.privkey-path=/home/imuge/jd/nodes/peer0/config/keys/gw1.key +#默认私钥的内容(加密的Base58编码数据);在 pk-path 和 pk 之间必须设置其一; +keys.default.privkey= +``` + +网关接入网络需要配置`GW`类型证书及对应的私钥信息,证书类型必须是`GW`。 + +网关接入时会做如下认证: +- 证书类型包含`GW` +- 根证书列表存在类型正确且有效证书 +- 网关证书由根证书列表中某个证书签出(此证书类型正确且有效) + +#### 交易认证 + +交易时使用证书持有者私钥签名,交易内容不包含签名用户证书信息。 +交易执行前会校验所有账本根证书,签名终端用户和节点用户的证书类型及有效性。 + +> 请务必在证书到期前更新证书有效期 + +#### 证书更新 + +1. 根证书 + +`SDK`方式: +```java +TransactionTemplate txTemp = blockchainService.newTransaction(ledger); +txTemp.metaInfo().ca(X509Utils.resolveCertificate("*.crt")); +``` + +命令行方式:[更新账本证书](tx.md#更新账本证书) + +2. 节点/网关/普通用户证书 + +> 在`JD Chain`中,共识节点,网关配置的接入账户和普通用户本质都是用户账户类型,它们对应的证书管理方式一致。 + +`SDK`方式: + +```java +txTemp.user("user address").ca(X509Utils.resolveCertificate("*.crt")); +``` + +命令行方式:[更新用户证书](tx.md#更新用户证书) + +### 证书生成 + +使用`jdchain-cli`提供的[keys](cli/keys.md)和[ca](cli/ca.md)指令工具创建公私钥对以及签发证书。 + +其中[ca-test](cli/ca.md#生成测试证书)可一键生成账本初始化所需的所有证书外加可用的普通用户证书。 \ No newline at end of file diff --git a/docs/cli/ca.md b/docs/cli/ca.md new file mode 100644 index 00000000..a8a8699e --- /dev/null +++ b/docs/cli/ca.md @@ -0,0 +1,248 @@ +### 证书管理 + +`jdchain-cli`提供**`ED25519`,`RSA`,`ECDSA`,`SM2`**密钥算法的证书签发工具:[证书列表](#证书列表),[显示证书](#显示证书),[CSR](#CSR),[CRT](#CRT),[更新证书](#更新证书),[生成测试证书](#生成测试证书) + +> 目前支持创建`ED25519`,RSA`,`ECDSA`,`SM2`四种签名算法,请使用对应算法的公私钥 + +```bash +:bin$ ./jdchain-cli.sh ca -h +Usage: jdchain-cli ca [-hV] [--pretty] [--home=] [COMMAND] +List, create, update certificates. + -h, --help Show this help message and exit. + --home= Set the home directory. + Default: ../ + --pretty Pretty json print + -V, --version Print version information and exit. +Commands: + list List all the certificates. + show Show certificate. + csr Create certificate signing request. + crt Create new certificate. + renew Update validity period. + test Create certificates for a testnet. + help Displays help information about the specified command +``` +- `home`,指定密钥和证书存储相关目录,`${home}/config/keys` + +#### 证书列表 +```bash +:bin$ ./jdchain-cli.sh ca list -h +List all the certificates. +Usage: jdchain-cli ca list [-hV] [--pretty] [--home=] + -h, --help Show this help message and exit. + --home= Set the home directory. + --pretty Pretty json print + -V, --version Print version information and exit. +``` + +如: +```bash +:bin$ ./jdchain-cli.sh keys list +NAME ALGORITHM ADDRESS PUBKEY +``` +- `NAME`,名称 +- `ALGORITHM`,算法 +- `ADDRESS`,地址 +- `PUBKEY`,公钥 + +#### 显示证书 +```bash +:bin$ ./jdchain-cli.sh ca show -h +Show certificate. +Usage: jdchain-cli ca show [-hV] [--pretty] [--home=] -n= + -h, --help Show this help message and exit. + --home= Set the home directory. + -n, --name= Name of the certificate + --pretty Pretty json print + -V, --version Print version information and exit. +``` +- `name`,证书名称 + +如显示`${home}/config/keys`下名为`G1`的证书信息: +```bash +:bin$ ./jdchain-cli.sh ca show -n G1 +./jdchain-cli.sh ca show -n G1 +NAME ALGORITHM TYPE ROLE PUBKEY +G1 SM2 ROLE-TODO [GW] SFZ6LjGKVz6wdU4G9PAraojyzCYPJ1BXAg1XBwSPCMC6Ug6u5oom5zcLPUzWtz42aCp9PLGXpHweBjSu3EW2aDzsa4JoT + [0] Version: 3 + SerialNumber: 440724497 + IssuerDN: O=JDT,OU=ROOT,C=CN,ST=BJ,L=BJ,CN=ROOT,E=imuge@jd.com + Start Date: Fri Sep 03 16:43:01 GMT+08:00 2021 + Final Date: Thu May 30 16:43:01 GMT+08:00 2024 + SubjectDN: O=JDT,OU=GW,C=CN,ST=BJ,L=BJ,CN=G1,E=imuge@jd.com + Public Key: EC Public Key [c0:b9:58:d1:35:3d:a9:bc:1d:85:2a:ea:bf:57:80:39:e9:f6:57:6d] + X: 67e4a4afe0a5beb1e5fb6e915314a9ed94b74f449cc4f50314ff78ecf62ba786 + Y: 2d5c233bfcd582f0c1098dbe4f1319db074fcf00023fdc9f3461a8d01488d9f2 + + Signature Algorithm: SM3WITHSM2 + Signature: 3046022100b70107554a723ec96569bbb23c65cb + ac6d7934f47722aa50f18a5e9ca3a978b9022100 + 9b68e5f3bd14bf103248c8516c493e5e1d9a872c + 39841c3704686ca85311bac0 +``` + +#### CSR + +生成证书请求文件 +```bash +:bin$ ./jdchain-cli.sh ca csr -h +Create certificate signing request. +Usage: jdchain-cli ca csr [-hV] [--pretty] [--home=] [-n=] + [--priv=] [--pub=] + -h, --help Show this help message and exit. + --home= Set the home directory. + -n, --name= Name of the key + --pretty Pretty json print + --priv= Path of the private key file + --pub= Path of the public key file + -V, --version Print version information and exit. +``` + +- `name`,密钥对名称,创建公私钥请参照[keys](keys.md)文档说明 + +如使用`${home}/config/keys`下名为`ROOT`的公私钥信息创建`CSR`: +```bash +:bin$ ./jdchain-cli.sh ca csr -n ROOT +// 选择证书角色,输入对应数字即可,多个角色使用半角逗号相隔 +input certificate roles (0 for ROOT, 1 for CA, 2 for PEER, 3 for GW, 4 for USER. multi values use ',' split): +> 1 +input country: +> CN +input locality: +> BJ +input province: +> BJ +input organization name: +> JDT +input email address: +> imuge@jd.com +// 输入ROOT私钥密码 +input password of the key: +> 1 +create [${home}/config/keys/ROOT.csr] success +``` +成功后会创建`${home}/config/keys/ROOT.csr`文件。 + +#### CRT + +签发证书: +```bash +:bin$ ./jdchain-cli.sh ca crt -h +Create new certificate. +Usage: jdchain-cli ca crt [-hV] [--pretty] [--csr=] --days= + [--home=] [--issuer-crt=] + [--issuer-name=] + [--issuer-priv=] [-n=] + --csr= Path of the certificate signing request file + --days= Days of certificate validity + -h, --help Show this help message and exit. + --home= Set the home directory. + --issuer-crt= + Path of the issuer certificate file + --issuer-name= + Name of the issuer key + --issuer-priv= + Path of the issuer private key file + -n, --name= Name of the certificate signing request file + --pretty Pretty json print + -V, --version Print version information and exit. +``` + +- `name`,`CSR`文件名,不为空时要求在`${home}/config/keys`目录下存在`${name.csr}`文件 +- `csr`,`CSR`文件路径,与`name`二选一,优先使用`name`参数 +- `days`,证书有效天数,当前签发时间开始计算 +- `issuer-name`,签发者公私钥对名称,不为空时需要`${home}/config/keys`目录下至少存在`${issuer-name}.priv`,`${issuer-name}.crt` +- `issuer-crt`,签发者证书文件 +- `issuer-priv`,签发者私钥文件 +> `issuer-name`为空时,`issuer-crt`和`issuer-priv`必须同时提供 + + +如使用`${home}/config/keys`下名为`ROOT`签发自签名证书: +```bash +./jdchain-cli.sh ca crt -n CA --issuer-name ROOT --days 1000 +// 输入签发者私钥密码 +input password of the issuer: +> 1 +create [${home}/config/keys/ROOT.crt] success +``` + +#### 更新证书 + +仅可更新证书有效天数 +```bash +Update validity period. +Usage: jdchain-cli ca renew [-hV] [--pretty] [--crt=] --days= + [--home=] [--issuer-crt=] + [--issuer-name=] + [--issuer-priv=] [-n=] + --crt= File of the certificate + --days= Days of certificate validity + -h, --help Show this help message and exit. + --home= Set the home directory. + --issuer-crt= + Path of the issuer certificate file + --issuer-name= + Name of the issuer key + --issuer-priv= + Path of the issuer private key file + -n, --name= Name of the certificate + --pretty Pretty json print + -V, --version Print version information and exit. +``` +- `name`,`CRT`文件名,不为空时要求在`${home}/config/keys`目录下存在`${name.crt}`文件 +- `crt`,`CRT`文件路径,与`name`二选一,优先使用`name`参数 +- `days`,证书有效天数,当前签发时间开始计算 +- `issuer-name`,签发者公私钥对名称,不为空时需要`${home}/config/keys`目录下至少存在`${issuer-name}.priv`,`${issuer-name}.crt` +- `issuer-crt`,签发者证书文件 +- `issuer-priv`,签发者私钥文件 +> `issuer-name`为空时,`issuer-crt`和`issuer-priv`必须同时提供 + +如更新`${home}/config/keys`下名为`ROOT`证书有效期: +```bash +./jdchain-cli.sh ca crt -n ROOT --issuer-name ROOT --days 2000 +input password of the issuer: +> 1 +renew [${home}/config/keys/ROOT.crt] success success +``` + +#### 生成测试证书 + +一键生成可用于初始化`JD Chain`网络及使用需要的证书 +```bash +:bin$ ./jdchain-cli.sh ca test -h +Create certificates for a testnet. +Usage: jdchain-cli ca test [-hV] [--pretty] [-a=] + --country= --email= [--gws=] + [--home=] --locality= + [--nodes=] --org= + [-p=] --province= + [--users=] + -a, --algorithm= + Crypto algorithm + --country= Country + --email= Email address + --gws= Gateway size + -h, --help Show this help message and exit. + --home= Set the home directory. + --locality= Locality + --nodes= Node size + --org= Organization name + -p, --password= Password of the key + --pretty Pretty json print + --province= Province + --users= Available user size + -V, --version Print version information and exit. +``` +- `algorithm`,签名算法,默认`ED25519`,仅支持传入`ED25519`, `RSA`,`ECDSA`,`SM2`之一 +- `nodes`,共识节点个数,生成`nodes`个`PEER`类型的证书,可用于节点使用。默认:`4` +- `gws`,网关节点个数,生成`gws`个`GW`类型的证书,可用于网关使用。默认:`1` +- `users`,用户个数,生成`users`可个可用于普通用户使用的证书。默认:`10` + +如创建基于`SM2`签名算法的一个`ROOT`类型证书,`4`个节点证书,`1`个网关证书,`10`个用户证书: +```bash +:bin$ ./jdchain-cli.sh ca test --org JDT --country CN --locality BJ --province BJ --email jdchain@jd.com +input private key password: +// 输入操作过程中生成的私钥加密密码 +> 1 +create test certificates in [${home}/config/keys] success +``` \ No newline at end of file diff --git a/docs/cli/keys.md b/docs/cli/keys.md index 29ca2b49..64305d1c 100644 --- a/docs/cli/keys.md +++ b/docs/cli/keys.md @@ -77,6 +77,8 @@ Usage: jdchain-cli keys add [-hV] [--pretty] [-a=] [--home=] --home= Set the home directory. -n, --name= Name of the key --pretty Pretty json print + -p, --password= + Password of the key -V, --version Print version information and exit. ``` diff --git a/docs/cli/participant.md b/docs/cli/participant.md index ad4a0986..7f6eb7c7 100644 --- a/docs/cli/participant.md +++ b/docs/cli/participant.md @@ -27,35 +27,39 @@ Commands: ```bash :bin$ ./jdchain-cli.sh participant register -h Register new participant. -Usage: jdchain-cli participant register [-hV] [--pretty] [--gw-host=] +Usage: jdchain-cli participant register [-hV] [--ca-mode] [--pretty] + [--crt=] [--gw-host=] [--gw-port=] [--home=] - --name= + [-n=] + --participant-name= + [--pubkey=] + --ca-mode Register with CA + --crt= File of the X509 certificate --gw-host= Set the gateway host. Default: 127.0.0.1 --gw-port= Set the gateway port. Default: 8080 -h, --help Show this help message and exit. --home= Set the home directory. - --name= Name of the participant + -n, --name= Name of the key + --participant-name= + Name of the participant --pretty Pretty json print + --pubkey= Pubkey of the user -V, --version Print version information and exit. ``` -- `name`,新节点名称 +- `participant-name`,新节点名称 +- `ca-mode`,身份认证模式是否为证书(`CA`)模式,默认`false` +- `name`,当`ca-mode`为`true`时会读取本地`${home}/config/keys/${name}.crt`文件,反之读取`${home}/config/keys/${name}.pub` +- `crt`,证书文件路径 +- `pubkey`,`Base58`编码公钥信息,仅在非`ca-mode`情况下使用 注册新节点: ```bash -:bin$ ./jdchain-cli.sh participant register --name node4 +:bin$ ./jdchain-cli.sh participant register --participant-name node4 --name node4 select ledger, input the index: INDEX LEDGER 0 j5sB3sVTFgTqTYzo7KtQjBLSy8YQGPpJpvQZaW9Eqk46dg // 选择账本 > 0 -// 选择待注册节点公私钥(链上必须不存在此公私钥对应的用户) -select keypair to register, input the index: -0 k1 LdeNq3862vtUCeptww1T5mVvLbAeppYqVNdqD -1 1627618939 LdeNyibeafrAQXgHjBxgQxoLbna6hL4BcXZiw -2 node4 LdeNwG6ECEGz57o2ufhwSbnW4C35TvPqANK7T -2 -input password of the key: -> 1 // 选择此交易签名用户(必须是链上存在的用户,且有相应操作权限) select keypair to sign tx, input the index: 0 k1 LdeNq3862vtUCeptww1T5mVvLbAeppYqVNdqD @@ -199,20 +203,16 @@ Usage: jdchain-cli participant inactive [-hV] [--pretty] --address=

--ledger= Set the ledger. --port= Set the participant service port. --pretty Pretty json print - --syn-host= Set synchronization participant host. - --syn-port= Set synchronization participant port. -V, --version Print version information and exit. ``` - `ledger`,账本哈希 - `address`,待移除节点共识端口 - `host`,待移除节点服务地址 - `port`,待移除节点服务端口 -- `syn-host`,数据同步节点地址 -- `syn-port`,数据同步节点服务端口 如移除`node4`: ```bash -:bin$ ./jdchain-cli.sh participant inactive --ledger j5sB3sVTFgTqTYzo7KtQjBLSy8YQGPpJpvQZaW9Eqk46dg --address LdeNwG6ECEGz57o2ufhwSbnW4C35TvPqANK7T --host 127.0.0.1 --port 7084 --syn-host 127.0.0.1 --syn-port 7080 +:bin$ ./jdchain-cli.sh participant inactive --ledger j5sB3sVTFgTqTYzo7KtQjBLSy8YQGPpJpvQZaW9Eqk46dg --address LdeNwG6ECEGz57o2ufhwSbnW4C35TvPqANK7T --host 127.0.0.1 --port 7084 participant inactivated ``` diff --git a/docs/cli/tx.md b/docs/cli/tx.md index 0d67aa4a..0cc2bffe 100644 --- a/docs/cli/tx.md +++ b/docs/cli/tx.md @@ -2,7 +2,8 @@ ```bash :bin$ ./jdchain-cli.sh tx -h -Usage: git status [...] [--] [...] +Usage: jdchain-cli tx [-hV] [--pretty] [--export=] [--gw-host=] + [--gw-port=] [--home=] [COMMAND] Build, sign or send transaction. --export= Transaction export directory --gw-host= Set the gateway host. Default: 127.0.0.1 @@ -15,14 +16,19 @@ Build, sign or send transaction. --pretty Pretty json print -V, --version Print version information and exit. Commands: + ledger-ca-update Update ledger certificates. user-register Register new user. + user-ca-update Update user certificate. + user-state-update Update user(certificate) state. role Create or config role. authorization User role authorization. data-account-register Register new data account. kv Set key-value. event Publish event. + event-listen Subscribe event. contract-deploy Deploy or update contract. contract Call contract method. + contract-state-update Update contract state. event-account-register Register event account. sign Sign transaction. send Send transaction. @@ -36,53 +42,102 @@ Commands: - `home`,指定密钥存储相关目录,`${home}/config/keys` 命令: +- `ledger-ca-update`,[更新账本证书](#更新账本证书) - `user-register`,[注册用户](#注册用户) +- `user-ca-update`,[更新用户证书](#更新用户证书) +- `user-state-update`,[更新用户(证书)状态](#更新用户(证书)状态) - `role`,[角色管理](#角色管理) - `authorization`,[权限配置](#权限配置) - `data-account-register`,[注册数据账户](#注册数据账户) - `kv`,[KV设值](#KV设值) -- `event-account-register`,[注册事件账户](#注册事件账户) +- `event-account-register`,[注册事件账户](#注册事件账户) - `event`,[发布事件](#发布事件) +- `event-listen`,[监听事件](#监听事件) - `contract-deploy`,[部署合约](#部署合约) - `contract`,[合约调用](#合约调用) +- `contract-state-update`,[更新合约状态](#更新合约状态) - `sign`,[离线交易签名](#离线交易签名) - `send`,[离线交易发送](#离线交易发送) +#### 更新账本证书 + +```bash +:bin$ ./jdchain-cli.sh tx ledger-ca-update -h +Update ledger certificates. +Usage: jdchain-cli tx ledger-ca-update [-hV] [--pretty] --crt= + [--export=] [--gw-host=] + [--gw-port=] [--home=] + --crt= File of the X509 certificate + --operation Operation for this certificate. Optional values: ADD,UPDATE,REMOVE + --export= Transaction export directory + --gw-host= Set the gateway host. Default: 127.0.0.1 + --gw-port= Set the gateway port. Default: 8080 + -h, --help Show this help message and exit. + --home= Set the home directory. + --pretty Pretty json print + -V, --version Print version information and exit. +``` +- `crt`,证书文件路径 +- `operation`,操作类型:`ADD`,`UPDATE`,`REMOVE` + +如: +```bash +:bin$ $ ./jdchain-cli.sh tx ledger-ca-update --crt /home/imuge/jd/nodes/peer0/config/keys/ledger.crt --operation UPDATE +select ledger, input the index: +INDEX LEDGER +0 j5pFrMigE47t6TobQJXsztnoeA29H31v1vHHF1wqCp4rzi +// 选择账本,当前网关服务只有上面一个可用账本 +> 0 +select keypair to sign tx: +INDEX KEY ADDRESS +0 peer0 LdeNpEmyh5DMwbAwamxNaiJgMVGn6aTtQDA5W +// 选择链上已存在且有注册用户权限的用户所对应的公私钥对,用于交易签名 +> 0 +input password of the key: +// 输入签名私钥密码 +> 1 +ledger ca: [7VeRBQ9jpsgNXje2NYXU5MhyGKVRj462RtkJ8f6FNL1oxYbX](pubkey) updated +``` +会更新链上公钥为`7VeRBQ9jpsgNXje2NYXU5MhyGKVRj462RtkJ8f6FNL1oxYbX`的账本证书信息。 + + #### 注册用户 ```bash :bin$ ./jdchain-cli.sh tx user-register -h Register new user. -Usage: jdchain-cli tx user-register [-hV] [--pretty] [--export=] +Usage: jdchain-cli tx user-register [-hV] [--ca-mode] [--pretty] + [--crt=] [--export=] [--gw-host=] [--gw-port=] - [--home=] + [--home=] [-n=] + [--pubkey=] + --ca-mode Register with CA + --crt= File of the X509 certificate --export= Transaction export directory --gw-host= Set the gateway host. Default: 127.0.0.1 --gw-port= Set the gateway port. Default: 8080 -h, --help Show this help message and exit. --home= Set the home directory. + -n, --name= Name of the key --pretty Pretty json print + --pubkey= Pubkey of the user -V, --version Print version information and exit. ``` +- `ca-mode`,身份认证模式是否为证书(`CA`)模式,默认`false` +- `name`,当`ca-mode`为`true`时会读取本地`${home}/config/keys/${name}.crt`文件,反之读取`${home}/config/keys/${name}.pub` +- `crt`,证书文件路径 +- `pubkey`,`Base58`编码公钥信息,仅在非`ca-mode`情况下使用 + 从`${home}/config/keys`目录下密钥对选择密钥注册到网关服务对应的区块链网络。 如: ```bash -:bin$ ./jdchain-cli.sh tx user-register +:bin$ ./jdchain-cli.sh tx user-register -name k1 select ledger, input the index: INDEX LEDGER 0 j5sB3sVTFgTqTYzo7KtQjBLSy8YQGPpJpvQZaW9Eqk46dg // 选择账本,当前网关服务只有上面一个可用账本 > 0 -select keypair to register: -INDEX KEY ADDRESS -0 peer0 LdeNyibeafrAQXgHjBxgQxoLbna6hL4BcXZiw -1 k1 LdeNwQWabrf6WSjZ35saFo52MfQFhVKvm11aC -// 选择公私钥对用于注册用户 -> 1 -input password of the key: -// 输入所选择公私钥对密钥密码 -> 1 select keypair to sign tx: INDEX KEY ADDRESS 0 peer0 LdeNyibeafrAQXgHjBxgQxoLbna6hL4BcXZiw @@ -96,6 +151,87 @@ register user: [LdeNwQWabrf6WSjZ35saFo52MfQFhVKvm11aC] ``` 会在链上注册地址为`LdeNwQWabrf6WSjZ35saFo52MfQFhVKvm11aC`的用户账户信息。 +#### 更新用户证书 + +```bash +:bin$ ./jdchain-cli.sh tx ledger-ca-update -h +Update user certificate. +Usage: jdchain-cli tx user-ca-update [-hV] [--pretty] [--crt=] + [--export=] [--gw-host=] + [--gw-port=] [--home=] + --crt= File of the X509 certificate + --export= Transaction export directory + --gw-host= Set the gateway host. Default: 127.0.0.1 + --gw-port= Set the gateway port. Default: 8080 + -h, --help Show this help message and exit. + --home= Set the home directory. + --pretty Pretty json print + -V, --version Print version information and exit. +``` +- `crt`,证书文件路径 + +如: +```bash +:bin$ $ ./jdchain-cli.sh tx user-ca-update --crt /home/imuge/jd/nodes/peer0/config/keys/peer0.crt +select ledger, input the index: +INDEX LEDGER +0 j5pFrMigE47t6TobQJXsztnoeA29H31v1vHHF1wqCp4rzi +// 选择账本,当前网关服务只有上面一个可用账本 +> 0 +select keypair to sign tx: +INDEX KEY ADDRESS +0 peer0 LdeNpEmyh5DMwbAwamxNaiJgMVGn6aTtQDA5W +// 选择链上已存在且有注册用户权限的用户所对应的公私钥对,用于交易签名 +> 0 +input password of the key: +// 输入签名私钥密码 +> 1 +user: [LdeNpEmyh5DMwbAwamxNaiJgMVGn6aTtQDA5W] ca updated +``` +会更新链上地址为`LdeNpEmyh5DMwbAwamxNaiJgMVGn6aTtQDA5W`的用户证书信息。 + +#### 更新用户(证书)状态 + +```bash +:bin$ ./jdchain-cli.sh tx user-state-update -h +Update user(certificate) state. +Usage: jdchain-cli tx user-state-update [-hV] [--pretty] --address=
+ [--export=] + [--gw-host=] + [--gw-port=] [--home=] + --state= + --address=
User address + --export= Transaction export directory + --gw-host= Set the gateway host. Default: 127.0.0.1 + --gw-port= Set the gateway port. Default: 8080 + -h, --help Show this help message and exit. + --home= Set the home directory. + --pretty Pretty json print + --state= User state,Optional values: FREEZE,NORMAL,REVOKE + -V, --version Print version information and exit. +``` +- `address`,用户地址 +- `state`,用户状态,可选值:FREEZE,NORMAL,REVOKE + +如冻结用户`LdeNpEmyh5DMwbAwamxNaiJgMVGn6aTtQDA5W`: +```bash +:bin$ $ ./jdchain-cli.sh tx user-state-update --address LdeNpEmyh5DMwbAwamxNaiJgMVGn6aTtQDA5W --state FREEZE +select ledger, input the index: +INDEX LEDGER +0 j5pFrMigE47t6TobQJXsztnoeA29H31v1vHHF1wqCp4rzi +// 选择账本,当前网关服务只有上面一个可用账本 +> 0 +select keypair to sign tx: +INDEX KEY ADDRESS +0 peer0 LdeNpEmyh5DMwbAwamxNaiJgMVGn6aTtQDA5W +// 选择链上已存在且有注册用户权限的用户所对应的公私钥对,用于交易签名 +> 0 +input password of the key: +// 输入签名私钥密码 +> 1 +user: [LdeNpEmyh5DMwbAwamxNaiJgMVGn6aTtQDA5W] revoked +``` +会冻结链上地址为`LdeNpEmyh5DMwbAwamxNaiJgMVGn6aTtQDA5W`的用户(证书),此用户无法再接入使用此网络。 #### 角色管理 ```bash @@ -366,6 +502,42 @@ input password of the key: event publish success ``` +#### 监听事件 +```bash +:bin$ ./jdchain-cli.sh tx event-listen -h +Subscribe event. +Usage: jdchain-cli tx event-listen [-hV] [--pretty] [--address=
] + [--export=] [--gw-host=] + [--gw-port=] [--home=] + --name= [--sequence=] + --address=
Event address + --export= Transaction export directory + --gw-host= Set the gateway host. Default: 127.0.0.1 + --gw-port= Set the gateway port. Default: 8080 + -h, --help Show this help message and exit. + --home= Set the home directory. + --name= Event name + --pretty Pretty json print + --sequence= Sequence of the event + -V, --version Print version information and exit. +``` +- `address`,事件账户地址,不传则表示监听系统事件 +- `name`,事件名,系统事件目前仅支持:`new_block_created` +- `sequence`,起始监听序号 + +如监听系统新区块事件: +```bash +:bin$ ./jdchain-cli.sh tx event-listen --name new_block_created --sequence 0 +select ledger, input the index: +INDEX LEDGER +0 j5mXXoNsmh6qadnWLjxFMXobyNGsXT1PmTNzXiHyiYMxoP +> 0 +# 会打印新区块事件:区块高度:最新区块高度 +New block:0:12 +New block:1:12 +New block:2:12 +``` + #### 部署合约 ```bash @@ -450,6 +622,48 @@ return string: LdeNqvSjL4izfpMNsGpQiBpTBse4g6qLxZ6j5 ``` 调用成功并返回了字符串:`LdeNqvSjL4izfpMNsGpQiBpTBse4g6qLxZ6j5` +#### 更新合约状态 + +```bash +:bin$ ./jdchain-cli.sh tx contract-state-update -h +Update contract state. +Usage: jdchain-cli tx contract-state-update [-hV] [--pretty] + --address=
[--export=] [--gw-host=] + [--gw-port=] [--home=] --state= + --address=
Contract address + --export= Transaction export directory + --gw-host= Set the gateway host. Default: 127.0.0.1 + --gw-port= Set the gateway port. Default: 8080 + -h, --help Show this help message and exit. + --home= Set the home directory. + --pretty Pretty json print + --state= Contract state,Optional values: FREEZE,NORMAL, + REVOKE + -V, --version Print version information and exit. +``` +- `address`,合约地址 +- `state`,合约状态,可选值:FREEZE,NORMAL,REVOKE + +如冻结合约`LdeNpEmyh5DMwbAwamxNaiJgMVGn6aTtQDA5W`: +```bash +:bin$ $ ./jdchain-cli.sh tx contract-state-update --address LdeNpEmyh5DMwbAwamxNaiJgMVGn6aTtQDA5W --state FREEZE +select ledger, input the index: +INDEX LEDGER +0 j5pFrMigE47t6TobQJXsztnoeA29H31v1vHHF1wqCp4rzi +// 选择账本,当前网关服务只有上面一个可用账本 +> 0 +select keypair to sign tx: +INDEX KEY ADDRESS +0 peer0 LdeNpEmyh5DMwbAwamxNaiJgMVGn6aTtQDA5W +// 选择链上已存在且有注册用户权限的用户所对应的公私钥对,用于交易签名 +> 0 +input password of the key: +// 输入签名私钥密码 +> 1 +contract: [LdeNpEmyh5DMwbAwamxNaiJgMVGn6aTtQDA5W] revoked +``` +会冻结链上地址为`LdeNpEmyh5DMwbAwamxNaiJgMVGn6aTtQDA5W`的合约,此合约不能再被调用。 + #### 离线交易签名 diff --git a/docs/jdchain_cli.md b/docs/jdchain_cli.md index dcab9053..74bcc153 100644 --- a/docs/jdchain_cli.md +++ b/docs/jdchain_cli.md @@ -14,8 +14,9 @@ transactions to jdchain network, query data from jdchain network. Commands: -The most commonly used git commands are: +The most commonly used commands are: keys List, create, update or delete keypairs. + ca List, create, update certificates. tx Build, sign or send transaction. query Query commands. participant Add, update or delete participant. @@ -26,5 +27,6 @@ See 'jdchain-cli help ' to read about a specific subcommand or concept. - `keys` [密钥管理](cli/keys.md) - `tx` [交易](cli/tx.md) +- `ca` [证书](cli/ca.md) - `query` [链上信息查询](cli/query.md) - `participant` [共识节点变更](cli/participant.md) \ No newline at end of file diff --git a/explorer b/explorer index 5907ebd0..ecbc5194 160000 --- a/explorer +++ b/explorer @@ -1 +1 @@ -Subproject commit 5907ebd035217371050e101196cb947b85fa2dd7 +Subproject commit ecbc519401ad29863a50c4d6cab1ff8604f4cab4 diff --git a/feature/ledger-database/.gitkeep b/feature/ledger-database/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/framework b/framework index a5dfbdfa..2cf36760 160000 --- a/framework +++ b/framework @@ -1 +1 @@ -Subproject commit a5dfbdfac61d2afac37b8b8bebf98be7c8f0e5c4 +Subproject commit 2cf367601c10676d9cb7bc7088ff579562760788 diff --git a/libs/bft-smart b/libs/bft-smart index 90e9666e..972c19f4 160000 --- a/libs/bft-smart +++ b/libs/bft-smart @@ -1 +1 @@ -Subproject commit 90e9666e469010979f2bfceed396265642ec5678 +Subproject commit 972c19f4eab34c59361522abe2ea98ae043d042f diff --git a/libs/binary-proto b/libs/binary-proto index cd0f9eb9..d9666111 160000 --- a/libs/binary-proto +++ b/libs/binary-proto @@ -1 +1 @@ -Subproject commit cd0f9eb99a6441874f8ddba7048d00ac6f8abeeb +Subproject commit d9666111bbb33cbbb0a34ff96ffcefba34f46c72 diff --git a/libs/httpservice b/libs/httpservice index c4265ebf..a6cb4583 160000 --- a/libs/httpservice +++ b/libs/httpservice @@ -1 +1 @@ -Subproject commit c4265ebf3a30a1dbe518a40d5b0584ca760fb35a +Subproject commit a6cb4583fc6271ce62e2b8b1d6273c3bdd03b810 diff --git a/libs/kvdb b/libs/kvdb index c3de2e7d..9a7235f1 160000 --- a/libs/kvdb +++ b/libs/kvdb @@ -1 +1 @@ -Subproject commit c3de2e7da6e33ec502e1ba285ee042e467b06f84 +Subproject commit 9a7235f1eb63f7f22bc1f5995778633c9a086c89 diff --git a/libs/utils b/libs/utils index dedda124..d2807e16 160000 --- a/libs/utils +++ b/libs/utils @@ -1 +1 @@ -Subproject commit dedda124dfeb4488ece714d1e6af24b8d5f0a17a +Subproject commit d2807e16e2c9a1104a712242733e3b04f3044ea8 diff --git a/pom.xml b/pom.xml index d080517b..e8583531 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.jd.blockchain jdchain-root - 1.5.0.RELEASE + 1.6.0-SNAPSHOT pom jdchain root project diff --git a/project b/project index e6a91274..731ab7ec 160000 --- a/project +++ b/project @@ -1 +1 @@ -Subproject commit e6a91274cc35748ad903e432aaf34e41b3803702 +Subproject commit 731ab7ec8602655d7b050516f05c194eb07f13d1 diff --git a/samples/contract-samples/pom.xml b/samples/contract-samples/pom.xml index 67c844ee..79a7b2ad 100644 --- a/samples/contract-samples/pom.xml +++ b/samples/contract-samples/pom.xml @@ -6,7 +6,7 @@ com.jd.blockchain jdchain-samples - 1.5.0.RELEASE + 1.6.0-SNAPSHOT diff --git a/samples/pom.xml b/samples/pom.xml index 43f31d16..7b89fee3 100644 --- a/samples/pom.xml +++ b/samples/pom.xml @@ -4,12 +4,12 @@ 4.0.0 com.jd.blockchain jdchain-samples - 1.5.0.RELEASE + 1.6.0-SNAPSHOT pom - 1.5.0.RELEASE - 1.5.0.RELEASE + 1.6.0-SNAPSHOT + 1.6.0-SNAPSHOT diff --git a/samples/sdk-samples/pom.xml b/samples/sdk-samples/pom.xml index 099cbb16..670da363 100644 --- a/samples/sdk-samples/pom.xml +++ b/samples/sdk-samples/pom.xml @@ -5,7 +5,7 @@ com.jd.blockchain jdchain-samples - 1.5.0.RELEASE + 1.6.0-SNAPSHOT sdk-samples diff --git a/test b/test index 068665c9..d51c0368 160000 --- a/test +++ b/test @@ -1 +1 @@ -Subproject commit 068665c9955ff2f577f0e48fd50cf25ed2767e3b +Subproject commit d51c036823918daef9199810817853b84836ac60