16 min read
Overview
On October 10, 2022 (Epoch 358), Solana added support for new transaction version types through a concept known as "Versioned Transactions". After this change, the Solana runtime now supports two types of transactions: "legacy" (older transactions) and "0" (transactions that include Address Lookup Tables). Address lookup tables bring a new way for developers to efficiently load many addresses into a transaction, so if you have had issues with storage size due to accounts, this could help you out!
The Address Lookup Table Program (Program ID: AddressLookupTab1e1111111111111111111111111) allows you to store public keys in on-chain lookup tables and call the Lookup Table in your Versioned Transaction. Because serialized transactions transmitted to Solana validators must not exceed 1,232 bytes (Source Code, Reference), leveraging a Lookup Table can reduce transaction size and enable more complex transaction instructions (e.g., more accounts, more integrated Cross-Program Invocations, etc.). Solana lookup tables "effectively 'compress' a 32-byte address into a 1-byte index value" (Source). This means by using lookup tables, our transactions sizes will be smaller (or that we can pack more into our transactions)!
What You Will Do
In this guide, you will:
-
create and execute a Version 0 (V0) Transaction,
-
create and populate an Address Lookup Table, and
-
compare the transaction size of two nearly identical transactions (one using a lookup table and one without).
If you need help with ensuring your existing client-side apps can support Versioned Transactions, check out our *Guide: How to Update Your Solana Client to Handle Versioned Transactions.
*
What You Will Need
-
Nodejs (version 16.15 or higher) installed
-
Typescript experience and ts-node installed
-
Experience with running basic Solana Transactions (Guide: How to Send Transactions on Solana using Javascript)
If you're coming over from our previous Guide: How to Use Versioned Transactions on Solana, you can reuse your app.ts and can Skip to the Assemble a Version 0 Transaction section. Otherwise, set up your project:
Set Up Your Project
Create a new project directory in your terminal with the following:
mkdir solana-versioned-tx
cd solana-versioned-tx
Create a file for your app, app.ts:
echo > app.ts
Initialize your project with the "yes" flag to use default values for your new package:
yarn init --yes
#or
npm init --yes
Create a tsconfig.json with .json importing enabled:
tsc -init --resolveJsonModule true
Install Solana Web3 Dependency
We will need to add the Solana Web3 library for this exercise. In your terminal, type:
yarn add @solana/web3.js@1
#or
npm install @solana/web3.js@1
Let's get started.
Set Up Your App
Import Necessary Dependencies
Open app.ts, and paste the following imports on line 1:
import { AddressLookupTableProgram, Connection, Keypair, LAMPORTS_PER_SOL, PublicKey, SystemProgram, Transaction, TransactionInstruction, TransactionMessage, VersionedTransaction, TransactionSignature, TransactionConfirmationStatus, SignatureStatus } from '@solana/web3.js';
We are importing a few essential methods and classes from the Solana Web3 library. There are probably a couple of imports you have not seen before (e.g., AddressLookupTableProgram and VersionedTransaction)--we will cover those later in this guide.
Create a Wallet and Airdrop SOL
The first task we'll need to accomplish is creating an account with a wallet and funding it. We'll be using the handy tool below to automatically generate a new wallet and airdrop 1 SOL to it. (You can also achieve this with the Keypair.generate() and requestAirdrop() functions if you prefer a more manual approach).
Note: Sending airdrop requests too frequently may trigger a 429 (Too Many Requests) error.
Once you've successfully generated your keypair, you'll notice two new constants: secret and SIGNER_WALLET, a Keypair. The secret is a 32-byte array that is used to generate the public and private keys. The SIGNER_WALLET is a Keypair instance that is used to sign transactions (we've airdropped some devnet SOL to cover the gas fees). Make sure to add it to your code below your other constants if you haven't yet.
Below your imports, paste your new secret, and add:
const secret = [0,...,0]; // 👈 Replace with your secret
const SIGNER_WALLET = Keypair.fromSecretKey(new Uint8Array(secret));
const DESTINATION_WALLET = Keypair.generate();
//const LOOKUP_TABLE_ADDRESS = new PublicKey(""); // We will add this later
We have defined two wallets: SIGNER_WALLET will send SOL to our DESTINATION_WALLET. We have also added a constant, LOOKUP_TABLE_ADDRESS, which we will update later to reference our Lookup Table's on-chain account ID.
Set Up Your Quicknode Endpoint
To build on Solana, you'll need an API endpoint to connect with the network. You're welcome to use public nodes or deploy and manage your own infrastructure; however, if you'd like 8x faster response times, you can leave the heavy lifting to us.
See why over 50% of projects on Solana choose Quicknode and sign up for an account here. We're going to use a Solana Devnet node.
Copy the HTTP Provider link:

Inside app.ts under your import statements, declare your RPC and establish your Connection to Solana:
const QUICKNODE_RPC = 'https://example.solana-devnet.quiknode.pro/0123456/';
const SOLANA_CONNECTION = new Connection(QUICKNODE_RPC);
Your environment should look like this:

Alright, let's BUILD!