HTS System Contract Skill について
HTS System Contract Skillは、SolidityコントラクトからHedera Token Serviceを利用する開発者向けのリファレンスです。トークン操作、コンプライアンス制御、手数料、レスポンスコード、実装パターンを扱います。
主な機能
- 01`0x167` HTSプリコンパイルの利用
- 02代替可能トークンとNFTのパターン
- 03トークンキーの構築ガイド
- 04KYC・凍結・一時停止制御
- 05カスタム手数料の資料
- 06レスポンスコードとエラー対応
活用シーン
- 01SolidityでHederaネイティブトークンを作成
- 02トークンコントラクトへのコンプライアンス制御追加
- 03トークン手数料とレスポンスコードの処理
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ hedera-dev/ hedera-skills --skill hts-system-contract-skillインストール後、Claude Code で/hts-system-contract-skillを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/response-codes.mdcompliance.mdapi.mdkeys.mdfees.mdtroubleshooting.mdstructs.md詳細
Hedera Token Service(HTS)システムコントラクト
0x167 の HTS プリコンパイルを使うと、Solidity コントラクトから、コンプライアンス制御(KYC、凍結、一時停止)とカスタム手数料を備えた Hedera ネイティブトークンを作成、管理できます。
クイックリファレンス
インポート:
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.sol、SafeViewHTS.sol
重要:HBAR の支払いが必要です
トークンの作成には、明示的な HBAR の支払いが必要です(ガス代だけではありません)。
// ❌ WRONG - fails with INSUFFICIENT_TX_FEE
(int rc, address token) = createNonFungibleToken(token);
// ✅ CORRECT
(int rc, address token) = createNonFungibleToken{value: msg.value}(token);
TypeScript からの呼び出し:
await contract.createToken(name, symbol, {
gasLimit: 350_000,
value: ethers.parseEther("15"), // ~$1-2 USD of HBAR
});
トークンキーシステム
7 種類のキーでトークン操作を制御します(keyType フィールドのビット位置)。
| キー | ビット | 値 | 制御内容 |
|---|---|---|---|
| ADMIN | 0 | 1 | トークン、キーの更新、削除 |
| KYC | 1 | 2 | KYC の付与/取り消し |
| FREEZE | 2 | 4 | アカウントの凍結/凍結解除 |
| WIPE | 3 | 8 | 残高の消去 |
| SUPPLY | 4 | 16 | ミント/バーン |
| FEE | 5 | 32 | 手数料の更新 |
| PAUSE | 6 | 64 | すべての操作の一時停止 |
キーの構築には KeyHelper を使用します。
keys[0] = getSingleKey(KeyType.SUPPLY, KeyValueType.CONTRACT_ID, address(this));
キー値の型と JSON タプル形式については、references/keys.md を参照してください。
アソシエーションモデル
アカウントはトークンを受け取る前に、そのトークンとアソシエートする必要があります。
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");
}
ミント可能な NFT コレクション
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 対応トークン
作成後、トレジャリーは自身に KYC を付与する必要があります。
// After token creation with KYC key
int kycRc = grantTokenKyc(tokenAddress, address(this));
require(kycRc == HederaResponseCodes.SUCCESS, "Self-KYC failed");
レスポンスコードの処理
必ずレスポンスコードを確認してください。SUCCESS は 22 です。
require(responseCode == HederaResponseCodes.SUCCESS, "Operation failed");
一般的なコードについては、references/response-codes.md を参照してください。
追加のリファレンス
- API リファレンス:references/api.md - すべての関数シグネチャ
- カスタム手数料:references/fees.md - 固定手数料、割合手数料、ロイヤリティ手数料
- コンプライアンス制御:references/compliance.md - KYC、凍結、一時停止の詳細
- 構造体の定義:references/structs.md - HederaToken、Expiry など
- トラブルシューティング:references/troubleshooting.md - よくあるエラーと解決方法