-
Notifications
You must be signed in to change notification settings - Fork 1.2k
contracts: Hybrid chain support #114
Description
https://www.rob.tech/blog/hybrid-chains/
As of right now crafting an interaction between the runtime and contracts hosted on its contracts pallet is cumbersome. We want this to be a nice experience without any manual labor. Almost all the bits and pieces to make this happen exist. We need to put them together and apply polish.
There are two sides to this endeavor and we explain them separately.
Calling a contract from the runtime
Calling into a contract from any pallet is not difficult as of right now. The pallet needs to depend on pallet-contracts and call Pallet::bare_call with the address of the contract. However, crafting the input and evaluating the output is not easy. The data is formatted according to the ink! ABI and specific to the contract. One has to manually craft code to encode input and decode output. This makes the whole thing rather pointless.
We want to change this to the following: Any runtime code that wants to call a contract will depend directly on the contract in its manifest (in addition to pallet-contracts). This dependency will then export (generated) types that allow to craft interactions for every function exposed by the contract. This code will make sure that in- and outputs are properly coded in a type safe way.
The issue for ink! to export those types can be found here. It includes a mock up of the envisioned API: use-ink/ink#1674
Next Steps
- Make ink! contracts viable dependencies for the runtime use-ink/ink#1674
- Add public function to
pallet-contractsthat accepts the types exported by a contract dependency.
Calling the runtime
Currently, in order to call functionality within a runtime that lies outside of the core API a ChainExtension needs to be created by runtime authors. It extends the set of functions a contract can call. It is manual work because those entry points must be safe for being called by hostile actors (contracts). That includes dealing with untrusted input and charging a sound amount of weight.
It turns out there is another type of function within the runtime which has the same requirements (dealing with untrusted input, charging weight): Dispatchables. Dispatchables are already describing the set of functions within a runtime which are safe to be called by hostile actors. We just need to make them available for contracts. As a matter of fact we already have the functionality to dispatch a Call into the runtime.
However, it cannot replace chain extensions for one simple reason: A Dispatchable can't return any data on success but rather uses a side channel for that (events). It might be nice to capture those events and copy them back to the contract.
Additional ways of improvement would be to add view functions to FRAME which can be used by contracts and add a suite of macros that allow for chain extensions to be derived while generating metadata for ink!.
Next Steps
Before starting to work on any of those points create a new issue and link it here.
- [FRAME Core] Add support for
view_functions#216 - Add subxt like generation of the
Callenum use-ink/ink#1675 - Allow
call_runtimeto capture events and copy back to the contract - Allow
call_runtimeto copy back the result of aCallto contract memory - Add a suite of macros to support with implementing
ChainExtension
Metadata
Metadata
Assignees
Labels
Type
Projects
Status