## 4 Discussion  
The blockchain-based traceability solution proposed should be considered as an open reference that can be adapted to different scenarios. Depending on the data stored in the blockchain, different balances can be achieved in terms of on-chain vs. off-chain processing. Taking the initial proposal in Figure 4 as a reference, actual implementations would range between two extreme scenarios:  
* A cryptographic digest of all data relevant to a batch is computed (i.e., batch payload and references to the previous nodes in the trace), which is bound to a unique batch identifier. Only the computed hash key and batch ID are stored on-chain, while all the batch content is stored off-chain, in a decentralised storage service (such as IPFS or Swarm [53]), or a traditional backend, at the operator's choice, using this cryptographic digest solely for on-chain batch notarisation (cf. Figure 9a). All traceability services' data are stored off-chain, while the blockchain guarantees that batch contents cannot be tampered with. At any time, any batch's digest can be computed off-chain and compared to the hash key stored on-chain using a smart contract's checking function. * All data relevant to a batch are stored in a JSON record, which is bound to a batch ID and stored on-chain (cf. Figure 9b). All traceability data are stored on-chain, and any entity with access to the blockchain data would be able to reconstruct any trace without the intervention of any centralised traceability service provider. However, data used to construct the new batch's JSON record may be retained in the traditional backend, in whole or in part, once the record is sent to the blockchain. It can serve for example as a cache to speed up trace calculations or to improve response times for user queries. structNode { address owner; // Node owner string batchInfo; // payload including contributions (J5 ON) } structNode { address owner; // Node owner bytes32 hash; // Node hash key } // Node mapping (node ID -> Node data) mapping(uint256 -> Node private_nodes; ) // Node mapping (node ID -> Node data) mapping(uint256 -> Node private_nodes; ) functioncreateNode(uint256 ->, string calldata payload) external returns (bytes32); (a) (b)  
Figure 9: Data structures in Figure 4 for the two extreme scenarios discussed. **(a)** Blockchain as a notarisation-only instrument. **(b)** Blockchain as an immutable storage of traceability data. In this example, the createNode function creates and returns an SHA-256 hash key of the data that can be used to retrieve a node’s data by means of the _hashKeys mapping. In general, all scenarios are based on the premise of separating batch creation from its notarisation on the blockchain. In other words, independently of the final storage chosen for the traceability-relevant batch information, off-chain or in a smart contract on a blockchain, the traditional backend serves to support the creation of the batch, even incrementally, as well as its validation. Once the batch's digital twin is finalised, that is, once it becomes the true reflection of a supply chain process that generates a certain number of units of a new product, final or intermediate, we proceed to its immutable storage (on-chain or IPFS, Swarm, cloud, local server, etc. ), as well as its notarisation on the blockchain. The actual functionality offered by the smart contract through its public functions depends on actual application's requirements. Functions allowing the modification of critical traceability information should not be implemented, as they would violate the traceability principle. In any case, state changes on the blockchain do not erase previous state information because the blockchain is immutable by definition. Every state change in the smart contract is performed as a transaction, which in turn will be permanently recorded in one of the blocks of the blockchain. The operational costs will vary depending on the actual information stored in the smart contract and the functionality offered.