Internet Computer では, キャニスタが HTTP インタフェイス経由で入ってくるメッセージを選択的に監査して, 受諾/拒絶 できます.
On the Internet Computer, a canister can selectively inspect and accept or decline ingress messages submitted through the HTTP interface:
キャニスタは, 実行前に入ってくるメッセージを監査することができます. IC がユーザから更新呼び出しを受け取ると, IC はキャニスタのメソッド
canister_inspect_message
を使って, メッセージを受け取るかどうかを決めます. キャニスタが空の (すなわち Wasm モジュールを持っていない) ときには, 入って来たメッセージは拒絶されます. キャニスタが空でなく,canister_inspect_message
を実装していなければ, 入って来たメッセージは受け入れられます.キャニスタは
canister_inspect_message
内でic0.accept_message : () → ()
を起動することでメッセージを受け入れることができます. 二度起動されるとこの関数はトラップを起こします. キャニスタがcanister_inspect_message
でトラップしたり,ic0.accept_message
を呼び出さなければ, アクセスは拒否されます.
canister_inspect_message
は HTTP の問い合わせ呼び出し, キャニスタ間呼び出し, 管理キャニスタに対する呼び出しに対しては起動され ません.
A canister can inspect ingress messages before executing them. When the IC receives an update call from a user, the IC will use the canister method canister_inspect_message to determine whether the message shall be accepted. If the canister is empty (i.e. does not have a Wasm module), then the ingress message will be rejected. If the canister is not empty and does not implement canister_inspect_message, then the ingress message will be accepted.
In
canister_inspect_message
, the canister can accept the message by invokingic0.accept_message : () → ()
. This function traps if invoked twice. If the canister traps incanister_inspect_message
or does not callic0.accept_message
, then the access is denied.The
canister_inspect_message
is not invoked for HTTP query calls, inter-canister calls or calls to the management canister.
メッセージ監査は, 望まざる無料呼び出しによってキャニスタのサイクルを枯渇させるようなサービス攻撃を軽減します.
Message inspection mitigates some denial of service attacks, designed to drain canisters of cycles by placing unsolicited free calls.
:::note
メソッド監査は「誰々 さんからコレクトコールです. お出になりますか」という, 昔風の交換手が出てくる電話のコレクト・コールの前置きのようなものだと考えてください.
You can think of method inspection as providing the "Collect call from name. Do you accept charges?" prologue of an old-fashioned, operator-assisted, collect phone call.
:::
Motoko では, アクタは inspect
という特別な system
関数を宣言することで, 入ってくるメッセージを監査して, そのメッセージを受けれるかどうかを選択することができます. 与えられたメッセージ属性のレコードに対して, この関数は Bool
値 true
か false
を返すことで, そのメッセージを許諾するか, 拒絶するかを示します. この関数は, 内向きのメッセージ毎に (システムによって) 起動されます. 問い合わせと同じように, その起動による副作用はすべて棄てられ, 一時的なものになります. 何らかの失敗によってトラップした呼び出しは, false
を返すのと同じ結果 (メッセージ拒絶) になります.
In Motoko, actors can elect to inspect and accept or decline ingress messages by declaring a particular system
function called inspect
. Given a record of message attributes, this function produces a Bool
that indicates whether to accept or decline the message by returning true
or false
. The function is invoked (by the system) on each ingress message. Similar to a query, any side-effects of an invocation are discarded and transient. A call that traps due to some fault has the same result as returning false
(message declination).
他のシステム関数とは異なり, この関数は決まった引数型を持ちますが, inspect
の引数の型はそのアクタを囲むインタフェイスによって変わってきます.
Unlike other system functions, that have a fixed argument type, the argument type of inspect
depends on the interface of the enclosing actor. In particular, the formal argument of inspect
is a record of fields of the following types:
caller : Principal
: そのメッセージの呼び出し元のプリンシパル (匿名の場合もある)
arg : Blob
: メッセージ引数の生なバイナリ表現
msg: <variant>
: 復号
関数 (たち) のヴァリアント (<variant> == {…; #<id>: () → T; …}
) で, アクタの共有関数 (<id>
) 毎に一つのヴァリアントがある. ヴァリアントのタグで呼ばれるべき関数を同定する. ヴァリアントの引数は関数で, 適用するとその呼び出しの (復号された) 引数の値 (型 T
) を返す
caller : Principal
: the principal, possibly anonymous, of the caller of the message;
arg : Blob
: the raw, binary content of the message argument;
msg : <variant>
: a variant of decoding functions, where <variant> == {…; #<id>: () → T; …}
contains one variant per shared function, <id>
, of the actor. The variant’s tag identifies the function to be called; The variant’s argument is a function that, when applied, returns the (decoded) argument of the call as a value of type T
.
#<id>
でタグ付けされたヴァリアントを用いて, 復号関数は型 T
を返すことができますが, この型は共有関数 <id>
の引数の型 (これも T
) に応じて変わります.
Using a variant, tagged with #<id>
, allows the return type, T
, of the decoding function to vary with the argument type (also T
) of the shared function <id>
.
このヴァリアントの引数は関数なので, (それが適切であれば) メッセージ復号の手間を避けることもできます.
The variant’s argument is a function so that one can avoid the expense of message decoding (when appropriate).
副型付けを活用し, 仮引数で必要ではないレコードを省いたり, 特定の共有関数の引数を選んで無視したりして, 関数を監査せずにその関数の名前を処理しても構いません.
Exploiting subtyping, the formal argument can omit record fields it does not require, or selectively ignore the arguments of particular shared functions, for example, in order to simply dispatch on the name of a function without inspecting its actual argument.
:::note
紛らわしいですが, 共有問い合わせ
関数でも, 認証された応答を得るために (敢えて) 通常の HTTP 経由で呼び出しすることもできます. ヴァリアント型に 共有問い合わせ
間も含まれているのはそのためです.
Confusingly, a shared query
function can be called using a regular HTTP call to obtain a certified response: this is why the variant type also includes shared query
functions.
:::
:::danger
inspect
システム・フィールドを宣言し損なっていると, すべての内向きのメッセージを受け取ることになってしまいます.
An actor that fails to declare system field inspect
will simply accept all ingress messages.
:::
:::danger
システム関数 inspect
を最終的なアクセス制御に用いては いけません. なぜならば inspect
は完全な同意ではなく一つのレプリカで実行され, その結果は悪意のある境界ノードによってなりすまされる可能性があるからです. 信頼のおけるアクセス制御の検査は inspect
によって保護された 共有
関数内部でのみ実行可能です.
System function inspect
should not be used for definitive access control. This is because inspect
is executed by a single replica, without full consensus, and its result could be spoofed by a malicious boundary node. Reliable access control checks can only be performed within the shared
functions guarded by inspect
.