solana指令解析-associated token account(ATA)
什么是associated token account(ATA)?
associated token account 称为关联代币账户,通过ATAP创建,用来保存有关特定代币、其余额及其所有者的信息。它是与特定代币账户(可以理解为以太坊的erc20合约)关联的账户。 ATA 允许用户对该代币进行交易和管理。
- solana中将erc20代币称为SPL代币(solana中一个代币,仅仅是一个归Token合约管理的普通的Account对象,即代币账户。关于具体相关说明,可参考:https://www.solanazh.com/course/1-3
- 参考学习:(推荐) https://www.alchemy.com/overviews/associated-token-account
- AssociatedTokenAccountProgramID: ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL
什么是Associated Token Account Program(ATAP)?
- Associated Token Account Program称关联代币程序(ATAP)是每个 ATA 的父程序。提供了将用户的钱包地址映射到他们持有的关联代币帐户的机制(ATA)。允许发送者为接收者创建关联的token帐户,以便token传输正常进行。
- ATAP能够确保如果一个用户想要向另一个用户发送token,接收者能够获得该token,即使他没有相应令牌的 ATA
token转账:
参考:【Token 轉帳交易部分】https://www.blocktempo.com/understand-solana-accounts-tokens-transactions-and-asset-security/
- 前提:默认账户A拥有’USDT’代币
- 拥有指定代币的用户拥有通过ATAP 创建的关联代币账户(ATA) (简单来说,拥有usdt代币的账户将会拥有一个由ATAP创建的一个与USDT代币关联的ATA账户,用来存储这个账户拥有的USDT代币的余额)
- 账户之间的token转账交易直接发生在账户的 ATA 之间,需要注意的是:在 token 转账指令中,source 和 destination 地址通常指的是 ATA 地址,而不是转账双方的直接账户地址
associated token account指令汇总
指令 值 说明 CreateAssociatedTokenAccount 0 创建一个关联代币账户(account已存在会报错) CreateIdempotent 1 创建一个幂等的(具有幂等性质的)关联代币账户,即多次执行同一操作,结果都是一样的。(account已存在不会报错) RecoverNested 2 用于从嵌套的关联代币账户中转移资金并关闭它。 源码地址:github.com/blocto/solana-go-sdk/program/associated_token_account
1.CreateAssociatedTokenAccount
该指令用于创建一个关联代币账户。在 Solana 区块链上,当用户需要与特定代币进行交互时,需要先创建一个关联代币账户,以便存储该代币的余额信息。该指令允许用户创建一个新的关联代币账户。
- 如果AssociatedTokenAccount已经存在,将会返回错误
1.1源码
type CreateParam struct { Funder common.PublicKey Owner common.PublicKey Mint common.PublicKey AssociatedTokenAccount common.PublicKey } // Create creates an associated token account for the given wallet address and token mint. Return an error if the account exists. func Create(param CreateParam) types.Instruction { data, err := borsh.Serialize(struct { Instruction Instruction }{ Instruction: InstructionCreate, }) if err != nil { panic(err) } return types.Instruction{ ProgramID: common.SPLAssociatedTokenAccountProgramID, Accounts: []types.AccountMeta{ {PubKey: param.Funder, IsSigner: true, IsWritable: true}, {PubKey: param.AssociatedTokenAccount, IsSigner: false, IsWritable: true}, {PubKey: param.Owner, IsSigner: false, IsWritable: false}, {PubKey: param.Mint, IsSigner: false, IsWritable: false}, {PubKey: common.SystemProgramID, IsSigner: false, IsWritable: false}, {PubKey: common.TokenProgramID, IsSigner: false, IsWritable: false}, {PubKey: common.SysVarRentPubkey, IsSigner: false, IsWritable: false}, }, Data: data, } }
1.2 指令参数:
- Funder:用于支付交易费用的账户的公钥。
- Owner:新关联代币账户的所有者的公钥。所有者是新关联代币账户的实际控制者,具有对该账户进行操作的权限。
- Mint:与新关联代币账户关联的代币的公钥。代币的发行者可以通过该公钥查看关联的代币账户。
- AssociatedTokenAccount:要创建的关联代币账户的公钥。
1.3AccountMate
- PubKey: 账户的公钥
- IsSigner :表示该账户是否需要签名验证。
- IsWritable: 表示该账户是否可以被写入数据
PubKey IsSigner IsWritable Funder true true AssociatedTokenAccount false true Owner false false Mint false false SystemProgramID false false TokenProgramID false false SysVarRentPubkey false false - SystemProgramID表示系统程序的公钥,用于执行 address_lookup_table 指令的程序。值为11111111111111111111111111111111
- TokenProgramID表示代币程序,是 Solana 区块链上管理代币的标准程序。在创建关联代币账户时,需要指定代币程序以确保账户与代币的管理逻辑一致。值为TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA
- SysVarRentPubkey是系统变量之一,用于存储账户租金信息。在创建关联代币账户时,需要考虑账户的租金,因此需要引用系统变量来获取相应的信息。值为SysvarRent111111111111111111111111111111111
2.CreateIdempotent
这个指令与 InstructionCreate 类似,但具有幂等性质。这意味着如果多次执行相同的创建关联代币账户的操作,结果都是相同的。这样的设计可以确保在网络中进行重试或发生错误时,不会导致创建多个相同的账户。
2.1源码
type CreateIdempotentParam struct { Funder common.PublicKey Owner common.PublicKey Mint common.PublicKey AssociatedTokenAccount common.PublicKey } // CreateIdempotent creates an associated token account for the given wallet address and token mint, // if it doesn't already exist. Returns an error if the account exists, but with a different owner. func CreateIdempotent(param CreateIdempotentParam) types.Instruction { data, err := borsh.Serialize(struct { Instruction Instruction }{ Instruction: InstructionCreateIdempotent, }) if err != nil { panic(err) } return types.Instruction{ ProgramID: common.SPLAssociatedTokenAccountProgramID, Accounts: []types.AccountMeta{ {PubKey: param.Funder, IsSigner: true, IsWritable: true}, {PubKey: param.AssociatedTokenAccount, IsSigner: false, IsWritable: true}, {PubKey: param.Owner, IsSigner: false, IsWritable: false}, {PubKey: param.Mint, IsSigner: false, IsWritable: false}, {PubKey: common.SystemProgramID, IsSigner: false, IsWritable: false}, {PubKey: common.TokenProgramID, IsSigner: false, IsWritable: false}, {PubKey: common.SysVarRentPubkey, IsSigner: false, IsWritable: false}, }, Data: data, } }
-
参数与accountmeta与CreateAssociatedTokenAccount 指令一致,参考上文即可
-
如果AssociatedTokenAccount 不存在,则创建一个新的关联代币账户,如果账户已经存在,但所有者不同,则返回错误。
3.RecoverNested
个指令用于从嵌套的关联代币账户中转移资金并关闭它。有时候,用户可能会创建一个关联代币账户,并将其作为另一个关联代币账户的所有者。当需要关闭这个嵌套的关联代币账户时,可以使用该指令将其中的资金转移到其他地方,并关闭该账户。
3.1源码
type RecoverNestedParam struct { Owner common.PublicKey OwnerMint common.PublicKey OwnerAssociatedTokenAccount common.PublicKey NestedMint common.PublicKey NestedMintAssociatedTokenAccount common.PublicKey DestinationAssociatedTokenAccount common.PublicKey } // RecoverNested transfers from and closes a nested associated token account: an associated token account owned by an associated token account. func RecoverNested(param RecoverNestedParam) types.Instruction { data, err := borsh.Serialize(struct { Instruction Instruction }{ Instruction: InstructionRecoverNested, }) if err != nil { panic(err) } return types.Instruction{ ProgramID: common.SPLAssociatedTokenAccountProgramID, Accounts: []types.AccountMeta{ {PubKey: param.NestedMintAssociatedTokenAccount, IsSigner: false, IsWritable: true}, {PubKey: param.NestedMint, IsSigner: false, IsWritable: false}, {PubKey: param.DestinationAssociatedTokenAccount, IsSigner: false, IsWritable: true}, {PubKey: param.OwnerAssociatedTokenAccount, IsSigner: false, IsWritable: true}, {PubKey: param.OwnerMint, IsSigner: false, IsWritable: false}, {PubKey: param.Owner, IsSigner: true, IsWritable: true}, {PubKey: common.TokenProgramID, IsSigner: false, IsWritable: false}, }, Data: data, } }
3.2指令参数
- Owner:表示要执行恢复操作的账户的公钥。
- OwnerMint:表示所属代币的公钥。
- OwnerAssociatedTokenAccount:表示所属关联代币账户的公钥。
- NestedMint:表示嵌套代币的公钥。
- NestedMintAssociatedTokenAccount:表示嵌套关联代币账户的公钥。
- DestinationAssociatedTokenAccount:表示目标关联代币账户的公钥。
3.3AccountMeta
PubKey IsSigner IsWritable NestedMintAssociatedTokenAccount false true NestedMint false false DestinationAssociatedTokenAccount false true OwnerAssociatedTokenAccount false true OwnerMint false false Owner true true TokenProgramID false false
-
- 如果AssociatedTokenAccount已经存在,将会返回错误
- 前提:默认账户A拥有’USDT’代币
还没有评论,来说两句吧...