The Cannonical Transaction Chain (CTC) Format
Every transaction submitted to Optimism is written to the mainnet Ethereum blockchain as call data, this is how Optimism inherits the availability and integrity guarantees of Ethereum. This is also the cause of the majority of the cost of Optimism transactions. At the time of writing it is cheaper to write a kilobytes to storage on Optimism than it is to add one byte to the calldata on Ethereum.
# Initial solution
The initial solution was to write a header with supporting data followed by a list of transactions.
To interpret a transaction, you can search for it on Etherscan (opens new window). To interpret a CTC transaction you need to Click to see more to see the calldata (called "Input Data" by Etherscan):
For example, here are the fields and their values for this initial solution CTC transaction (opens new window):
|0-3||4||Function signature||0xd0f89344||appendSequencerBatch() (opens new window)|
|4-8||5||Starting tx index||4025992||this transaction (opens new window)|
|9-11||3||Elements to append||89|
|15-30||14||Context 0 (multiple fields)|
|15-17||3||Transactions sent directly to L2||3|
|18-20||3||Deposits with this context||0|
|26-30||5||L1 block number||The L1 block number in this context, as obtained by calling OVM_L1BlockNumber (opens new window). (14301739 (opens new window))|
|31-33||3||Transactions sent directly to L2||8|
|37-41||5||Timestamp||1646146451||15 seconds after the previous batch|
|42-47||5||L1 block number||14301739 (opens new window)|
|16n+15-16n+17||3||Transactions sent directly to L2|
|16n+18-16n+20||3||Deposits with this context|
|16n+26-16n+30||5||L1 block number|
This transaction has 15 batch contexts (numbered 0-14), so the first byte after the last context in this transaction, which starts the transaction list, is
Transactions are provided as a three byte length followed by the RLP encoded transaction.
Looking at locations 255-257, we see
0x00016e, so the first transaction is 366 bytes long, at locations 258-623.
The next transaction length starts at byte 624, and the next transaction itself starts at byte 627.
# Additional batch types
The initial solution did not have a batch type. However, to modify the format (for example, to add compression) a batch type is needed. The solution is to set the timestamp of the first context to zero. This does not create ambiguity because a timestamp of zero represents January 1st, 1970 (based on the UNIX convention), which cannot happen. The block number then represents the transaction type.
# CTC transaction type zero
After the normal header and the first context, which has a timestamp of zero and a block number of zero, the other contexts contain the normal data. After that the list of transaction lengths and transaction data is compressed using zlib (opens new window).