Expand description
OBCE is a library that provides tools to create custom chain extensions with automatic generation of bindings for both ink! smart contracts and Substrate-based chains.
Usage
obce::definition
macro is OBCE’s entrypoint. Using this macro you can
define the API of your chain extension for usage in both ink! and Substrate:
#[obce::definition]
pub trait MyChainExtension {
fn chain_extension_method(&self, val: u32) -> u64;
}
With ink
feature enabled, obce::definition
automatically produces
glue code to correctly call Substrate part of a chain extension. This glue code
takes care of argument encoding/decoding, identifier matching, etc.
On the other hand, when substrate
feature is enabled, the usage of obce::implementation
is required to complete the chain extension implementation.
obce::implementation
is used on an impl
block to
generate the code necessary for usage in Substrate:
use obce::substrate::{
frame_system::Config as SysConfig,
pallet_contracts::Config as ContractConfig,
sp_runtime::traits::StaticLookup,
ChainExtensionEnvironment,
ExtensionContext
};
#[obce::definition]
pub trait MyChainExtension {
fn chain_extension_method(&self, val: u32) -> u64;
}
pub struct ChainExtension;
#[obce::implementation]
impl<'a, E, T, Env> MyChainExtension for ExtensionContext<'a, E, T, Env, ChainExtension>
where
T: SysConfig + ContractConfig,
<<T as SysConfig>::Lookup as StaticLookup>::Source: From<<T as SysConfig>::AccountId>,
Env: ChainExtensionEnvironment<E, T>,
{
fn chain_extension_method(&self, val: u32) -> u64 {
val as u64
}
}
There are various configuration options available for both obce::definition
and obce::implementation
, all of which are documented
in corresponding API sections.
Custom errors
Your chain extension may have chain-specific errors, some of which
may terminate contract execution itself. You may use obce::error
macro to create your custom error type, with an optional variant that holds critical errors:
use obce::substrate::CriticalError;
#[obce::error]
enum Error {
One(u32),
#[obce(critical)]
Two(CriticalError)
}
Testing
OBCE also provides infrastructure for testing your chain extension
using obce::mock
.
To start testing your chain extension, mark chain extension definition
impl
block as obce::mock
, and fill the impl
block
with the required methods:
#[obce::definition]
pub trait MyChainExtension {
fn chain_extension_method(&self, val: u32) -> u64;
}
// Contract code...
mod simple_test {
struct Context;
#[obce::mock]
impl crate::ChainExtension for Context {
fn chain_extension_method(&self, val: u32) -> u64 {
val as u64
}
}
#[test]
fn call_contract() {
register_chain_extensions(Context);
// Call the contract as usual
}
}
For a complete usage example, as well as more details on how to use the macro correctly see the corresponding API section.
Modules
- Automatically generated traits that provide the necessary information about the chain extension.
Macros
- Chain extension identifier lookup.
Attribute Macros
- Chain extension definition for use with Substrate-based nodes and ink! smart contracts.
- Chain extension error.
- Chain extension implementation for use with Substrate-based nodes.
- Chain extension mocking utility.