github.com/hashgraph/hedera-sdk-go/v2@v2.48.0/examples/transfer_tokens/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 func main() { 11 var client *hedera.Client 12 var err error 13 14 // Retrieving network type from environment variable HEDERA_NETWORK 15 client, err = hedera.ClientForName(os.Getenv("HEDERA_NETWORK")) 16 if err != nil { 17 panic(fmt.Sprintf("%v : error creating client", err)) 18 } 19 20 // Retrieving operator ID from environment variable OPERATOR_ID 21 operatorAccountID, err := hedera.AccountIDFromString(os.Getenv("OPERATOR_ID")) 22 if err != nil { 23 panic(fmt.Sprintf("%v : error converting string to AccountID", err)) 24 } 25 26 // Retrieving operator key from environment variable OPERATOR_KEY 27 operatorKey, err := hedera.PrivateKeyFromString(os.Getenv("OPERATOR_KEY")) 28 if err != nil { 29 panic(fmt.Sprintf("%v : error converting string to PrivateKey", err)) 30 } 31 32 // Setting the client operator ID and key 33 client.SetOperator(operatorAccountID, operatorKey) 34 35 key1, err := hedera.GeneratePrivateKey() 36 if err != nil { 37 panic(fmt.Sprintf("%v : error generating PrivateKey", err)) 38 } 39 key2, err := hedera.GeneratePrivateKey() 40 if err != nil { 41 panic(fmt.Sprintf("%v : error generating PrivateKey", err)) 42 } 43 44 fmt.Printf("privateKey = %v\n", key1.String()) 45 fmt.Printf("publicKey = %v\n", key1.PublicKey().String()) 46 fmt.Printf("privateKey = %v\n", key2.String()) 47 fmt.Printf("publicKey = %v\n", key2.PublicKey().String()) 48 49 // Creating 2 accounts for transferring tokens 50 transactionResponse, err := hedera.NewAccountCreateTransaction(). 51 // The key that must sign each transfer out of the account. If receiverSigRequired is true, then 52 // it must also sign any transfer into the account. 53 SetKey(key1.PublicKey()). 54 Execute(client) 55 if err != nil { 56 panic(fmt.Sprintf("%v : error creating account", err)) 57 } 58 59 // First receipt with account ID 1, will error if transaction failed 60 transactionReceipt, err := transactionResponse.GetReceipt(client) 61 if err != nil { 62 panic(fmt.Sprintf("%v : error retrieving account creation receipt", err)) 63 } 64 65 // Retrieving account ID out of the first receipt 66 accountID1 := *transactionReceipt.AccountID 67 68 fmt.Printf("account = %v\n", accountID1.String()) 69 70 // Creating a new account for the token 71 transactionResponse, err = hedera.NewAccountCreateTransaction(). 72 // The key that must sign each transfer out of the account. If receiverSigRequired is true, then 73 // it must also sign any transfer into the account. 74 SetKey(key2.PublicKey()). 75 Execute(client) 76 if err != nil { 77 panic(fmt.Sprintf("%v : error creating second account", err)) 78 } 79 80 // Second receipt with account ID 2, will error if transaction failed 81 transactionReceipt, err = transactionResponse.GetReceipt(client) 82 if err != nil { 83 panic(fmt.Sprintf("%v : error retrieving second account creation receipt", err)) 84 } 85 86 // Retrieving account ID out of the second receipt 87 accountID2 := *transactionReceipt.AccountID 88 89 fmt.Printf("account = %v\n", accountID2.String()) 90 91 // Creating a new token 92 transactionResponse, err = hedera.NewTokenCreateTransaction(). 93 // The publicly visible name of the token 94 SetTokenName("ffff"). 95 // The publicly visible token symbol 96 SetTokenSymbol("F"). 97 SetMaxTransactionFee(hedera.NewHbar(1000)). 98 SetNodeAccountIDs([]hedera.AccountID{transactionResponse.NodeID}). 99 // For tokens of type FUNGIBLE_COMMON - the number of decimal places a 100 // token is divisible by. For tokens of type NON_FUNGIBLE_UNIQUE - value 101 // must be 0 102 SetDecimals(3). 103 // Specifies the initial supply of tokens to be put in circulation. The 104 // initial supply is sent to the Treasury Account. The supply is in the 105 // lowest denomination possible. In the case for NON_FUNGIBLE_UNIQUE Type 106 // the value must be 0 107 SetInitialSupply(1000000). 108 // The account which will act as a treasury for the token. This account 109 // will receive the specified initial supply or the newly minted NFTs in 110 // the case for NON_FUNGIBLE_UNIQUE Type 111 SetTreasuryAccountID(client.GetOperatorAccountID()). 112 // The key which can perform update/delete operations on the token. If empty, the token can be 113 // perceived as immutable (not being able to be updated/deleted) 114 SetAdminKey(client.GetOperatorPublicKey()). 115 // The key which can sign to freeze or unfreeze an account for token transactions. If empty, 116 // freezing is not possible 117 SetFreezeKey(client.GetOperatorPublicKey()). 118 // The key which can wipe the token balance of an account. If empty, wipe is not possible 119 SetWipeKey(client.GetOperatorPublicKey()). 120 // The key which can grant or revoke KYC of an account for the token's transactions. If empty, 121 // KYC is not required, and KYC grant or revoke operations are not possible. 122 SetKycKey(client.GetOperatorPublicKey()). 123 // The key which can change the supply of a token. The key is used to sign Token Mint/Burn 124 // operations 125 SetSupplyKey(client.GetOperatorPublicKey()). 126 // The default Freeze status (frozen or unfrozen) of Hedera accounts relative to this token. If 127 // true, an account must be unfrozen before it can receive the token 128 SetFreezeDefault(false). 129 Execute(client) 130 if err != nil { 131 panic(fmt.Sprintf("%v : error creating token", err)) 132 } 133 134 // Make sure the token create transaction ran 135 transactionReceipt, err = transactionResponse.GetReceipt(client) 136 if err != nil { 137 panic(fmt.Sprintf("%v : error retrieving token creation receipt", err)) 138 } 139 140 // Retrieve the token out of the receipt 141 tokenID := *transactionReceipt.TokenID 142 143 fmt.Printf("token = %v\n", tokenID.String()) 144 145 // Associating the token with the first account, so it can interact with the token 146 transaction, err := hedera.NewTokenAssociateTransaction(). 147 // The account ID to be associated 148 SetAccountID(accountID1). 149 SetNodeAccountIDs([]hedera.AccountID{transactionResponse.NodeID}). 150 // The token ID that the account will be associated to 151 SetTokenIDs(tokenID). 152 FreezeWith(client) 153 if err != nil { 154 panic(fmt.Sprintf("%v : error freezing token associate transaction", err)) 155 } 156 157 // Has to be signed by the account1's key 158 transactionResponse, err = transaction. 159 Sign(key1). 160 Execute(client) 161 if err != nil { 162 panic(fmt.Sprintf("%v : error associating token", err)) 163 } 164 165 // Make sure the transaction succeeded 166 transactionReceipt, err = transactionResponse.GetReceipt(client) 167 if err != nil { 168 panic(fmt.Sprintf("%v : error retrieving token associate transaction receipt", err)) 169 } 170 171 fmt.Printf("Associated account %v with token %v\n", accountID1.String(), tokenID.String()) 172 173 // Associating the token with the first account, so it can interact with the token 174 transaction, err = hedera.NewTokenAssociateTransaction(). 175 // The account ID to be associated 176 SetAccountID(accountID2). 177 SetNodeAccountIDs([]hedera.AccountID{transactionResponse.NodeID}). 178 // The token ID that the account will be associated to 179 SetTokenIDs(tokenID). 180 FreezeWith(client) 181 if err != nil { 182 panic(fmt.Sprintf("%v : error freezing token associate transaction", err)) 183 } 184 185 // Has to be signed by the account1's key 186 transactionResponse, err = transaction. 187 Sign(key2). 188 Execute(client) 189 if err != nil { 190 panic(fmt.Sprintf("%v : error associating token", err)) 191 } 192 193 // Make sure the transaction succeeded 194 transactionReceipt, err = transactionResponse.GetReceipt(client) 195 if err != nil { 196 panic(fmt.Sprintf("%v : error retrieving token associate transaction receipt", err)) 197 } 198 199 fmt.Printf("Associated account %v with token %v\n", accountID2.String(), tokenID.String()) 200 201 // This transaction grants Kyc to the first account 202 // Must be signed by the Token's kycKey. 203 transactionResponse, err = hedera.NewTokenGrantKycTransaction(). 204 SetTokenID(tokenID). 205 SetNodeAccountIDs([]hedera.AccountID{transactionResponse.NodeID}). 206 // The account that KYC is being granted to 207 SetAccountID(accountID1). 208 // As the token kyc key is client.GetOperatorPublicKey(), we don't have to explicitly sign with anything 209 // as it's done automatically by execute for the operator 210 Execute(client) 211 if err != nil { 212 panic(fmt.Sprintf("%v : error granting kyc", err)) 213 } 214 215 transactionReceipt, err = transactionResponse.GetReceipt(client) 216 if err != nil { 217 panic(fmt.Sprintf("%v : error retrieving grant kyc transaction receipt", err)) 218 } 219 220 fmt.Printf("Granted KYC for account %v on token %v\n", accountID1.String(), tokenID.String()) 221 222 // This transaction grants Kyc to the second account 223 transactionResponse, err = hedera.NewTokenGrantKycTransaction(). 224 SetTokenID(tokenID). 225 SetNodeAccountIDs([]hedera.AccountID{transactionResponse.NodeID}). 226 // The account that KYC is being granted to 227 SetAccountID(accountID2). 228 // As the token kyc key is client.GetOperatorPublicKey(), we don't have to explicitly sign with anything 229 // as it's done automatically by execute for the operator 230 Execute(client) 231 if err != nil { 232 panic(fmt.Sprintf("%v : error granting kyc to second account", err)) 233 } 234 235 // Make sure the transaction succeeded 236 transactionReceipt, err = transactionResponse.GetReceipt(client) 237 if err != nil { 238 panic(fmt.Sprintf("%v : error retrieving grant kyc transaction receipt", err)) 239 } 240 241 fmt.Printf("Granted KYC for account %v on token %v\n", accountID2.String(), tokenID.String()) 242 243 transactionResponse, err = hedera.NewTransferTransaction(). 244 // Same as for Hbar transfer, token value has to be negated to denote they are being taken out 245 AddTokenTransfer(tokenID, client.GetOperatorAccountID(), -10). 246 // Same as for Hbar transfer, the 2 transfers here have to be equal, otherwise it will lead to an error 247 AddTokenTransfer(tokenID, accountID1, 10). 248 // We don't have to sign this one as we are transferring tokens from the operator 249 Execute(client) 250 if err != nil { 251 panic(fmt.Sprintf("%v : error transferring from operator to account1", err)) 252 } 253 254 // Make sure the transaction succeeded 255 transactionReceipt, err = transactionResponse.GetReceipt(client) 256 if err != nil { 257 panic(fmt.Sprintf("%v : error retrieving transfer from operator to account1 receipt", err)) 258 } 259 260 fmt.Printf( 261 "Sent 10 tokens from account %v to account %v on token %v\n", 262 client.GetOperatorAccountID().String(), 263 accountID1.String(), 264 tokenID.String(), 265 ) 266 267 transferTransaction, err := hedera.NewTransferTransaction(). 268 // 10 tokens from account 1 269 AddTokenTransfer(tokenID, accountID1, -10). 270 // 10 token to account 2 271 AddTokenTransfer(tokenID, accountID2, 10). 272 FreezeWith(client) 273 if err != nil { 274 panic(fmt.Sprintf("%v : error freezing transfer from account1 to account2", err)) 275 } 276 277 // As we are now transferring tokens from accountID1 to accountID2, this has to be signed by accountID1's key 278 transferTransaction = transferTransaction.Sign(key1) 279 280 // Execute the transfer transaction 281 transactionResponse, err = transferTransaction.Execute(client) 282 if err != nil { 283 panic(fmt.Sprintf("%v : error transferring from account1 to account2", err)) 284 } 285 286 // Make sure the transaction succeeded 287 transactionReceipt, err = transactionResponse.GetReceipt(client) 288 if err != nil { 289 panic(fmt.Sprintf("%v : error retrieving transfer from account1 to account2 receipt", err)) 290 } 291 292 fmt.Printf( 293 "Sent 10 tokens from account %v to account %v on token %v\n", 294 accountID1.String(), 295 accountID2.String(), 296 tokenID.String(), 297 ) 298 299 transferTransaction, err = hedera.NewTransferTransaction(). 300 // 10 tokens from account 2 301 AddTokenTransfer(tokenID, accountID2, -10). 302 // 10 token to account 1 303 AddTokenTransfer(tokenID, accountID1, 10). 304 FreezeWith(client) 305 if err != nil { 306 panic(fmt.Sprintf("%v : error freezing transfer from account2 to account1", err)) 307 } 308 309 // As we are now transferring tokens from accountID2 back to accountID1, this has to be signed by accountID2's key 310 transferTransaction = transferTransaction.Sign(key2) 311 312 // Executing the transfer transaction 313 transactionResponse, err = transferTransaction.Execute(client) 314 if err != nil { 315 panic(fmt.Sprintf("%v : error transferring from account2 to account1", err)) 316 } 317 318 // Make sure the transaction succeeded 319 transactionReceipt, err = transactionResponse.GetReceipt(client) 320 if err != nil { 321 panic(fmt.Sprintf("%v : error retrieving transfer from account2 to account1 receipt", err)) 322 } 323 324 fmt.Printf( 325 "Sent 10 tokens from account %v to account %v on token %v\n", 326 accountID2.String(), 327 accountID1.String(), 328 tokenID.String(), 329 ) 330 331 // Clean up 332 333 // Now we can wipe the 10 tokens that are in possession of accountID1 334 // Has to be signed by wipe key of the token, in this case it was the operator key 335 transactionResponse, err = hedera.NewTokenWipeTransaction(). 336 SetNodeAccountIDs([]hedera.AccountID{transactionResponse.NodeID}). 337 // From which account 338 SetAccountID(accountID1). 339 // For which token 340 SetTokenID(tokenID). 341 // How many 342 SetAmount(10). 343 Execute(client) 344 if err != nil { 345 panic(fmt.Sprintf("%v : error wiping from token", err)) 346 } 347 348 // Make sure the transaction succeeded 349 _, err = transactionResponse.GetReceipt(client) 350 if err != nil { 351 panic(fmt.Sprintf("%v : error retrieving token wipe transaction receipt", err)) 352 } 353 354 fmt.Printf("Wiped account %v on token %v\n", accountID1.String(), tokenID.String()) 355 356 // Now to delete the token 357 // Has to be signed by admin key of the token, in this case it was the operator key 358 transactionResponse, err = hedera.NewTokenDeleteTransaction(). 359 SetTokenID(tokenID). 360 SetNodeAccountIDs([]hedera.AccountID{transactionResponse.NodeID}). 361 Execute(client) 362 if err != nil { 363 panic(fmt.Sprintf("%v : error deleting token", err)) 364 } 365 366 // Make sure the transaction succeeded 367 transactionReceipt, err = transactionResponse.GetReceipt(client) 368 if err != nil { 369 panic(fmt.Sprintf("%v : error retrieving token delete transaction receipt", err)) 370 } 371 372 fmt.Printf("DeletedAt token %v\n", tokenID.String()) 373 374 // Now that the tokens have been wiped from accountID1, we can safely delete it 375 accountDeleteTx, err := hedera.NewAccountDeleteTransaction(). 376 SetAccountID(accountID1). 377 SetNodeAccountIDs([]hedera.AccountID{transactionResponse.NodeID}). 378 // Tp which account to transfer the account 1 balance 379 SetTransferAccountID(client.GetOperatorAccountID()). 380 FreezeWith(client) 381 if err != nil { 382 panic(fmt.Sprintf("%v : error freezing account delete transaction", err)) 383 } 384 385 // Account deletion has to always be signed by the key for the account 386 transactionResponse, err = accountDeleteTx. 387 Sign(key1). 388 Execute(client) 389 if err != nil { 390 panic(fmt.Sprintf("%v : error deleting account 1", err)) 391 } 392 393 // Make sure the transaction succeeded 394 transactionReceipt, err = transactionResponse.GetReceipt(client) 395 if err != nil { 396 panic(fmt.Sprintf("%v : error retrieving transfer transaction receipt", err)) 397 } 398 399 fmt.Printf("DeletedAt account %v\n", accountID1.String()) 400 401 accountDeleteTx, err = hedera.NewAccountDeleteTransaction(). 402 SetAccountID(accountID2). 403 SetNodeAccountIDs([]hedera.AccountID{transactionResponse.NodeID}). 404 // Tp which account to transfer the account 2 balance 405 SetTransferAccountID(client.GetOperatorAccountID()). 406 FreezeWith(client) 407 if err != nil { 408 panic(fmt.Sprintf("%v : error freezing account delete transaction", err)) 409 } 410 411 // Account deletion has to always be signed by the key for the account 412 transactionResponse, err = accountDeleteTx. 413 Sign(key2). 414 Execute(client) 415 if err != nil { 416 panic(fmt.Sprintf("%v : error deleting account2", err)) 417 } 418 419 // Make sure the transaction succeeded 420 transactionReceipt, err = transactionResponse.GetReceipt(client) 421 if err != nil { 422 panic(fmt.Sprintf("%v : error retrieving account delete transaction receipt", err)) 423 } 424 425 fmt.Printf("DeletedAt account %v\n", accountID2.String()) 426 }