如何用Hashgraph JS SDK关联/解除HTS代币?附关联必要性说明
问题描述
我已使用JavaScript SDK在HTS上创建了新的Fungible Token,代码如下:
// Create an HTS Fungible Token async function createFungibleToken( client, treasuryAccountId, treasuryAccountPrivateKey, ) { // Generate supply key const supplyKeyForFT = PrivateKey.generateED25519(); // Configure the token const createFTokenTxn = await new TokenCreateTransaction() .setTokenName('PowerToken') .setTokenSymbol('PT') .setTokenType(TokenType.FungibleCommon) .setDecimals(1) .setInitialSupply(100) .setTreasuryAccountId(treasuryAccountId) .setSupplyKey(supplyKeyForFT) .setMaxTransactionFee(new Hbar(30)) .freezeWith(client); // Sign the transaction with the treasury account private key const createFTokenTxnSigned = await createFTokenTxn.sign(treasuryAccountPrivateKey); const createFTokenTxnResponse = await createFTokenTxnSigned.execute(client); const createFtTokenTxnReceipt = await createFTokenTxnResponse.getReceipt(client); const fungibleTokenId = createFtTokenTxnReceipt.tokenId; console.log(`Fungible token ID: ${fungibleTokenId}`); }
随后我尝试通过TransferTransaction()将代币转账至某账户,代码如下:
async function transferHtsToken(tokenId, senderAccountId, receiverAccoundId, myPrivateKey) { const transferTransaction = new TransferTransaction() .addTokenTransfer(tokenId, senderAccountId, -1) .addTokenTransfer(tokenId, receiverAccoundId, 1) .freezeWith(client); const signTx = await transferTransaction.sign(myPrivateKey); const txResponse = await signTx.execute(client); const receipt = await txResponse.getReceipt(client); const txStatus = receipt.status; console.log(`Transaction status ${txStatus}`); }
但遇到了如下错误:
ReceiptStatusError: receipt for transaction 0.0.565763@1692941232.156398491 contained error status TOKEN_NOT_ASSOCIATED_TO_ACCOUNT
请问为何在Hedera上必须对代币进行“关联”操作?又该如何实现代币的关联与解除关联?
解答
为什么需要代币关联操作?
在Hedera网络中,账户默认不会自动追踪所有代币的余额——如果不对代币进行关联操作,账户无法存储该代币的余额,也无法接收或发送该代币。这一设计是为了优化账户存储效率,避免账户被大量无关代币的余额数据占用空间。只有当账户与代币建立关联后,Hedera账本才会为该账户分配存储该代币余额的空间,转账等操作才能正常执行。你遇到的TOKEN_NOT_ASSOCIATED_TO_ACCOUNT错误,就是因为接收方账户还没和你创建的PowerToken建立关联。
如何实现代币关联与解除关联
1. 代币关联(Token Associate)
关联操作需要接收方账户的私钥签名,因为这是接收方主动授权账本为其分配代币余额存储空间的操作。示例代码如下:
async function associateToken(client, accountId, accountPrivateKey, tokenId) { // 创建关联交易 const associateTx = new TokenAssociateTransaction() .setAccountId(accountId) .setTokenIds([tokenId]) // 支持同时关联多个代币 .setMaxTransactionFee(new Hbar(5)); // 冻结交易并签名 const frozenTx = await associateTx.freezeWith(client); const signedTx = await frozenTx.sign(accountPrivateKey); // 执行交易并获取回执 const txResponse = await signedTx.execute(client); const receipt = await txResponse.getReceipt(client); console.log(`关联交易状态: ${receipt.status}`); }
2. 代币解除关联(Token Dissociate)
解除关联同样需要账户自身私钥签名,解除后账户将无法再接收该代币,已有的余额会被保留,但无法进行转账操作(除非重新关联)。示例代码如下:
async function dissociateToken(client, accountId, accountPrivateKey, tokenId) { // 创建解除关联交易 const dissociateTx = new TokenDissociateTransaction() .setAccountId(accountId) .setTokenIds([tokenId]) // 支持同时解除多个代币关联 .setMaxTransactionFee(new Hbar(5)); // 冻结交易并签名 const frozenTx = await dissociateTx.freezeWith(client); const signedTx = await frozenTx.sign(accountPrivateKey); // 执行交易并获取回执 const txResponse = await signedTx.execute(client); const receipt = await txResponse.getReceipt(client); console.log(`解除关联交易状态: ${receipt.status}`); }
注意事项
- 代币的财库账户(Treasury Account)在创建代币时会自动关联该代币,无需额外操作。
- 转账前必须确保接收方账户已完成代币关联,否则会触发
TOKEN_NOT_ASSOCIATED_TO_ACCOUNT错误。
内容的提问来源于stack exchange,提问作者Abi
相关产品推荐
相关产品推荐

