如何使用 EVM 交易关联/分离 HTS 代币?

Alf*_*rez 6 solidity hedera-hashgraph

在接收 HTS 令牌之前,我需要首先与令牌 ID 关联。\n如果我使用 JS SDK,我知道要执行以下操作,其中这是accountId我想要与令牌关联的帐户。

\n
  const associateTransaction = await new TokenAssociateTransaction()\n    .setAccountId(accountId)\n    .setTokenIds([tokenId])\n    .freezeWith(client);\n
Run Code Online (Sandbox Code Playgroud)\n

但是,如何使用 EVM 交易关联/分离 HTS 代币?

\n

I\xe2\x80\x99ve 尝试在我的智能合约中执行以下操作

\n
function mintNft(\n        address token,\n        bytes[] memory metadata\n    ) public payable returns(int64){\n\n        (int response, , int64[] memory serial) = HederaTokenService.mintToken(token, 0, metadata);\n        if(response != HederaResponseCodes.SUCCESS){\n            revert("Failed to mint non-fungible token");\n        }\n\n        int res = HederaTokenService.associateToken(\n            address(msg.sender),\n            token\n        );\n\n        if(res != HederaResponseCodes.SUCCESS){\n            revert("Failed to associate non-fungible token");\n        }\n        \n        return serial[0];\n    }\n
Run Code Online (Sandbox Code Playgroud)\n

但是,当我尝试转移合同时,合同会恢复并出现以下错误:

\n
TOKEN_NOT_ASSOCIATED_TO_ACCOUNT\n
Run Code Online (Sandbox Code Playgroud)\n

我\xe2\x80\x99d 希望能够在部署到 HSCS 的智能合约中执行此操作。如果这不可能,还有其他方法吗?

\n

Luk*_*Lee 8

调用System Contract 已被associateToken弃用 HederaTokenService,并且不能再关联到address(msg.sender). 它只能关联到address(this). 用户必须直接调用代币合约上的关联函数。

\n

智能合约无法更改外部拥有的帐户状态,这意味着合约无法代表用户关联、转移和批准交易。虽然非常有用,但通过允许合约更改 EOA 状态,可能会允许不良行为者代表用户进行恶意行为。因此,不允许在智能合约中关联/解除关联 HTS 代币。您可以在此处进一步了解智能合约的安全更新。

\n

我将向您展示如何使用 ethers.js 关联/分离

\n

您首先要设置以太坊提供商、请求访问帐户并获取签名者。

\n
const provider = new ethers.providers.Web3Provider(window.ethereum, "any");\nawait provider.send("eth_requestAccounts", []);\nconst signer = provider.getSigner();\n
Run Code Online (Sandbox Code Playgroud)\n

接下来你将构造你abi想要执行哪种合约函数

\n
const abi = ["function associate()"];\n
Run Code Online (Sandbox Code Playgroud)\n

您可以将 HTS 代币视为 ERC20/ERC721 代币。此功能允许我们直接在 HTS 代币上调用associate/函数。dissociate为此,您必须首先将 HTS tokenID 转换为带有 \xe2\x80\x980x\xe2\x80\x99 前缀的 \xe2\x80\x99s 实体地址。

\n
const tokenSolidityAddress = \'0x\' + TokenId.fromString(\'0.0.572609\').tokenSolidityAddress();\n
Run Code Online (Sandbox Code Playgroud)\n

最后,创建一个合约实例并直接在合约上调用 Associate。

\n
// create contract instance using token solidity address, abi, and signer\n  const contract = new ethers.Contract(tokenSolidityAddress, abi, signer);\n\n  try {\n    const transactionResult = await contract.associate();\n    return transactionResult.hash;\n  } catch (error) {\n    console.warn(error.message ? error.message : error);\n    return null;\n  }\n
Run Code Online (Sandbox Code Playgroud)\n

如何解绑HTS代币:

\n
async function dissociateToken() {\n    // set up your ethers provider\n    const provider = new ethers.providers.Web3Provider(window.ethereum, "any");\n    // request access to the user\'s account\n    await provider.send("eth_requestAccounts", []);\n    // get signer\n    const signer = provider.getSigner();\n    const abi = ["function dissociate()"];\n    const tokenSolidityAddress = \'0x\' + TokenId.fromString(\'0.0.572609\').tokenSolidityAddress();\n    // create contract instance using token solidity address, abi, and signer\n    const contract = new ethers.Contract(tokenSolidityAddress, abi, signer);\n  \n    try {\n      const transactionResult = await contract.dissociate();\n      return transactionResult.hash;\n    } catch (error) {\n      console.warn(error.message ? error.message : error);\n      return null;\n    } \n};\n
Run Code Online (Sandbox Code Playgroud)\n