'Concept of Token Program & Associated Token Account Program

I'm trying to send a token [USDT] from one wallet to another. But I think I'm having some trouble understanding the concept of Associated Token Account [ATA]

According to my understanding:

1 - Every wallet account that wants to keep, receive or send tokens, must register in the account for these tokens in the network?

2 - The sending person can register the account of the receiving person

3- Are these concepts correct?

All of the above are done by the following instructions => AssociatedTokenAccountProgram.CreateAssociatedTokenAccount

4 - Once the recipient's wallet address is registered, can send the tokens to him via instructions => 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);

I'm so sorry for the long wait, but after a lot of attempts, all of them were unsuccessful, I really think I need someone to explain how sending tokens works.



Solution 1:[1]

After a long struggle I was able to reach some results, I will leave this comment as a solution to the problem and an understanding of how things work, and if it contains some errors, please do not hesitate to leave an explanation and a correction for this

Let's agree on some concepts first:

1- Wallet account is a normal account, owned by the system Program and called [account owner]

2- The person who owns the private key is known as the authority

3 - Each token has an account on the chain, has its own owner and authority

what is happening now ?

If you want to own some of these tokens for the first time, you must create an account known as Associated Token Account

Associated Token Account: It is simply an account within the network that associates each wallet with a special and unique address of a token!! Is this clear??

Your wallet number => Associated Token Account <= token account number

G1G2G3G4 => A1T2A3T4 <= USDTADDRESS243

Its job is to save and store data for a specific wallet address with a specific token address, such as quantity, balance and many other features that I have not seen yet

The first time you will send these tokens to an account that does not contain [ATA], you will build instructions to create [ATA] for this account, and attach instructions directly to send the tokens with the same transaction, this structure worked for me,

enter image description here

Finally: It is possible to know the Associated Token Account for a wallet simply, because we will need to send the tokens with the Associated Tokens and not the addresses of the main wallets

Here is the code to create a Associated Token Account and send some USDT to the address:

    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);

enter image description here

So finally, please bring a cup of coffee and read this article, I think it is good to clarify some concepts about the Solana Blockchain : https://www.brianfriel.xyz/how-to-create-a-token-on-solana/

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1