We know how solidity receives data and process them. But there isn’t much docs on how data received is treated from L1 to L2 and L2 to L2. It seems to be designed with some differentiation in encoding and offsets. Hence can someone explain how data received and sent treated? @Nazeeh21 @david
In essence, how data is formatted and transmitted between contracts and from L1 to L2?
In FuelERC20Gatewayv4.sol
bytes memory depositMessage = abi.encodePacked(
assetIssuerId,
uint256(data.length == 0 ? MessageType.DEPOSIT_TO_CONTRACT : MessageType.DEPOSIT_WITH_DATA),
bytes32(uint256(uint160(tokenAddress))),
uint256(0), // token_id = 0 for all erc20 deposits
bytes32(uint256(uint160(msg.sender))),
to,
l2MintedAmount,
uint256(decimals),
data
);
Constants.sw for offsets
library;
// A message is encoded as
// 0x00 => CONTRACT_ID
// 0x20 => MESSAGE_TYPE
// 0x40 => TOKEN_ADDRESS
// 0x60 => TOKEN_ID
pub const OFFSET_MESSAGE_TYPE: u64 = 32; //0x20
pub const OFFSET_TOKEN_ADDRESS: u64 = OFFSET_MESSAGE_TYPE + 32; //0x40
pub const OFFSET_TOKEN_ID: u64 = OFFSET_TOKEN_ADDRESS + 32; //0x60
// 0x80 and onwards: payload, with offsets defined as below
// Offsets for a deposit message
pub const OFFSET_FROM: u64 = OFFSET_TOKEN_ID + 32;
pub const OFFSET_TO: u64 = OFFSET_FROM + 32;
pub const OFFSET_AMOUNT: u64 = OFFSET_TO + 32; //0xC0
pub const OFFSET_DECIMALS: u64 = OFFSET_AMOUNT + 32;
// Offsets for a metadata message
pub const OFFSET_NAME_PTR: u64 = OFFSET_TOKEN_ID + 32;
pub const OFFSET_SYMBOL_PTR: u64 = OFFSET_NAME_PTR + 32;
// Type of messages that can be received
pub const DEPOSIT: u8 = 0;
pub const CONTRACT_DEPOSIT: u8 = 1;
pub const CONTRACT_DEPOSIT_WITH_DATA: u8 = 2;
pub const METADATA: u8 = 3;
In deposit_message.sw
// pub struct DepositMessage {
// pub amount: b256,
// pub from: b256,
// pub to: Identity,
// pub token_address: b256,
// pub token_id: b256,
// pub decimals: u8,
// pub deposit_type: DepositType,
// }
/// Read the bytes passed as message data into an in-memory representation using the DepositMessage type
pub fn parse_deposit_to_contract_with_data(msg_idx: u64) -> Self {
Self {
amount: input_message_data(msg_idx, OFFSET_AMOUNT).into(),
from: input_message_data(msg_idx, OFFSET_FROM).into(),
token_address: input_message_data(msg_idx, OFFSET_TOKEN_ADDRESS).into(),
to: Identity::ContractId(ContractId::from(b256::from(input_message_data(msg_idx, OFFSET_TO)))),
token_id: input_message_data(msg_idx, OFFSET_TOKEN_ID).into(),
decimals: input_message_data(msg_idx, OFFSET_DECIMALS).get(31).unwrap(),
deposit_type: DepositType::ContractWithData,
}
}