In the previous post concerning the management of some data coming from an ioT device, we had created a smart-contract that could contain all the data exactly as they were transmitted by the device. The data was stored on the blockchain exactly in the sending format. A fundamental problem now arises. How much data are we willing to store in the Blockchain in the case of very frequent arriving data? Is it necessary to create a smart contract for every type of data coming from the device? We can think of storing only the hash of the data and storing off-chain all the data coming from the device. Let's see how.
Storing the data Hash
Let's look at the picture below and then describe it in detail:
1) the IoT Device sends its data in the default format for that specific device
2) the IoT Hub (in our case an Asp.net Core Web application) receives data from the device, creates the Hash and then sends (as parameters of a smart contract method) the hash and an array of strings containing all the data received to the blockchain
3) The BlockChain creates a smart contract that contains the newly transmitted hash
4) This causes an event that retransmits the input data (concatenated by means of a special character, in our case an asterisk). In this way we are sure that the blockchain has received exactely those data that must obviously coincide with the data received from the device.
5) A record is created on an off-chain Data Base that will contain the newly created Blockchain address and the transmitted data linked by the special character ('*')
What are the advantages of this approach? Surely only the hashes of the data are stored on the blockchain. It simplifies the type of smart contract used which will have only the field containing the data hash, therefore the smart contract can be used for all types of devices, without having to create a type of smart contract for each different data format.
The smart contracts
The first smart contract that we see is the smart contract that contains the data hash
We must note the first pragma directive. This indicates that we are using a new (experimental) version of the ABI encoder. Naturally, the Ethereum team's advice is to not use this directive in contracts in production, because always in an experimental phase. Furthermore we know that under certain conditions (certainly rare and complex) this directive can introduce vulnerabilities. However, this directive must be used if, for example, we want to pass an array of strings to a method or a constructor as in the case of the smart contract illustrated above.
In the figure above we have instead the first part of the smart contract that manages the storage and retrieval of data in IoTHash contracts. Note how the DataArrived event is defined, which is invoked when the new IoTHash smart contract instance is stored and returns the concatenated data and address of the newly created smart contract.
Managing strings in Solidity
The second part of the smart contract code concerns the methods for managing the creation of the new smart contract.
In input the method receives both the data hash and the string array containing the data coming from the device (the array is not sized, so I can pass an array with any number of elements). In Solidity the string management is really very particular (in the sense that it must be done practically everything by hand) and in this case we have resorted to a particular function of the 'abi' object called encodePack to which we can pass two strings and these are concatenated managing the sequence of the characters of the string as a succession of bytes.
All data is stored off-chain and it will be possible to verify its correctness with the following procedural scheme:
1) The application reads the record with the data to be verified from the off-chain database
2) The hash of the data received at the time from the device and the corresponding Blockchain address is calculated
3) The Blockchain is queried to obtain the hash stored at the address. Recall that this hash was calculated based on the data received at the time the device sent it.
4) if the Hash it's the same then the off-chain data are authentic and unchanged as transmitted by the device.
We have seen how it is possible using arrays of strings, managing any type of data coming from a device, thus being able to always use the same smart contract on all occasions. The only caveat is the use of the experimental pragma directive for using arrays as parameters.