* 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> |