0x167 lets a Solidity contract create native HTS tokens. The resulting token is a real HTS token: same association rules, same mirror node REST responses, same HashScan view as an SDK-created one. You can operate on it through the HTS interface or through ERC-20 / ERC-721 redirects.
At a glance
Why use this instead of a plain ERC-20?
Two practical reasons. The first is compliance features. HTS tokens get native support for KYC keys, freeze, pause, wipe, supply caps, and royalty fees, and the network enforces them. If you build the same controls into an ERC-20 contract, you write them yourself and pay gas every time they fire. The second is pricing. HTS operations are priced in USD and paid in HBAR by the network. ERC-20 operations are priced in EVM gas, which scales with whatever you put in your contract. If you don’t need any of that, a plain ERC-20 is simpler and works fine. The choice is per-token; nothing stops you from using both in one app.Required imports
The helper library isHederaTokenService.sol, in the hiero-contracts repository. Copy these files into your contracts/ directory:
Example: fungible token
Example: non-fungible token
Paying for it
Token creation costs HBAR. The caller has to forward enoughmsg.value to cover the TokenCreate transaction fee, which buys the token its initial auto-renew period (~92 days). The current base fee is around $1 USD worth of HBAR for both fungible and non-fungible tokens.
Two important things to know about how Hedera handles the money:
- Gas is charged on consumption. Per HIP-1249, Hedera refunds 100% of unused gas, and the per-transaction limit is 15M (HIP-185). Set a generous gas limit; you only pay for what you actually use.
- Excess
msg.valueis not refunded. Anything you forward beyond what the precompile consumes for theTokenCreatefee stays in the calling contract’s balance. There is no automatic refund to the EOA.
msg.sender after the precompile call.
Token keys
TheHederaToken.tokenKeys array decides who can do what to the token. Each entry is a (keyType, keyValue) pair:
Build each entry with
KeyHelper.getSingleKey(KeyType.X, KeyValueType.Y, address). Common KeyValueType values: CONTRACT_ID (the contract signs implicitly), INHERIT_ACCOUNT_KEY (use the caller’s key), ED25519 / ECDSA (provide a raw public key).
See also
HTS System Contract Overview
Full function reference for the HTS precompile, including transfer, mint, burn, freeze, pause, and KYC operations.