All Products
Document Center

Sending notary data

Last Updated: Aug 12, 2019

Data Classification

To maintain the readability of data, data classifications are set on a blockchain based on different business scenarios as the data convention for all members. Data on any blockchain must meet this convention.


Before reading this Developing Demo , please contact the administrator to confirm the data classifications. If you are the administrator, please refer to Data Classification to complete the configurations. After the data classifications have been configured, users can download and unzip the SDK package, and develop sample code as illustrated in this document.

To download the SDK package, users should log on to the BaaS platform, click Blockchain List in the left-side navigation pane, and find the blockchain that you want to access. After you find the blockchain, right click more, then click Download Signed Certificate, and Download SDK.

download bizview

You can check your data classifications in the file schema.txt contained in Each classification is called a Category. You can configure multiple categories on one blockchain and each category will be assigned one unique Category ID. After the configuration is completed, users can access and filter data on the blockchain through Category ID.

Developing Demo

We will use a simple schema.txt file as an instance to show you how to construct and read notary data. You can replace the data type GuestInfo here with your own data category based on the content in your schema.txt file. In this scenario, a category named GuestInfo is declared with three members, which are username, birthday, and email. All of these members are of type String. The constraints of members are listed in the comments area.

Note: please replace the data type GuestInfo here with your own data category based on the content in your schema.txt file.

  1. // schema.txt Definition:information of guests
  2. GuestInfo {
  3. String userName; // name,not null, length within 20
  4. String birthday; // birthday, not null
  5. String email; // email address, not null
  6. }

Based on the definition, we build notary data with GuestInfoBuilder in our client code.

  1. // client code
  2. // build notary data
  3. GuestInfoBuilder builder = new GuestInfoBuilder();
  4. byte[] bizData = builder.buildUserName("Bob")
  5. .buildBirthday("2000-01-01")
  6. .buildEmail("")
  7. .build();

With the notary data constructed, we next build the payload. Here the users need to use an enumeration class BizCategory. The SDK generated in this class is advance based on the data classification to help users recognize different categories. In this example, the BizCategory class would as follows.

  1. // BizCategory class in SDK
  2. public class BizCategory {
  3. public static final int GuestInfo = 0x00010001;
  4. ...
  5. }

We can now pass the notary data to the payload, assign BizCategory.GuestInfo to its category, and build a notary transaction. Afterwards, we can send the transaction with the client, and the notary work is complete.

  1. // client code
  2. // build ContentOnlyNotary Transaction
  3. TransactionDO tx = TransactionBuilder.getContentOnlyNotaryPayloadBuilder()
  4. .setContent(bizData)//set your notary data
  5. .setTimestamp(System.currentTimeMillis())//set time
  6. .setCategory(BizCategory.GuestInfo)//set category throught BizCategory
  7. .build();//build Transaction
  8. // send the Transaction
  9. Response<TransactionDO> response = client.sendTransaction(tx);

After the notary data is sent to the blockchain, we have to wait for the new block to be generated before we can query data from the blockchain. When reading data, we also use the value of BizCategory.GuestInfo to recognize the type of notary data, and cast notary data to the object. Two modules are provided to read block data. The first module is to monitor the message of new block generation and process new blocks, the second module is to pull new blocks periodically through a timed cron job. For more information refer to Best Practices .

Below are several code samples。

Sample 1. Sending notary data

  1. // load the configuration file of client
  2. Properties p = new Properties();
  3. p.load(new FileInputStream(""));
  4. ClientConfig config = new ClientPropertyConfig(p);
  5. // initialize the client with the configurations
  6. Client client = new Client(config);
  7. // constuct the notary data
  8. GuestInfoBuilder builder = new GuestInfoBuilder();
  9. byte[] bizData = builder.buildUserName("Bob")
  10. .buildBirthday("2000-01-01")
  11. .buildEmail("")
  12. .build();
  13. // build a ContentOnlyNotary Transaction
  14. TransactionDO tx = TransactionBuilder.getContentOnlyNotaryPayloadBuilder()
  15. .setContent(bizData)//set notary data
  16. .setTimestamp(System.currentTimeMillis())//set time
  17. .setCategory(BizCategory.GuestInfo)//set category
  18. .build();//build Transaction
  19. // send the Transaction
  20. Response<TransactionDO> response = client.sendTransaction(tx);
  21. if(response.isSuccess()){
  22. // sent successfully, save the Transaction Hash corresponding to this notary
  23. return tx.getTxHashValue();
  24. }else{
  25. // failed sending transaction and throw an exception
  26. // a retry is recommended, the status of the blockchain is unknown when an RPC failed
  27. throw a new RuntimeException("Failed sending data to the blockchain");
  28. }

Sample 2. Reading notary data

  1. // get the latest block header
  2. final Response<BlockHeader> blockHeader = client.getLatestBlockHeader();
  3. if(!blockHeader.isSuccess()) {
  4. LOGGER.error("Get block header fail: ", blockHeader.getErrorMsg());
  5. return;
  6. }
  7. // oldHeight = current height of local blocks
  8. long beginHeight = oldHeight + 1;
  9. long finalHeight = blockHeader.getData().getHeight();
  10. // start pulling when new blocks are found
  11. while(beginHeight < finalHeight) {
  12. long endHeight = Math.min(beginHeight + FETCH_LIMIT - 1, finalHeight);
  13. Response<List<Block>> response = client.getBlocks((int)beginHeight, (int)endHeight);
  14. if (!response.isSuccess()) {
  15. LOGGER.error("Get response fail: ", response.getErrorMsg());
  16. return;
  17. }
  18. List<Block> blocks = response.getData();
  19. for (Block block : blocks) {
  20. // get notary transactions in the block
  21. List<TransactionDO> transactions = block.getTransactions();
  22. for (TransactionDO transaction : transactions) {
  23. // get the payload
  24. if (ContentOnlyNotaryPayloadDO.class.isInstance(transaction.getPayload())) {
  25. ContentOnlyNotaryPayloadDO contentOnlyNotaryPayloadDO =
  26. ContentOnlyNotaryPayloadDO.class.cast(transaction.getPayload());
  27. // construct the GuestInfo object
  28. ByteArrayInputStream bis = new ByteArrayInputStream (contentOnlyNotaryPayloadDO.getContent());
  29. ObjectInputStream ois = new ObjectInputStream (bis);
  30. // check the category of the payload
  31. if (contentOnlyNotaryPayloadDO.getCategory() == BizCategory.GuestInfo) {
  32. // construct the object
  33. GuestInfo renter = GuestInfo.class.cast(constructUtil.construct(
  34. contentOnlyNotaryPayloadDO.getContent(), GuestInfo.class));
  35. // read data of renter
  36. System.out.println(renter.getUserName());
  37. }
  38. }
  39. }
  40. beginHeight = block.getHeader().getHeight() + 1;
  41. }
  42. }

Finally, if you want to quit, please call shutdown. The client will close the thread pool safely and quickly in shutdown().

  1. client.shutdown();


Ant Blockchain uses Transaction (the model of notary transactions) to perform notarizations. The usage of ContentOnlyNotaryPayload is shown above. The business system can use other models of Transaction to communicate with the blockchain based on specific scenarios. Please refer to Notarization Transaction Models for more details.