スマートコントラクトの権限チェック require_auth で何をやっているかを調べてみました
結論
require_auth(user) は、user アカウントがアクションの認証情報にあるかどうかを確認して、存在していない場合は、アクションを以上終了させるようにしています。
詳細
まず、アクションの定義は下記になっています。
struct action {
scope_name scope; // the contract defining the primary code to execute for code/type
action_name name; // the action to be taken
permission_level[] authorization; // the accounts and permission levels provided
bytes data; // opaque data processed by code
};
コメントどおりですが、パラメータの意味は下記になります
| パラメータ | 意味 |
|---|---|
| scope | 実行するアクションのターゲットになっているスマートコントラクトのアカウント |
| name | 実行したいアクション名 |
| authorization | アクションの呼び出しに認可されている権限レベル |
| data | 実行するアクションに必要なパラメータ |
たとえば、cleos push action hello hi '["bob"]' -p bob@active でアクションを送信する時は、
| パラメータ | 値 |
|---|---|
| scope | hello |
| name | hi |
| authorization | [{ "account": "bob", "permission":"active" }] |
| data | ["bob"] |
次は、require_auth(user) が呼び出された時は、authorization に user の認可情報があるかどうかをチェックします。
認可情報がない場合は、アクションを失敗させ、異常終了にします。
上記例ですと、
-
require_auth('bob')でチェックする場合は、bobの認可情報があるので、正常に処理されます。 -
require_auth('alice')でチェックする場合は、aliceの認可情報がない為、アクションが失敗になります。
横展開
単にチェックするだけ、異常終了したくない場合は、has_auth 関数があります。
bool has_auth( account_name name );
チェックする仕組みは一緒ですが、認可情報に該当するアカウントが存在してない場合は、失敗せずに、戻り値が false になるだけです。
また、上記はアカウント名だけでチェックしていますが、もっと厳密的に、権限名もチェックしたい場合は、下記の require_auth2 関数があります。
void require_auth2( account_name name, permission_name permission );
チェックしたいアカウント名と権限名を厳密的にチェックされます。
require_auth と同じく、チェックに引っかかった場合処理失敗になります。
厳密のイコールなので、仮に、チェック対象権限より上位権限で実行しても失敗になります
まとめ
スマートコントラクトの開発には、セキュリティがすごく重要なので、慎重に権限をチェックしましょう。