@@ -0,0 +1,70 @@ | |||||
<?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> | |||||
<artifactId>docker-sdk</artifactId> | |||||
<properties> | |||||
<ledger.version>1.3.0.RELEASE</ledger.version> | |||||
</properties> | |||||
<dependencies> | |||||
<dependency> | |||||
<groupId>com.jd.blockchain</groupId> | |||||
<artifactId>crypto-classic</artifactId> | |||||
<version>${ledger.version}</version> | |||||
</dependency> | |||||
<dependency> | |||||
<groupId>com.jd.blockchain</groupId> | |||||
<artifactId>crypto-sm</artifactId> | |||||
<version>${ledger.version}</version> | |||||
</dependency> | |||||
<dependency> | |||||
<groupId>com.jd.blockchain</groupId> | |||||
<artifactId>ledger-model</artifactId> | |||||
<version>${ledger.version}</version> | |||||
</dependency> | |||||
<dependency> | |||||
<groupId>com.jd.blockchain</groupId> | |||||
<artifactId>sdk-client</artifactId> | |||||
<version>${ledger.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,191 @@ | |||||
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); | |||||
// 生成发布合约操作 | |||||
if(contractParams.isHasVersion()){ | |||||
// txTpl.contracts().deploy(contractParams.contractIdentity, contractCode, contractParams.version); | |||||
} else { | |||||
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); | |||||
} |