mcpField
S
Schedule Service System Contract Skill

Schedule Service System Contract Skill

github.com/hedera-dev開発2875 回インストール8 週間前に更新
リポジトリ

Schedule Service System Contract Skill について

SolidityコントラクトからHederaのSchedule Serviceシステムコントラクトを利用するためのスキルです。トークン作成やコントラクト呼び出しの予約、コントラクトによる承認と署名、容量制限や非リバート応答の扱いを説明します。

主な機能

  1. 01ネイティブHTSトークン作成の予約
  2. 02任意のコントラクト呼び出しの予約
  3. 03スケジュールの承認と署名
  4. 04スケジュール容量とスロットルの確認
  5. 05レスポンスコードと失敗の処理

活用シーン

  1. 01必要な署名がそろってからHTSトークンを作成
  2. 02将来のDeFiやDAOのコントラクト処理を予約
  3. 03スケジュールへのコントラクト承認の追加
  4. 04予約前に混雑する有効期限枠を回避

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/hedera-dev/hedera-skills --skill schedule-service-system-contract-skill

インストール後、Claude Code で/schedule-service-system-contract-skillを入力して読み込まれたか確認します。

同梱ファイルreferences/api.md

詳細

Hedera Schedule Service(HSS)システムコントラクト

0x16b にある Hedera Schedule Service システムコントラクトは、Solidity 内からスケジュール済みトランザクションを作成、管理するための関数を公開します。以下をサポートしています。

  • HIP-755:コントラクトからスケジュールを承認、署名する
  • HIP-756:ネイティブ HTS トークンの作成をスケジュールする(createFungibleToken、createNonFungibleToken など)
  • HIP-1215:汎用スケジュール済みコントラクト呼び出し — DeFi の自動化、ベスティング、DAO の操作のために、任意のコントラクト(または自身)への呼び出しをスケジュールする

クイックリファレンス

コントラクトアドレス: 0x16b

インポート:

import {HederaScheduleService} from "@hashgraph/smart-contracts/contracts/system-contracts/hedera-schedule-service/HederaScheduleService.sol";
import {IHRC1215ScheduleFacade} from "@hashgraph/smart-contracts/contracts/system-contracts/hedera-schedule-service/IHRC1215ScheduleFacade.sol";

HederaScheduleService は抽象コントラクトです(HTS の HederaTokenService と同様です)。これを継承すると、0x16b への低レベル呼び出しを処理する internal ヘルパー関数を利用できます。HederaResponseCodes は推移的に利用可能です。

レスポンスコード: SUCCESS = 22(HederaResponseCodes.SUCCESS)。関数の全一覧については、references/api.md とHedera のレスポンスコードを参照してください。

重要:継承パターン

IHederaScheduleService は空のインターフェースです。 関数は IHRC755、IHRC756、IHRC1215 で定義され、HederaScheduleService の internal ヘルパーとしてラップされています。コントラクトは HederaScheduleService を継承する必要があります。

contract MyScheduler is HederaScheduleService {
    error ScheduleFailed();

    function doSchedule() external {
        (int64 rc, address scheduleAddr) = scheduleCall(target, expiry, gasLimit, 0, data);
        if (rc != HederaResponseCodes.SUCCESS) revert ScheduleFailed();
    }
}

重要:リバートしない動作(HIP-1215)

もscheduleCall、scheduleCallWithPayer、executeCallOnPayerSignature 関数はリバートしません。失敗時は (responseCode, address(0)) を返します。必ず以下のように確認してください。

error ScheduleFailed();

(int64 rc, address scheduleAddr) = scheduleCall(target, expiry, gasLimit, 0, data);
if (rc != HederaResponseCodes.SUCCESS || scheduleAddr == address(0)) {
    revert ScheduleFailed();
}

容量とスロットリング(HIP-1215)

スケジュール済み呼び出しは、1 秒あたりの上限が設定されています。SCHEDULE_EXPIRY_IS_BUSY を避けるため、スケジュールする前に hasScheduleCapacity(expirySecond, gasLimit) を使用してください。

bool capacity = hasScheduleCapacity(expirySecond, gasLimit);
if (!capacity) {
    // Retry with a later expiry or different gas limit
    // See HIP-1215 findAvailableSecond() pattern for exponential backoff + jitter
}

共通の概念

  • スケジュール済みトランザクション:署名のしきい値に達したときに実行されるよう、Hedera トランザクション(ネイティブ HTS 呼び出しまたは EVM コントラクト呼び出し)をラップします。
  • 支払者:手数料を支払う責任を負うアカウントです。scheduleCall では、呼び出し元のコントラクトが支払者になります。scheduleCallWithPayer/executeCallOnPayerSignature では、別の支払者を指定できます。
  • authorizeSchedule:呼び出し元のコントラクトのキー(ContractKey 形式 0.0.<ContractId>)でスケジュールに署名します。
  • signSchedule:EOA またはほかのキーによる protobuf エンコード済み署名を追加します。
  • 有効期限:expirySecond より前に必要な署名をすべて集められなかったスケジュールは、ネットワークから自動的に削除されます。

使用パターン

ネイティブトークンの作成をスケジュールする(HIP-756)

注: スケジュールの実行時に、支払者が十分な HBAR を保有している必要があります(トークン作成手数料の支払い用)。

import {HederaScheduleService} from "@hashgraph/smart-contracts/contracts/system-contracts/hedera-schedule-service/HederaScheduleService.sol";
import {IHederaTokenService} from "@hashgraph/smart-contracts/contracts/system-contracts/hedera-token-service/IHederaTokenService.sol";

contract ScheduledTokenCreator is HederaScheduleService {
    error FailToSchedule();

    function scheduleTokenCreate(
        IHederaTokenService.HederaToken memory token,
        int64 initialSupply,
        int32 decimals,
        address payer
    ) external returns (address scheduleAddr) {
        bytes memory callData = abi.encodeCall(
            IHederaTokenService.createFungibleToken,
            (token, initialSupply, decimals)
        );
        int64 rc;
        (rc, scheduleAddr) = scheduleNative(
            address(0x167), callData, payer
        );
        if (rc != HederaResponseCodes.SUCCESS) revert FailToSchedule();
    }
}
任意のコントラクト呼び出しをスケジュールする(HIP-1215)
import {HederaScheduleService} from "@hashgraph/smart-contracts/contracts/system-contracts/hedera-schedule-service/HederaScheduleService.sol";

contract Scheduler is HederaScheduleService {
    error FailToSchedule();
    event ScheduleCreated(address);

    function scheduleFutureCall(
        address target,
        uint256 expirySecond,
        uint256 gasLimit,
        bytes memory callData
    ) external returns (address scheduleAddr) {
        if (!hasScheduleCapacity(expirySecond, gasLimit)) revert FailToSchedule();

        int64 rc;
        (rc, scheduleAddr) = scheduleCall(
            target,
            expirySecond > 0 ? expirySecond : block.timestamp + 5,
            gasLimit,
            0,
            callData
        );
        if (rc != HederaResponseCodes.SUCCESS) {
            revert FailToSchedule();
        }
        emit ScheduleCreated(scheduleAddr);
    }
}
コントラクトでスケジュールに署名する(HIP-755)
import {HederaScheduleService} from "@hashgraph/smart-contracts/contracts/system-contracts/hedera-schedule-service/HederaScheduleService.sol";

contract ScheduleSigner is HederaScheduleService {
    error FailToAuthorize();
    error FailToSign();

    function signAsContract(address scheduleAddr) external {
        int64 rc = authorizeSchedule(scheduleAddr);
        if (rc != HederaResponseCodes.SUCCESS) revert FailToAuthorize();
    }

    function signWithSignatureMap(address scheduleAddr, bytes memory sigMap) external {
        int64 rc = signSchedule(scheduleAddr, sigMap);
        if (rc != HederaResponseCodes.SUCCESS) revert FailToSign();
    }
}
スケジュールを削除する
import {HederaScheduleService} from "@hashgraph/smart-contracts/contracts/system-contracts/hedera-schedule-service/HederaScheduleService.sol";
import {IHRC1215ScheduleFacade} from "@hashgraph/smart-contracts/contracts/system-contracts/hedera-schedule-service/IHRC1215ScheduleFacade.sol";

contract ScheduleManager is HederaScheduleService {
    error FailToDeleteSchedule();

    // Option 1: Internal helper (inheriting HederaScheduleService)
    function deleteScheduleExample(address scheduleAddr) external {
        int64 rc = deleteSchedule(scheduleAddr);
        if (rc != HederaResponseCodes.SUCCESS) {
            revert FailToDeleteSchedule();
        }
    }

    // Option 2: Redirect — call deleteSchedule() on the schedule's address
    // (works for contracts and EOAs)
    function deleteScheduleProxy(address scheduleAddr) external {
        int64 rc = IHRC1215ScheduleFacade(scheduleAddr).deleteSchedule();
        if (rc != HederaResponseCodes.SUCCESS) {
            revert FailToDeleteSchedule();
        }
    }
}

コスト

  • スケジュールトランザクションの手数料は HAPI ScheduleCreate と同額ですが、システムコントラクトの使用には20%の上乗せがあります。
  • ガス、ストレージ、コンセンサスの手数料が含まれます。有効期限切れのトランザクションには、スケジュール作成時や署名時の費用を超える追加手数料は発生しません。

参考資料

コメント