cadence
cadence copied to clipboard
Generate unique paths
Idea from @rheaplex:
In Lisp, gensym
is a function that generates a unique symbol within a program's namespace. This is essentially a new and unused variable name that is guaranteed not to clash with any others.
Let us imagine a similar function for Cadence paths:
pub fun pathGen(domain: Path.Domain): Path
In a simple implementation, this would do the following:
- Increment a blockchain-global numeric value by one, similarly to how
uuid
currently functions. - Create a path of the form
/<DOMAIN>/--gensym--<GLOBAL_NUMERIC_VALUE>
, where--gensym--
is an otherwise invalid path component to ensure that gensym paths cannot be constructed by any other means. - Return the created path as the correct concrete type, e.g.
/public/βgensymβ234567891345
.
If this value is not stored it will be lost and cannot be recreated. It also cannot be serialized/deserialized to be returned from or passed into scripts or transactions.
This means that the path must be stored in a variable when it is created. Ideally a contract-level public variable for easy reference.
If we apply this to current contract design patterns, then rather than storing easily confused paths for resources and for public capabilities or having to find a way to construct unique memorable paths for capability link farms, we treat path components as essentially opaque and rely on variables to name them.
e.g.:
init() {
self.collectionPathStorage = /storage/Collection
self.collectionPathPublic = /public/Collection
}
becomes:
init() {
self.collectionPathStorage = pathGen(domain: Path.Storage)
self.collectionPathPublic = pathGen(domain: Path.Public)
}
This makes paths easier and less error-prone to create but harder to reason about without access to the contract code that declares them.
This can complement contract-specific storage or replace it in some scenarios.