Auditing Data
Introduction
STRATO offers the ability to easily track the history of any contract's data over time. This enables easy data auditing and traceability. While it is possible on any blockchain to view the history of a contract's state, STRATO makes it easy by integrating the functionality into its Cirrus API. Contract history can also be referred to as a contract's Audit Log, or Audit Trail, since it provides a log of previous data. As of STRATO 8.2.0, the contract history feature is automatically enabled for every contract posted to the blockhain.
Accessing Contract History
A contract's history may be accessed through the Cirrus API. Cirrus records all contracts of the same name within the same history table, just like normal contract tables. The contents of a contract's history table is its state data and relevant timestamp and transaction information. This allows you to know exactly when a change occurred what address initiated the transaction, and in what transaction the change occurred.
Contract history tables are accessible through the following API endpoint:
GET https://<strato_address>/cirrus/search/history@<contract-name>
Example
Imagine a SimpleStorage contract is created with the initial value of 10. Then another user sets storedData
to 5. Then it is set to 15. By querying history@SimpleStorage
, we can see each of these changes as separate records in the history table.
In the query we specify the specific instance of this contract by its address, and we sort in order of oldest to newest by block_timestamp
.
curl -X GET \
-H "Authorization: Bearer <token>" \
-H "Accept: application/json" \
"https://<strato_address>/cirrus/search/history@SimpleStorage?address=eq.<contract-address>&order=block_timestamp.asc"
const query = {
address: `eq.${contractAddress}`,
order: 'block_timestamp.asc'
}
const newOptions = {
...options,
query
}
const contract = {
name: 'history@SimpleStorage'
}
const rows = await rest.search(stratoUser, contract, newOptions)
Response
[
{
"address": "803af30af892a9d84aa2231077779e143ea80fb0",
"chainId": "",
"block_hash": "5b336c2537afda79291581ff4f8d89138ec653c0d137192e6b2e931a0c890da1",
"block_timestamp": "2021-09-28 15:19:17 UTC",
"block_number": "6",
"transaction_hash": "2f3fd0cefd452a1dbf539ff443a93b3f098a6485b33dbc83e3642b982663f1bf",
"transaction_sender": "f6fedad2c09578a52100835c27de7927d73e6f2c",
"transaction_function_name": "",
"storedData": 10
},
{
"address": "803af30af892a9d84aa2231077779e143ea80fb0",
"chainId": "",
"block_hash": "3b370b4061dc7643204123eb112f416507ad322cec015cf82f7434a6062e2ece",
"block_timestamp": "2021-09-28 15:25:41 UTC",
"block_number": "7",
"transaction_hash": "1f2b255f01e0f80ed95c028a55adb29f7603916638f3b3aaf810d4e47237fc62",
"transaction_sender": "008d73e6f2cf6fedad235c27de7927c09578a521",
"transaction_function_name": "",
"storedData": 5
},
{
"address": "803af30af892a9d84aa2231077779e143ea80fb0",
"chainId": "",
"block_hash": "c7643204123eb062e2ece13b370b4061d12f416507ad322cec015cf82f7434a6",
"block_timestamp": "2021-09-28 15:28:10 UTC",
"block_number": "7",
"transaction_hash": "1f2b255f01e0f80ed95c028a55adb29f7603916638f3b3aaf810d4e47237fc62",
"transaction_sender": "f6fedad2c09578a52100835c27de7927d73e6f2c",
"transaction_function_name": "",
"storedData": 15
}
]
As shown in the response, the history of events as they happened are recorded. The initial value of storedData
was set to 5
by f6fedad2c09578a52100835c27de7927d73e6f2c
in transaction 2f3fd0cefd452a1dbf539ff443a93b3f098a6485b33dbc83e3642b982663f1bf
. Then in the next listing storedData
was set to 15 a few minutes later, and so on.