0x05 | Abort & Assert 中止和断言

abort 中止

abort 中止( abort v. 退出, 舍弃 abortion n. 堕胎)

  • 用法 : abort 0

  • 打断当前脚本的执行,打断完成后,脚本会恢复初始的状态。

  • abort 表达式停止执行当前函数并恢复当前事务的所有更改。

    • 即中止执行,恢复事务

Move 中,事务要么全有,要么全无,这意味着只有在事务成功的情况下,才会同时对全局存储进行所有更改。由于这种更改的事务性承诺,在中止之后,不需要再手动恢复更改。

如下示例,Debug::print(&temp); 没有在 abort(1) 后接着执行。

    let temp:u8 = 10;
    if (temp == 10)  abort(1);
    Debug::print(&temp);
post image

abort 的类型:

  • abort i 表达式可以有任意类型!这是因为其打破了正常控制流,因为永远不需要计算该类型的值。

在你有一个分支指令,并且这个指令会产生某些分支(不是全部)的值的时候,这种行为会非常有用。

  let z: u8 = if (x > y) {
    x
  } else if (x < y) {
    y
  } else {
    abort 101
  //^^^^^^^^ `abort 101` 的类型为 `u8`
  };

assert 断言

  • assert is a builtin macro provided by the Move compiler. It takes two arguments, a condition of type bool and a abort code of type u64.

  • assert 是 Move 编译器提供的内置宏。它有两个参数,一个bool类型的条件和一个u64类型的中止状态码

assert!(condition, code)
assert!(y != 0, 100);
  • 由于它是一个宏,因此必须使用 ! 调用它。它不是一个正常的函数,在字节码级别不存在。

  • 它将被编译器替换为 if 条件和 abort 语句。

如下的示例代码将替换为:

fun div(x: u64, y: u64): u64 {
  assert!(y != 0, 100);  ///  替换为 if (y != 0) () else abort 100;
  x / y
}

fun div(x: u64, y: u64): u64 {
  if (y != 0) () else abort 100;  /// 
  x / y
}
  • 如果用户的登录状态 loginStatus == false, 则抛出 code == 401 Unauthorized

    // let loginStatus:bool = false;
    assert!(loginStatus, 401);
    Debug::print(&loginStatus);
post image
  • 当减数大于被减数时,以状态码 100 中止。

use Std::Debug::print;

fun subtract(x: u64, y: u64) {
  assert!( !(x < y), 100);

  let z = x - y;
  print(&z);
}