diff --git a/.changeset/quiet-seals-destroy.md b/.changeset/quiet-seals-destroy.md
new file mode 100644
index 0000000000000000000000000000000000000000..feb236197121895bfa5f509359a478060f46808c
--- /dev/null
+++ b/.changeset/quiet-seals-destroy.md
@@ -0,0 +1,5 @@
+---
+'@eth-optimism/contracts': minor
+---
+
+Reduce CTC gas costs by storing only a blockhash.
diff --git a/packages/contracts/contracts/L1/rollup/CanonicalTransactionChain.sol b/packages/contracts/contracts/L1/rollup/CanonicalTransactionChain.sol
index 68aa91a7b19608a969e8199e7ce433e4a556ddf7..83f89f01cab4504683231c7ffa4dbbbf47668831 100644
--- a/packages/contracts/contracts/L1/rollup/CanonicalTransactionChain.sol
+++ b/packages/contracts/contracts/L1/rollup/CanonicalTransactionChain.sol
@@ -358,9 +358,6 @@ contract CanonicalTransactionChain is ICanonicalTransactionChain, Lib_AddressRes
         IChainStorageContainer queueRef = queue();
         uint40 queueLength = _getQueueLength(queueRef);
 
-        // Each leaf index corresponds to a tx, either sequenced or enqueued.
-        uint32 leafIndex = 0;
-
         // Counter for number of sequencer transactions appended so far.
         uint32 numSequencerTransactions = 0;
 
@@ -380,7 +377,12 @@ contract CanonicalTransactionChain is ICanonicalTransactionChain, Lib_AddressRes
 
             // Now process any subsequent queue transactions.
             nextQueueIndex += uint40(curContext.numSubsequentQueueTransactions);
+
         }
+        require(
+            nextQueueIndex <= queueLength,
+            "Attempted to append more elements than are available in the queue."
+        );
 
         // Generate the required metadata that we need to append this batch
         uint40 numQueuedTransactions = totalElementsToAppend - numSequencerTransactions;
@@ -590,96 +592,6 @@ contract CanonicalTransactionChain is ICanonicalTransactionChain, Lib_AddressRes
         return uint40(_queueRef.length() / 2);
     }
 
-    /**
-     * Retrieves the hash of a sequencer element.
-     * @param _context Batch context for the given element.
-     * @param _nextTransactionPtr Pointer to the next transaction in the calldata.
-     * @param _txDataLength Length of the transaction item.
-     * @return Hash of the sequencer element.
-     */
-    function _getSequencerLeafHash(
-        BatchContext memory _context,
-        uint256 _nextTransactionPtr,
-        uint256 _txDataLength,
-        bytes memory _hashMemory
-    )
-        internal
-        pure
-        returns (
-            bytes32
-        )
-    {
-        // Only allocate more memory if we didn't reserve enough to begin with.
-        if (BYTES_TILL_TX_DATA + _txDataLength > _hashMemory.length) {
-            _hashMemory = new bytes(BYTES_TILL_TX_DATA + _txDataLength);
-        }
-
-        uint256 ctxTimestamp = _context.timestamp;
-        uint256 ctxBlockNumber = _context.blockNumber;
-
-        bytes32 leafHash;
-        assembly {
-            let chainElementStart := add(_hashMemory, 0x20)
-
-            // Set the first byte equal to `1` to indicate this is a sequencer chain element.
-            // This distinguishes sequencer ChainElements from queue ChainElements because
-            // all queue ChainElements are ABI encoded and the first byte of ABI encoded
-            // elements is always zero
-            mstore8(chainElementStart, 1)
-
-            mstore(add(chainElementStart, 1), ctxTimestamp)
-            mstore(add(chainElementStart, 33), ctxBlockNumber)
-            // solhint-disable-next-line max-line-length
-            calldatacopy(add(chainElementStart, BYTES_TILL_TX_DATA), add(_nextTransactionPtr, 3), _txDataLength)
-
-            leafHash := keccak256(chainElementStart, add(BYTES_TILL_TX_DATA, _txDataLength))
-        }
-
-        return leafHash;
-    }
-
-    /**
-     * Retrieves the hash of a sequencer element.
-     * @param _txChainElement The chain element which is hashed to calculate the leaf.
-     * @return Hash of the sequencer element.
-     */
-    function _getSequencerLeafHash(
-        Lib_OVMCodec.TransactionChainElement memory _txChainElement
-    )
-        internal
-        view
-        returns(
-            bytes32
-        )
-    {
-        bytes memory txData = _txChainElement.txData;
-        uint256 txDataLength = _txChainElement.txData.length;
-
-        bytes memory chainElement = new bytes(BYTES_TILL_TX_DATA + txDataLength);
-        uint256 ctxTimestamp = _txChainElement.timestamp;
-        uint256 ctxBlockNumber = _txChainElement.blockNumber;
-
-        bytes32 leafHash;
-        assembly {
-            let chainElementStart := add(chainElement, 0x20)
-
-            // Set the first byte equal to `1` to indicate this is a sequencer chain element.
-            // This distinguishes sequencer ChainElements from queue ChainElements because
-            // all queue ChainElements are ABI encoded and the first byte of ABI encoded
-            // elements is always zero
-            mstore8(chainElementStart, 1)
-
-            mstore(add(chainElementStart, 1), ctxTimestamp)
-            mstore(add(chainElementStart, 33), ctxBlockNumber)
-            // solhint-disable-next-line max-line-length
-            pop(staticcall(gas(), 0x04, add(txData, 0x20), txDataLength, add(chainElementStart, BYTES_TILL_TX_DATA), txDataLength))
-
-            leafHash := keccak256(chainElementStart, add(BYTES_TILL_TX_DATA, txDataLength))
-        }
-
-        return leafHash;
-    }
-
     /**
      * Inserts a batch into the chain of batches.
      * @param _transactionRoot Root of the transaction tree for this batch.
diff --git a/packages/contracts/test/contracts/L1/rollup/CanonicalTransactionChain.spec.ts b/packages/contracts/test/contracts/L1/rollup/CanonicalTransactionChain.spec.ts
index 1ca440070ce702c3304c9594b4f17d7c04aacb0b..7dcae164275e37bae085803a7d661eb4e22a5a4f 100644
--- a/packages/contracts/test/contracts/L1/rollup/CanonicalTransactionChain.spec.ts
+++ b/packages/contracts/test/contracts/L1/rollup/CanonicalTransactionChain.spec.ts
@@ -420,6 +420,26 @@ describe('CanonicalTransactionChain', () => {
       )
     })
 
+    it('should revert if attempting to append more elements than are available in the queue.', async () => {
+      await expect(
+        appendSequencerBatch(CanonicalTransactionChain, {
+          transactions: ['0x1234'],
+          contexts: [
+            {
+              numSequencedTransactions: 1,
+              numSubsequentQueueTransactions: 1,
+              timestamp: 0,
+              blockNumber: 0,
+            },
+          ],
+          shouldStartAtElement: 0,
+          totalElementsToAppend: 2,
+        })
+      ).to.be.revertedWith(
+        'Attempted to append more elements than are available in the queue.'
+      )
+    })
+
     it('should revert if not called by the sequencer', async () => {
       await expect(
         appendSequencerBatch(CanonicalTransactionChain.connect(signer), {