トランザクションは成功するか失敗するかのどちらかです。実行が成功すると、オブジェクトやオンチェーンデータに加えられた変更がすべて適用され、トランザクションがブロックチェーンにコミットされます。一方、トランザクションが中断された場合、変更は適用されません。abortキーワードは、トランザクションを中断し、それまでに行われた変更を元に戻すために使用されます。

Moveには catch メカニズムがないことに注意することが重要です。トランザクションが中断されると、それまでに行われた変更は元に戻され、トランザクションは失敗したとみなされます。

Abort

abortキーワードは、トランザクションの実行を中断するために使用されます。これは中断コードと組み合わせて使用され、中断コードはトランザクションの呼び出し元に返されます。中断コードはu64型の整数です。

let user_has_access = true;

// user_has_accessがfalseの場合、事前定義された定数で中断する
if (!user_has_access) {
    abort 0
};

// 括弧を使用する代替構文もある
if (user_has_access) {
   abort(1)
};

上記のコードは、もちろん中断コード1で中断します。

assert!

assert!マクロは、条件を確認するために使用できる組み込みマクロです。条件が偽の場合、トランザクションは指定された中断コードで中断します。assert!マクロは、条件が満たされない場合にトランザクションを中断する便利な方法です。このマクロは、if式とabortを使用して書かれるコードを短縮します。code引数は必須で、u64値である必要があります。

// user_has_accessがfalseの場合、中断コード0で中断する
assert!(user_has_access, 0);

// 以下のように展開される:
if (!user_has_access) {
    abort 0
};

エラー定数

エラーコードをより説明的にするために、エラー定数を定義することがよい習慣です。エラー定数はconst宣言として定義され、通常Eの後にキャメルケースの名前が続きます。エラー定数は他の定数と何ら変わりはなく、特別な扱いはありませんが、コードの可読性を高め、中断シナリオを理解しやすくするために使用されます。

/// ユーザーがアクセス権を持っていない場合のエラーコード。
const ENoAccess: u64 = 0;
/// 存在しないフィールドにアクセスしようとしている。
const ENoField: u64 = 1;

/// レコードを更新する。
public fun update_record(/* ... , */ user_has_access: bool, field_exists: bool) {
    // assertsがより読みやすくなった
    assert!(user_has_access, ENoAccess);
    assert!(field_exists, ENoField);

    /* ... */
}

参考文献

The Move Book へ戻る