Solana’s Token Program, Explained

Breaking down how fungible and non-fungible tokens work in Solana.

Solana’s Account Model

The account on the left is a program account that can increment a counter. The counter’s value needs to be stored in a separate data account. The data account is owned by the program account, which means the program account can modify the data account’s state.

What is Solana’s Token Program?

How Does Solana’s Token Program Work?

$ echo $SOLADDR1
3sdsSwWWjjGA7HpPBQfGaXRE2HqmdKicMXHRapqLAu4L
$ echo $SOLADDR2
ES2C1YPzNh5JjQu7DdxrveaPUHj9CnrRWSdrFo4ku5Zh
$ spl-token create-token --mint-authority ~/my_solana_wallet1.json                                         
Creating token 6ifRGEkJ6XmEjuqfTFNqAjjomUiDJTjRv4GHqBH6usWr
$ solana account $TOKEN1
Public Key: Aqf1rBKNQYgX1mjE64STwV3miEwXEe2ioZzD7n4vkpXk
Balance: 0.0014616 SOL
Owner: TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA
Executable: false
Rent Epoch: 207
Length: 82 (0x52) bytes
0000: 01 00 00 00 2a b0 1a 64 bb c5 f0 df bf 57 d5 61 ....*..d.....W.a
0010: 56 a8 b8 85 8f a8 0b 09 f1 f1 a2 dc 4d 51 b3 63 V...........MQ.c
0020: 8f 72 bd e9 00 00 00 00 00 00 00 00 09 01 00 00 .r..............
0030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0040: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0050: 00 00 ..
https://explorer.solana.com/address/TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA?cluster=devnet
https://explorer.solana.com/address/Aqf1rBKNQYgX1mjE64STwV3miEwXEe2ioZzD7n4vkpXk?cluster=devnet
The Token Program’s owner is the BPF Loader. I don’t picture it here because it’s not that important, and it clutters up the diagram.
$ spl-token create-account $TOKEN1 --owner $SOLADDR1                              
Creating account 9EYnoqiBQmJPR55db44cF4wkN1PD5D6vjxEz61r2Ujak
$ solana account $TOKENACCT1
Public Key: 9EYnoqiBQmJPR55db44cF4wkN1PD5D6vjxEz61r2Ujak
Balance: 0.00203928 SOL
Owner: TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA
Executable: false
Rent Epoch: 207
https://explorer.solana.com/address/9EYnoqiBQmJPR55db44cF4wkN1PD5D6vjxEz61r2Ujak?cluster=devnet
$ spl-token balance $TOKEN1 --owner $SOLADDR1
0
$ spl-token mint $TOKEN1 10 $TOKENACCT1 --mint-authority ~/my_solana_wallet1.json
Minting 10 tokens
Token: Aqf1rBKNQYgX1mjE64STwV3miEwXEe2ioZzD7n4vkpXk
Recipient: 9EYnoqiBQmJPR55db44cF4wkN1PD5D6vjxEz61r2Ujak
$ spl-token balance $TOKEN1 --owner $SOLADDR1
10
The token balance gets updated in Solana Explorer as well. https://explorer.solana.com/address/9EYnoqiBQmJPR55db44cF4wkN1PD5D6vjxEz61r2Ujak?cluster=devnet.
$ spl-token accounts  --owner $SOLADDR1                                                                                                      
Token Balance
---------------------------------------------------------------
Aqf1rBKNQYgX1mjE64STwV3miEwXEe2ioZzD7n4vkpXk 10
$ spl-token mint $TOKEN1 10 $TOKENACCT1 --mint-authority ~/my_solana_wallet2.json
Minting 10 tokens
Token: Aqf1rBKNQYgX1mjE64STwV3miEwXEe2ioZzD7n4vkpXk
Recipient: 9EYnoqiBQmJPR55db44cF4wkN1PD5D6vjxEz61r2Ujak
RPC response error -32002: Transaction simulation failed: Error processing Instruction 0: custom program error: 0x4 [5 log messages]
$ spl-token transfer $TOKEN1 1 $SOLADDR2 --owner ~/my_solana_wallet1.json
Transfer 5 tokens
Sender: 9EYnoqiBQmJPR55db44cF4wkN1PD5D6vjxEz61r2Ujak
Recipient: ES2C1YPzNh5JjQu7DdxrveaPUHj9CnrRWSdrFo4ku5Zh
Recipient associated token account: FFednTgQRKDbGYjXrXk8SWPfzSJW3Q8ApN5mGCpGdAtE
Error: Recipient's associated token account does not exist. Add `--fund-recipient` to fund their account
$ spl-token create-account $TOKEN1 --owner $SOLADDR2
Creating account FFednTgQRKDbGYjXrXk8SWPfzSJW3Q8ApN5mGCpGdAtE
$ spl-token transfer $TOKEN1 1 $SOLADDR2 --owner ~/my_solana_wallet1.json
Transfer 1 tokens
Sender: 9EYnoqiBQmJPR55db44cF4wkN1PD5D6vjxEz61r2Ujak
Recipient: ES2C1YPzNh5JjQu7DdxrveaPUHj9CnrRWSdrFo4ku5Zh
Recipient associated token account: FFednTgQRKDbGYjXrXk8SWPfzSJW3Q8ApN5mGCpGdAtE
$ spl-token balance $TOKEN1 --owner $SOLADDR2
1
$ spl-token wrap 1 ~/my_solana_wallet1.json
Wrapping 1 SOL into DXWzvX3RtZbito65G8ZgqmEzJM6Z6Fqy7NHkbpEmCUZD
$ spl-token unwrap DXWzvX3RtZbito65G8ZgqmEzJM6Z6Fqy7NHkbpEmCUZD ~/my_solana_wallet1.json
Unwrapping DXWzvX3RtZbito65G8ZgqmEzJM6Z6Fqy7NHkbpEmCUZD
Amount: 1 SOL
Recipient: 3sdsSwWWjjGA7HpPBQfGaXRE2HqmdKicMXHRapqLAu4L

Wait, What About NFTS?

Software Engineer. Tweeting @pencilflip. Mediocre boulderer, amateur tennis player, terrible at Avalon. https://www.mattlim.me/