solana指令解析-associated token account

solana指令解析-associated token account

码农世界 2024-05-23 后端 59 次浏览 0个评论

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指令汇总

          指令说明
          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

转载请注明来自码农世界,本文标题:《solana指令解析-associated token account》

百度分享代码,如果开启HTTPS请参考李洋个人博客
每一天,每一秒,你所做的决定都会改变你的人生!

发表评论

快捷回复:

评论列表 (暂无评论,59人围观)参与讨论

还没有评论,来说两句吧...

Top