diff --git a/samples/README.md b/samples/README.md index 3684e7e4..f4c57797 100644 --- a/samples/README.md +++ b/samples/README.md @@ -2,7 +2,7 @@ 本项目为`JD Chain SDK`的使用样例,开发者可以参考此项目快速上手`JD Chain SDK`,主要包括[交易发送查询](#交易发送查询),[合约开发部署](#合约开发部署)两部分。 -本项目提供了基于内存的`JD Chain`四节点+网关的网络环境启动程序[TestNet](/sdk-samples/src/main/java/com/jdchain/samples/sdk/TestNet.java),运行`TestNet`的`main`方法启动测试网络,等待日志输出:`START TESTNET SUCCESS`,网络启动成功会写入一些测试数据,可直接运行本项目提供的所有测试用例。 +本项目提供了基于内存的`JD Chain`四节点+网关的网络环境启动程序[TestNet](sdk-samples/src/main/java/com/jdchain/samples/sdk/TestNet.java),运行`TestNet`的`main`方法启动测试网络,等待日志输出:`START TESTNET SUCCESS`,网络启动成功会写入一些测试数据,可直接运行本项目提供的所有测试用例。 > `TestNet`测试网络默认会占用`8910`/`8920`/`8930`/`8940`/`8911`/`8921`/`8931`/`8941`用于共识服务,`12000`/`12010`/`12020`/`12030`用于四节点`API`服务端口,`11000`用于网关`API`服务端口,启动前请检查相关端口可用。 @@ -10,31 +10,31 @@ ### 交易发送查询 -相关代码放在[sdk-sample](/sdk-samples/src)下。 +相关代码放在[sdk-sample](sdk-samples/src)下。 -> 若并非使用`TestNet`启动的测试网络,开发者在运行本样例前,请根据实际环境修改[config.properties](/sdk-samples/src/main/resources/config.properties)中的网关配置,用户配置等信息。 +> 若并非使用`TestNet`启动的测试网络,开发者在运行本样例前,请根据实际环境修改[config.properties](sdk-samples/src/main/resources/config.properties)中的网关配置,用户配置等信息。 #### 交易发送 -参照[UserSample](/sdk-samples/src/test/java/com/jdchain/samples/sdk/UserSample.java)实现注册用户,配置用户角色权限功能; +参照[UserSample](sdk-samples/src/test/java/com/jdchain/samples/sdk/UserSample.java)实现注册用户,配置用户角色权限功能; -参照[DataAccountSample](/sdk-samples/src/test/java/com/jdchain/samples/sdk/DataAccountSample.java)实现注册数据账户,存储`KV`数据功能; +参照[DataAccountSample](sdk-samples/src/test/java/com/jdchain/samples/sdk/DataAccountSample.java)实现注册数据账户,存储`KV`数据功能; -参照[EventSample](/sdk-samples/src/test/java/com/jdchain/samples/sdk/EventSample.java)实现注册事件账户,发布事件,事件监听功能; +参照[EventSample](sdk-samples/src/test/java/com/jdchain/samples/sdk/EventSample.java)实现注册事件账户,发布事件,事件监听功能; -参照[ContractSample](/sdk-samples/src/test/java/com/jdchain/samples/sdk/ContractSample.java)实现合约调用,非插件方式合约部署功能。 +参照[ContractSample](sdk-samples/src/test/java/com/jdchain/samples/sdk/ContractSample.java)实现合约调用,非插件方式合约部署功能。 #### 数据查询 -参照[QuerySample](/sdk-samples/src/test/java/com/jdchain/samples/sdk/QuerySample.java)实现对于区块链上数据查询功能。 +参照[QuerySample](sdk-samples/src/test/java/com/jdchain/samples/sdk/QuerySample.java)实现对于区块链上数据查询功能。 ### 合约开发部署 -[contract-samples](/contract-samples/src)提供了通过合约注册用户,注册数据账户,注册事件账户,设置`KV`,发布事件的简单合约样例。 +[contract-samples](contract-samples/src)提供了通过合约注册用户,注册数据账户,注册事件账户,设置`KV`,发布事件的简单合约样例。 -> 若并非使用`TestNet`启动的测试网络,开发者在运行本样例前,请根据实际环境修改[pom.xml](/contract-samples/pom.xml)中的网关配置,用户配置等信息。 +> 若并非使用`TestNet`启动的测试网络,开发者在运行本样例前,请根据实际环境修改[pom.xml](contract-samples/pom.xml)中的网关配置,用户配置等信息。 修改相关代码,确认配置正确,`contract-samples`项目目录下命令行执行: diff --git a/samples/contract-samples/src/main/java/com/jdchain/samples/contract/SampleContractImpl.java b/samples/contract-samples/src/main/java/com/jdchain/samples/contract/SampleContractImpl.java index 5777640c..2eb46fdf 100644 --- a/samples/contract-samples/src/main/java/com/jdchain/samples/contract/SampleContractImpl.java +++ b/samples/contract-samples/src/main/java/com/jdchain/samples/contract/SampleContractImpl.java @@ -27,7 +27,10 @@ public class SampleContractImpl implements EventProcessingAware, SampleContract @Override public void setKV(String address, String key, String value) { // 查询最新版本,初始为-1 - TypedKVEntry[] entries = eventContext.getLedger().getDataEntries(eventContext.getCurrentLedgerHash(), address, key); + // 查询已提交区块数据,不包括此操作所在未提交区块的所有数据 + // TypedKVEntry[] entries = eventContext.getLedger().getDataEntries(eventContext.getCurrentLedgerHash(), address, key); + // 可查询包括此操作所在未提交区块的所有数据 + TypedKVEntry[] entries = eventContext.getUncommittedLedger().getDataEntries(address, key); long version = -1; if (null != entries && entries.length > 0) { version = entries[0].getVersion(); @@ -76,7 +79,10 @@ public class SampleContractImpl implements EventProcessingAware, SampleContract @Override public void publishEvent(String address, String topic, String content) { // 查询最新序号,初始为-1 - Event event = eventContext.getLedger().getLatestEvent(eventContext.getCurrentLedgerHash(), address, topic); + // 查询已提交区块数据,不包括此操作所在未提交区块的所有数据 + // Event event = eventContext.getLedger().getRuntimeLedger().getLatestEvent(address, topic); + // 可查询包括此操作所在未提交区块的所有数据 + Event event = eventContext.getUncommittedLedger().getLatestEvent(address, topic); long sequence = -1; if (null != event) { sequence = event.getSequence(); diff --git a/samples/sdk-samples/src/main/java/com/jdchain/samples/sdk/TestNet.java b/samples/sdk-samples/src/main/java/com/jdchain/samples/sdk/TestNet.java index 40dc0343..086bc83f 100644 --- a/samples/sdk-samples/src/main/java/com/jdchain/samples/sdk/TestNet.java +++ b/samples/sdk-samples/src/main/java/com/jdchain/samples/sdk/TestNet.java @@ -284,7 +284,7 @@ public class TestNet { txTemp.eventAccounts().register(user.getIdentity()); txTemp.eventAccount(user.getAddress()).publish("sample-event", "sample-content", -1); // 初始化一个合约 - txTemp.contracts().deploy(user.getIdentity(), FileUtils.readBytes(new ClassPathResource("contract-samples-1.4.0.RELEASE.car").getFile())); + txTemp.contracts().deploy(user.getIdentity(), FileUtils.readBytes(new ClassPathResource("contract-samples-1.4.2.RELEASE.car").getFile())); PreparedTransaction ptx = txTemp.prepare(); ptx.sign(admin); diff --git a/samples/sdk-samples/src/main/resources/contract-samples-1.4.0.RELEASE.car b/samples/sdk-samples/src/main/resources/contract-samples-1.4.0.RELEASE.car deleted file mode 100644 index fb6ccbb5..00000000 Binary files a/samples/sdk-samples/src/main/resources/contract-samples-1.4.0.RELEASE.car and /dev/null differ diff --git a/samples/sdk-samples/src/main/resources/contract-samples-1.4.2.RELEASE.car b/samples/sdk-samples/src/main/resources/contract-samples-1.4.2.RELEASE.car new file mode 100644 index 00000000..cdbc372e Binary files /dev/null and b/samples/sdk-samples/src/main/resources/contract-samples-1.4.2.RELEASE.car differ diff --git a/samples/sdk-samples/src/test/java/com/jdchain/samples/sdk/ContractSample.java b/samples/sdk-samples/src/test/java/com/jdchain/samples/sdk/ContractSample.java index 30146310..fcbaae93 100644 --- a/samples/sdk-samples/src/test/java/com/jdchain/samples/sdk/ContractSample.java +++ b/samples/sdk-samples/src/test/java/com/jdchain/samples/sdk/ContractSample.java @@ -1,5 +1,8 @@ package com.jdchain.samples.sdk; +import com.jd.blockchain.crypto.KeyGenUtils; +import com.jd.blockchain.ledger.BlockchainIdentity; +import com.jd.blockchain.ledger.BlockchainIdentityData; import com.jd.blockchain.ledger.BlockchainKeyGenerator; import com.jd.blockchain.ledger.BlockchainKeypair; import com.jd.blockchain.ledger.BytesDataList; @@ -40,7 +43,30 @@ public class ContractSample extends SampleBase { BlockchainKeypair contractAccount = BlockchainKeyGenerator.getInstance().generate(); System.out.println("合约地址:" + contractAccount.getAddress()); // 部署合约 - txTemp.contracts().deploy(contractAccount.getIdentity(), FileUtils.readBytes("src/main/resources/contract-samples-1.4.0.RELEASE.car")); + txTemp.contracts().deploy(contractAccount.getIdentity(), FileUtils.readBytes("src/main/resources/contract-samples-1.4.2.RELEASE.car")); + // 准备交易 + PreparedTransaction ptx = txTemp.prepare(); + // 交易签名 + ptx.sign(adminKey); + // 提交交易 + TransactionResponse response = ptx.commit(); + Assert.assertTrue(response.isSuccess()); + } + + /** + * 有两种方式更新合约代码: + * 1. contract-samples模块下,配置好pom里面的参数,其中contractAddress设置为已部署上链合约公钥信息,执行 mvn clean deploy 即可 + * 2. 打包contract-samples项目生成 car包,参考testUpdate测试代码部署 + */ + @Test + public void testUpdate() { + // 新建交易 + TransactionTemplate txTemp = blockchainService.newTransaction(ledger); + // 解析合约身份信息 + BlockchainIdentity contractIdentity = new BlockchainIdentityData(KeyGenUtils.decodePubKey("7VeRCfSaoBW3uRuvTqVb26PYTNwvQ1iZ5HBY92YKpEVN7Qht")); + System.out.println("合约地址:" + contractIdentity.getAddress()); + // 部署合约 + txTemp.contracts().deploy(contractIdentity, FileUtils.readBytes("src/main/resources/contract-samples-1.4.2.RELEASE.car")); // 准备交易 PreparedTransaction ptx = txTemp.prepare(); // 交易签名 diff --git a/samples/sdk-samples/src/test/java/com/jdchain/samples/sdk/DataAccountSample.java b/samples/sdk-samples/src/test/java/com/jdchain/samples/sdk/DataAccountSample.java index d5206147..22b279ff 100644 --- a/samples/sdk-samples/src/test/java/com/jdchain/samples/sdk/DataAccountSample.java +++ b/samples/sdk-samples/src/test/java/com/jdchain/samples/sdk/DataAccountSample.java @@ -47,7 +47,7 @@ public class DataAccountSample extends SampleBase { TransactionTemplate txTemp = blockchainService.newTransaction(ledger); // 请正确填写数据账户地址 - // expVersion是针对此key的插入更新操作次数严格递增,初始为-1 + // expVersion是针对此key的插入更新操作次数严格递增,初始为-1,再次运行本测试用例请修改该值,否则服务端将报版本冲突异常。 txTemp.dataAccount(Bytes.fromBase58("LdeNr7H1CUbqe3kWjwPwiqHcmd86zEQz2VRye")) .setText("key1", "value1", -1) .setInt64("key2", 1, -1) diff --git a/samples/sdk-samples/src/test/java/com/jdchain/samples/sdk/EventSample.java b/samples/sdk-samples/src/test/java/com/jdchain/samples/sdk/EventSample.java index f5c114cf..064d2b9c 100644 --- a/samples/sdk-samples/src/test/java/com/jdchain/samples/sdk/EventSample.java +++ b/samples/sdk-samples/src/test/java/com/jdchain/samples/sdk/EventSample.java @@ -98,7 +98,7 @@ public class EventSample extends SampleBase { TransactionTemplate txTemp = blockchainService.newTransaction(ledger); // 请正确填写数据账户地址 - // sequence是针对此消息name的插入更新操作次数严格递增,初始为-1 + // sequence是针对此消息name的插入更新操作次数严格递增,初始为-1,再次运行本测试用例请修改该值,否则服务端将报版本冲突异常。 txTemp.eventAccount(Bytes.fromBase58("LdeNr7H1CUbqe3kWjwPwiqHcmd86zEQz2VRye")) .publish("topic1", "content1", -1) .publish("topic1", "content2", 0) diff --git a/samples/sdk-samples/src/test/java/com/jdchain/samples/sdk/QuerySample.java b/samples/sdk-samples/src/test/java/com/jdchain/samples/sdk/QuerySample.java index f81142ba..c7340b47 100644 --- a/samples/sdk-samples/src/test/java/com/jdchain/samples/sdk/QuerySample.java +++ b/samples/sdk-samples/src/test/java/com/jdchain/samples/sdk/QuerySample.java @@ -35,7 +35,10 @@ import org.junit.Test; public class QuerySample extends SampleBase { HashDigest sampleHash = Crypto.resolveAsHashDigest(Base58Utils.decode("j5sTuEAWmLWKFwXgpdUCxbQN1XmZfkQdC94UT2AqQEt7hp")); - String sampleAddress = "LdeNr7H1CUbqe3kWjwPwiqHcmd86zEQz2VRye"; + String sampleUserAddress = "LdeNr7H1CUbqe3kWjwPwiqHcmd86zEQz2VRye"; + String sampleDataAccountAddress = "LdeNr7H1CUbqe3kWjwPwiqHcmd86zEQz2VRye"; + String sampleContractAddress = "LdeNr7H1CUbqe3kWjwPwiqHcmd86zEQz2VRye"; + String sampleEventAddress = "LdeNr7H1CUbqe3kWjwPwiqHcmd86zEQz2VRye"; String sampleKey = "sample-key"; String sampleEvent = "sample-event"; long sampleVersion = 0; @@ -287,7 +290,7 @@ public class QuerySample extends SampleBase { */ @Test public void getUser() { - UserInfo user = blockchainService.getUser(ledger, sampleAddress); + UserInfo user = blockchainService.getUser(ledger, sampleUserAddress); if (null != user) { System.out.println(user.getAddress().toString()); } @@ -298,7 +301,7 @@ public class QuerySample extends SampleBase { */ @Test public void getDataAccount() { - DataAccountInfo dataAccount = blockchainService.getDataAccount(ledger, sampleAddress); + DataAccountInfo dataAccount = blockchainService.getDataAccount(ledger, sampleDataAccountAddress); if (null != dataAccount) { System.out.println(dataAccount.getAddress().toString()); } @@ -309,7 +312,7 @@ public class QuerySample extends SampleBase { */ @Test public void getDataEntriesByKey() { - TypedKVEntry[] kvs = blockchainService.getDataEntries(ledger, sampleAddress, sampleKey); + TypedKVEntry[] kvs = blockchainService.getDataEntries(ledger, sampleDataAccountAddress, sampleKey); for (TypedKVEntry kv : kvs) { System.out.println(kv.getKey() + ":" + kv.getVersion() + ":" + kv.getValue()); } @@ -320,7 +323,7 @@ public class QuerySample extends SampleBase { */ @Test public void getDataEntriesWithKeyAndVersion() { - TypedKVEntry[] kvs = blockchainService.getDataEntries(ledger, sampleAddress, new KVInfoVO(new KVDataVO[]{new KVDataVO(sampleKey, new long[]{-1})})); + TypedKVEntry[] kvs = blockchainService.getDataEntries(ledger, sampleDataAccountAddress, new KVInfoVO(new KVDataVO[]{new KVDataVO(sampleKey, new long[]{0})})); for (TypedKVEntry kv : kvs) { System.out.println(kv.getKey() + ":" + kv.getVersion() + ":" + kv.getValue()); } @@ -331,7 +334,7 @@ public class QuerySample extends SampleBase { */ @Test public void getDataEntriesTotalCount() { - long count = blockchainService.getDataEntriesTotalCount(ledger, sampleAddress); + long count = blockchainService.getDataEntriesTotalCount(ledger, sampleDataAccountAddress); System.out.println(count); } @@ -340,7 +343,7 @@ public class QuerySample extends SampleBase { */ @Test public void getDataEntries() { - TypedKVEntry[] kvs = blockchainService.getDataEntries(ledger, sampleAddress, 0, 1); + TypedKVEntry[] kvs = blockchainService.getDataEntries(ledger, sampleDataAccountAddress, 0, 1); for (TypedKVEntry kv : kvs) { System.out.println(kv.getKey() + ":" + kv.getVersion() + ":" + kv.getValue()); } @@ -351,7 +354,7 @@ public class QuerySample extends SampleBase { */ @Test public void getContract() { - ContractInfo contract = blockchainService.getContract(ledger, sampleAddress); + ContractInfo contract = blockchainService.getContract(ledger, sampleContractAddress); if (null != contract) { System.out.println(contract.getAddress().toString()); } @@ -418,7 +421,7 @@ public class QuerySample extends SampleBase { */ @Test public void getUserEventAccount() { - BlockchainIdentity id = blockchainService.getUserEventAccount(ledger, sampleAddress); + BlockchainIdentity id = blockchainService.getUserEventAccount(ledger, sampleEventAddress); if (null != id) { System.out.println(id.getAddress().toString()); } @@ -438,7 +441,7 @@ public class QuerySample extends SampleBase { */ @Test public void getUserEventNameTotalCount() { - long count = blockchainService.getUserEventNameTotalCount(ledger, sampleAddress); + long count = blockchainService.getUserEventNameTotalCount(ledger, sampleEventAddress); System.out.println(count); } @@ -447,7 +450,7 @@ public class QuerySample extends SampleBase { */ @Test public void getUserEventNames() { - String[] names = blockchainService.getUserEventNames(ledger, sampleAddress, 0, 1); + String[] names = blockchainService.getUserEventNames(ledger, sampleEventAddress, 0, 1); for (String name : names) { System.out.println(name); } @@ -458,7 +461,7 @@ public class QuerySample extends SampleBase { */ @Test public void getLatestUserEvent() { - Event event = blockchainService.getLatestEvent(ledger, sampleAddress, sampleEvent); + Event event = blockchainService.getLatestEvent(ledger, sampleEventAddress, sampleEvent); if (null != event) { BytesValue content = event.getContent(); switch (content.getType()) { @@ -483,7 +486,7 @@ public class QuerySample extends SampleBase { */ @Test public void getUserEventsTotalCount() { - long count = blockchainService.getUserEventsTotalCount(ledger, sampleAddress, sampleEvent); + long count = blockchainService.getUserEventsTotalCount(ledger, sampleEventAddress, sampleEvent); System.out.println(count); } @@ -492,7 +495,7 @@ public class QuerySample extends SampleBase { */ @Test public void getUserEvents() { - Event[] events = blockchainService.getUserEvents(ledger, sampleAddress, sampleEvent, 0, 1); + Event[] events = blockchainService.getUserEvents(ledger, sampleEventAddress, sampleEvent, 0, 1); for (Event event : events) { BytesValue content = event.getContent(); switch (content.getType()) { @@ -517,7 +520,7 @@ public class QuerySample extends SampleBase { */ @Test public void getContractByAddressAndVersion() { - ContractInfo contract = blockchainService.getContract(ledger, sampleAddress, sampleVersion); + ContractInfo contract = blockchainService.getContract(ledger, sampleContractAddress, sampleVersion); if (null != contract) { System.out.println(contract.getAddress().toString()); System.out.println(contract.getChainCodeVersion()); @@ -573,7 +576,7 @@ public class QuerySample extends SampleBase { */ @Test public void getUserPrivileges() { - UserPrivilegeSet userPrivileges = blockchainService.getUserPrivileges(ledger, sampleAddress); + UserPrivilegeSet userPrivileges = blockchainService.getUserPrivileges(ledger, sampleUserAddress); if (null != userPrivileges) { for (String role : userPrivileges.getUserRole()) { System.out.println(role);