トランザクション ポリシーの評価

マルチパーティ コンピューティングは、トランザクションに署名する前に、インスタンスのトランザクション ポリシーに照らしてトランザクションを評価します。このドキュメントでは、評価されるポリシー、ポリシーのライフサイクル、ポリシーで確認できる内容、トランザクションが拒否される理由について説明します。

トランザクションの評価方法

トランザクション ポリシーは、1 つの Cedar permit ステートメントまたは forbid ステートメントです。署名者が CreateTransaction を呼び出すと、インスタンスは Transaction.schema のパーサーを使用して Transaction.payload の未署名のトランザクションをデコードし、鍵共有が使用される前に、トランザクションに対して適用されたすべてのポリシーを評価します。ポリシーは、状態が ACTIVE または PENDING_DISABLED の場合に適用されます。詳細については、ポリシーのライフサイクルをご覧ください。

この決定は、次の 3 つのルールに従います。

  1. デフォルトで拒否。トランザクションは、少なくとも 1 つの permit ポリシーが一致する場合にのみ許可されます。適用されたポリシーがない場合、すべてのトランザクションが拒否されます。
  2. 勝利を禁止する。forbid ポリシーが一致すると、permit ポリシーも一致する場合でも、トランザクションは拒否されます。
  3. 評価に失敗したポリシーは一致しません。たとえば、トランザクションにないオプションのコンテキスト属性を読み取るポリシーは評価に失敗します。インスタンスはエラーを記録し、そのポリシーをスキップして、残りの適用されたポリシーで決定します。これは forbid ポリシーにも適用されるため、属性が欠落しても失敗しない forbid ポリシーを作成してください。例については、シナリオ 8 とシナリオ 9 をご覧ください。

複数の転送を含むトランザクション(複数の転送指示を含む Solana トランザクションなど)は、転送ごとに 1 回評価されます。トランザクションは、すべての転送が許可されている場合にのみ許可されます。転送が拒否された場合やデコードできない場合は、トランザクション全体が拒否されます。

各評価(許可または拒否)により、Transaction.policyEvaluationRecord のトランザクションで返される評価レコードが生成されます。

この決定により、インスタンスが他の署名者を待たずにトランザクションに署名できるかどうかが制御されます。

  • PERMIT: CreateTransaction リクエストに、KeyRing の鍵ポリシーを満たすのに十分な署名者の認可がすでに含まれている場合、トランザクションはすぐに SIGNING に移行します。それ以外の場合は PENDING_AUTHORIZATION で作成され、追加の署名者を待ちます。
  • DENY: インスタンスはトランザクションに自動的に署名しません。トランザクションは PENDING_AUTHORIZATION で作成され、policyEvaluationRecord.decision は DENY に設定されます。署名者は評価レコードを確認し、トランザクションを拒否(DENY を指定して RecordSignerDecision)するか、承認(AUTHORIZE)できます。トランザクションは、鍵ポリシーを満たすのに十分な署名者が承認した場合にのみ署名されます。

トランザクション ポリシーは、自動署名のガードレールであり、署名者のブロックではありません。署名者は、ポリシーで拒否されたトランザクションを承認できます。元の PolicyEvaluationRecord は、監査のためにトランザクションに接続されたままになります。

ポリシーのライフサイクル

トランザクション ポリシーは変更できません。TransactionPolicy には更新メソッドがなく、rule は不変です。ルールを変更するには、DisableTransactionPolicy でポリシーを無効にし、CreateTransactionPolicy で新しいポリシーを作成します。

ポリシーを有効または無効にするには、ポリシー作成者(User.roleStatuses でアクティブな POLICY_AUTHOR ロールを持つユーザー)の定足数による承認が必要です。各ポリシー作成者は、ポリシー(CreateTransactionPolicy の場合はインスタンス)、アクション(ACTIVATE または DISABLE)、rule.cedarDocument を指定する TransactionPolicySigningPayload に署名します。変更を提案するリクエストは、最初の承認としてカウントされます。他のポリシー作成者は ApproveTransactionPolicy で承認します。必要な承認数は activationInfo.requiredApprovals と deactivationInfo.requiredApprovals にあります。インスタンスに必要な承認が 1 つだけの場合、変更はすぐに有効になります。

次の表に、各ポリシーの状態と、その状態のポリシーが適用されるかどうかを示します。

状態 意味 適用済み
PENDING_ACTIVE ポリシーが提案され、ポリシー作成者の承認を待っています。 いいえ
ACTIVE ポリシーには activationInfo.requiredApprovals 件の承認があります。 はい
PENDING_DISABLED ポリシー作成者がポリシーの無効化をリクエストし、リクエストが承認待ちになっています。 はい、リクエストの承認数が deactivationInfo.requiredApprovals 件に達するまで
DISABLED ポリシーが無効になっているか、有効になる前に取り消されました。無効になったポリシーは監査用に保持されます。 いいえ

ポリシーは、次の順序で状態が変化します。

  • PENDING_ACTIVE から ACTIVE: 有効化に十分な承認があります。
  • PENDING_ACTIVE から DISABLED: ポリシー作成者が、ポリシーが有効になる前に DisableTransactionPolicy を使用してポリシーを取り消します。
  • ACTIVE~PENDING_DISABLED: ポリシー作成者が DisableTransactionPolicy を呼び出します。
  • PENDING_DISABLED から DISABLED: 無効化リクエストに十分な承認があります。

ポリシーが各保留状態になるのは、最大で 1 回です。無効にしたポリシーを再度有効にすることはできません。代わりに新しいポリシーを作成してください。

これらのメソッドを呼び出すことができるユーザーについては、ユーザーロールをご覧ください。

ポリシーセットのバージョン

ポリシーセットは、ある時点で適用されるポリシーのセット(ACTIVE または PENDING_DISABLED)です。有効化または無効化が完了するたびに、インスタンスはその移行にインスタンスのカウンタの次の番号を割り当て、activationInfo.transitionSequence または deactivationInfo.transitionSequence に記録します。この番号は、移行によって生成されたポリシーセットのバージョンです。

次の表は、一連のイベントでポリシーセットのバージョンがどのように変化するかを示しています。

イベント 移行シーケンス 適用されているポリシー
ポリシー A が有効になっている。 A: activationInfo.transitionSequence = 1 A
ポリシー B が有効になります。 B: activationInfo.transitionSequence = 2 A、B
ポリシー C が提案され(PENDING_ACTIVE)、その後取り下げられます。 なし A、B
ポリシー A の無効化リクエストが承認されます。 A: deactivationInfo.transitionSequence = 3 B

PENDING_ACTIVE ポリシーを取り消しても、適用されるポリシーのセットは変更されないため、移行シーケンスは取得されず、ポリシーセットのバージョンも変更されません。移行が承認待ちの間、transitionSequence は設定されません。

各評価では、トランザクションの createTime の時点のポリシー、KeyList、鍵が読み取られ、その時点で完了した最も高い移行シーケンスが policyEvaluationRecord.policySetVersion に記録されます。2 つの評価に同じポリシーセット バージョンがある場合、同じポリシーが使用されています。

Cedar リクエスト

Cedar リクエストには、プリンシパル、アクション、リソース、コンテキストがあります。次に例を示します。

permit (
  principal == User::"alice@example.com",
  action == Action::"buy_transaction",
  resource == Resource::"transaction_management"
)
when {
  context.principal_keyring == "institutional-treasury" &&
  context has fiat_amount && context.fiat_amount <= 10000
};

ユーザーが Cedar プリンシパルにマッピングされる仕組み

プリンシパルはトランザクションの開始者です。principal が CreateTransaction の呼び出し元の認証済み ID と一致するユーザーです。そのユーザーには、有効な SIGNER ロールが必要です。Cedar では、プリンシパルは User エンティティであり、その ID はユーザーの principal フィールド(例: User::"alice@example.com")です。

インスタンスはエンティティ データを Cedar に渡しません。User エンティティには属性も親もありません。

  • principal == User::"alice@example.com" は、Alice が開始したトランザクションと一致します。
  • principal in Team::"treasury" が一致することはありません。鍵で署名できるユーザーを制限するには、KeyRing の鍵ポリシーを使用します。ルールのスコープを鍵のグループに設定するには、context.principal_keyring を確認します。
  • principal の属性(principal.team など)を読み取るルールは評価に失敗します。

ユーザーの principal は変更できないため、プリンシパルを指定するルールは同じ ID を参照し続けます。

アクションとリソース

  • action: CreateTransaction リクエストの Transaction.action の値。Cedar Action エンティティとしてフォーマットされます。CreateTransaction は、次のアクションを受け入れます。

    アクション 用途
    Action::"buy_transaction" アセットを取得するトランザクション。
    Action::"sell_transaction" 資産を処分する取引。
    Action::"internal_transfer_transaction" 支払い、鍵間のスイープなど、アセットの移動。

    イニシエーターがアクションを選択します。マルチパーティ コンピューティングはペイロードからアクションを推測しません。ルールは、1 つのアクション(action == Action::"buy_transaction")、アクションのリスト(action in [Action::"buy_transaction", Action::"sell_transaction"])に一致させることができます。また、action を制約なしのままにして、すべてのアクションに一致させることもできます。

  • resource: トランザクション評価の場合は常に Resource::"transaction_management"。ルールは resource == Resource::"transaction_management" をチェックすることも、resource を制約なしのままにすることもできます。

コンテキスト属性

コンテキストには、ポリシーがチェックする属性が保持されます。これらは次の 2 つの場所から取得されます。

  • トランザクション ペイロードと署名鍵。インスタンスは Transaction.payload をデコードし、署名鍵とその KeyRing の ID を追加します。これらの属性は、principal_keyring、principal_key、blockchain、schema、secondary_key、amount_token_scaled、token_symbol、contract_address、chain_id、max_fee_atomic、payload、time_stamp です。完全な表と各ブロックチェーンの動作については、書き込みトランザクション ポリシーのルールをご覧ください。
  • トランザクションの metadata フィールド。これは、イニシエーターが CreateTransaction で設定します。

次の表に、メタデータ属性を示します。

Transaction.metadata フィールド Cedar 属性 Cedar タイプ 値
fiatAmount context.fiat_amount Long 取引の金額(米ドル、google.type.Money)。currencyCode は USD、units は 0 以上、nanos は 0 にする必要があります。
validity context.validity Long トランザクションの有効期間(google.protobuf.Duration)(秒単位)。0 秒より大きい値を指定してください。秒の小数部分は指定できません。
principalValue1 context.principal_value1 String 定義する値(最大 256 文字)。トレーディング デスクやコストセンターなど。
principalValue2 context.principal_value2 String 定義する値(最大 256 文字)。たとえば、内部チケットや相手方 ID などです。

メタデータには次のルールが適用されます。

  • 未設定のフィールドはコンテキストに含まれません。トランザクションに fiatAmount がない場合、context.fiat_amount は存在せず、それを読み取るポリシーの評価は失敗します。context has fiat_amount && context.fiat_amount <= 10000 のように、まず has で属性を確認します。
  • メタデータが無効な場合、リクエストは失敗します。フィールドが上記の表のルールに違反している場合(EUR の fiatAmount、ゼロ以外の nanos、0 秒の validity、256 文字を超える principalValue1 など)、CreateTransaction は INVALID_ARGUMENT で失敗し、ポリシーは評価されません。
  • インスタンスは、トランザクションに対してメタデータをチェックしません。fiatAmount は、開始者が取引の価値として指定したものです。他の署名者は、承認する前に Transaction.metadata と policyEvaluationRecord.evaluationContext のメタデータを確認します。メタデータとは別にオンチェーンの金額を制限するには、context.amount_token_scaled と context.contract_address を確認します。
  • トランザクションの作成後にメタデータを変更することはできません。

キーリング

KeyRing は鍵をグループ化します。すべてのトランザクションのコンテキストには principal_keyring と principal_key があります。そのため、ルールは KeyRing 内のすべての鍵(後で作成された鍵を含む)に適用でき、KeyRing は KeyList のエントリにできます。詳細とルールの例については、KeyRings をご覧ください。

KeyLists

KeyList は、ポリシーが参照できるブロックチェーン アドレスの名前付きリストです。たとえば、宛先の許可リストなどです。各エントリは次のいずれかになります。

  • 手動エントリ(manualEntry): インスタンスが管理しないアドレス。source フィールドと reason フィールドは省略可能です。
  • インスタンス内のキー(key): キーのアドレスと一致します。
  • インスタンス内の KeyRing(keyRing): エントリの追加後に作成された鍵を含む、KeyRing 内のすべてのアクティブな鍵のアドレスと一致します。

KeyList は、ポリシーが承認された後に変更されることがあります。AddKeyListEntries または RemoveKeyListEntries を使用してエントリを追加または削除すると、KeyList を参照するすべてのポリシーは、ポリシー作成者の新しい承認なしで、次の評価から新しいエントリを使用します。PENDING_ACTIVE、ACTIVE、PENDING_DISABLED ポリシーが KeyList を参照している間は、DeleteKeyList で KeyList を削除できません。

Cedar コンテキストの KeyList

評価時に、インスタンスは各 KeyList を String ブロックチェーン アドレスのフラットな Set に展開します。これには、手動エントリと、すべての鍵と KeyRing エントリから派生したアドレスが含まれます。各セットは context.key_lists["<var>KEY_LIST_ID</var>"] として Cedar に渡されます。ここで、KEY_LIST_ID は KeyList のリソース名の {keyList} ID です(例: projects/my-project/locations/us-central1/instances/my-instance/keyLists/trusted-destinations の trusted-destinations)。

ルールは、Cedar contains 演算子を使用して、デコードされた宛先アドレス context.secondary_key に対してメンバーシップをテストします。たとえば、trusted-destinations KeyList のアドレスへの転送のみを許可するには、次のようにします。

// Assuming you created a KeyList with ID "trusted-destinations":
permit (principal, action, resource)
when { context.key_lists["trusted-destinations"].contains(context.secondary_key) };

blocked-addresses KeyList のアドレスへの転送を拒否するには:

// Assuming you created a KeyList with ID "blocked-addresses":
forbid (principal, action, resource)
when { context.key_lists["blocked-addresses"].contains(context.secondary_key) };

次の点にご注意ください。

  • KeyList ID には、ドット構文ではなく、ブラケット構文を使用します。Cedar のドット構文(context.key_lists.trusted-destinations)は、ID にハイフンが含まれている場合(Cedar は減算として読み取ります)、またはサーバー生成の UUID のように数字で始まる場合、解析に失敗します。ブラケット構文 context.key_lists["<var>KEY_LIST_ID</var>"] は、すべての ID で機能します。
  • key_lists は常に存在し、ルールは KeyList を直接読み取ることができます。CreateTransactionPolicy は、ルールが参照するすべての KeyList が存在することを確認します。DeleteKeyList は、ポリシーが参照している KeyList の削除を拒否します。context.key_lists has "<var>KEY_LIST_ID</var>" は、ルールがまだ存在しない KeyList を参照している場合にのみ使用します。
  • アドレスは文字列として比較されます。secondary_key は、トランザクション ポリシー ルールを記述するでブロックチェーンごとに記述されている形式を使用します。たとえば、Ethereum の場合は大文字と小文字が混在する EIP-55 チェックサム形式です。同じ形式で手動エントリを追加します。
  • Solana トークン転送の secondary_key は、オーナーのウォレットではなく、宛先トークン アカウントです。ウォレットを許可するには、許可するミントごとにトークン アカウントを追加します。

各評価では、トランザクションの createTime(ポリシーと同じ時刻)の時点で KeyList メンバーシップが解決され、結果が policyEvaluationRecord.keyListMemberships に記録されます。KeyList、テストされたアドレス、メンバーかどうか、一致したエントリが記録されます。

KeyList はポリシーで許可される内容を変更するため、変更できるユーザーを制限します。KeyList メソッドには roles/mpc.admin が必要です。詳細については、IAM 権限をご覧ください。

不承認の理由

policyEvaluationRecord.decision が DENY の場合、policyEvaluationRecord.denyReason に理由が示されます。次の表に、各拒否理由を示します。

拒否の理由 日時 ポリシーの決定
FORBID_RULE_MATCHED 適用された forbid ポリシーが 1 つ以上一致しました。 一致した forbid ポリシー。
NO_PERMIT_RULE_MATCHED ペイロードがデコードされ、一致する forbid ポリシーがなく、評価に失敗したポリシーがなく、一致する permit ポリシーがありません。 なし
EVALUATION_ERROR permit ポリシーまたは forbid ポリシーが一致せず、少なくとも 1 つのポリシーの評価に失敗しました。たとえば、コンテキストにないオプション属性を読み取ったためです。 なし。evaluationErrors にエラーが一覧表示されます。
UNRECOGNIZED_PAYLOAD インスタンスが Transaction.payload をデコードできなかったか、コンテキストに投影できませんでした。たとえば、バイト形式が正しくない、サポートされていない命令またはコントラクト オペレーション、複数の受信者がいるビットコイン トランザクションなどが原因です。ポリシーは評価されません。 なし。evaluationErrors には、パーサーエラーが一覧表示されます。

理由は次の順序で決定されます。

  1. ペイロードをデコードできない場合や、コンテキストに投影できない場合、決定は UNRECOGNIZED_PAYLOAD を含む DENY になります。
  2. それ以外の場合は、適用されているすべてのポリシーが評価されます。forbid ポリシーが一致する場合、permit ポリシーも一致するか、他のポリシーの評価に失敗した場合でも、判定は FORBID_RULE_MATCHED の DENY になります。
  3. それ以外の場合、少なくとも 1 つの permit ポリシーが一致すると、判定は PERMIT になります。他のポリシーのエラーは引き続き evaluationErrors に記録されます。
  4. それ以外の場合、評価に失敗したポリシーがあれば、決定は EVALUATION_ERROR を含む DENY になります。すべてのポリシーが一致せずに評価された場合は、NO_PERMIT_RULE_MATCHED になります。

判定が PERMIT の場合でもエラーが記録されるため、常に失敗して一致しないポリシーの評価レコードを確認してください。

シナリオ

シナリオ 1 ~ 9 では、アリス(User::"alice@example.com")が、action を Action::"internal_transfer_transaction" に設定した有効な Ethereum 転送と、次のメタデータを作成します(シナリオで特に指定がない場合)。

"metadata": {
  "fiatAmount": {"currencyCode": "USD", "units": "5000"},
  "principalValue1": "treasury-desk"
}

トランザクションに validity と principalValue2 がありません。

次の表に、各シナリオの概要を示します。

シナリオ 違反措置の適用プロセスに関するポリシーまたはペイロード 決定 拒否の理由
1 なし DENY NO_PERMIT_RULE_MATCHED
2 一致する permit が 1 つ PERMIT
3 一致しない permit が 1 つあります DENY NO_PERMIT_RULE_MATCHED
4 2 つの permit、1 つが一致 PERMIT
5 permit と forbid の両方が一致する DENY FORBID_RULE_MATCHED
6 欠落している属性を読み取る permit DENY EVALUATION_ERROR
7 同じ permit、has DENY NO_PERMIT_RULE_MATCHED
8 欠落している属性を読み取る forbid と、一致する permit PERMIT
9 属性を必要とする forbid DENY FORBID_RULE_MATCHED
10 デコードできないペイロード DENY UNRECOGNIZED_PAYLOAD

シナリオ 1: 適用されているポリシーがない

インスタンスに ACTIVE ポリシーまたは PENDING_DISABLED ポリシーがない。

決定事項: DENY、NO_PERMIT_RULE_MATCHED。一致する permit ポリシーがない場合、すべてのトランザクションが拒否されます。新しいインスタンスでは、ポリシー作成者が permit ポリシーを有効にするまで、トランザクションは自動的に署名されません。署名者は各トランザクションを承認する必要があります。

シナリオ 2: 一致する許可証が 1 つある

permit (principal, action, resource)
when { context has fiat_amount && context.fiat_amount <= 10000 };

決定事項: PERMIT。金額 5,000 は 10,000 以下です。determiningPolicyIds にこのポリシーが記載されています。

シナリオ 3: 一致しない許可証が 1 つある

permit (principal, action, resource)
when { context has fiat_amount && context.fiat_amount <= 1000 };

決定事項: DENY、NO_PERMIT_RULE_MATCHED。金額 5,000 は 1,000 を超えており、この取引を許可するポリシーは他にありません。

シナリオ 4: 2 つの許可証、1 つが一致

ポリシー A:

permit (principal, action, resource)
when { context has fiat_amount && context.fiat_amount <= 1000 };

ポリシー B:

permit (
  principal == User::"alice@example.com",
  action == Action::"internal_transfer_transaction",
  resource == Resource::"transaction_management"
)
when {
  context has fiat_amount && context.fiat_amount <= 25000 &&
  context has principal_value1 && context.principal_value1 == "treasury-desk"
};

決定事項: PERMIT。ポリシー A は一致しませんが、ポリシー B は一致します。一致する permit ポリシーが 1 つあれば十分です。determiningPolicyIds にはポリシー B のみが一覧表示されます。

シナリオ 5: 禁止が許可をオーバーライドする

ポリシー A:

permit (principal, action, resource)
when { context has fiat_amount && context.fiat_amount <= 10000 };

ポリシー B:

forbid (principal, action, resource)
when { context has principal_value1 && context.principal_value1 == "treasury-desk" };

決定事項: DENY、FORBID_RULE_MATCHED。両方のポリシーが一致し、forbid が優先されます。determiningPolicyIds にはポリシー B のみが一覧表示されます。

シナリオ 6: 許可証に欠落している属性が読み取られる

permit (principal, action, resource)
when { context.validity <= 3600 };

決定事項: DENY、EVALUATION_ERROR。トランザクションに validity がないため、context.validity は存在せず、ポリシーの評価は失敗します。このトランザクションを許可するポリシーは他にありません。evaluationErrors にエラーが一覧表示されます。

シナリオ 7: 同じ許可証に

permit (principal, action, resource)
when { context has validity && context.validity <= 3600 };

決定事項: DENY、NO_PERMIT_RULE_MATCHED。context has validity が false であるため、ポリシーは失敗ではなく false と評価されます。トランザクションは引き続き拒否されますが、ポリシーが評価され、一致しなかったことが理由として表示されます。

シナリオ 8: 拒否が欠落している属性を読み取る

ポリシー A:

permit (principal, action, resource)
when { context has fiat_amount && context.fiat_amount <= 10000 };

ポリシー B:

forbid (principal, action, resource)
when { context.principal_value2 == "sanctioned-counterparty" };

決定事項: PERMIT。トランザクションに principalValue2 がないため、ポリシー B の評価は失敗し、スキップされます。ポリシー A が一致します。determiningPolicyIds にはポリシー A が一覧表示され、evaluationErrors にはポリシー B のエラーが一覧表示されます。

シナリオ 9: 属性を必要とする禁止

ポリシー A は、シナリオ 8 の permit ポリシーです。ポリシー B:

forbid (principal, action, resource)
unless { context has fiat_amount };

決定: このようなシナリオのトランザクションでは PERMIT。fiatAmount があります。Alice が fiatAmount を省略した場合、決定は DENY、FORBID_RULE_MATCHED です。context has fiat_amount は false であるため、forbid ポリシーが一致します。このポリシーは has のみを使用するため、評価に失敗することはありません。

必須属性とその値のチェックを 1 つの forbid ポリシーにまとめるには、まず属性をチェックします。

forbid (principal, action, resource)
unless { context has fiat_amount && context.fiat_amount <= 10000 };

シナリオ 10: デコードできないペイロード

アリスは、Transaction.schema のパーサーでデコードできない payload を含むトランザクションを作成します。たとえば、切り捨てられた RLP バイト、複数の受信者を含むビットコイン PSBT、サポートされていない命令を含む Solana トランザクションなどです。

決定事項: DENY、UNRECOGNIZED_PAYLOAD。ポリシーは評価されません。evaluationErrors にはパーサーエラーが一覧表示され、determiningPolicyIds は空です。

評価記録

各評価では、変更できない PolicyEvaluationRecord が生成されます。Transaction.policyEvaluationRecord で返され、次のフィールドがあります。

フィールド 値
decision PERMIT または DENY
denyReason 拒否理由のいずれか。判定が PERMIT の場合は設定されません。
determiningPolicyIds PERMIT で、一致した permit ポリシーの ID。FORBID_RULE_MATCHED で、一致した forbid ポリシーの ID。それ以外の場合は空です。
evaluationErrors 評価に失敗したポリシーのエラー、または denyReason が UNRECOGNIZED_PAYLOAD の場合のパーサーエラー。
evaluationContext ポリシーが評価された Cedar コンテキスト(google.protobuf.Struct)。64 ビット整数は、精度を維持するために 10 進数の文字列として保存されます。
policySetVersion 評価で使用されたポリシーセットのバージョン。
keyListMemberships 評価中に解決された KeyList メンバーシップ。
intentDigest 評価されたトランザクション ペイロードの小文字の 16 進数エンコード ダイジェスト。ハッシュはペイロードのスキーマによって異なります。ETHEREUM_TX_V2 の場合はトランザクションの Keccak-256、BITCOIN_TX_V2 の場合は最初の入力の sighash、SOLANA_TX_V1 の場合は未署名メッセージの SHA-256、EIP712_TYPED_DATA_V1 の場合は EIP-712 署名ダイジェスト keccak256(0x1901 ++ domainSeparator ++ hashStruct(message)) です。
evaluationTime 評価が実行された日時。