hts-system-contract
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseHedera Token Service (HTS) System Contract
Hedera Token Service (HTS) 系统合约
HTS precompile at enables Solidity contracts to create and manage Hedera-native tokens with built-in compliance controls (KYC, freeze, pause) and custom fees.
0x167位于 的 HTS 预编译合约支持 Solidity 合约创建和管理 Hedera 原生代币,内置合规控制(KYC、冻结、暂停)和自定义手续费功能。
0x167Quick Reference
快速参考
Imports:
solidity
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.solSafeViewHTS.sol导入:
solidity
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";安全变体(失败时自动回滚):、
SafeHTS.solSafeViewHTS.solCritical: HBAR Payment Required
重要提示:需要支付 HBAR
Token creation requires explicit HBAR value payment (not just gas):
solidity
// ❌ 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:
typescript
await contract.createToken(name, symbol, {
gasLimit: 350_000,
value: ethers.parseEther("15"), // ~$1-2 USD of HBAR
});创建代币需要显式支付 HBAR 金额(不仅仅是 gas 费):
solidity
// ❌ WRONG - fails with INSUFFICIENT_TX_FEE
(int rc, address token) = createNonFungibleToken(token);
// ✅ CORRECT
(int rc, address token) = createNonFungibleToken{value: msg.value}(token);TypeScript 调用示例:
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 field):
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 |
Use for key construction:
KeyHelpersolidity
keys[0] = getSingleKey(KeyType.SUPPLY, KeyValueType.CONTRACT_ID, address(this));See references/keys.md for key value types and JSON tuple format.
七种密钥类型控制代币操作( 字段的位位置):
keyType| 密钥类型 | 位 | 值 | 控制范围 |
|---|---|---|---|
| ADMIN | 0 | 1 | 更新代币、密钥、删除代币 |
| KYC | 1 | 2 | 授予/撤销 KYC |
| FREEZE | 2 | 4 | 冻结/解冻账户 |
| WIPE | 3 | 8 | 擦除余额 |
| SUPPLY | 4 | 16 | 铸造/销毁 |
| FEE | 5 | 32 | 更新手续费 |
| PAUSE | 6 | 64 | 暂停所有操作 |
使用 构建密钥:
KeyHelpersolidity
keys[0] = getSingleKey(KeyType.SUPPLY, KeyValueType.CONTRACT_ID, address(this));有关密钥值类型和 JSON 元组格式,请参阅 references/keys.md。
Association Model
关联模型
Accounts must associate with tokens before receiving them:
solidity
int rc = associateToken(accountAddress, tokenAddress);
require(
rc == HederaResponseCodes.SUCCESS ||
rc == HederaResponseCodes.TOKEN_ALREADY_ASSOCIATED_TO_ACCOUNT,
"Association failed"
);账户在接收代币前必须先与代币建立关联:
solidity
int rc = associateToken(accountAddress, tokenAddress);
require(
rc == HederaResponseCodes.SUCCESS ||
rc == HederaResponseCodes.TOKEN_ALREADY_ASSOCIATED_TO_ACCOUNT,
"Association failed"
);Common Patterns
常用模式
Fungible Token Creation
同质化代币创建
solidity
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");
}solidity
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
可铸造 NFT 集合
solidity
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");
}solidity
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
启用 KYC 的代币
Treasury must self-grant KYC after creation:
solidity
// After token creation with KYC key
int kycRc = grantTokenKyc(tokenAddress, address(this));
require(kycRc == HederaResponseCodes.SUCCESS, "Self-KYC failed");金库地址必须在代币创建后为自身授予 KYC 权限:
solidity
// 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.
solidity
require(responseCode == HederaResponseCodes.SUCCESS, "Operation failed");Common codes: See references/response-codes.md
始终检查响应码。SUCCESS = 22。
solidity
require(responseCode == HederaResponseCodes.SUCCESS, "Operation failed");常用响应码:请参阅 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
- API 参考:references/api.md - 所有函数签名
- 自定义手续费:references/fees.md - 固定手续费、分级手续费、版税手续费
- 合规控制:references/compliance.md - KYC、冻结、暂停详情
- 结构体定义:references/structs.md - HederaToken、Expiry 等
- 故障排查:references/troubleshooting.md - 常见错误及修复方法