Rendu depuis le dépôt source en conservant titres, exemples, code, tableaux, liens et images.
Hedera Token Service (HTS) System Contract
HTS precompile at 0x167 enables Solidity contracts to create and manage Hedera-native tokens with built-in compliance controls (KYC, freeze, pause) and custom fees.
Quick Reference
Imports:
import {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";Safe variants (auto-revert on failure): SafeHTS.sol, SafeViewHTS.sol
Critical: HBAR Payment Required
Token creation requires explicit HBAR value payment (not just gas):
// ❌ WRONG - fails with INSUFFICIENT_TX_FEE
(int rc, address token) = createNonFungibleToken(token);
// ✅ CORRECT
(int rc, address token) = createNonFungibleToken{value: msg.value}(token);Call from TypeScript:
await contract.createToken(name, symbol, {
gasLimit: 350_000,
value: ethers.parseEther("15"), // ~$1-2 USD of HBAR
});Token Key System
Seven key types control token operations (bit positions for keyType field):
| 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 |
Use KeyHelper for key construction:
keys[0] = getSingleKey(KeyType.SUPPLY, KeyValueType.CONTRACT_ID, address(this));See references/keys.md for key value types and JSON tuple format.
Association Model
Accounts must associate with tokens before receiving them:
int rc = associateToken(accountAddress, tokenAddress);
require(
rc == HederaResponseCodes.SUCCESS ||
rc == HederaResponseCodes.TOKEN_ALREADY_ASSOCIATED_TO_ACCOUNT,
"Association failed"
);Common Patterns
Fungible Token Creation
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");
}Mintable NFT Collection
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");
}KYC-Enabled Token
Treasury must self-grant KYC after creation:
// After token creation with KYC key
int kycRc = grantTokenKyc(tokenAddress, address(this));
require(kycRc == HederaResponseCodes.SUCCESS, "Self-KYC failed");Response Code Handling
Always check response codes. SUCCESS = 22.
require(responseCode == HederaResponseCodes.SUCCESS, "Operation failed");Common codes: See references/response-codes.md
Additional References
- API Reference: references/api.md - All function signatures
- Custom Fees: references/fees.md - Fixed, fractional, royalty fees
- Compliance Controls: references/compliance.md - KYC, freeze, pause details
- Struct Definitions: references/structs.md - HederaToken, Expiry, etc.
- Troubleshooting: references/troubleshooting.md - Common errors and fixes

