NAC_Blockchain/charter-std-zh/utils/utils.ch

554 lines
13 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

///! 工具模块: 常用工具库
///! NAC的通用工具函数集合
///!
///! **版本**: v1.0
///! **模块**: charter-std-zh/utils/utils.ch
使用 资产::gnacs::GNACS编码;
// ============================================================================
// 数学工具库
// ============================================================================
/// 数学工具库
库 数学 {
/// 最小值
///
/// # 参数
/// - `a`: 第一个数
/// - `b`: 第二个数
///
/// # 返回
/// - `u256`: 较小的数
函数 最小值(a: u256, b: u256) -> u256 {
如果 a < b {
返回 a;
} 否则 {
返回 b;
}
}
/// 最大值
///
/// # 参数
/// - `a`: 第一个数
/// - `b`: 第二个数
///
/// # 返回
/// - `u256`: 较大的数
函数 最大值(a: u256, b: u256) -> u256 {
如果 a > b {
返回 a;
} 否则 {
返回 b;
}
}
/// 平方根(牛顿迭代法)
///
/// # 参数
/// - `x`: 输入值
///
/// # 返回
/// - `u256`: 平方根(向下取整)
函数 平方根(x: u256) -> u256 {
如果 x == 0 {
返回 0;
}
让 可变 z = (x + 1) / 2;
让 可变 y = x;
循环 y > z {
y = z;
z = (x / z + z) / 2;
}
返回 y;
}
/// 安全加法
///
/// # 参数
/// - `a`: 第一个数
/// - `b`: 第二个数
///
/// # 返回
/// - `u256`: 和
函数 安全加(a: u256, b: u256) -> u256 {
让 c = a + b;
要求(c >= a, "数学: 加法溢出");
返回 c;
}
/// 安全减法
///
/// # 参数
/// - `a`: 被减数
/// - `b`: 减数
///
/// # 返回
/// - `u256`: 差
函数 安全减(a: u256, b: u256) -> u256 {
要求(b <= a, "数学: 减法下溢");
返回 a - b;
}
/// 安全乘法
///
/// # 参数
/// - `a`: 第一个数
/// - `b`: 第二个数
///
/// # 返回
/// - `u256`: 积
函数 安全乘(a: u256, b: u256) -> u256 {
如果 a == 0 {
返回 0;
}
让 c = a * b;
要求(c / a == b, "数学: 乘法溢出");
返回 c;
}
/// 安全除法
///
/// # 参数
/// - `a`: 被除数
/// - `b`: 除数
///
/// # 返回
/// - `u256`: 商
函数 安全除(a: u256, b: u256) -> u256 {
要求(b > 0, "数学: 除数为零");
返回 a / b;
}
/// 百分比计算
///
/// # 参数
/// - `数值`: 基数
/// - `百分比`: 百分比基点10000=100%
///
/// # 返回
/// - `u256`: 计算结果
函数 百分比(数值: u256, 百分比: u256) -> u256 {
返回 数值 * 百分比 / 10000;
}
}
// ============================================================================
// 地址工具库
// ============================================================================
/// 地址工具库
库 地址工具 {
/// 判断是否为合约地址
///
/// # 参数
/// - `地址`: 待检查的地址
///
/// # 返回
/// - `布尔`: 是否为合约地址
函数 是否为合约(地址: 地址) -> 布尔 {
让 代码大小 = 地址.代码大小();
返回 代码大小 > 0;
}
/// 判断是否为零地址
///
/// # 参数
/// - `地址`: 待检查的地址
///
/// # 返回
/// - `布尔`: 是否为零地址
函数 是否为零地址(地址: 地址) -> 布尔 {
返回 地址 == 地址::零地址();
}
/// 发送NAC币
///
/// # 参数
/// - `接收者`: 接收者地址
/// - `数量`: 发送数量
///
/// # 返回
/// - `布尔`: 是否发送成功
函数 发送(接收者: 地址, 数量: u256) -> 布尔 {
让 (成功, _) = 接收者.调用带值(数量, 字节数组::新建());
返回 成功;
}
}
// ============================================================================
// 字符串工具库
// ============================================================================
/// 字符串工具库
库 字符串工具 {
/// 字符串长度
///
/// # 参数
/// - `字符串`: 输入字符串
///
/// # 返回
/// - `u256`: 字符串长度
函数 长度(字符串: 字符串) -> u256 {
返回 字符串.长度();
}
/// 字符串拼接
///
/// # 参数
/// - `a`: 第一个字符串
/// - `b`: 第二个字符串
///
/// # 返回
/// - `字符串`: 拼接后的字符串
函数 拼接(a: 字符串, b: 字符串) -> 字符串 {
返回 a + b;
}
/// 字符串比较
///
/// # 参数
/// - `a`: 第一个字符串
/// - `b`: 第二个字符串
///
/// # 返回
/// - `布尔`: 是否相等
函数 相等(a: 字符串, b: 字符串) -> 布尔 {
返回 a == b;
}
/// 数字转字符串
///
/// # 参数
/// - `数字`: 输入数字
///
/// # 返回
/// - `字符串`: 字符串表示
函数 数字转字符串(数字: u256) -> 字符串 {
如果 数字 == 0 {
返回 "0";
}
让 可变 临时 = 数字;
让 可变 位数 = 0;
循环 临时 != 0 {
位数 = 位数 + 1;
临时 = 临时 / 10;
}
让 可变 字节 = 字节数组::新建带容量(位数);
临时 = 数字;
对于 i 在 0..位数 {
字节[位数 - 1 - i] = (临时 % 10 + 48) 作为 u8;
临时 = 临时 / 10;
}
返回 字符串::从字节(字节);
}
}
// ============================================================================
// 数组工具库
// ============================================================================
/// 数组工具库
库 数组工具 {
/// 数组求和
///
/// # 参数
/// - `数组`: 输入数组
///
/// # 返回
/// - `u256`: 数组元素之和
函数 求和(数组: 数组<u256>) -> u256 {
让 可变 总和 = 0;
对于 i 在 0..数组.长度() {
总和 = 总和 + 数组[i];
}
返回 总和;
}
/// 数组平均值
///
/// # 参数
/// - `数组`: 输入数组
///
/// # 返回
/// - `u256`: 数组元素平均值
函数 平均值(数组: 数组<u256>) -> u256 {
要求(数组.长度() > 0, "数组工具: 数组为空");
返回 求和(数组) / 数组.长度();
}
/// 数组最大值
///
/// # 参数
/// - `数组`: 输入数组
///
/// # 返回
/// - `u256`: 数组最大值
函数 最大值(数组: 数组<u256>) -> u256 {
要求(数组.长度() > 0, "数组工具: 数组为空");
让 可变 最大 = 数组[0];
对于 i 在 1..数组.长度() {
如果 数组[i] > 最大 {
最大 = 数组[i];
}
}
返回 最大;
}
/// 数组最小值
///
/// # 参数
/// - `数组`: 输入数组
///
/// # 返回
/// - `u256`: 数组最小值
函数 最小值(数组: 数组<u256>) -> u256 {
要求(数组.长度() > 0, "数组工具: 数组为空");
让 可变 最小 = 数组[0];
对于 i 在 1..数组.长度() {
如果 数组[i] < 最小 {
最小 = 数组[i];
}
}
返回 最小;
}
/// 数组包含元素
///
/// # 参数
/// - `数组`: 输入数组
/// - `元素`: 待查找元素
///
/// # 返回
/// - `布尔`: 是否包含
函数 包含(数组: 数组<u256>, 元素: u256) -> 布尔 {
对于 i 在 0..数组.长度() {
如果 数组[i] == 元素 {
返回 真;
}
}
返回 假;
}
}
// ============================================================================
// 哈希工具库
// ============================================================================
/// 哈希工具库
库 哈希工具 {
/// 计算SHA3-384哈希
///
/// # 参数
/// - `数据`: 输入数据
///
/// # 返回
/// - `哈希`: 48字节哈希值
函数 哈希384(数据: 字节数组) -> 哈希 {
返回 哈希::从字节(密码学::sha3_384(数据));
}
/// 计算消息哈希
///
/// # 参数
/// - `消息`: 消息内容
///
/// # 返回
/// - `哈希`: 消息哈希
函数 消息哈希(消息: 字符串) -> 哈希 {
返回 哈希384(消息.作为字节());
}
/// 计算地址哈希
///
/// # 参数
/// - `地址`: 地址
///
/// # 返回
/// - `哈希`: 地址哈希
函数 地址哈希(地址: 地址) -> 哈希 {
返回 哈希384(地址.作为字节());
}
}
// ============================================================================
// 时间工具库
// ============================================================================
/// 时间工具库
库 时间工具 {
/// 获取当前时间戳
///
/// # 返回
/// - `u256`: 当前时间戳(秒)
函数 当前时间() -> u256 {
返回 区块::时间戳();
}
/// 获取当前区块号
///
/// # 返回
/// - `u256`: 当前区块号
函数 当前区块() -> u256 {
返回 区块::号();
}
/// 计算天数
///
/// # 参数
/// - `秒数`: 秒数
///
/// # 返回
/// - `u256`: 天数
函数 秒转天(秒数: u256) -> u256 {
返回 秒数 / 86400;
}
/// 计算小时数
///
/// # 参数
/// - `秒数`: 秒数
///
/// # 返回
/// - `u256`: 小时数
函数 秒转小时(秒数: u256) -> u256 {
返回 秒数 / 3600;
}
/// 计算分钟数
///
/// # 参数
/// - `秒数`: 秒数
///
/// # 返回
/// - `u256`: 分钟数
函数 秒转分钟(秒数: u256) -> u256 {
返回 秒数 / 60;
}
}
// ============================================================================
// 权限控制工具
// ============================================================================
/// 可拥有合约
///
/// 提供基础的所有权管理功能
合约 可拥有 {
私有 _所有者: 地址;
事件 所有权转移 {
前所有者: 地址,
新所有者: 地址
}
构造函数() {
_所有者 = 消息::发送者();
}
修饰符 仅所有者() {
要求(消息::发送者() == _所有者, "可拥有: 非所有者");
_;
}
函数 所有者() -> 地址 {
返回 _所有者;
}
函数 转移所有权(新所有者: 地址) 仅所有者 {
要求(新所有者 != 地址::零地址(), "可拥有: 新所有者地址无效");
让 旧所有者 = _所有者;
_所有者 = 新所有者;
触发 所有权转移 {
前所有者: 旧所有者,
新所有者: 新所有者
};
}
函数 放弃所有权() 仅所有者 {
让 旧所有者 = _所有者;
_所有者 = 地址::零地址();
触发 所有权转移 {
前所有者: 旧所有者,
新所有者: 地址::零地址()
};
}
}
/// 可暂停合约
///
/// 提供暂停和恢复功能
合约 可暂停 实现 可拥有 {
私有 _已暂停: 布尔;
事件 暂停 {}
事件 恢复 {}
构造函数() {
_已暂停 = 假;
}
修饰符 未暂停() {
要求(!_已暂停, "可暂停: 已暂停");
_;
}
修饰符 已暂停() {
要求(_已暂停, "可暂停: 未暂停");
_;
}
函数 是否已暂停() -> 布尔 {
返回 _已暂停;
}
函数 暂停() 仅所有者 未暂停 {
_已暂停 = 真;
触发 暂停 {};
}
函数 恢复() 仅所有者 已暂停 {
_已暂停 = 假;
触发 恢复 {};
}
}
// ============================================================================
// 重入保护
// ============================================================================
/// 重入保护合约
///
/// 防止重入攻击
合约 重入保护 {
私有 _状态: u256;
常量 未进入: u256 = 1;
常量 已进入: u256 = 2;
构造函数() {
_状态 = 未进入;
}
修饰符 防重入() {
要求(_状态 != 已进入, "重入保护: 重入调用");
_状态 = 已进入;
_;
_状态 = 未进入;
}
}