
Cách lấy danh sách người nắm giữ token trên Solana
Trong hướng dẫn này, chúng ta sẽ tìm hiểu cách lấy danh sách tất cả người nắm giữ một token có thể thay thế như USDC. Điều này hữu ích khi bạn muốn theo dõi người nắm giữ token hoặc trao thưởng cho họ thông qua airdrop.
Tổng quan
Trước tiên, hãy tìm hiểu cách token, đặc biệt là token không thể thay thế, hoạt động trên Solana. Khi tạo token, nhà phát triển sử dụng chương trình token để tạo một tài khoản mint. Tài khoản mint này lưu trữ thông tin về một token cụ thể, chẳng hạn như tên, địa chỉ token và hình ảnh. Sau khi tài khoản mint được tạo, token có thể được mint và lưu trữ trong tài khoản token. Tài khoản token là tài khoản lưu trữ thông tin về một token cụ thể thuộc sở hữu của một địa chỉ cụ thể. Thông tin này bao gồm địa chỉ mint, địa chỉ chủ sở hữu và số lượng token cụ thể trong tài khoản. Ví dụ: một địa chỉ nắm giữ USDC (một token SPL) sẽ có một tài khoản token dành cho USDC.
Sau khi đã hiểu cách token và tài khoản token hoạt động, chúng ta có thể tìm cách lấy danh sách tất cả người nắm giữ một token nhất định. Mỗi ví nắm giữ một token cụ thể sẽ có một tài khoản token dành cho token đó. Điều này có nghĩa là token này sẽ được liên kết với các tài khoản token của tất cả ví đang nắm giữ nó. Đây là cách chúng ta xác định tất cả người nắm giữ. Nếu có thể lấy tất cả tài khoản token liên kết với một token rồi lấy chủ sở hữu của các tài khoản đó, chúng ta sẽ có danh sách đầy đủ những người nắm giữ!
Phương thức getTokenAccounts
May mắn là phương thức API getTokenAccounts của Helius cho phép chúng ta thực hiện chính xác điều này. Chúng ta có thể đưa địa chỉ mint của bất kỳ token nào vào tham số của lệnh gọi API và nhận lại danh sách tất cả tài khoản token đã được tạo cho token đó. Ngoài ra, API cũng trả về chủ sở hữu của từng tài khoản token; chủ sở hữu này chính là người mà chúng ta thường gọi là người nắm giữ token. Một điểm nhỏ cần lưu ý là một tài khoản có thể có nhiều tài khoản token cho cùng một token. Đây không phải vấn đề lớn; chúng ta chỉ cần thiết lập một số logic để xử lý các tài khoản token có chung chủ sở hữu.
Triển khai
Bây giờ, hãy đi sâu vào mã để xem cách thực hiện. Bạn sẽ cần khóa Helius API để làm theo hướng dẫn. Bạn có thể nhận khóa miễn phí bằng cách truy cập bảng điều khiển Helius của bạn và đăng ký tài khoản. Để bắt đầu, chúng ta phải tạo một tệp JavaScript có tên getTokenHolders.js. Trước tiên, chúng ta có thể thêm URL Helius và nhập thư viện fs để lưu kết quả vào tệp JSON.
const url = `https://mainnet.helius-rpc.com/?api-key=`;
const fs = require("fs");Tiếp theo, chúng ta sẽ tạo một phương thức để truy xuất tất cả tài khoản token liên kết với token cụ thể. Có thể bắt đầu bằng cách tạo phương thức có tên findHolders, phương thức này sẽ sử dụng getTokenAccounts để lấy dữ liệu cần thiết. Bạn có thể đọc thêm về phương thức getTokenAccounts tại đây.
Một điều quan trọng cần lưu ý là mỗi lệnh gọi API chỉ có thể trả về tối đa 1.000 tài khoản token. Hầu hết các token lớn trên Solana đều có hơn 100.000 tài khoản token. Để xử lý vấn đề này, chúng ta sẽ sử dụng kỹ thuật phân trang để duyệt qua tất cả tài khoản token và tiếp tục gọi API cho đến khi truy xuất được dữ liệu liên quan đến mọi tài khoản token hiện có.
Trong phương thức này, chúng ta sẽ đưa mint của token vào các tham số của lệnh gọi getTokenAccounts. Khi lặp qua tất cả tài khoản token, chúng ta sẽ thêm từng chủ sở hữu tài khoản token duy nhất vào một danh sách. Sau khi phương thức chạy xong, chúng ta sẽ lưu danh sách này vào một tệp JSON chứa tất cả người nắm giữ token.
const findHolders = async () => {
// Pagination logic
let page = 1;
// allOwners will store all the addresses that hold the token
let allOwners = new Set();
while (true) {
const response = await fetch(url, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
jsonrpc: "2.0",
method: "getTokenAccounts",
id: "helius-test",
params: {
page: page,
limit: 1000,
displayOptions: {},
//mint address for the token we are interested in
mint: "CKfatsPMUf8SkiURsDXs7eK6GWb4Jsd6UDbs7twMCWxo",
},
}),
});
// Check if any error in the response
if (!response.ok) {
console.log(
`Error: ${response.status}, ${response.statusText}`
);
break;
}
const data = await response.json();
// Pagination logic.
if (!data.result || data.result.token_accounts.length === 0) {
console.log(`No more results. Total pages: ${page - 1}`);
break;
}
console.log(`Processing results from page ${page}`);
// Adding unique owners to a list of token owners.
data.result.token_accounts.forEach((account) =>
allOwners.add(account.owner)
);
page++;
}
fs.writeFileSync(
"output.json",
JSON.stringify(Array.from(allOwners), null, 2)
);
};Trong ví dụ trên, phương thức getTokenAccounts được gọi nhiều lần trong quá trình phân trang qua tất cả tài khoản token. Phản hồi API sẽ cung cấp dữ liệu sau cho mỗi tài khoản token:
{
"address": "CVMR1nbxTcQ7Jpa1p137t5TyKFii3Y7Vazt9fFct3tk9",
"mint": "SHDWyBxihqiCj6YekG2GUr7wqKLeLAMK1gHZck9pL6y",
"owner": "CckxW6C1CjsxYcXSiDbk7NYfPLhfqAm3kSB5LEZunnSE",
"amount": 100000000,
"delegated_amount": 0,
"frozen": false
},Chúng ta đã trích xuất chủ sở hữu từ các tài khoản token này và thêm họ vào danh sách. Nếu muốn, chúng ta cũng có thể lưu số lượng token mà mỗi tài khoản token nắm giữ để xác định những người nắm giữ nhiều nhất.
Sau khi hoàn tất, tất cả những gì cần làm là gọi phương thức:
findHolders();Mã hoàn chỉnh trong tệp getTokenHolders.js sẽ có dạng như sau:
const url = `https://mainnet.helius-rpc.com/?api-key=`;
const fs = require("fs");
const findHolders = async () => {
let page = 1;
let allOwners = new Set();
while (true) {
const response = await fetch(url, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
jsonrpc: "2.0",
method: "getTokenAccounts",
id: "helius-test",
params: {
page: page,
limit: 1000,
displayOptions: {},
mint: "DezXAZ8z7PnrnRJjz3wXBoRgixCa6xjnB7YaB1pPB263",
},
}),
});
// Check if any error in the response
if (!response.ok) {
console.log(
`Error: ${response.status}, ${response.statusText}`
);
break;
}
const data = await response.json();
if (!data.result || data.result.token_accounts.length === 0) {
console.log(`No more results. Total pages: ${page - 1}`);
break;
}
console.log(`Processing results from page ${page}`);
data.result.token_accounts.forEach((account) =>
allOwners.add(account.owner)
);
page++;
}
fs.writeFileSync(
"output.json",
JSON.stringify(Array.from(allOwners), null, 2)
);
};
findHolders();Kết quả đầu ra
Kết quả đầu ra của mã sẽ là danh sách tất cả người nắm giữ và có dạng tương tự như sau:
[
"111An9SVxuPpgjnuXW9Ub7hcVmZpYNrYZF4edsGwJEW",
"11Mmng3DoMsq2Roq8LBcqdz6d4kw9oSD8oka9Pwfbj",
"112uNfcC8iwX9P2TkRdJKyPatg6a4GNcr9NC5mTc2z3",
"113uswn5HNgEfBUKfK4gVBmd2GpZYbxd1N6h1uUWReg",
"11CyvpdYTqFmCVWbJJeKFNX8F8RSjNSYW5VVUi8eX4P",
"11MANeaiHEy9S9pRQNu3nqKa2gpajzX2wrRJqWrf8dQ",
…
]Bạn có thể tự kiểm thử thông qua ví dụ trên Replit của chúng tôi.
Kết luận
Đến đây, chúng ta đã tìm hiểu đầy đủ quy trình xác định người nắm giữ token trên Solana thông qua API getTokenAccounts của Helius. Hướng dẫn này sẽ cung cấp cho bạn những kỹ năng cần thiết để tương tác trực tiếp với cộng đồng token của mình, dù là để thực hiện airdrop, thu thập thông tin chuyên sâu hay triển khai các hoạt động khác. Nếu có bất kỳ câu hỏi nào, bạn có thể liên hệ với chúng tôi qua Twitter hoặc Discord.
Bài viết liên quan
Đăng ký nhận tin từ Helius
Luôn cập nhật những thông tin mới nhất về phát triển Solana và nhận thông báo khi chúng tôi đăng bài


