Skip to main content

Crate obce

Crate obce 

Source
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§

codegen
Automatically generated traits that provide the necessary information about the chain extension.

Macros§

id
Chain extension identifier lookup.

Attribute Macros§

definition
Chain extension definition for use with Substrate-based nodes and ink! smart contracts.
error
Chain extension error.
implementation
Chain extension implementation for use with Substrate-based nodes.
mock
Chain extension mocking utility.