Facet Transaction Spec
Overview
Facet transactions are the primary mechanism for interacting with the Facet protocol. They follow a format similar to EIP-1559 Ethereum transactions and Optimism's Deposit transactions, with specific adaptations for the Facet ecosystem.
Transaction Format
Facet transactions use the EIP-2718 transaction type 0x46
(70 in base 10) and contain the following fields:
chain_id
Distinguishes the payload as being relevant only to Facet
• Mainnet: 1027303
(0xface7
in hex)
• Sepolia testnet: 16436858
(0xface7a
in hex)
to
L2 recipient's address (EOA or L2 contract). Blank for contract creations
value
Amount of FCT being transferred in the transaction
gas_limit
The gas limit of the L2 transaction
data
EVM input data (ABI encoded contract call or contract creation code)
mine_boost
Optional appended data that increases payload size to increase FCT mining (see below)
Important: Facet transactions have no signature field. The "from" address is inferred from the properties of the Ethereum transaction in which they are delivered.
Serialization Format
Facet transactions must be serialized in this specific format for Facet nodes to process them:
0x46 ++ rlp_encode([chain_id, to, value, gas_limit, data, mine_boost])
Fee Model
Facet uses a base-fee-only pricing model on L2. There is no per-transaction priority fee and no max_fee_per_gas
field in Facet transactions. All transactions pay the current L2 base fee computed by the protocol.
Execution on L2 (Deposit Type 0x7D)
Facet payloads are executed on L2 as deposit transactions of type 0x7D
(125 decimal). The execution-layer transaction includes fields like sourceHash
, from
, optional mint
, value
(FCT), gas
, isSystemTransaction
, and data
. For hashing, the typed-transaction hash treats mint
as zero/nil so the mint amount does not affect the transaction hash. See Reference → Chain State Derivation for full field definitions and hashing rules.
Transaction Submission Methods
There are two methods to submit Facet transactions to the network:
Method 1: From EOA via Calldata
EOAs (Externally Owned Accounts) can create Facet transactions by sending a successful Ethereum transaction (receipt status = 1) to the Facet inbox address:
0x00000000000000000000000000000000000face7
This L1 transaction acts as an "envelope" that carries the RLP-encoded Facet transaction as a payload within its calldata. The signer of the Ethereum envelope transaction determines the "from" address on the Facet transaction.
Note on ETH value: The L1 envelope transaction to the inbox address must set value = 0
. Never send ETH to 0xface7
. Any L2 transfer amount should be expressed via the Facet payload’s value
field, which is denominated in FCT and applied on L2 during execution.
Implementation Example (TypeScript/Viem)
const transactionData = [
toHex(l2ChainId),
to ?? "0x",
value ? toHex(value) : "0x",
gasLimit ? toHex(gasLimit) : "0x",
data ?? "0x",
mineBoost ?? "0x"
];
const encodedTransaction = concatHex([toHex(70), toRlp(transactionData)]);
const l1Transaction = {
account: l1WalletClient.account,
to: "0x00000000000000000000000000000000000face7",
value: 0n,
data: encodedTransaction,
chain: l1WalletClient.chain,
};
await l1WalletClient.sendTransaction(l1Transaction);
Method 2: From L1 Smart Contract via Event Logs
L1 Smart Contracts can create Facet transactions by emitting events with the following specification:
Event Format Requirements
Topic Requirements:
Exactly one topic: The event MUST have exactly one topic
Topic value:
0x00000000000000000000000000000000000000000000000000000000000face7
. This isbytes32(uint256(0xface7))
- the number0xface7
cast to uint256, then to bytes32.
Data Requirements:
Payload location: The entire Facet transaction payload MUST be in the event's
data
fieldPayload format: Same RLP-encoded transaction format as calldata method (
0x46
+ RLP)No indexed parameters: The event MUST NOT have any indexed parameters beyond the single topic
One Transaction Per Ethereum Transaction Rule:
Single Facet transaction: Each Ethereum transaction can contain at most ONE valid Facet transaction
Multiple candidates: If an Ethereum transaction contains multiple events with the Facet signature, only the first valid Facet transaction is processed
Processing order: Calldata is checked before events. Within events, they are processed in log index order
Failure semantics: Subsequent Facet transaction candidates in the same Ethereum transaction are silently ignored, not treated as errors
Implementation Example (Solidity)
import { LibRLP } from "lib/solady/src/utils/LibRLP.sol";
contract FacetSender {
using LibRLP for LibRLP.List;
bytes32 constant facetEventSignature = 0x00000000000000000000000000000000000000000000000000000000000face7;
uint8 constant facetTxType = 0x46;
function sendFacetTransaction(
uint256 chainId,
bytes memory to,
uint256 value,
uint256 gasLimit,
bytes memory data,
bytes memory mineBoost
) internal {
LibRLP.List memory list;
list.p(chainId);
list.p(to);
list.p(value);
list.p(gasLimit);
list.p(data);
list.p(mineBoost);
bytes memory payload = abi.encodePacked(facetTxType, list.encode());
assembly {
log1(add(payload, 32), mload(payload), facetEventSignature)
}
}
}
Key Differences Between Methods
Sender Type
Externally Owned Account
L1 Smart Contract
Delivery Method
Transaction calldata to inbox address
Event emission with Facet signature
From Address
EOA that signed the L1 transaction
The aliased address of the smart contract that emitted the event
Use Case
Direct user interactions
Programmatic/bridged transactions
Best Practices
Chain ID Verification: Always ensure you're using the correct chain ID for your target network (mainnet vs testnet)
Gas Estimation: Properly estimate gas limits to ensure transaction success
Error Handling: Verify that L1 transactions have a successful receipt status before considering the Facet transaction submitted
Mine Boost: Use the optional
mine_boost
field strategically to increase FCT mining rewards when needed
Security Considerations
The Facet inbox address (
0x00000000000000000000000000000000000face7
) has no known private key, ensuring it cannot be controlled by any partyAlways validate transaction parameters before submission
Monitor L1 transaction success to ensure proper Facet transaction delivery
Last updated