Object and Package Versioning
You reference every object stored on chain by an ID and version. When a transaction modifies an object, it writes the new contents to an on-chain reference with the same ID but a later version. This means that a single object (with ID I) might appear in multiple entries in the distributed store:
(I, v0) => ...
(I, v1) => ... # v0 < v1
(I, v2) => ... # v1 < v2
Despite appearing multiple times in the store, only one version of the object is available to transactions - the latest version (v2 in the previous example). Moreover, only one transaction can modify the object at that version to create a new version, guaranteeing a linear history (v1 was created in a state where I was at v0, and v2 was created in a state where I was at v1).
Versions are strictly increasing and (ID, version) pairs are never re-used. This structure allows node operators to prune their stores of old object versions that are now inaccessible, if they choose. This is not a requirement, though, as node operators might keep prior object versions around to serve requests for an object's history, either from other nodes that are catching up, or from RPC requests.