You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
A near contract is a Rust struct with it's determined behavior. That struct (as a set of fields with specific values, at a given time) is usually saved as the contract's state, in which case that behavior may also refer, depend or interact with other struct's saved/stored states.
The contract definition, including it's entire behavior, is saved/stored as a wasm file, which actually has it's set of "exported functions." Those are used by the near runtime for various forms of interactions which users can refer to.
Once a contract is deployed on the blockchain (where it's then online), it can have it's exported functions invoked by users. This resembles a server, where users can make their requests to the contract - but each party is always intermediated by the runtime, they never communicate directly.
To help on how to receive and parse input and whatnot, some macros from near-sdk can be used, such as ext_contract and near_bindgen. ext_contract can be used by users/clients to represent an online contract/server's available interactions. near_bindgen can be used, while the contract is being built, to facilitate interactions which will be started from the runtime (while representing user invocations in the future).
Limitation
Currently those macros don't support Rust's generics and so they are limited to definitions that are also non-generic. Overall, this makes it non-trivial to compose a contracts's behavior, which can be considered important for building contracts (but actually not so much important for invoking them).
Composition
Contract composing can seen as defining a new contract (a new struct) which is composed of some previously defined structures. That is, it contains others previously defined structures, where those components structures can relate to all sorts of behaviors.
Considering this, the "final" contract can be seen as a root structure which is composed of other structures. Those can also be composed of other structures themselves.
Given that scenario, where the structural composition is already in place, the problem is on how to "inherit behavior." On how the root structure inherit/copies/replicates the behavior of it's composed fields - and also while being able to modify those inherit behaviors.
Newtype
One common Rust pattern for composition is using "newtypes." It is about specifying a generic structure that will be composed of structures of specific behaviors, and that structure can then replicate those behaviors while also being able to modifying them.
The behaviors can be defined as Rust's Traits, and the newtypes can both be composed of inner structures that implement a specific trait, while also re-implementing that trait itself, defining it's own behavior in regards to that trait.
That could be seen as a "inheritance", or "bubbling up" of behavior up to that newtype structure.
And so the root structure, the final contract itself, is the outermost, ultimate destination of all those propagations of structural compositions and intended (and potentially adapted) behaviors.
Conclusion
Possibly, the usual generic-newtype pattern can facilitate contract composition, but as generics aren't currently available by the referred macros, I believe the issue for further design and explorations is valid!
The text was updated successfully, but these errors were encountered:
Related issue: #303
Generics for Near Contract Composition
A near contract is a Rust
struct
with it's determined behavior. Thatstruct
(as a set of fields with specific values, at a given time) is usually saved as the contract's state, in which case that behavior may also refer, depend or interact with otherstruct
's saved/stored states.The contract definition, including it's entire behavior, is saved/stored as a wasm file, which actually has it's set of "exported functions." Those are used by the near runtime for various forms of interactions which users can refer to.
Once a contract is deployed on the blockchain (where it's then online), it can have it's exported functions invoked by users. This resembles a server, where users can make their requests to the contract - but each party is always intermediated by the runtime, they never communicate directly.
To help on how to receive and parse input and whatnot, some macros from near-sdk can be used, such as
ext_contract
andnear_bindgen
.ext_contract
can be used by users/clients to represent an online contract/server's available interactions.near_bindgen
can be used, while the contract is being built, to facilitate interactions which will be started from the runtime (while representing user invocations in the future).Currently those macros don't support Rust's generics and so they are limited to definitions that are also non-generic. Overall, this makes it non-trivial to compose a contracts's behavior, which can be considered important for building contracts (but actually not so much important for invoking them).
Contract composing can seen as defining a new contract (a new struct) which is composed of some previously defined structures. That is, it contains others previously defined structures, where those components structures can relate to all sorts of behaviors.
Considering this, the "final" contract can be seen as a root structure which is composed of other structures. Those can also be composed of other structures themselves.
Given that scenario, where the structural composition is already in place, the problem is on how to "inherit behavior." On how the root structure inherit/copies/replicates the behavior of it's composed fields - and also while being able to modify those inherit behaviors.
One common Rust pattern for composition is using "newtypes." It is about specifying a generic structure that will be composed of structures of specific behaviors, and that structure can then replicate those behaviors while also being able to modifying them.
The behaviors can be defined as Rust's
Trait
s, and the newtypes can both be composed of inner structures that implement a specific trait, while also re-implementing that trait itself, defining it's own behavior in regards to that trait.That could be seen as a "inheritance", or "bubbling up" of behavior up to that newtype structure.
And so the root structure, the final contract itself, is the outermost, ultimate destination of all those propagations of structural compositions and intended (and potentially adapted) behaviors.
Possibly, the usual generic-newtype pattern can facilitate contract composition, but as generics aren't currently available by the referred macros, I believe the issue for further design and explorations is valid!
The text was updated successfully, but these errors were encountered: