* commit '5a895f61620c0666ac274b40764f57897c015ed2': add docker-sdk; add the docker's module to optimize the constructure of docker-demo; update the log4j2.xml; add docker-sdk; add docker-sdk; modify the md for: how to generate the image; check the zip and sdk.jar; add the dos2unix for win; add docker-sdk; add docker-sdk; add docker-sdk; add the docker-demo submodule;tags/1.4.0^2
| @@ -0,0 +1,134 @@ | |||
| <?xml version="1.0" encoding="UTF-8"?> | |||
| <project xmlns="http://maven.apache.org/POM/4.0.0" | |||
| xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | |||
| xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | |||
| <parent> | |||
| <artifactId>docker</artifactId> | |||
| <groupId>com.jd.blockchain</groupId> | |||
| <version>1.3.0.RELEASE</version> | |||
| </parent> | |||
| <modelVersion>4.0.0</modelVersion> | |||
| <artifactId>docker-demo</artifactId> | |||
| <dependencies> | |||
| <dependency> | |||
| <groupId>com.jd.blockchain</groupId> | |||
| <artifactId>docker-sdk</artifactId> | |||
| <version>${project.version}</version> | |||
| </dependency> | |||
| </dependencies> | |||
| <build> | |||
| <finalName>jdchain-demo</finalName> | |||
| <plugins> | |||
| <plugin> | |||
| <groupId>org.apache.maven.plugins</groupId> | |||
| <artifactId>maven-compiler-plugin</artifactId> | |||
| <version>3.8.1</version> | |||
| <configuration> | |||
| <source>1.8</source> | |||
| <target>1.8</target> | |||
| <encoding>UTF-8</encoding> | |||
| <optimize>false</optimize> | |||
| <debug>true</debug> | |||
| <showDeprecation>false</showDeprecation> | |||
| <showWarnings>false</showWarnings> | |||
| </configuration> | |||
| </plugin> | |||
| <!-- <plugin>--> | |||
| <!-- <groupId>org.apache.maven.plugins</groupId>--> | |||
| <!-- <artifactId>maven-dependency-plugin</artifactId>--> | |||
| <!-- <executions>--> | |||
| <!-- <execution>--> | |||
| <!-- <id>copy-dependencies</id>--> | |||
| <!-- <phase>package</phase>--> | |||
| <!-- <goals>--> | |||
| <!-- <goal>copy-dependencies</goal>--> | |||
| <!-- </goals>--> | |||
| <!-- <configuration>--> | |||
| <!-- <outputDirectory>${project.build.directory}/dependencies</outputDirectory>--> | |||
| <!-- <excludeTransitive>false</excludeTransitive>--> | |||
| <!-- <stripVersion>false</stripVersion>--> | |||
| <!-- <includeScope>runtime</includeScope>--> | |||
| <!-- </configuration>--> | |||
| <!-- </execution>--> | |||
| <!-- </executions>--> | |||
| <!-- </plugin>--> | |||
| <plugin> | |||
| <artifactId>maven-resources-plugin</artifactId> | |||
| <version>3.0.2</version> | |||
| <executions> | |||
| <execution> | |||
| <id>copy-resources</id> | |||
| <phase>validate</phase> | |||
| <goals> | |||
| <goal>copy-resources</goal> | |||
| </goals> | |||
| <configuration> | |||
| <!-- 将资源文件拷贝到config目录下 --> | |||
| <encoding>UTF-8</encoding> | |||
| <outputDirectory>${project.basedir}/src/main/docker/zip</outputDirectory> | |||
| <overwrite>false</overwrite> | |||
| <resources> | |||
| <resource> | |||
| <directory>${project.basedir}/../../deploy-peer/target/</directory> | |||
| <filtering>false</filtering> | |||
| <includes> | |||
| <include>jdchain-peer-${project.version}.zip</include> | |||
| </includes> | |||
| </resource> | |||
| <resource> | |||
| <directory>${project.basedir}/../../deploy-gateway/target/</directory> | |||
| <filtering>false</filtering> | |||
| <includes> | |||
| <include>jdchain-gateway-${project.version}.zip</include> | |||
| </includes> | |||
| </resource> | |||
| <!-- sdk --> | |||
| <resource> | |||
| <directory>${project.basedir}/../docker-sdk/target/</directory> | |||
| <filtering>false</filtering> | |||
| <includes> | |||
| <include>docker-sdk-${project.version}.jar</include> | |||
| </includes> | |||
| </resource> | |||
| </resources> | |||
| </configuration> | |||
| </execution> | |||
| </executions> | |||
| </plugin> | |||
| <!-- 使用Maven插件直接将应用打包为一个Docker镜像 --> | |||
| <plugin> | |||
| <groupId>com.spotify</groupId> | |||
| <artifactId>docker-maven-plugin</artifactId> | |||
| <version>1.2.2</version> | |||
| <!--将插件绑定在某个phase执行--> | |||
| <executions> | |||
| <execution> | |||
| <id>build-image</id> | |||
| <!--将插件绑定在package这个phase上。也就是说,用户只需执行mvn package ,就会自动执行mvn docker:build--> | |||
| <phase>package</phase> | |||
| <goals> | |||
| <goal>build</goal> | |||
| </goals> | |||
| </execution> | |||
| </executions> | |||
| <configuration> | |||
| <imageName>jdchain-demo</imageName> | |||
| <imageTags>${docker.tag}</imageTags> | |||
| <!-- 指定 Dockerfile 路径--> | |||
| <dockerDirectory>${project.basedir}/src/main/docker</dockerDirectory> | |||
| </configuration> | |||
| </plugin> | |||
| </plugins> | |||
| </build> | |||
| </project> | |||
| @@ -0,0 +1,37 @@ | |||
| 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 | |||
| @@ -0,0 +1,4 @@ | |||
| #!/bin/bash | |||
| ps -ef|grep 'jdchain'|grep -v grep|cut -c 9-15|xargs kill -9 | |||
| @@ -0,0 +1,34 @@ | |||
| #!/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 | |||
| @@ -0,0 +1,36 @@ | |||
| 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 | |||
| @@ -0,0 +1,5 @@ | |||
| #!/bin/bash | |||
| echo "停止network" | |||
| docker-compose -f docker-compose-all.yaml down | |||
| echo "启动jdchain" | |||
| docker-compose -f docker-compose-all.yaml up -d | |||
| @@ -0,0 +1,9 @@ | |||
| #/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 | |||
| @@ -0,0 +1,66 @@ | |||
| <?xml version="1.0" encoding="UTF-8"?> | |||
| <project xmlns="http://maven.apache.org/POM/4.0.0" | |||
| xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | |||
| xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | |||
| <parent> | |||
| <artifactId>docker</artifactId> | |||
| <groupId>com.jd.blockchain</groupId> | |||
| <version>1.3.0.RELEASE</version> | |||
| </parent> | |||
| <modelVersion>4.0.0</modelVersion> | |||
| <artifactId>docker-sdk</artifactId> | |||
| <dependencies> | |||
| <dependency> | |||
| <groupId>com.jd.blockchain</groupId> | |||
| <artifactId>crypto-classic</artifactId> | |||
| <version>${project.version}</version> | |||
| </dependency> | |||
| <dependency> | |||
| <groupId>com.jd.blockchain</groupId> | |||
| <artifactId>crypto-sm</artifactId> | |||
| <version>${project.version}</version> | |||
| </dependency> | |||
| <dependency> | |||
| <groupId>com.jd.blockchain</groupId> | |||
| <artifactId>ledger-model</artifactId> | |||
| <version>${project.version}</version> | |||
| </dependency> | |||
| <dependency> | |||
| <groupId>com.jd.blockchain</groupId> | |||
| <artifactId>sdk-client</artifactId> | |||
| <version>${project.version}</version> | |||
| </dependency> | |||
| </dependencies> | |||
| <build> | |||
| <plugins> | |||
| <plugin> | |||
| <artifactId>maven-assembly-plugin</artifactId> | |||
| <configuration> | |||
| <appendAssemblyId>false</appendAssemblyId> | |||
| <descriptorRefs> | |||
| <descriptorRef>jar-with-dependencies</descriptorRef> | |||
| </descriptorRefs> | |||
| <archive> | |||
| <manifest> | |||
| <!-- 程序入口 --> | |||
| <mainClass>com.jd.blockchain.SDKDemo</mainClass> | |||
| </manifest> | |||
| </archive> | |||
| </configuration> | |||
| <executions> | |||
| <execution> | |||
| <id>make-assembly</id> | |||
| <phase>package</phase> | |||
| <goals> | |||
| <goal>single</goal> | |||
| </goals> | |||
| </execution> | |||
| </executions> | |||
| </plugin> | |||
| </plugins> | |||
| </build> | |||
| </project> | |||
| @@ -0,0 +1,107 @@ | |||
| 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; | |||
| } | |||
| } | |||
| @@ -0,0 +1,68 @@ | |||
| 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)); | |||
| } | |||
| } | |||
| @@ -0,0 +1,46 @@ | |||
| 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 = "3snPdw7i7PisoLpqqtETdqzQeKVjQReP2Eid9wYK67q9z6trvByGZs"; | |||
| 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); | |||
| } | |||
| } | |||
| } | |||
| @@ -0,0 +1,186 @@ | |||
| package com.jd.blockchain; | |||
| import com.jd.blockchain.crypto.HashDigest; | |||
| import com.jd.blockchain.ledger.*; | |||
| import com.jd.blockchain.sdk.BlockchainService; | |||
| import com.jd.blockchain.sdk.client.GatewayServiceFactory; | |||
| import com.jd.blockchain.transaction.GenericValueHolder; | |||
| import com.jd.blockchain.utils.Bytes; | |||
| import com.jd.chain.contract.TransferContract; | |||
| import static com.jd.blockchain.SDKDemo_Constant.readChainCodes; | |||
| import static com.jd.blockchain.transaction.ContractReturnValue.decode; | |||
| 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<String> 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; | |||
| } | |||
| } | |||
| @@ -0,0 +1,32 @@ | |||
| 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); | |||
| } | |||
| @@ -0,0 +1,25 @@ | |||
| <?xml version="1.0" encoding="UTF-8"?> | |||
| <project xmlns="http://maven.apache.org/POM/4.0.0" | |||
| xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | |||
| xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | |||
| <parent> | |||
| <artifactId>deploy-root</artifactId> | |||
| <groupId>com.jd.blockchain</groupId> | |||
| <version>1.4.0-SNAPSHOT</version> | |||
| </parent> | |||
| <modelVersion>4.0.0</modelVersion> | |||
| <version>1.3.0.RELEASE</version> | |||
| <packaging>pom</packaging> | |||
| <artifactId>docker</artifactId> | |||
| <properties> | |||
| <docker.tag>1.3.0</docker.tag> | |||
| </properties> | |||
| <modules> | |||
| <module>docker-sdk</module> | |||
| <module>docker-demo</module> | |||
| </modules> | |||
| </project> | |||
| @@ -0,0 +1,44 @@ | |||
| # jdchain-demo镜像使用说明 | |||
| 本镜像主要为快速构建JDChain测试环境使用,内嵌固定的公私钥,不可用于生产正式环境。 | |||
| JDChain在docker中的安装路径:/export/jdchain,网关对外端口为:8080。可通过docker-compose-all文件来修改端口。 | |||
| demo环境构建完成后执行sdk加载部分测试数据,区块高度:7,交易总数:8,用户总数:5,数据账户总数:2,合约总数:1。 | |||
| ## 如何生成镜像 | |||
| 1. 如果构建的docker镜像为当前开发版本,将docker模块中的<version>和<docker-tag>跟主版本对齐,然后在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=3snPdw7i7PisoLpqqtETdqzQeKVjQReP2Eid9wYK67q9z6trvByGZs | |||
| #默认私钥的内容(加密的Base58编码数据);在 pk-path 和 pk 之间必须设置其一; | |||
| keys.default.privkey=177gk2PbxhHeEdfAAqGfShJQyeV4XvGsJ9CvJFUbToBqwW1YJd5obicySE1St6SvPPaRrUP | |||
| #默认私钥的解码密码; | |||
| keys.default.privkey-password=8EjkXVSTxMFjCvNNsTo8RBMDEVQmk7gYkW4SCDuvdsBG | |||
| ```` | |||
| @@ -20,6 +20,7 @@ | |||
| <module>../core</module> | |||
| <module>deploy-gateway</module> | |||
| <module>deploy-peer</module> | |||
| </modules> | |||
| <module>docker</module> | |||
| </modules> | |||
| </project> | |||