## 3 Results
### A Generic Blockchain-Based Traceability System
In this example (mapping_creators), some string associated with the creator is assumed to exist off-chain. If an address is not mapped, a default value depending on the value's data type will be returned (i.e., false for a boolean and an empty string in the case of a string). Conversely, a key can be unmapped by assigning to it the corresponding default value. If guards are placed after state information is modified and they are not satisfied, changes will be reverted. In other words, a transaction implying a smart contract's state modification will not be completed unless all guards in the function are satisfied. Events will also be stored in the blockchain, in this case indexed by the unique node identifier to facilitate the efficient location of events corresponding to a particular node. Figure 7 illustrates the definition of such an event. Event fields in this example are the blockchain address performing the operation, the ID of the node involved, the operation performed (from an enumerated data type), and further details to enrich the event's information (e.g., when creating a new node, this field will store the hash summary of  
Figure 5: Example of a JSON structure to record contributions to a new batch on-chain (cf. Figure 3). Figure 6: Smart contract function to create a new node (cf. Figure 4). the new node). This example also indexes events according to the node creator, which facilitates the identification of activities performed by a given blockchain address. Function getNode in Figure 8 can be used to obtain all the notarisation data corresponding to a node in the blockchain. As it only returns state information and does not modify state data, the function does not require a blockchain transaction to be executed, and will be run on the copy of the virtual machine of the blockchain node receiving the call. In general, a traceability smart contract will implement an application programmer's interface (API) offering the minimal functionality below:  
* Creating and accessing node records, as depicted in Figures 6 and 8. * Getters and setters for accessing and updating individual node fields, as required by each particular application. * Registering and disabling blockchain addresses to perform traceability operations. According to a general traceability principle, the hash digest would not be among the updatable fields because that would break trace immutability. Traceability Nodes stored in the blockchain model perfected supply chain activities that occurred in the real world (e.g., production of a batch, transportation of a batch to a given destination, etc. ), which cannot be undone. In any case, if a setter is provided for the hash field, an event will also be generated that will immutably record that action (with event details including, for example, the blockchain address updating the hash key, the node involved, and the new hash key). Address management in the blockchain (i.e., registering and disabling blockchain addresses to perform traceability operations) would be a task performed by the owner of the traceability smart contract (i.e., the blockchain address offering the traceability service on-chain). To offer this feature, the minimal support would consist of functions to register and disable addresses, defined to be executed only by the owner of the smart contract, and a mapping of registered addresses (e.g., mapping _nodes in Figure 6. The Ownable.sol contract from the OpenZeppelin's library [50] is a Solidity contract designed to enforce basic access control mechanisms for smart contracts, and to simplify the implementation of ownership features in a contract, where there is a blockchain address (i.e., the contract's owner) that has exclusive access to specific functions, registering and disabling blockchain addresses to perform traceability operations in our case. With the proposed system, a newly created product batch is registered for traceability as follows:  
1.