github.com/hashgraph/hedera-sdk-go/v2@v2.48.0/examples/token_airdrop/main.go (about)

     1  package main
     2  
     3  import (
     4  	"fmt"
     5  	"os"
     6  
     7  	"github.com/hashgraph/hedera-sdk-go/v2"
     8  )
     9  
    10  /**
    11   * @summary HIP-904 https://hips.hedera.com/hip/hip-904
    12   * @description Airdrop fungible and non fungible tokens to an account
    13   */
    14  func main() {
    15  
    16  	var client *hedera.Client
    17  	var err error
    18  
    19  	// Retrieving network type from environment variable HEDERA_NETWORK
    20  	client, err = hedera.ClientForName(os.Getenv("HEDERA_NETWORK"))
    21  	if err != nil {
    22  		panic(fmt.Sprintf("%v : error creating client", err))
    23  	}
    24  
    25  	// Retrieving operator ID from environment variable OPERATOR_ID
    26  	operatorAccountID, err := hedera.AccountIDFromString(os.Getenv("OPERATOR_ID"))
    27  	if err != nil {
    28  		panic(fmt.Sprintf("%v : error converting string to AccountID", err))
    29  	}
    30  
    31  	// Retrieving operator key from environment variable OPERATOR_KEY
    32  	operatorKey, err := hedera.PrivateKeyFromString(os.Getenv("OPERATOR_KEY"))
    33  	if err != nil {
    34  		panic(fmt.Sprintf("%v : error converting string to PrivateKey", err))
    35  	}
    36  
    37  	// Setting the client operator ID and key
    38  	client.SetOperator(operatorAccountID, operatorKey)
    39  
    40  	fmt.Println("Example Start!")
    41  
    42  	/*
    43  	 * Step 1:
    44  	 * Create 4 accounts
    45  	 */
    46  	privateKey1, _ := hedera.PrivateKeyGenerateEd25519()
    47  	accountCreateResp, err := hedera.NewAccountCreateTransaction().
    48  		SetKey(privateKey1).
    49  		SetInitialBalance(hedera.NewHbar(10)).
    50  		SetMaxAutomaticTokenAssociations(-1).
    51  		Execute(client)
    52  	if err != nil {
    53  		panic(fmt.Sprintf("%v error creating account", err))
    54  	}
    55  	receipt, err := accountCreateResp.GetReceipt(client)
    56  	if err != nil {
    57  		panic(fmt.Sprintf("%v error creating account", err))
    58  	}
    59  	alice := receipt.AccountID
    60  
    61  	privateKey2, _ := hedera.PrivateKeyGenerateEd25519()
    62  	accountCreateResp, err = hedera.NewAccountCreateTransaction().
    63  		SetKey(privateKey2).
    64  		SetInitialBalance(hedera.NewHbar(10)).
    65  		SetMaxAutomaticTokenAssociations(1).
    66  		Execute(client)
    67  	if err != nil {
    68  		panic(fmt.Sprintf("%v error creating account", err))
    69  	}
    70  	receipt, err = accountCreateResp.GetReceipt(client)
    71  	if err != nil {
    72  		panic(fmt.Sprintf("%v error creating account", err))
    73  	}
    74  	bob := receipt.AccountID
    75  
    76  	privateKey3, _ := hedera.PrivateKeyGenerateEd25519()
    77  	accountCreateResp, err = hedera.NewAccountCreateTransaction().
    78  		SetKey(privateKey3).
    79  		SetInitialBalance(hedera.NewHbar(10)).
    80  		SetMaxAutomaticTokenAssociations(0).
    81  		Execute(client)
    82  	if err != nil {
    83  		panic(fmt.Sprintf("%v error creating account", err))
    84  	}
    85  	receipt, err = accountCreateResp.GetReceipt(client)
    86  	if err != nil {
    87  		panic(fmt.Sprintf("%v error creating account", err))
    88  	}
    89  	carol := receipt.AccountID
    90  
    91  	treasuryKey, _ := hedera.PrivateKeyGenerateEd25519()
    92  	accountCreateResp, err = hedera.NewAccountCreateTransaction().
    93  		SetKey(treasuryKey).
    94  		SetInitialBalance(hedera.NewHbar(10)).
    95  		Execute(client)
    96  	if err != nil {
    97  		panic(fmt.Sprintf("%v error creating account", err))
    98  	}
    99  
   100  	receipt, err = accountCreateResp.GetReceipt(client)
   101  	if err != nil {
   102  		panic(fmt.Sprintf("%v error creating account", err))
   103  	}
   104  	treasury := receipt.AccountID
   105  
   106  	/*
   107  	 * Step 2:
   108  	 * Create FT and NFT and mint
   109  	 */
   110  	tokenCreateTxn, _ := hedera.NewTokenCreateTransaction().
   111  		SetTokenName("Fungible Token").
   112  		SetTokenSymbol("TFT").
   113  		SetTokenMemo("Example memo").
   114  		SetDecimals(3).
   115  		SetInitialSupply(1000).
   116  		SetMaxSupply(1000).
   117  		SetTreasuryAccountID(*treasury).
   118  		SetSupplyType(hedera.TokenSupplyTypeFinite).
   119  		SetAdminKey(operatorKey).
   120  		SetFreezeKey(operatorKey).
   121  		SetSupplyKey(operatorKey).
   122  		SetMetadataKey(operatorKey).
   123  		SetPauseKey(operatorKey).
   124  		FreezeWith(client)
   125  
   126  	tokenCreateResp, err := tokenCreateTxn.Sign(treasuryKey).Execute(client)
   127  	if err != nil {
   128  		panic(fmt.Sprintf("%v error creating token", err))
   129  	}
   130  
   131  	receipt, err = tokenCreateResp.GetReceipt(client)
   132  	if err != nil {
   133  		panic(fmt.Sprintf("%v : error creating token", err))
   134  	}
   135  	tokenID := receipt.TokenID
   136  
   137  	nftCreateTransaction, _ := hedera.NewTokenCreateTransaction().
   138  		SetTokenName("Example NFT").
   139  		SetTokenSymbol("ENFT").
   140  		SetTokenType(hedera.TokenTypeNonFungibleUnique).
   141  		SetDecimals(0).
   142  		SetInitialSupply(0).
   143  		SetMaxSupply(10).
   144  		SetTreasuryAccountID(*treasury).
   145  		SetSupplyType(hedera.TokenSupplyTypeFinite).
   146  		SetAdminKey(operatorKey).
   147  		SetFreezeKey(operatorKey).
   148  		SetSupplyKey(operatorKey).
   149  		FreezeWith(client)
   150  	tokenCreateResp, err = nftCreateTransaction.Sign(treasuryKey).Execute(client)
   151  	if err != nil {
   152  		panic(fmt.Sprintf("%v : error creating token", err))
   153  	}
   154  	nftCreateReceipt, err := tokenCreateResp.GetReceipt(client)
   155  	if err != nil {
   156  		panic(fmt.Sprintf("%v : error creating token", err))
   157  	}
   158  	nftID := *nftCreateReceipt.TokenID
   159  	var initialMetadataList = [][]byte{{2, 1}, {1, 2}, {1, 5}}
   160  
   161  	mintTransaction, _ := hedera.NewTokenMintTransaction().
   162  		SetTokenID(nftID).
   163  		SetMetadatas(initialMetadataList).
   164  		FreezeWith(client)
   165  
   166  	mintTransactionSubmit, err := mintTransaction.Sign(operatorKey).Execute(client)
   167  	if err != nil {
   168  		panic(fmt.Sprintf("%v : error minting NFT", err))
   169  	}
   170  	receipt, err = mintTransactionSubmit.GetReceipt(client)
   171  	if err != nil {
   172  		panic(fmt.Sprintf("%v : error minting NFT", err))
   173  	}
   174  
   175  	/*
   176  	 * Step 3:
   177  	 * Airdrop fungible tokens to all 3 accounts
   178  	 */
   179  
   180  	airdropTx, _ := hedera.NewTokenAirdropTransaction().
   181  		AddTokenTransfer(*tokenID, *alice, 100).
   182  		AddTokenTransfer(*tokenID, *bob, 100).
   183  		AddTokenTransfer(*tokenID, *carol, 100).
   184  		AddTokenTransfer(*tokenID, *treasury, -300).
   185  		FreezeWith(client)
   186  	airdropResponse, err := airdropTx.Sign(treasuryKey).Execute(client)
   187  	if err != nil {
   188  		panic(fmt.Sprintf("%v : error airdropping tokens", err))
   189  	}
   190  	record, err := airdropResponse.GetRecord(client)
   191  	if err != nil {
   192  		panic(fmt.Sprintf("%v : error airdropping tokens", err))
   193  	}
   194  
   195  	fmt.Println("Pending airdrops length: ", len(record.PendingAirdropRecords))
   196  	fmt.Println("Pending airdrops: ", record.PendingAirdropRecords[0].String())
   197  
   198  	/*
   199  	 * Step 5:
   200  	 * Query to verify alice and bob received the airdrops and carol did not
   201  	 */
   202  	aliceBalance, _ := hedera.NewAccountBalanceQuery().
   203  		SetAccountID(*alice).
   204  		Execute(client)
   205  
   206  	bobBalance, _ := hedera.NewAccountBalanceQuery().
   207  		SetAccountID(*alice).
   208  		Execute(client)
   209  	carolBalance, _ := hedera.NewAccountBalanceQuery().
   210  		SetAccountID(*alice).
   211  		Execute(client)
   212  
   213  	fmt.Println("Alice ft balance after airdrop: ", aliceBalance.Tokens.Get(*tokenID))
   214  	fmt.Println("Bob ft balance after airdrop: ", bobBalance.Tokens.Get(*tokenID))
   215  	fmt.Println("Carol ft balance after airdrop: ", carolBalance.Tokens.Get(*tokenID))
   216  
   217  	/*
   218  	 * Step 6:
   219  	 * Claim the airdrop for carol
   220  	 */
   221  	fmt.Println("Claiming ft with carol")
   222  
   223  	claimTx, _ := hedera.NewTokenClaimAirdropTransaction().
   224  		AddPendingAirdropId(record.PendingAirdropRecords[0].GetPendingAirdropId()).
   225  		FreezeWith(client)
   226  
   227  	_, err = claimTx.Sign(privateKey3).Execute(client)
   228  	if err != nil {
   229  		panic(fmt.Sprintf("%v : error claiming tokens", err))
   230  	}
   231  	carolBalance, _ = hedera.NewAccountBalanceQuery().
   232  		SetAccountID(*alice).
   233  		Execute(client)
   234  	fmt.Println("Carol ft balance after claim: ", carolBalance.Tokens.Get(*tokenID))
   235  
   236  	/*
   237  	 * Step 7:
   238  	 * Airdrop the NFTs to all three accounts
   239  	 */
   240  
   241  	airdropTx, _ = hedera.NewTokenAirdropTransaction().
   242  		AddNftTransfer(nftID.Nft(1), *treasury, *alice).
   243  		AddNftTransfer(nftID.Nft(2), *treasury, *bob).
   244  		AddNftTransfer(nftID.Nft(3), *treasury, *carol).
   245  		FreezeWith(client)
   246  	airdropResponse, err = airdropTx.Sign(treasuryKey).Execute(client)
   247  	if err != nil {
   248  		panic(fmt.Sprintf("%v : error airdropping tokens", err))
   249  	}
   250  	record, err = airdropResponse.GetRecord(client)
   251  	if err != nil {
   252  		panic(fmt.Sprintf("%v : error airdropping tokens", err))
   253  	}
   254  
   255  	/*
   256  	 * Step 8:
   257  	 * Get the transaction record and verify two pending airdrops (for bob & carol)
   258  	 */
   259  
   260  	fmt.Println("Pending airdrops length: ", len(record.PendingAirdropRecords))
   261  	fmt.Println("Pending airdrops for Bob: ", record.PendingAirdropRecords[0].String())
   262  	fmt.Println("Pending airdrops for Carol: ", record.PendingAirdropRecords[1].String())
   263  
   264  	/*
   265  	 * Step 9:
   266  	 * Query to verify alice received the airdrop and bob and carol did not
   267  	 */
   268  
   269  	aliceBalance, _ = hedera.NewAccountBalanceQuery().
   270  		SetAccountID(*alice).
   271  		Execute(client)
   272  
   273  	bobBalance, _ = hedera.NewAccountBalanceQuery().
   274  		SetAccountID(*alice).
   275  		Execute(client)
   276  	carolBalance, _ = hedera.NewAccountBalanceQuery().
   277  		SetAccountID(*alice).
   278  		Execute(client)
   279  
   280  	fmt.Println("Alice nft balance after airdrop: ", aliceBalance.Tokens.Get(nftID))
   281  	fmt.Println("Bob nft balance after airdrop: ", bobBalance.Tokens.Get(nftID))
   282  	fmt.Println("Carol nft balance after airdrop: ", carolBalance.Tokens.Get(nftID))
   283  
   284  	/*
   285  	 * Step 10:
   286  	 * Claim the airdrop for bob
   287  	 */
   288  	fmt.Println("Claiming nft with Bob")
   289  	claimTx, _ = hedera.NewTokenClaimAirdropTransaction().
   290  		AddPendingAirdropId(record.PendingAirdropRecords[0].GetPendingAirdropId()).
   291  		FreezeWith(client)
   292  
   293  	claimResp, err := claimTx.Sign(privateKey2).Execute(client)
   294  	if err != nil {
   295  		panic(fmt.Sprintf("%v : error claiming tokens", err))
   296  	}
   297  	_, err = claimResp.GetReceipt(client)
   298  	if err != nil {
   299  		panic(fmt.Sprintf("%v : error claiming tokens", err))
   300  	}
   301  	bobBalance, _ = hedera.NewAccountBalanceQuery().
   302  		SetAccountID(*bob).
   303  		Execute(client)
   304  	fmt.Println("Bob nft balance after claim: ", bobBalance.Tokens.Get(nftID))
   305  
   306  	/*
   307  	 * Step 11:
   308  	 * Cancel the airdrop for carol
   309  	 */
   310  	fmt.Println("Canceling nft with Carol")
   311  	cancelTx, _ := hedera.NewTokenCancelAirdropTransaction().
   312  		AddPendingAirdropId(record.PendingAirdropRecords[1].GetPendingAirdropId()).
   313  		FreezeWith(client)
   314  
   315  	cancelResp, err := cancelTx.Sign(treasuryKey).Execute(client)
   316  	if err != nil {
   317  		panic(fmt.Sprintf("%v : error canceling tokens", err))
   318  	}
   319  	_, err = cancelResp.GetReceipt(client)
   320  	if err != nil {
   321  		panic(fmt.Sprintf("%v : error canceling tokens", err))
   322  	}
   323  	carolBalance, _ = hedera.NewAccountBalanceQuery().
   324  		SetAccountID(*carol).
   325  		Execute(client)
   326  	fmt.Println("Carol nft balance after cancel: ", carolBalance.Tokens.Get(nftID))
   327  
   328  	/*
   329  	 * Step 12:
   330  	 * Reject the NFT for bob
   331  	 */
   332  	fmt.Println("Rejecting nft with Bob")
   333  
   334  	rejectTxn, _ := hedera.NewTokenRejectTransaction().
   335  		AddNftID(nftID.Nft(2)).
   336  		SetOwnerID(*bob).
   337  		FreezeWith(client)
   338  
   339  	rejectResp, err := rejectTxn.Sign(privateKey2).Execute(client)
   340  	if err != nil {
   341  		panic(fmt.Sprintf("%v : error rejecting tokens", err))
   342  	}
   343  	_, err = rejectResp.GetReceipt(client)
   344  	if err != nil {
   345  		panic(fmt.Sprintf("%v : error rejecting tokens", err))
   346  	}
   347  
   348  	/*
   349  	 * Step 13:
   350  	 * Query to verify bob no longer has the NFT
   351  	 */
   352  	bobBalance, _ = hedera.NewAccountBalanceQuery().
   353  		SetAccountID(*bob).
   354  		Execute(client)
   355  	fmt.Println("Bob nft balance after reject: ", bobBalance.Tokens.Get(nftID))
   356  
   357  	/*
   358  	 * Step 13:
   359  	 * Query to verify the NFT was returned to the Treasury
   360  	 */
   361  	treasuryBalance, _ := hedera.NewAccountBalanceQuery().
   362  		SetAccountID(*treasury).
   363  		Execute(client)
   364  	fmt.Println("Treasury nft balance after reject: ", treasuryBalance.Tokens.Get(nftID))
   365  
   366  	/*
   367  	 * Step 14:
   368  	 * Reject the fungible tokens for Carol
   369  	 */
   370  
   371  	rejectTxn, _ = hedera.NewTokenRejectTransaction().
   372  		AddTokenID(*tokenID).
   373  		SetOwnerID(*carol).
   374  		FreezeWith(client)
   375  
   376  	rejectResp, err = rejectTxn.Sign(privateKey3).Execute(client)
   377  	if err != nil {
   378  		panic(fmt.Sprintf("%v : error rejecting tokens", err))
   379  	}
   380  	_, err = rejectResp.GetReceipt(client)
   381  	if err != nil {
   382  		panic(fmt.Sprintf("%v : error rejecting tokens", err))
   383  	}
   384  
   385  	/*
   386  	 * Step 14:
   387  	 * Query to verify carol no longer has the fungible tokens
   388  	 */
   389  	carolBalance, _ = hedera.NewAccountBalanceQuery().
   390  		SetAccountID(*alice).
   391  		Execute(client)
   392  	fmt.Println("Carol ft balance after claim: ", carolBalance.Tokens.Get(*tokenID))
   393  
   394  	/*
   395  	 * Step 15:
   396  	 * Query to verify Treasury received the rejected fungible tokens
   397  	 */
   398  	treasuryBalance, _ = hedera.NewAccountBalanceQuery().
   399  		SetAccountID(*treasury).
   400  		Execute(client)
   401  	fmt.Println("Treasury ft balance after reject: ", treasuryBalance.Tokens.Get(*tokenID))
   402  
   403  	/*
   404  	 * Clean up:
   405  	 */
   406  	client.Close()
   407  
   408  	fmt.Println("Example Complete!")
   409  
   410  }