---
title: "什麼是 Solana 上的 associated token account？"
description: "了解什麼是 Associated Token Account、其運作方式，以及如何建立一個"
---

# 什麼是 Solana 上的 associated token account？

[Solana Account Model](https://www.alchemy.com/overviews/solana-account-model) 負責組織與儲存所有鏈上資料，而 Associated Token Accounts（ATA）正是這個模型的核心元件之一。本文將說明什麼是 ATA、它的運作方式，以及如何為自己建立一個 Associated Token Account。

## **什麼是 associated token account？**

**Associated Token Account 是透過 Solana Associated Token Account Program 建立的帳戶，用來存放特定 token 的資訊、餘額與擁有者。** 它是 [Program Derived Address](https://www.alchemy.com/overviews/program-derived-address) 的一種變體。

以下說明每個名詞的意思：

- **Associated Token Account** - 與某個 token 關聯的帳戶（可以想成 Solana Token Program）
- **Program Derived Address** - 由 Solana 程式「衍生」（建立）出來的地址，在此指 Associated Token Account Program

### Associated token account 之間如何運作與轉帳？

**Associated Token Account 之間的轉帳直接發生在帳戶之間，並間接透過它們的錢包地址進行。**

Token account 相當於 Ethereum 上的 ERC-20 token，但有一個根本上的差異：Ethereum 智能合約擁有自己的狀態與程式碼，而 Solana 上的 token account 只包含程式碼，並將其狀態（例如 token 餘額）「輸出」到 Associated Token Account 中，而每個持有該 token 的擁有者都會建立一個這樣的帳戶。

**讓我們快速以 USDC 為例，複習一下目前所學的內容：**

- Solana 上的 USDC 是一個 token account
- token account 由 [System Program](https://www.alchemy.com/overviews/solana-data-vs-program-accounts) 建立，並由 SPL Token Program 初始化為 Token mint
- USDC token 初始化後，使用者就可以開始進行轉帳
- 持有 USDC token 的使用者會透過 Associated Token Account Program（ATP）建立 Associated Token Account
- 兩個使用者之間的 USDC 交換，是發生在他們各自的 ATA 之間

<ImageBlock
  src="https://media.alchemy.com/1703696237-associated-token-account-on-solana.jpg"
  alt="USDC 轉帳在 Solana 上不同 Associated Token Account 之間流動的示意圖"
  width={1600}
  height={901}
  caption="Solana 上的 Associated Token Account"
/>

USDC 轉帳直接發生在使用者的 ATA 之間，並間接透過 [Solana nodes](https://www.alchemy.com/overviews/solana-nodes) 上的錢包地址進行。這些轉帳必須發生在使用相同 token mint seed 建立 ATA 的使用者之間。

## **什麼是 associated token account program？**

Associated Token Account Program 是 [**Solana Program Library**](https://www.alchemy.com/overviews/solana-program-library) 的一部分，是每個 ATA 的父程式，負責將使用者的錢包對應到他有權限操作的 ATA。此外，ATA Program 也確保：如果使用者想把 token 傳送給另一個使用者，即使對方沒有對應該 token 的 ATA，也能收到。在這種情況下，程式會在智能合約於 [RPC node](https://www.alchemy.com/overviews/solana-rpc) 上執行時，自動建立一個 ATA 帳戶。

Associated Token Account Program 的原始碼是以 Rust 撰寫，可以在 [GitHub](https://github.com/solana-labs/solana-program-library) 上查看。

以下是 ATA 在 TypeScript 底層的建立方式：

<ImageBlock
  src="https://media.alchemy.com/1703696380-creating-associated-account-source-code.jpg"
  alt="在 Solana 上建立 Associated Account Program 的原始碼"
  width={1600}
  height={1338}
  caption="在 Solana 上建立 Associated Account Program 的原始碼"
/>

### **Associated token account program 如何運作？**

以下說明 ATA program 內部發生的事：

#### **1. 取得常數的 ID**

首先，我們取得 \`TOKEN_PROGRAM_ID\` 與 \`SPL_ASSOCIATED_TOKEN_ACCOUNT_PROGRAM_ID\` 這兩個常數。program ID 其實就是該程式地址的另一種說法。

#### **2. 取得 findAssociatedTokenAddress 函式**

接著，我們使用 \`findAssociatedTokenAddress\` 函式，它會回傳 publicKey，也就是新建立的 ATA 的地址。

#### **3. 呼叫 findProgramAddress 方法**

在函式內部，會呼叫 \`findProgramAddress\` 方法，並傳入兩個參數：

- 一組 Seed 陣列
- SPL_ASSOCIATED_TOKEN_ACCOUNT_PROGRAM_ID

由於 ATA 是 Program Derived Address（PDA）的一種形式，該帳戶可以透過將參數傳入程式來建立。建立 PDA 時需要傳入 seed 作為參數，在此情況下分別是：

1. **wallet_address** - 擁有 ATA 中資金的帳戶地址（authority）
1. **token_program_id** - SPL Token Program 的 program ID
1. **token_mint_address** - 將儲存於 ATA 中的 Token account 地址

Associated Token Account Program 的 ID 是 SPL_ASSOCIATED_TOKEN_ACCOUNT_PROGRAM_ID。

## **如何建立 associated token account**

建立 Associated Token Account 就跟在 Solana 上使用 spl-token-cli 呼叫 create-token 一樣簡單。建立 ATA 也假設它所要「關聯」的 token 已經存在。

<ImageBlock
  src="https://media.alchemy.com/1703696504-creating-associated-token-account-on-solana.jpg"
  alt="在 Solana 上建立 associated token account"
  width={1600}
  height={749}
  caption="在 Solana 上建立 associated token account"
/>

這段程式碼呼叫了 \`create-account\` 指令，該指令接受 \`&lt;TOKEN_MINT_ADDRESS&gt;\` 作為參數。

要建立 Associated Token Account，必須依照以下四個步驟：

1. 轉入 SOL - System Program 初始化 ATA，並使其符合免租金條件（rent-exempt）
1. 建立可用空間 - System Program 為 ATA 分配可用空間
1. 轉移擁有權 - System Program 將帳戶的擁有權轉移給 SPL Associated Token Account Program
1. 初始化帳戶 - 這個過程完成帳戶初始化，並設定 token 地址、新建立的 ATA 地址及其擁有者

### **Owner 與 authority 有什麼差別？**

*Owner* 是指控制該 ATA 的 Solana 程式類型，而 *authority* 則是指發送交易給 owner 程式的帳戶（錢包），owner 程式接著會代表該 authority 更改 ATA 中的資料。

### **Associated token account 的成本是多少？**

預設情況下，Associated Token Account 在建立時必須符合[**免租金（rent-exempt）**](https://www.alchemy.com/overviews/how-to-calculate-rent-for-solana-programs)的條件，因此帳戶必須持有的最低金額至少為 0.00203928 SOL。System Program 會將這筆 SOL 轉入 ATA，並從發起交易的帳戶中扣除。

除了這筆初始費用外，之後的任何互動花費都不會超過 Solana 上一般交易的成本。

### **如何查看 associated token account**

**你可以透過像 Phantom 這類的客戶端來查看 Associated Token Account，它會自動推導出使用者錢包有權限操作的所有 ATA。** 此外，由於區塊鏈是公開的，你也可以借助 Solscan.io 之類的瀏覽器來取得這些資訊。

貼上你想查看的錢包地址，其 ATA 就會顯示在 Token Accounts 底下：

<ImageBlock
  src="https://media.alchemy.com/1703696658-solscan-interface.png"
  alt="用來查詢錢包 ATA 的 Solscan.io 介面"
  width={1600}
  height={785}
  caption="用來查詢錢包 ATA 的 Solscan.io 介面"
/>

### **可以將 associated token account 連結到現有帳戶嗎？**

**將 Associated Token Account 連結到現有帳戶，本來就是預設在幕後完成的行為。由於 ATA 的建立方式，程式或客戶端可以輕易看到每個帳戶的 seed。** 這些 seed 可以視為是連結到以下項目的「連結」：

- 有權限操作該 ATA 的錢包
- Token account 的地址（即該 ATA 所持有的 token 類型）

## **使用 Alchemy 打造你的 Solana 應用程式**

了解 Associated Token Account 是成為一名成熟的 Solana 開發者的第一步之一。當你熟悉 Solana nodes 並選好 RPC provider 之後，就可以使用我們易於上手的 [Solana API](https://www.alchemy.com/docs/reference/solana-api-quickstart) 快速展開你的第一個 dApp 開發。

## 常見問題

### 什麼是 Solana 上的 associated token account（ATA）？

Associated Token Account 是透過 Solana Associated Token Account Program 建立的帳戶，用來存放特定 token 的資訊、餘額與擁有者。它是 Program Derived Address 的一種變體，會將使用者的錢包對應到特定的 token。

### ATA 與一般的 token account 有什麼不同？

Solana 上的 token account 只包含程式碼，並將其狀態「輸出」到 Associated Token Account 中，而每個持有該 token 的擁有者都會建立一個這樣的帳戶。ATA 是同時連結到某個錢包與特定 token mint 的確定性衍生地址。

### 什麼是 associated token account program？

Associated Token Account Program 是 Solana Program Library 的一部分，負責將使用者的錢包對應到他有權限操作的 ATA。當使用者將 token 傳送給沒有該 token 對應 ATA 的接收者時，它會自動建立 ATA 帳戶。

### 建立一個 associated token account 需要多少成本？

ATA 在建立時必須符合免租金條件，需要至少 0.00203928 SOL 的最低餘額。這筆金額會從發起交易的帳戶中轉出，用以支付持續的租金需求。

### 衍生 ATA 地址時使用哪些 seed？

ATA 地址是透過三個 seed 衍生而來：錢包地址（authority）、token program ID，以及 token mint 地址。這些會傳入 Associated Token Account Program，以建立確定性的地址。

### 我要如何建立 associated token account？

你可以使用 spl-token-cli，呼叫 \`create-account\` 指令並帶入 token mint 地址作為參數來建立 ATA。整個過程包含轉入 SOL、建立空間、轉移擁有權，以及初始化帳戶。

### 我要如何查看自己的 associated token accounts？

你可以透過像 Phantom 這樣的錢包來查看你的 ATA，它會自動推導出你的錢包有權限操作的所有 ATA；或者也可以使用像 Solscan.io 這類的區塊鏈瀏覽器，搜尋你的錢包地址並查看 Token Accounts 區塊。

### 如果我把 token 傳送給沒有 ATA 的人，會發生什麼事？

如果接收者的 ATA 尚未存在，Associated Token Account Program 會在轉帳過程中自動為其建立，並從發送者的帳戶中扣除免租金所需的 SOL 金額，用來建立新的 ATA。
