## 5 Experimental Results and Discussion
### Data Storage and Retrieval with IPFS and Smart Contract  
In this section, we report the performance of the wrapper functions and demonstrate the advantage of integrating IPFS and smart contract as described in Section 4.1. We measure the latency for uploading and downloading data to/from IPFS and the latency in issuing write/read transactions to the smart contract (with user access control). Additionally, we also measure the gas consumption for the write and read transactions to our smart contract. We experimented with two scenarios: (1) storing only the IPFS hash with a tag to the smart contract (using the wrapper functions illustrated in Figure 9); and (2) storing the entire data with a tag to the smart contract (without using the wrapper \begin{table}
\begin{tabular}{l c c} \hline \hline
**Role** & **grantrole** & **delete** \\ \hline Admin & 95,198 & 37,262 \\ \hline Write & 72,867 & 31,347 \\ \hline Read & 49,977 & 28,613 \\ \hline \hline \end{tabular}
\end{table} 
Table 2: Gas consumption for user management operations. Figure 12: Gas consumption for granting roles and deleting roles. functions). During the experiments, we vary the data size from 100 to 2000 bytes with a step of 100 bytes. The transactions use distinct tags for subsequent transactions. The latency results for the write and read transactions on the smart contract are illustrated in Figure 13. The curves labeled with \"Contract Write\" and \"Contract Read\" are the results for Scenario (1) where only the IPFS hash is stored at the smart contract. The curves labeled with \"Contract Write Full\" and \"Contract Read Full\" are the results for Scenario (2) where the entire data entry is stored at the smart contract without the integration with IPFS. As can be seen, the latency for the write/read transactions generally increases with the data entry size in Scenario (2). The latency for the write/read transactions in Scenario (1) remains constant and lower than that for Scenario (2). These results are as expected because in Scenario (1) the transaction size is the same for all original data entry sizes, and in Scenario (2) the write transaction size and the transaction receipt for the read transaction increase with the data entry sizes. As can be seen in Figure 13, the latency is below 0.5 s for all scenarios and for all data entry sizes. We regard this latency satisfactory because the transaction rate must be kept relatively low by considering several factors: (1) there is a very limited system throughput capability due to the need for reaching decentralized consensus in blockchain (in Ethereum, the target block interval is 12 s and there are usually less than 500 transactions per block); (2) transactions that mutate the blockchain state (i.e., contract write) would incur significant financial cost and even read-only transaction submitted to the blockchain (i.e., not served locally) would still incur the base transaction gas fee. As such, users should only store the most critical data in the smart contract and the calls on the smart contract should be made infrequent, for example, at most a few times per hour. The observed latency results in our experiments mean that our system can sustain a 1 Hz transaction generation rate (i.e., one transaction per second), which is much higher than that recommended for practical uses. The latency results for IPFS uploading (i.e., add_json()) and downloading (i.e., get_json()) are shown in Figure 14. Downloading data from IPFS incurs the least latency (0.002-0.003 s), and the latency remains small for all data sizes. However, the latency for uploading data to IPFS is much larger (around 0.1 s) and has huge jitters for the first few times. Again, this is expected because uploading would need to push the data first to the local IPFS node, and then to a few nearby IPFS nodes, which takes time, and downloading can be performed with the local IPFS node. Figure 13: Latency results in interaction with the smart contract.