네트워크에서 데이터 읽기

이 섹션에서는 다양한 계정을 가져와 Solana 계정의 구조를 이해하면서 Solana 네트워크에서 데이터를 읽는 방법을 살펴봅니다.

Solana에서 모든 데이터는 "계정"에 존재합니다. Solana의 데이터는 단일 "계정" 테이블이 있는 공개 데이터베이스로 생각할 수 있으며, 각 항목은 동일한 기본 계정 유형을 가진 계정입니다.

Base Account Type
#[derive(PartialEq, Eq, Clone, Default)]
pub struct Account {
/// lamports in the account
pub lamports: u64,
/// data held in this account
#[cfg_attr(feature = "serde", serde(with = "serde_bytes"))]
pub data: Vec<u8>,
/// the program that owns this account. If executable, the program that loads this account.
pub owner: Pubkey,
/// this account's data contains a loaded program (and is now read-only)
pub executable: bool,
/// the epoch at which this account will next owe rent
pub rent_epoch: Epoch,
}

계정계정

Solana 계정은 "상태" 또는 "실행 가능한" 프로그램을 저장할 수 있습니다. 각 계정은 해당 온체인 데이터를 찾는 데 사용되는 고유 ID 역할을 하는 "주소"(공개 키)를 가지고 있습니다.

Solana 계정은 다음 중 하나를 포함합니다:

  • 상태: 읽고 유지되어야 하는 데이터. 예를 들어, 토큰에 관한 정보, 사용자 데이터 또는 프로그램 내에 정의된 기타 데이터가 있습니다.
  • 실행 가능한 프로그램: Solana 프로그램의 실제 코드를 포함하는 계정. 이러한 계정은 사용자가 호출할 수 있는 명령어를 저장합니다.

프로그램 코드와 프로그램 상태의 이러한 분리는 Solana 계정 모델의 핵심 기능입니다. 자세한 내용은 Solana 계정 모델 페이지를 참조하세요.

지갑 계정 가져오기

이 예제는 다음을 보여줍니다:

  1. 새로운 keypair(공개/개인 키 쌍)를 생성합니다.
  2. 새 주소에 SOL 에어드롭을 요청하여 자금을 지원합니다.
  3. 자금이 지원된 주소의 계정 데이터를 검색합니다.

Solana에서 새 주소에 SOL로 자금을 지원하면 System Program이 소유한 계정이 자동으로 생성됩니다. 모든 "지갑" 계정은 단순히 SOL을 보유하고 트랜잭션에 서명할 수 있는 System Program 소유 계정입니다.

Fetch Account
import { Keypair, Connection, LAMPORTS_PER_SOL } from "@solana/web3.js";
const keypair = Keypair.generate();
console.log(`Public Key: ${keypair.publicKey}`);
const connection = new Connection("http://localhost:8899", "confirmed");
// Funding an address with SOL automatically creates an account
const signature = await connection.requestAirdrop(
keypair.publicKey,
LAMPORTS_PER_SOL
);
await connection.confirmTransaction(signature, "confirmed");
const accountInfo = await connection.getAccountInfo(keypair.publicKey);
console.log(JSON.stringify(accountInfo, null, 2));
Console
Click to execute the code.

Solana에서 "지갑"은 Solana의 내장 프로그램 중 하나인 시스템 프로그램이 소유한 계정입니다. 지갑 계정은 주로 SOL을 보관하고(lamports 필드에서 추적됨) 트랜잭션에 서명하는 데 사용됩니다.

지갑 계정을 조회하면, 응답에는 예제 출력에 표시된 필드들이 포함됩니다.

data 필드에는 바이트로 저장된 계정의 데이터가 포함되어 있습니다.

지갑 계정의 경우, 이 필드는 비어 있습니다(0바이트). 다른 계정들은 이 필드를 프로그램 상태 또는 실행 가능한 프로그램 코드를 저장하는 데 사용합니다.

executable 필드는 계정의 data 필드에 실행 가능한 프로그램 코드가 포함되어 있는지 여부를 나타냅니다.

지갑 및 프로그램 상태를 저장하는 계정의 경우, 이 필드는 false입니다.

lamports 필드에는 lamport 단위로 표시된 계정의 SOL 잔액이 포함되어 있습니다.

Lamport는 SOL의 최소 단위입니다. 1 SOL = 1,000,000,000 lamport입니다.

owner 필드는 계정을 소유한 프로그램을 보여줍니다.

지갑의 경우, 소유자는 항상 주소가 11111111111111111111111111111111인 System Program입니다.

rentEpoch 필드는 계정이 네트워크에 데이터를 유지하기 위해 "rent"(lamport 단위)를 지불하던 더 이상 사용되지 않는 메커니즘의 레거시 필드입니다.

이 필드는 현재 사용되지 않지만 이전 버전과의 호환성을 위해 포함되어 있습니다.

space 필드는 data 필드의 바이트 수를 보여줍니다. 이것은 Account 타입 자체의 필드가 아니지만 응답에 포함됩니다.

이 예제에서 space 필드는 data 필드가 0바이트의 데이터를 포함하고 있기 때문에 0입니다.

Solana에서 "지갑"은 Solana의 내장 프로그램 중 하나인 시스템 프로그램이 소유한 계정입니다. 지갑 계정은 주로 SOL을 보관하고(lamports 필드에서 추적됨) 트랜잭션에 서명하는 데 사용됩니다.

지갑 계정을 조회하면, 응답에는 예제 출력에 표시된 필드들이 포함됩니다.

data 필드에는 바이트로 저장된 계정의 데이터가 포함되어 있습니다.

지갑 계정의 경우, 이 필드는 비어 있습니다(0바이트). 다른 계정들은 이 필드를 프로그램 상태 또는 실행 가능한 프로그램 코드를 저장하는 데 사용합니다.

executable 필드는 계정의 data 필드에 실행 가능한 프로그램 코드가 포함되어 있는지 여부를 나타냅니다.

지갑 및 프로그램 상태를 저장하는 계정의 경우, 이 필드는 false입니다.

lamports 필드에는 lamport 단위로 표시된 계정의 SOL 잔액이 포함되어 있습니다.

Lamport는 SOL의 최소 단위입니다. 1 SOL = 1,000,000,000 lamport입니다.

owner 필드는 계정을 소유한 프로그램을 보여줍니다.

지갑의 경우, 소유자는 항상 주소가 11111111111111111111111111111111인 System Program입니다.

rentEpoch 필드는 계정이 네트워크에 데이터를 유지하기 위해 "rent"(lamport 단위)를 지불하던 더 이상 사용되지 않는 메커니즘의 레거시 필드입니다.

이 필드는 현재 사용되지 않지만 이전 버전과의 호환성을 위해 포함되어 있습니다.

space 필드는 data 필드의 바이트 수를 보여줍니다. 이것은 Account 타입 자체의 필드가 아니지만 응답에 포함됩니다.

이 예제에서 space 필드는 data 필드가 0바이트의 데이터를 포함하고 있기 때문에 0입니다.

Example Output
{
"data": {
"type": "Buffer",
"data": []
},
"executable": false,
"lamports": 1000000000,
"owner": "11111111111111111111111111111111",
"rentEpoch": 0,
"space": 0
}

Token Program 가져오기

이 예제는 지갑 계정과 프로그램 계정 간의 차이점을 보여주기 위해 Token Program을 가져옵니다.

프로그램 계정은 Token Program의 소스 코드에 대한 컴파일된 바이트코드를 저장합니다. Solana Explorer에서 이 프로그램 계정을 볼 수 있습니다.

Fetch Program Account
import { Connection, PublicKey } from "@solana/web3.js";
const connection = new Connection(
"https://api.mainnet-beta.solana.com",
"confirmed"
);
const address = new PublicKey("TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA");
const accountInfo = await connection.getAccountInfo(address);
Console
Click to execute the code.

Token Program은 Solana의 실행 가능한 program account입니다. 지갑 계정과 마찬가지로 프로그램도 동일한 기본 Account 데이터 구조를 가지고 있지만 필드에 주요 차이점이 있습니다.

executable 필드는 true로 설정되어 있으며, 이는 이 계정의 data 필드에 실행 가능한 프로그램 코드가 포함되어 있음을 나타냅니다.

program account의 경우, data 필드에 프로그램의 실행 코드가 저장됩니다. 반면에 지갑 계정은 데이터 필드가 비어 있습니다.

Solana 프로그램을 배포할 때, 프로그램의 실행 코드는 계정의 data 필드에 저장됩니다.

실행 가능한 program account에는 해당 계정의 owner로 지정된 프로그램도 있습니다.

모든 program account는 Loader 프로그램이 소유하고 있으며, 이는 Solana에서 실행 가능한 program account를 소유하는 내장 프로그램의 카테고리입니다.

Token Program의 경우, owner는 BPFLoader2 프로그램입니다.

Token Program은 Solana의 실행 가능한 program account입니다. 지갑 계정과 마찬가지로 프로그램도 동일한 기본 Account 데이터 구조를 가지고 있지만 필드에 주요 차이점이 있습니다.

executable 필드는 true로 설정되어 있으며, 이는 이 계정의 data 필드에 실행 가능한 프로그램 코드가 포함되어 있음을 나타냅니다.

program account의 경우, data 필드에 프로그램의 실행 코드가 저장됩니다. 반면에 지갑 계정은 데이터 필드가 비어 있습니다.

Solana 프로그램을 배포할 때, 프로그램의 실행 코드는 계정의 data 필드에 저장됩니다.

실행 가능한 program account에는 해당 계정의 owner로 지정된 프로그램도 있습니다.

모든 program account는 Loader 프로그램이 소유하고 있으며, 이는 Solana에서 실행 가능한 program account를 소유하는 내장 프로그램의 카테고리입니다.

Token Program의 경우, owner는 BPFLoader2 프로그램입니다.

Token Program Account
{
"data": {
"type": "Buffer",
"data": [127, "...truncated, total bytes: 134080...", 0]
},
"executable": true,
"lamports": 4522329612,
"owner": "BPFLoader2111111111111111111111111111111111",
"rentEpoch": 18446744073709552000,
"space": 134080
}

mint account 가져오기

이 예제는 USD 코인(USDC) mint account를 가져와 Solana의 프로그램이 별도의 계정에 상태를 저장하는 방법을 보여줍니다.

Mint 계정은 Token Program이 소유한 계정입니다. 이 계정은 총 공급량, 소수점 자릿수, 토큰을 발행하거나 동결할 권한이 있는 계정 등 특정 토큰에 대한 전역 메타데이터를 저장합니다. mint account의 주소는 Solana 네트워크에서 토큰을 고유하게 식별합니다.

Fetch Program Account
import { Connection, PublicKey } from "@solana/web3.js";
const connection = new Connection(
"https://api.mainnet-beta.solana.com",
"confirmed"
);
const address = new PublicKey("EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v");
const accountInfo = await connection.getAccountInfo(address);
Console
Click to execute the code.

이 예시에서 주목해야 할 핵심 포인트는 Mint 계정이 실행 가능한 코드가 아닌 상태를 저장한다는 것입니다.

Mint 계정은 Token Program이 소유하며, Token Program은 Mint 계정을 생성하고 업데이트하는 방법을 정의하는 명령어를 포함합니다.

Mint Account
{
"data": {
"type": "Buffer",
"data": [1, "...truncated, total bytes: 82...", 103]
},
"executable": false,
"lamports": 407438077149,
"owner": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA",
"rentEpoch": 18446744073709552000,
"space": 82
}

executable 필드는 mint account의 data 필드가 실행 가능한 코드가 아닌 상태를 저장하기 때문에 false입니다.

Token Program은 mint account의 data 필드에 저장되는 Mint 데이터 타입을 정의합니다.

Mint Account
{
"data": {
"type": "Buffer",
"data": [1, "...truncated, total bytes: 82...", 103]
},
"executable": false,
"lamports": 407438077149,
"owner": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA",
"rentEpoch": 18446744073709552000,
"space": 82
}

data 필드는 발행 권한, 총 공급량, 소수점 자릿수와 같은 직렬화된 Mint 계정 상태를 포함합니다.

Mint 계정에서 읽으려면 data 필드를 Mint 데이터 타입으로 역직렬화해야 합니다. 이는 다음 단계에서 다룹니다.

Mint Account
{
"data": {
"type": "Buffer",
"data": [1, "...truncated, total bytes: 82...", 103]
},
"executable": false,
"lamports": 407438077149,
"owner": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA",
"rentEpoch": 18446744073709552000,
"space": 82
}

Token Program(TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA)이 mint account를 소유합니다.

이는 mint account의 data 필드가 Token Program에 정의된 명령어로만 수정될 수 있음을 의미합니다.

Mint Account
{
"data": {
"type": "Buffer",
"data": [1, "...truncated, total bytes: 82...", 103]
},
"executable": false,
"lamports": 407438077149,
"owner": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA",
"rentEpoch": 18446744073709552000,
"space": 82
}

이 예시에서 주목해야 할 핵심 포인트는 Mint 계정이 실행 가능한 코드가 아닌 상태를 저장한다는 것입니다.

Mint 계정은 Token Program이 소유하며, Token Program은 Mint 계정을 생성하고 업데이트하는 방법을 정의하는 명령어를 포함합니다.

executable 필드는 mint account의 data 필드가 실행 가능한 코드가 아닌 상태를 저장하기 때문에 false입니다.

Token Program은 mint account의 data 필드에 저장되는 Mint 데이터 타입을 정의합니다.

data 필드는 발행 권한, 총 공급량, 소수점 자릿수와 같은 직렬화된 Mint 계정 상태를 포함합니다.

Mint 계정에서 읽으려면 data 필드를 Mint 데이터 타입으로 역직렬화해야 합니다. 이는 다음 단계에서 다룹니다.

Token Program(TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA)이 mint account를 소유합니다.

이는 mint account의 data 필드가 Token Program에 정의된 명령어로만 수정될 수 있음을 의미합니다.

Mint Account
{
"data": {
"type": "Buffer",
"data": [1, "...truncated, total bytes: 82...", 103]
},
"executable": false,
"lamports": 407438077149,
"owner": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA",
"rentEpoch": 18446744073709552000,
"space": 82
}

Mint 계정 역직렬화

Solana 계정의 data 필드는 원시 바이트를 포함합니다. 이 데이터를 의미 있게 해석하려면 계정을 소유한 프로그램에서 정의한 적절한 데이터 타입으로 역직렬화해야 합니다.

대부분의 Solana 프로그램은 역직렬화 과정을 추상화하는 헬퍼 함수가 있는 클라이언트 라이브러리를 제공합니다. 이러한 함수는 원시 계정 바이트를 구조화된 데이터 타입으로 변환하여 계정 데이터를 더 쉽게 다룰 수 있게 합니다.

예를 들어, *shell@solana/spl-token*에는 Mint 계정의 data 필드를 Mint 데이터 타입으로 역직렬화하는 데 도움이 되는 getMint() 함수가 포함되어 있습니다.

Deserialize Mint Account Data
import { PublicKey, Connection } from "@solana/web3.js";
import { getMint } from "@solana/spl-token";
const connection = new Connection(
"https://api.mainnet-beta.solana.com",
"confirmed"
);
const address = new PublicKey("EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v");
const mintData = await getMint(connection, address, "confirmed");
Console
Click to execute the code.
Mint Account Type
pub struct Mint {
/// Optional authority used to mint new tokens. The mint authority may only
/// be provided during mint creation. If no mint authority is present
/// then the mint has a fixed supply and no further tokens may be
/// minted.
pub mint_authority: COption<Pubkey>,
/// Total supply of tokens.
pub supply: u64,
/// Number of base 10 digits to the right of the decimal place.
pub decimals: u8,
/// Is `true` if this structure has been initialized
pub is_initialized: bool,
/// Optional authority to freeze token accounts.
pub freeze_authority: COption<Pubkey>,
}

getMint() 함수는 mint account의 data 필드를 Token Program에서 정의한 Mint 데이터 타입으로 역직렬화합니다.

Mint Account
{
"data": {
"type": "Buffer",
"data": [1, "...truncated, total bytes: 82...", 103]
},
"executable": false,
"lamports": 407438077149,
"owner": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA",
"rentEpoch": 18446744073709552000,
"space": 82
}

Solana 익스플로러에서 완전히 역직렬화된 Mint Account 데이터를 볼 수 있습니다.

address 필드는 Mint account의 주소를 포함합니다.

mint account의 주소는 Solana 네트워크에서 토큰을 식별하는 데 사용됩니다.

mintAuthority 필드는 새 토큰을 발행할 수 있는 권한을 가진 계정을 보여줍니다.

이것은 토큰의 새로운 단위를 생성할 수 있는 유일한 계정입니다.

supply 필드는 발행된 토큰의 총 수량을 보여줍니다.

이 값은 토큰의 가장 작은 단위로 표시됩니다. 표준 단위로 총 공급량을 얻으려면, supply 필드의 값을 decimals에 맞게 조정하세요.

decimals 필드는 토큰의 소수점 자릿수를 나타냅니다.

isInitialized 필드는 mint account가 초기화되었는지 여부를 나타냅니다. 이 필드는 Token Program에서 사용되는 보안 검사입니다.

freezeAuthority 필드는 token account를 동결할 수 있는 권한을 가진 주체를 보여줍니다.

동결된 token account는 계정 내 토큰을 전송하거나 소각할 수 없습니다.

tlvData 필드는 Token Extensions에 대한 추가 데이터를 포함합니다(추가 역직렬화 필요).

이 필드는 Token Extension Program(Token2022)에 의해 생성된 계정에만 관련이 있습니다.

getMint() 함수는 mint account의 data 필드를 Token Program에서 정의한 Mint 데이터 타입으로 역직렬화합니다.

Mint Account
{
"data": {
"type": "Buffer",
"data": [1, "...truncated, total bytes: 82...", 103]
},
"executable": false,
"lamports": 407438077149,
"owner": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA",
"rentEpoch": 18446744073709552000,
"space": 82
}

Solana 익스플로러에서 완전히 역직렬화된 Mint Account 데이터를 볼 수 있습니다.

address 필드는 Mint account의 주소를 포함합니다.

mint account의 주소는 Solana 네트워크에서 토큰을 식별하는 데 사용됩니다.

mintAuthority 필드는 새 토큰을 발행할 수 있는 권한을 가진 계정을 보여줍니다.

이것은 토큰의 새로운 단위를 생성할 수 있는 유일한 계정입니다.

supply 필드는 발행된 토큰의 총 수량을 보여줍니다.

이 값은 토큰의 가장 작은 단위로 표시됩니다. 표준 단위로 총 공급량을 얻으려면, supply 필드의 값을 decimals에 맞게 조정하세요.

decimals 필드는 토큰의 소수점 자릿수를 나타냅니다.

isInitialized 필드는 mint account가 초기화되었는지 여부를 나타냅니다. 이 필드는 Token Program에서 사용되는 보안 검사입니다.

freezeAuthority 필드는 token account를 동결할 수 있는 권한을 가진 주체를 보여줍니다.

동결된 token account는 계정 내 토큰을 전송하거나 소각할 수 없습니다.

tlvData 필드는 Token Extensions에 대한 추가 데이터를 포함합니다(추가 역직렬화 필요).

이 필드는 Token Extension Program(Token2022)에 의해 생성된 계정에만 관련이 있습니다.

Deserialized Mint Data
{
"address": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
"mintAuthority": "BJE5MMbqXjVwjAF7oxwPYXnTXDyspzZyt4vwenNw5ruG",
"supply": "8985397351591790",
"decimals": 6,
"isInitialized": true,
"freezeAuthority": "7dGbd2QZcCKcTndnHcTL8q7SMVXAkp688NTQYwrRCrar",
"tlvData": {
"type": "Buffer",
"data": []
}
}

Is this page helpful?

목차

페이지 편집