代币计划和相关代币账户计划的概念

Concept of Token Program & Associated Token Account Program

我正在尝试将代币 [USDT] 从一个钱包发送到另一个钱包。但我想我在理解关联令牌帐户 [ATA]

的概念时遇到了一些问题

据我了解:

1 - 每个想要保存、接收或发送代币的钱包账户都必须在网络中注册这些代币的账户吗?

2 - 发件人可以注册收件人的账号

3- 这些概念正确吗?

以上都是按照以下指令完成=> AssociatedTokenAccountProgram.CreateAssociatedTokenAccount

4 - 一旦收件人的钱包地址被注册,就可以通过指令将代币发送给他 => TokenProgram.Transfer

  Account ownerAccount = wallet.Account;
  PublicKey UsdtAddress = new PublicKey("Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB");
  PublicKey ToAddress = new PublicKey("CDQ3Gya9QermsPzU3cTNW9QPLbMVLbALQ2S8AwbruVJ");

  var Transaction = new TransactionBuilder().
             SetRecentBlockHash(blockHash.Result.Value.Blockhash).
             SetFeePayer(wallet.Account).

             AddInstruction(AssociatedTokenAccountProgram.CreateAssociatedTokenAccount(
             ownerAccount, // Sender Account [Wallet Owner]   ?
             UsdtAddress,    // Tether Address On-Chain         ?
             ToAddress)).  // The Recipient Wallet Address    ?
             
             AddInstruction(TokenProgram.Transfer(
             ownerAccount,
             ToAddress,
             100,
             ownerAccount)).

             Build(new List<Account> { ownerAccount });

  var txReq = await rpcClient.SendTransactionAsync(Transaction);

很抱歉让你久等了,但经过多次尝试,都没有成功,我真的觉得我需要有人来解释发送令牌是如何工作的。

经过长时间的努力,我取得了一些成果,我将留下此评论作为问题的解决方案和对事情如何运作的理解,如果其中包含一些错误,请毫不犹豫地对此进行解释和更正

让我们先就一些概念达成一致:

1- 钱包账户为普通账户,归系统程序所有,称为[账户所有者]

2-拥有私钥的人被称为权威

3 - 每个代币都有一个链上账户,有自己的所有者和权限

现在发生了什么?

如果您想第一次拥有其中一些代币,您必须创建一个名为关联代币账户的账户

关联代币账户:它只是网络中的一个账户,将每个钱包与一个特殊且唯一的代币地址相关联!!看清楚了吗??

您的钱包号码=> 关联代币账户 <=代币账号

G1G2G3G4 => A1T2A3T4 <= USDTADDRESS243

它的工作是保存和存储特定钱包地址和特定代币地址的数据,例如数量、余额和许多其他我还没有看到的功能

第一次将这些代币发送到不包含 [ATA] 的账户时,您将构建指令为该账户创建 [ATA],并直接附加指令以使用相同的交易发送代币,这种结构对我有用,

最后:可以简单地知道钱包的关联令牌帐户,因为我们需要发送带有关联令牌的令牌而不是主钱包的地址

这是创建关联令牌帐户并将一些 USDT 发送到地址的代码:

    PublicKey UsdtAddress = new PublicKey("Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB");

    //The [ATA] for my public address in the USDT token account = Sender
    Account ownerAccount = wallet.Account;
    var FromAssociatedTokenAccount=AssociatedTokenAccountProgram.DeriveAssociatedTokenAccount(ownerAccount,UsdtAddress); 

    //The [ATA] for Receiver public address in the USDT token account = Sender = Receiver 
    PublicKey ToAddress = new PublicKey("DqiE6PDXPFMMDC2jzoqY45VEqyEzdGd5qauVCQY8s3A7");
    var ToAssociatedTokenAccount = AssociatedTokenAccountProgram.DeriveAssociatedTokenAccount(ToAddress, UsdtAddress);
    //Note that a ToAssociatedTokenAccount can be defined, with the possibility that it is not registered/created on-Chain



    var blockHash = await rpcClient.GetRecentBlockHashAsync();
    var Transaction = new TransactionBuilder().
             SetRecentBlockHash(blockHash.Result.Value.Blockhash).
             SetFeePayer(ownerAccount).
 AddInstruction(AssociatedTokenAccountProgram.CreateAssociatedTokenAccount(
             ownerAccount,
             ToAddress,
             UsdtAddress)).

             AddInstruction(TokenProgram.Transfer(
             FromAssociatedTokenAccount,
             ToAssociatedTokenAccount,
             1,
             ownerAccount)).

             Build(new List<Account> { ownerAccount });
     var txReq = await rpcClient.SendTransactionAsync(Transaction);

所以最后,请带杯咖啡阅读这篇文章,我认为澄清一些关于 Solana 区块链的概念是很好的: https://www.brianfriel.xyz/how-to-create-a-token-on-solana/