ledgers/{ledgerHash}/accounts/{address}/entries-version
test OK.
tags/1.0.0
| @@ -5,6 +5,7 @@ import com.jd.blockchain.crypto.PrivKey; | |||
| import com.jd.blockchain.crypto.PubKey; | |||
| import com.jd.blockchain.ledger.BlockchainKeypair; | |||
| import com.jd.blockchain.tools.keygen.KeyGenCommand; | |||
| import com.jd.blockchain.utils.StringUtils; | |||
| import com.jd.blockchain.utils.codec.Base58Utils; | |||
| import com.jd.blockchain.utils.io.FileUtils; | |||
| import org.apache.maven.plugin.AbstractMojo; | |||
| @@ -1,10 +0,0 @@ | |||
| package com.jd.blockchain; | |||
| /** | |||
| * @Author zhaogw | |||
| * @Date 2018/11/26 20:46 | |||
| */ | |||
| public abstract class StringUtils { | |||
| public static boolean isEmpty(Object str) { | |||
| return str == null || "".equals(str); | |||
| } | |||
| } | |||
| @@ -1,9 +1,9 @@ | |||
| #项目源文件存放的位置; | |||
| #PROJECT_BASE_DIR | |||
| PROJECT_BASE_DIR=E:\\gitCode\\block\\prototype\\ | |||
| #合同使用的类库存放的位置,可能不在项目中,故采用全新的地址; | |||
| #LEDGER_BASE_CLASS_PATH | |||
| LEDGER_BASE_CLASS_PATH=E:\\gitCode\\block\\prototype\\libs\\ | |||
| #为了测试,临时添加的变量; | |||
| #deploy and execute the contract; | |||
| cParam=com.jd.blockchain.contract.AssetContract3 | |||
| sParam=E:\\gitCode\\block\\prototype\\source\\sdk\\contract-sample\\src\\main\\java\\ | |||
| eParam=utf-8 | |||
| @@ -1,80 +0,0 @@ | |||
| <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"> | |||
| <modelVersion>4.0.0</modelVersion> | |||
| <parent> | |||
| <groupId>com.jd.blockchain</groupId> | |||
| <artifactId>contract</artifactId> | |||
| <version>0.9.0-SNAPSHOT</version> | |||
| </parent> | |||
| <artifactId>contract-tools</artifactId> | |||
| <dependencies> | |||
| <dependency> | |||
| <groupId>com.jd.blockchain</groupId> | |||
| <artifactId>contract-compiler</artifactId> | |||
| <version>${project.version}</version> | |||
| </dependency> | |||
| <dependency> | |||
| <groupId>com.jd.blockchain</groupId> | |||
| <artifactId>contract-jar</artifactId> | |||
| <version>${project.version}</version> | |||
| </dependency> | |||
| <dependency> | |||
| <groupId>commons-io</groupId> | |||
| <artifactId>commons-io</artifactId> | |||
| <version>${commons-io.version}</version> | |||
| </dependency> | |||
| <dependency> | |||
| <groupId>junit</groupId> | |||
| <artifactId>junit</artifactId> | |||
| <scope>test</scope> | |||
| </dependency> | |||
| <dependency> | |||
| <groupId>org.mockito</groupId> | |||
| <artifactId>mockito-core</artifactId> | |||
| <scope>test</scope> | |||
| </dependency> | |||
| <dependency> | |||
| <groupId>org.slf4j</groupId> | |||
| <artifactId>slf4j-log4j12</artifactId> | |||
| </dependency> | |||
| </dependencies> | |||
| <build> | |||
| <plugins> | |||
| <plugin> | |||
| <groupId>org.apache.maven.plugins</groupId> | |||
| <artifactId>maven-surefire-plugin</artifactId> | |||
| <version>2.5</version> | |||
| <configuration> | |||
| <skipTests>true</skipTests> | |||
| </configuration> | |||
| </plugin> | |||
| </plugins> | |||
| </build> | |||
| <!--<build>--> | |||
| <!--<plugins>--> | |||
| <!--<plugin>--> | |||
| <!--<groupId>org.apache.maven.plugins</groupId>--> | |||
| <!--<artifactId>maven-compiler-plugin</artifactId>--> | |||
| <!--<version>3.1</version>--> | |||
| <!--<configuration>--> | |||
| <!--<source>1.8</source>--> | |||
| <!--<target>1.8</target>--> | |||
| <!--<encoding>UTF-8</encoding>--> | |||
| <!--<compilerArgs>--> | |||
| <!--<!–<arg>-verbose</arg>–>--> | |||
| <!--<!–<arg>-Xlint:unchecked</arg>–>--> | |||
| <!--<!–<arg>-Xlint:deprecation</arg>–>--> | |||
| <!--<!–<arg>-bootclasspath</arg>–>--> | |||
| <!--<!–<arg>${env.JAVA_HOME}/jre/lib/rt.jar</arg>–>--> | |||
| <!--<arg>-extdirs</arg>--> | |||
| <!--<arg>${project.basedir}/../contract/contract-libs;$JAVA_HOME/jre/lib/ext</arg>--> | |||
| <!--</compilerArgs>--> | |||
| <!--</configuration>--> | |||
| <!--</plugin>--> | |||
| <!--</plugins>--> | |||
| <!--</build>--> | |||
| </project> | |||
| @@ -239,6 +239,14 @@ public class BlockBrowserController implements BlockchainExtendQueryService { | |||
| return peerService.getQueryService().getDataEntries(ledgerHash, address, keys); | |||
| } | |||
| @RequestMapping(method = {RequestMethod.GET, RequestMethod.POST}, path = "ledgers/{ledgerHash}/accounts/{address}/entries-version") | |||
| public KVDataEntry[] getDataEntries(@PathVariable("ledgerHash") HashDigest ledgerHash, | |||
| @PathVariable("address") String address, | |||
| @RequestParam("keys") String keys[], | |||
| @RequestParam("versions") String versions[]) { | |||
| return peerService.getQueryService().getDataEntries(ledgerHash, address, keys, versions); | |||
| } | |||
| @RequestMapping(method = {RequestMethod.GET, RequestMethod.POST}, path = "ledgers/{ledgerHash}/accounts/address/{address}/entries") | |||
| @Override | |||
| public KVDataEntry[] getDataEntries(@PathVariable("ledgerHash") HashDigest ledgerHash, | |||
| @@ -2,6 +2,7 @@ package com.jd.blockchain.ledger.core.impl; | |||
| import com.jd.blockchain.binaryproto.BinaryProtocol; | |||
| import com.jd.blockchain.binaryproto.PrimitiveType; | |||
| import com.jd.blockchain.contract.ContractException; | |||
| import com.jd.blockchain.crypto.HashDigest; | |||
| import com.jd.blockchain.ledger.*; | |||
| import com.jd.blockchain.ledger.core.ContractAccountSet; | |||
| @@ -15,6 +16,7 @@ import com.jd.blockchain.ledger.core.UserAccountSet; | |||
| import com.jd.blockchain.transaction.BlockchainQueryService; | |||
| import com.jd.blockchain.utils.Bytes; | |||
| import com.jd.blockchain.utils.QueryUtil; | |||
| import com.jd.blockchain.utils.StringUtils; | |||
| public class LedgerQueryService implements BlockchainQueryService { | |||
| @@ -263,6 +265,9 @@ public class LedgerQueryService implements BlockchainQueryService { | |||
| long ver; | |||
| for (int i = 0; i < entries.length; i++) { | |||
| ver = dataAccount.getDataVersion(Bytes.fromString(keys[i])); | |||
| dataAccount.getBytes(Bytes.fromString(keys[i]),1); | |||
| if (ver < 0) { | |||
| entries[i] = new KVDataObject(keys[i], -1, PrimitiveType.NIL, null); | |||
| }else { | |||
| @@ -275,6 +280,42 @@ public class LedgerQueryService implements BlockchainQueryService { | |||
| return entries; | |||
| } | |||
| public KVDataEntry[] getDataEntries(HashDigest ledgerHash, String address, String[] keys, String[] versions) { | |||
| if (keys == null || keys.length == 0) { | |||
| return null; | |||
| } | |||
| if (versions == null || versions.length == 0) { | |||
| return null; | |||
| } | |||
| if(keys.length != versions.length){ | |||
| throw new ContractException("keys.length!=versions.length!"); | |||
| } | |||
| LedgerRepository ledger = ledgerService.getLedger(ledgerHash); | |||
| LedgerBlock block = ledger.getLatestBlock(); | |||
| DataAccountSet dataAccountSet = ledger.getDataAccountSet(block); | |||
| DataAccount dataAccount = dataAccountSet.getDataAccount(Bytes.fromBase58(address)); | |||
| KVDataEntry[] entries = new KVDataEntry[keys.length]; | |||
| long ver = -1; | |||
| for (int i = 0; i < entries.length; i++) { | |||
| // ver = dataAccount.getDataVersion(Bytes.fromString(keys[i])); | |||
| // dataAccount.getBytes(Bytes.fromString(keys[i]),1); | |||
| if(StringUtils.isNumber(versions[i])){ | |||
| ver = Long.parseLong(versions[i]); | |||
| } | |||
| if (ver < 0) { | |||
| entries[i] = new KVDataObject(keys[i], -1, PrimitiveType.NIL, null); | |||
| }else { | |||
| byte[] value = dataAccount.getBytes(Bytes.fromString(keys[i]), ver); | |||
| BytesValue decodeData = BinaryProtocol.decode(value); | |||
| entries[i] = new KVDataObject(keys[i], ver, PrimitiveType.valueOf(decodeData.getType().CODE), decodeData.getValue().toBytes()); | |||
| } | |||
| } | |||
| return entries; | |||
| } | |||
| @Override | |||
| public KVDataEntry[] getDataEntries(HashDigest ledgerHash, String address, int fromIndex, int count) { | |||
| @@ -156,6 +156,11 @@ public class ContractLedgerContext implements LedgerContext { | |||
| return innerQueryService.getDataEntries(ledgerHash, address, keys); | |||
| } | |||
| @Override | |||
| public KVDataEntry[] getDataEntries(HashDigest ledgerHash, String address, String[] keys, String[] versions) { | |||
| return innerQueryService.getDataEntries(ledgerHash, address, keys, versions); | |||
| } | |||
| @Override | |||
| public KVDataEntry[] getDataEntries(HashDigest ledgerHash, String address, int fromIndex, int count) { | |||
| return innerQueryService.getDataEntries(ledgerHash, address, fromIndex, count); | |||
| @@ -261,6 +261,8 @@ public interface BlockchainQueryService { | |||
| */ | |||
| KVDataEntry[] getDataEntries(HashDigest ledgerHash, String address, String... keys); | |||
| KVDataEntry[] getDataEntries(HashDigest ledgerHash, String address, String[] keys, String[] versions); | |||
| /** | |||
| * 返回指定数据账户中KV数据的总数; <br> | |||
| * | |||
| @@ -1,7 +1,8 @@ | |||
| package com.jd.blockchain.peer.web; | |||
| import com.jd.blockchain.contract.ContractException; | |||
| import com.jd.blockchain.ledger.*; | |||
| import com.jd.blockchain.ledger.core.*; | |||
| import com.jd.blockchain.utils.StringUtils; | |||
| import org.springframework.beans.factory.annotation.Autowired; | |||
| import org.springframework.web.bind.annotation.PathVariable; | |||
| import org.springframework.web.bind.annotation.RequestMapping; | |||
| @@ -12,6 +13,15 @@ import org.springframework.web.bind.annotation.RestController; | |||
| import com.jd.blockchain.binaryproto.BinaryProtocol; | |||
| import com.jd.blockchain.binaryproto.PrimitiveType; | |||
| import com.jd.blockchain.crypto.HashDigest; | |||
| import com.jd.blockchain.ledger.core.ContractAccountSet; | |||
| import com.jd.blockchain.ledger.core.DataAccount; | |||
| import com.jd.blockchain.ledger.core.DataAccountSet; | |||
| import com.jd.blockchain.ledger.core.LedgerAdministration; | |||
| import com.jd.blockchain.ledger.core.LedgerRepository; | |||
| import com.jd.blockchain.ledger.core.LedgerService; | |||
| import com.jd.blockchain.ledger.core.ParticipantCertData; | |||
| import com.jd.blockchain.ledger.core.TransactionSet; | |||
| import com.jd.blockchain.ledger.core.UserAccountSet; | |||
| import com.jd.blockchain.transaction.BlockchainQueryService; | |||
| import com.jd.blockchain.utils.Bytes; | |||
| import com.jd.blockchain.utils.QueryUtil; | |||
| @@ -342,6 +352,46 @@ public class LedgerQueryController implements BlockchainQueryService { | |||
| return entries; | |||
| } | |||
| @RequestMapping(method = {RequestMethod.GET, RequestMethod.POST}, path = "ledgers/{ledgerHash}/accounts/{address}/entries-version") | |||
| @Override | |||
| public KVDataEntry[] getDataEntries(@PathVariable(name = "ledgerHash") HashDigest ledgerHash, | |||
| @PathVariable(name = "address") String address, | |||
| @RequestParam("keys") String[] keys, | |||
| @RequestParam("versions") String[] versions) { | |||
| if (keys == null || keys.length == 0) { | |||
| return null; | |||
| } | |||
| if (versions == null || versions.length == 0) { | |||
| return null; | |||
| } | |||
| if(keys.length != versions.length){ | |||
| throw new ContractException("keys.length!=versions.length!"); | |||
| } | |||
| LedgerRepository ledger = ledgerService.getLedger(ledgerHash); | |||
| LedgerBlock block = ledger.getLatestBlock(); | |||
| DataAccountSet dataAccountSet = ledger.getDataAccountSet(block); | |||
| DataAccount dataAccount = dataAccountSet.getDataAccount(Bytes.fromBase58(address)); | |||
| KVDataEntry[] entries = new KVDataEntry[keys.length]; | |||
| long ver = -1; | |||
| for (int i = 0; i < entries.length; i++) { | |||
| // ver = dataAccount.getDataVersion(Bytes.fromString(keys[i])); | |||
| if(StringUtils.isNumber(versions[i])){ | |||
| ver = Long.parseLong(versions[i]); | |||
| } | |||
| if (ver < 0) { | |||
| entries[i] = new KVDataObject(keys[i], -1, PrimitiveType.NIL, null); | |||
| }else { | |||
| byte[] value = dataAccount.getBytes(Bytes.fromString(keys[i]), ver); | |||
| BytesValue decodeData = BinaryProtocol.decode(value); | |||
| entries[i] = new KVDataObject(keys[i], ver, PrimitiveType.valueOf(decodeData.getType().CODE), decodeData.getValue().toBytes()); | |||
| } | |||
| } | |||
| return entries; | |||
| } | |||
| @RequestMapping(method = {RequestMethod.GET, RequestMethod.POST}, path = "ledgers/{ledgerHash}/accounts/address/{address}/entries") | |||
| @Override | |||
| public KVDataEntry[] getDataEntries(@PathVariable(name = "ledgerHash") HashDigest ledgerHash, | |||
| @@ -147,6 +147,11 @@ public abstract class BlockchainServiceProxy implements BlockchainService { | |||
| return getQueryService(ledgerHash).getDataEntries(ledgerHash, address, keys); | |||
| } | |||
| @Override | |||
| public KVDataEntry[] getDataEntries(HashDigest ledgerHash, String address, String[] keys, String[] versions) { | |||
| return getQueryService(ledgerHash).getDataEntries(ledgerHash, address, keys, versions); | |||
| } | |||
| @Override | |||
| public KVDataEntry[] getDataEntries(HashDigest ledgerHash, String address, int fromIndex, int count) { | |||
| return getQueryService(ledgerHash).getDataEntries(ledgerHash, address, fromIndex, count); | |||
| @@ -496,7 +496,12 @@ public interface HttpBlockchainQueryService extends BlockchainExtendQueryService | |||
| @PathParam(name="address") String address, | |||
| @RequestParam(name="keys", array = true) String... keys); | |||
| @HttpAction(method = HttpMethod.POST, path = "ledgers/{ledgerHash}/accounts/address/{address}/entries") | |||
| @HttpAction(method=HttpMethod.POST, path="ledgers/{ledgerHash}/accounts/{address}/entries-version") | |||
| @Override | |||
| KVDataEntry[] getDataEntries(@PathParam(name="ledgerHash", converter=HashDigestToStringConverter.class) HashDigest ledgerHash, | |||
| @PathParam(name="address") String address, | |||
| @RequestParam(name="keys", array = true) String[] keys, | |||
| @RequestParam(name="versions", array = true) String[] versions); | |||
| /** | |||
| * 返回数据账户中指定序号的最新值; | |||
| @@ -513,6 +518,7 @@ public interface HttpBlockchainQueryService extends BlockchainExtendQueryService | |||
| * 如果参数值为 -1,则返回全部的记录;<br> | |||
| * @return | |||
| */ | |||
| @HttpAction(method = HttpMethod.POST, path = "ledgers/{ledgerHash}/accounts/address/{address}/entries") | |||
| @Override | |||
| KVDataEntry[] getDataEntries(@PathParam(name = "ledgerHash") HashDigest ledgerHash, | |||
| @PathParam(name = "address") String address, | |||
| @@ -0,0 +1,24 @@ | |||
| package com.jd.blockchain.utils; | |||
| import java.util.regex.Pattern; | |||
| /** | |||
| * @Author zhaogw | |||
| * date 2018/11/26 20:46 | |||
| */ | |||
| public class StringUtils { | |||
| public static boolean isEmpty(Object str) { | |||
| return str == null || "".equals(str); | |||
| } | |||
| /* | |||
| * 判断是否为整数 | |||
| * @param str 传入的字符串 | |||
| * @return 是整数返回true,否则返回false | |||
| */ | |||
| public static boolean isNumber(String str) { | |||
| Pattern pattern = Pattern.compile("^[-\\+]?[\\d]*$"); | |||
| return pattern.matcher(str).matches(); | |||
| } | |||
| } | |||