solana指令解析-associated token account

本文介绍了Solana区块链中的关联代币账户(ATA)概念,包括如何通过ATAP创建与特定代币关联的账户,以及CreateAssociatedTokenAccount、CreateIdempotent和RecoverNested指令的作用。还讨论了在交易中如何转移和管理SPL代币的过程。
摘要由CSDN通过智能技术生成

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’代币
不存在
存在
A给B转账代币`USDT`
B是否拥有对应`USDT`的ATA
ATAP调用Create Associated Account 指令为B账户创建与`USDT`关联的APT
执行Token Transfer 指令完成转账
  • 拥有指定代币的用户拥有通过ATAP 创建的关联代币账户(ATA) (简单来说,拥有usdt代币的账户将会拥有一个由ATAP创建的一个与USDT代币关联的ATA账户,用来存储这个账户拥有的USDT代币的余额)
  • 账户之间的token转账交易直接发生在账户的 ATA 之间,需要注意的是:在 token 转账指令中,source 和 destination 地址通常指的是 ATA 地址,而不是转账双方的直接账户地址

associated token account指令汇总

指令说明
CreateAssociatedTokenAccount0创建一个关联代币账户(account已存在会报错)
CreateIdempotent1创建一个幂等的(具有幂等性质的)关联代币账户,即多次执行同一操作,结果都是一样的。(account已存在不会报错)
RecoverNested2用于从嵌套的关联代币账户中转移资金并关闭它。

源码地址: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: 表示该账户是否可以被写入数据
PubKeyIsSignerIsWritable
Fundertruetrue
AssociatedTokenAccountfalsetrue
Ownerfalsefalse
Mintfalsefalse
SystemProgramIDfalsefalse
TokenProgramIDfalsefalse
SysVarRentPubkeyfalsefalse
  • 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
PubKeyIsSignerIsWritable
NestedMintAssociatedTokenAccountfalsetrue
NestedMintfalsefalse
DestinationAssociatedTokenAccountfalsetrue
OwnerAssociatedTokenAccountfalsetrue
OwnerMintfalsefalse
Ownertruetrue
TokenProgramIDfalsefalse
  • 17
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值