Skip to content

数学

各种数学辅助函数。

min

solidity
fun min(x: Int, y: Int): Int;

计算并返回两个 Intxy最小值

使用示例:

solidity
min(1, 2);        // 1
min(2, 2);        // 2
min(007, 3);      // 3
min(0x45, 3_0_0); // 69, nice
//  ↑     ↑
//  69    300

max

solidity
fun max(x: Int, y: Int): Int;

计算并返回两个 Intxy最大值

使用示例:

solidity
max(1, 2);        // 2
max(2, 2);        // 2
max(007, 3);      // 7
max(0x45, 3_0_0); // 300
//  ↑     ↑
//  69    300

abs

solidity
fun abs(x: Int): Int

计算并返回 Intx绝对值

使用示例:

solidity
abs(42);        // 42
abs(-42);       // 42
abs(-(-(-42))); // 42

log

solidity
fun log(num: Int, base: Int): Int;

计算并返回 num $> 0$ 以 base $≥ 1$ 为底的对数。结果向下取整。传递非正的 num 值或小于 $1$ 的 base 会抛出错误,错误代码为 exit code 5整数超出预期范围

使用示例:

solidity
log(1000, 10); // 3, 因为 10^3 是 1000
//  ↑     ↑             ↑       ↑
//  num   base          base    num

log(1001, 10);  // 3
log(999, 10);   // 2
try {
  log(-1000, 10); // 抛出错误代码 5 因为 num 为非正数
}
log(1024, 2);   // 10
try {
  log(1024, -2);  // 抛出错误代码 5 因为 base 小于 1
}

注意,如果你只需要获取以 $2$ 为底的对数,使用 log2() 函数,因为它更节省 gas。

log2

solidity
fun log2(num: Int): Int;

类似于 log(),但将 base 设置为 $2$。

使用示例:

solidity
log2(1024); // 10, 因为 2^10 是 1024
//   ↑                ↑       ↑
//   num              base₂   num

为了减少 gas 使用,当你只需要获取以 $2$ 为底的对数时,优先使用此函数而不是调用 log()

pow

solidity
fun pow(base: Int, exp: Int): Int;

计算并返回两个数的base 和指数(或 powerexp。指数 exp 必须为非负,否则会抛出错误,错误代码为 exit code 5整数超出预期范围

注意,此函数在运行时和编译时均可工作。

使用示例:

solidity
contract Example {
    // 持久化状态变量
    p23: Int = pow(2, 3); // 将 2 提升到 3 次方,结果是 8
    one: Int = pow(5, 0); // 将 5 提升到 0 次方,总是产生 1
                          // 在编译时工作!

    // 接收内部消息,接受消息 ExtMsg
    receive() {
        pow(self.p23, self.one + 1); // 64, 在运行时也工作!
        pow(0, -1);                  // 错误!错误代码 5:整数超出预期范围
    }
}

注意,如果你只需要获取 $2$ 的幂,使用 pow2() 函数,因为它更节省 gas。

仅在编译时工作的函数列表:API Comptime

pow2

solidity
fun pow2(exp: Int): Int;

类似于 pow(),但将 base 设置为 $2$。在运行时和编译时均可工作。

使用示例:

solidity
contract Example {
    // 持久化状态变量
    p23: Int = pow2(3); // 将 2 提升到 3 次方,结果是 8
    one: Int = pow2(0); // 将 2 提升到 0 次方,总是产生 1
                        // 在编译时工作!

    // 接收内部消息,接受消息 ExtMsg
    receive() {
        pow2(self.one + 1); // 4, 在运行时也工作!
        pow2(-1);           // 错误!错误代码 5:整数超出预期范围
    }
}

为了减少 gas 使用,当你只需要获取 $2$ 的幂时,优先使用此函数而不是调用 pow()

仅在编译时工作的函数列表:API Comptime

checkSignature

solidity
fun checkSignature(hash: Int, signature: Slice, public_key: Int): Bool;

使用 public_key 检查 $256$-bit 无符号 Int hashEd25519 signature。签名必须包含至少 $512$ 位数据,但只使用前 $512$ 位。

如果签名有效,返回 true,否则返回 false

使用示例:

solidity
message ExtMsg {
    signature: Slice;
    data: Cell;
}

contract Showcase {
    // 持久化状态变量
    pub: Int as uint256; // 作为 256-bit 无符号 Int 的公钥

    // 初始化函数 init(),初始化所有变量
    init(pub: Int) {
        self.pub = pub; // 在合约初始化时存储公钥
    }

    // 接收外部消息,接受消息 ExtMsg
    external(msg: ExtMsg) {
        let hash: Int = beginCell().storeRef(msg.data).endCell().hash();
        let check: Bool = checkSignature(hash, msg.signature, self.pub);
        //                               ----  -------------  --------
        //                               ↑     ↑              ↑
        //                               |     |              存储在合约中的公钥
        //                               |     从接收到的消息中获取的签名
        //                               使用接收到的消息数据计算的哈希
        // ... 后续逻辑 ...
    }
}

checkDataSignature

solidity
fun checkDataSignature(data: Slice, signature: Slice, public_key: Int): Bool;

使用 public_key 检查 dataEd25519 signature,类似于 checkSignature()。如果 data 的位长度不是 $8$ 的倍数,此函数会抛出错误,错误代码为 exit code 9Cell underflow。验证本身是间接完成的:在 data 的 [SHA-256][sha2] 哈希上进行。

如果签名有效,返回 true,否则返回 false

使用示例:

solidity
let data: Slice = ...;
let signature: Slice = ...;
let publicKey: Int = ...;

let check: Bool = checkSignature(data, signature, publicKey);

sha256

solidity
fun sha256(data: Slice): Int;
fun sha256(data: String): Int;

计算并返回传递的 SliceString dataSHA-256 哈希,作为 $256$-bit 无符号 Int

如果 data 是一个 String,它应该有一个位数是 $8$ 的倍数,如果它是一个 Slice,它必须没有引用(即总共最多 1023 位数据)。

此函数在可能的情况下尝试在编译时解析常量字符串值。

使用示例:

solidity
sha256(beginCell().asSlice());
sha256("Hello, world!"); // 将在编译时解析
sha256(someVariableElsewhere); // 将尝试在编译时解析,
                               // 并回退到运行时评估