Loading...
Loading...
Hedera Token Service (HTS) smart contract development. Use when creating, managing, or interacting with Hedera-native tokens via Solidity contracts. Triggers include HTS tokens, Hedera token creation, HTS precompile, token minting/burning on Hedera, KYC/freeze/pause token controls, custom fee schedules, NFT collections on Hedera, or any token operations using the 0x167 precompile.
npx skill4agent add hedera-dev/hedera-skills hts-system-contract0x167import {HederaTokenService} from "@hashgraph/smart-contracts/contracts/system-contracts/hedera-token-service/HederaTokenService.sol";
import {KeyHelper} from "@hashgraph/smart-contracts/contracts/system-contracts/hedera-token-service/KeyHelper.sol";
import {ExpiryHelper} from "@hashgraph/smart-contracts/contracts/system-contracts/hedera-token-service/ExpiryHelper.sol";
import {HederaResponseCodes} from "@hashgraph/smart-contracts/contracts/system-contracts/hedera-token-service/HederaResponseCodes.sol";SafeHTS.solSafeViewHTS.sol// ❌ WRONG - fails with INSUFFICIENT_TX_FEE
(int rc, address token) = createNonFungibleToken(token);
// ✅ CORRECT
(int rc, address token) = createNonFungibleToken{value: msg.value}(token);await contract.createToken(name, symbol, {
gasLimit: 350_000,
value: ethers.parseEther("15"), // ~$1-2 USD of HBAR
});keyType| Key | Bit | Value | Controls |
|---|---|---|---|
| ADMIN | 0 | 1 | Update token, keys, deletion |
| KYC | 1 | 2 | Grant/revoke KYC |
| FREEZE | 2 | 4 | Freeze/unfreeze accounts |
| WIPE | 3 | 8 | Wipe balances |
| SUPPLY | 4 | 16 | Mint/burn |
| FEE | 5 | 32 | Update fees |
| PAUSE | 6 | 64 | Pause all operations |
KeyHelperkeys[0] = getSingleKey(KeyType.SUPPLY, KeyValueType.CONTRACT_ID, address(this));int rc = associateToken(accountAddress, tokenAddress);
require(
rc == HederaResponseCodes.SUCCESS ||
rc == HederaResponseCodes.TOKEN_ALREADY_ASSOCIATED_TO_ACCOUNT,
"Association failed"
);function createToken() external payable {
IHederaTokenService.HederaToken memory token;
token.name = "My Token";
token.symbol = "MTK";
token.treasury = address(this);
token.expiry = createAutoRenewExpiry(address(this), 7776000); // 90 days
(int rc, address created) = createFungibleToken{value: msg.value}(
token, 1000000, 18 // initialSupply, decimals
);
require(rc == HederaResponseCodes.SUCCESS, "Create failed");
}function createNFT() external payable {
IHederaTokenService.HederaToken memory token;
token.name = "My NFT";
token.symbol = "MNFT";
token.treasury = address(this);
token.tokenSupplyType = true; // FINITE
token.maxSupply = 10000;
IHederaTokenService.TokenKey[] memory keys = new IHederaTokenService.TokenKey[](1);
keys[0] = getSingleKey(KeyType.SUPPLY, KeyValueType.CONTRACT_ID, address(this));
token.tokenKeys = keys;
token.expiry = createAutoRenewExpiry(address(this), 7776000);
(int rc, address created) = createNonFungibleToken{value: msg.value}(token);
require(rc == HederaResponseCodes.SUCCESS, "Create failed");
}
function mintNFT(bytes memory metadata) external {
bytes[] memory metas = new bytes[](1);
metas[0] = metadata;
(int rc, , int64[] memory serials) = mintToken(tokenAddress, 0, metas);
require(rc == HederaResponseCodes.SUCCESS, "Mint failed");
}// After token creation with KYC key
int kycRc = grantTokenKyc(tokenAddress, address(this));
require(kycRc == HederaResponseCodes.SUCCESS, "Self-KYC failed");require(responseCode == HederaResponseCodes.SUCCESS, "Operation failed");