darwinia-network / darwinia-messages-sol

Darwinia cross-chain messages gateway and protocol for EVM developers 💌
MIT License
29 stars 8 forks source link

Move scale encode precompile functions to solidity library #154

Closed hackfisher closed 2 years ago

hackfisher commented 2 years ago

For example, this new added one and others https://github.com/darwinia-network/darwinia-common/pull/1186

The simple way will be summary common used Calls or structs need to be encoded in solidity.

For example, for following call

pallet_bridge_messages::Call::<Runtime, WithPangoroMessages>::send_message {
                    lane_id,
                    payload,
                    delivery_and_dispatch_fee: fee.saturated_into(),
                }
                .into()
        #[pallet::weight(T::WeightInfo::send_message_weight(payload, T::DbWeight::get()))]
        pub fn send_message(
            origin: OriginFor<T>,
            lane_id: LaneId,
            payload: T::OutboundPayload,
            delivery_and_dispatch_fee: T::OutboundMessageFee,
        ) -> DispatchResultWithPostInfo {

We can use some mocked enum call type for encoding, something similar to.

    pub enum PangoroRuntime {
        #[codec(index = 20)]
        Sub2SubBacking(S2SBackingCall),
    }
    #[derive(Encode, Decode, Debug, PartialEq, Eq, Clone)]
    #[allow(non_camel_case_types)]
    pub enum S2SBackingCall {
        #[codec(index = 2)]
        unlock_from_remote(H160, U256, Vec<u8>),
    }

    #[derive(Encode, Decode, Debug, PartialEq, Eq, Clone)]
    pub enum PangolinRuntime {
        #[codec(index = 49)]
        Sub2SubIssuing(S2SIssuingCall),
    }

    #[derive(Encode, Decode, Debug, PartialEq, Eq, Clone)]
    #[allow(non_camel_case_types)]
    pub enum S2SIssuingCall {
        #[codec(index = 0)]
        register_from_remote(TokenMetadata),
        #[codec(index = 1)]
        issue_from_remote(H160, U256, H160),
    }

/// The parameters box for the pallet runtime call.
#[derive(Encode, Decode, Debug, PartialEq, Eq, Clone)]
pub enum CallParams {
    #[codec(index = 0)]
    S2sIssuingPalletRegisterFromRemote(TokenMetadata),
    #[codec(index = 1)]
    S2sIssuingPalletIssueFromRemote(H160, U256, H160),
    #[codec(index = 2)]
    S2sBackingPalletUnlockFromRemote(H160, U256, Vec<u8>),
}

For general way of ABI to SCALE transcoding, we might need some util function like

fn ABI_to_SCALE(bytes _data, bytes _type)

The _data is the data in ABI encoding format and to be transcoded, the _type is some compact format to represent the struct of the data, both for ABI and SCALE.

The first choice would be pure solidity, but if the implementation cost too much gas, we can consider using precompile.

hackfisher commented 2 years ago

Some existing SCALE solidity library for reference, including some basic implementations

https://github.com/darwinia-network/darwinia-bridges-sol/blob/master/contracts/utils/contracts/Scale.sol

wuminzhe commented 2 years ago

a simple implemention https://github.com/darwinia-network/darwinia-bridges-sol/commit/9ed65805404f3e9abc3946ffa8dc777d61c68c7f