Rust大数运算库cosmwasm-bignumber的使用,支持区块链智能合约中的高精度数值计算

Rust大数运算库cosmwasm-bignumber的使用,支持区块链智能合约中的高精度数值计算

概述

cosmwasm-bignumber是一个用于区块链智能合约开发的Rust大数运算库,提供了Uint256和Decimal256两种大数类型,支持高精度数值计算。

安装

在你的项目目录中运行以下Cargo命令:

cargo add cosmwasm-bignumber

或者在Cargo.toml中添加:

cosmwasm-bignumber = "2.2.0"

示例代码

以下是cosmwasm-bignumber库的使用示例:

use cosmwasm_bignumber::{Uint256, Decimal256};
use std::str::FromStr;

fn main() {
    // Uint256 示例
    let a = Uint256::from(123456789u64);
    let b = Uint256::from_str("987654321").unwrap();
    
    // 加法
    let sum = a + b;
    println!("Sum: {}", sum);
    
    // 乘法
    let product = a * b;
    println!("Product: {}", product);
    
    // Decimal256 示例
    let dec_a = Decimal256::from_str("123.456").unwrap();
    let dec_b = Decimal256::from_str("789.012").unwrap();
    
    // 加法
    let dec_sum = dec_a + dec_b;
    println!("Decimal Sum: {}", dec_sum);
    
    // 乘法
    let dec_product = dec_a * dec_b;
    println!("Decimal Product: {}", dec_product);
    
    // 除法
    let dec_quotient = dec_b / dec_a;
    println!("Decimal Quotient: {}", dec_quotient);
}

完整示例

以下是一个更完整的智能合约示例,展示如何在CosmWasm智能合约中使用cosmwasm-bignumber进行高精度计算:

use cosmwasm_std::{DepsMut, Env, MessageInfo, Response, StdResult};
use cosmwasm_bignumber::{Uint256, Decimal256};
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};

#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
pub struct InstantiateMsg {
    pub initial_value: String,
}

#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
pub enum ExecuteMsg {
    Add { value: String },
    Multiply { value: String },
    Divide { value: String },
}

pub fn instantiate(
    deps: DepsMut,
    _env: Env,
    _info: MessageInfo,
    msg: InstantiateMsg,
) -> StdResult<Response> {
    // 将初始值存储为Decimal256
    let initial_value = Decimal256::from_str(&msg.initial_value)?;
    
    // 存储到状态中...
    Ok(Response::default())
}

pub fn execute(
    deps: DepsMut,
    _env: Env,
    _info: MessageInfo,
    msg: ExecuteMsg,
) -> StdResult<Response> {
    match msg {
        ExecuteMsg::Add { value } => {
            // 从状态中读取当前值
            // let current = read_current_value(deps.storage)?;
            let current = Decimal256::zero(); // 示例中简化
            
            // 执行加法运算
            let to_add = Decimal256::from_str(&value)?;
            let new_value = current + to_add;
            
            // 存储新值...
            
            Ok(Response::new()
                .add_attribute("action", "add")
                .add_attribute("new_value", new_value.to_string()))
        }
        ExecuteMsg::Multiply { value } => {
            // 执行乘法运算
            let current = Decimal256::zero(); // 示例中简化
            let multiplier = Decimal256::from_str(&value)?;
            let new_value = current * multiplier;
            
            Ok(Response::new()
                .add_attribute("action", "multiply")
                .add_attribute("new_value", new_value.to_string()))
        }
        ExecuteMsg::Divide { value } => {
            // 执行除法运算
            let current = Decimal256::zero(); // 示例中简化
            let divisor = Decimal256::from_str(&value)?;
            let new_value = current / divisor;
            
            Ok(Response::new()
                .add_attribute("action", "divide")
                .add_attribute("new_value", new_value.to_string()))
        }
    }
}

特性

  • 支持256位无符号整数(Uint256)和高精度小数(Decimal256)
  • 提供基本的算术运算(加、减、乘、除)
  • 支持从字符串解析大数
  • 专为CosmWasm智能合约设计
  • 适用于需要高精度计算的区块链场景

这个库特别适用于需要处理加密货币金额、代币数量或其他需要高精度计算的区块链应用场景。


1 回复

Rust大数运算库cosmwasm-bignumber使用指南

简介

cosmwasm-bignumber是一个专为CosmWasm智能合约设计的大数运算库,特别适合区块链环境中需要高精度数值计算的场景。它提供了Decimal和Integer两种大数类型,支持各种数学运算和比较操作。

主要特性

  • 高精度十进制运算(Decimal)
  • 大整数运算(Integer)
  • 支持加减乘除等基本运算
  • 比较操作
  • 序列化和反序列化支持
  • 适用于CosmWasm智能合约环境

安装

在Cargo.toml中添加依赖:

[dependencies]
cosmwasm-bignumber = "0.3"

基本用法

Decimal类型示例

use cosmwasm_bignumber::Decimal;

fn decimal_operations() {
    // 创建Decimal
    let a = Decimal::from_str("123.456").unwrap();
    let b = Decimal::from_str("789.012").unwrap();
    
    // 加法
    let sum = a + b;
    println!("Sum: {}", sum);
    
    // 减法
    let diff = b - a;
    println!("Difference: {}", diff);
    
    // 乘法
    let product = a * b;
    println!("Product: {}", product);
    
    // 除法
    let quotient = b / a;
    println!("Quotient: {}", quotient);
    
    // 比较
    if a > b {
        println!("a is greater than b");
    } else {
        println!("a is not greater than b");
    }
}

Integer类型示例

use cosmwasm_bignumber::Integer;

fn integer_operations() {
    // 创建Integer
    let a = Integer::from_str("12345678901234567890").unwrap();
    let b = Integer::from_str("98765432109876543210").unwrap();
    
    // 基本运算
    let sum = a + b;
    println!("Sum: {}", sum);
    
    let diff = b - a;
    println!("Difference: {}", diff);
    
    let product = a * b;
    println!("Product: {}", product);
    
    let quotient = b / a;
    println!("Quotient: {}", quotient);
    
    // 模运算
    let remainder = b % a;
    println!("Remainder: {}", remainder);
}

在智能合约中的使用示例

use cosmwasm_std::{Response, StdResult, DepsMut, MessageInfo};
use cosmwasm_bignumber::{Decimal, Decimal256};

pub fn execute_divide_funds(
    deps: DepsMut,
    _info: MessageInfo,
    total_amount: u128,
    weights: Vec<u64>,
) -> StdResult<Response> {
    // 计算总权重
    let total_weight: u64 = weights.iter().sum();
    let total_weight_dec = Decimal::from_ratio(total_weight, 1u64);
    
    // 转换为Decimal256进行高精度计算
    let total_amount_dec = Decimal256::from_ratio(total_amount, 1u64);
    
    let mut allocations = vec![];
    for weight in weights {
        let weight_dec = Decimal::from_ratio(weight, 1u64);
        let ratio = Decimal256::from(weight_dec / total_weight_dec);
        let allocation = ratio * total_amount_dec;
        allocations.push(allocation.to_u128()?);
    }
    
    Ok(Response::new().add_attributes(vec![
        ("action", "divide_funds"),
        ("total_amount", &total_amount.to_string()),
    ]))
}

高级功能

精度控制示例

use cosmwasm_bignumber::Decimal;

fn precision_control() {
    let a = Decimal::from_str("1.23456789").unwrap();
    let b = Decimal::from_str("9.87654321").unwrap();
    
    // 设置精度为4位小数
    let result = (a * b).set_precision(4).unwrap();
    println!("Rounded result: {}", result);  // 输出: 12.1936
}

序列化和反序列化示例

use cosmwasm_bignumber::Decimal;
use serde::{Serialize, Deserialize};

#[derive(Serialize, Deserialize)]
struct ContractState {
    price: Decimal,
    total_supply: Decimal,
}

fn serialization_example() {
    let state = ContractState {
        price: Decimal::from_str("123.456").unwrap(),
        total_supply: Decimal::from_str("1000000.0").unwrap(),
    };
    
    // 序列化为JSON
    let json = serde_json::to_string(&state).unwrap();
    println!("Serialized: {}", json);
    
    // 从JSON反序列化
    let deserialized: ContractState = serde_json::from_str(&json).unwrap();
    println!("Deserialized price: {}", deserialized.price);
}

完整示例demo

以下是一个完整的智能合约示例,展示了cosmwasm-bignumber在合约中的典型用法:

use cosmwasm_std::{
    entry_point, Binary, Deps, DepsMut, Env, MessageInfo, Response, StdResult,
};
use cosmwasm_bignumber::{Decimal, Decimal256};
use serde::{Deserialize, Serialize};

#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
pub struct State {
    pub total_staked: Decimal,
    pub reward_rate: Decimal,
}

#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
pub struct InstantiateMsg {
    pub reward_rate: String,
}

#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
pub enum ExecuteMsg {
    Stake { amount: String },
    Withdraw { amount: String },
    ClaimRewards {},
}

#[entry_point]
pub fn instantiate(
    deps: DepsMut,
    _env: Env,
    _info: MessageInfo,
    msg: InstantiateMsg,
) -> StdResult<Response> {
    let reward_rate = Decimal::from_str(&msg.reward_rate)?;
    
    let state = State {
        total_staked: Decimal::zero(),
        reward_rate,
    };
    
    // 存储状态
    deps.storage.save(b"state", &to_binary(&state)?)?;
    
    Ok(Response::default())
}

#[entry_point]
pub fn execute(
    deps: DepsMut,
    env: Env,
    info: MessageInfo,
    msg: ExecuteMsg,
) -> StdResult<Response> {
    match msg {
        ExecuteMsg::Stake { amount } => stake(deps, env, info, amount),
        ExecuteMsg::Withdraw { amount } => withdraw(deps, env, info, amount),
        ExecuteMsg::ClaimRewards {} => claim_rewards(deps, env, info),
    }
}

fn stake(
    deps: DepsMut,
    _env: Env,
    info: MessageInfo,
    amount: String,
) -> StdResult<Response> {
    let mut state: State = deps.storage.load(b"state")?;
    let stake_amount = Decimal::from_str(&amount)?;
    
    // 更新总质押量
    state.total_staked = state.total_staked + stake_amount;
    
    deps.storage.save(b"state", &to_binary(&state)?)?;
    
    Ok(Response::new()
        .add_attribute("action", "stake")
        .add_attribute("sender", info.sender)
        .add_attribute("amount", amount))
}

fn claim_rewards(
    deps: DepsMut,
    env: Env,
    info: MessageInfo,
) -> StdResult<Response> {
    let state: State = deps.storage.load(b"state")?;
    
    // 使用Decimal256进行高精度计算
    let reward_rate = Decimal256::from(state.reward_rate);
    let total_staked = Decimal256::from(state.total_staked);
    
    // 假设1个区块时间单位
    let time_elapsed = Decimal256::one();
    
    // 计算奖励
    let rewards = reward_rate * total_staked * time_elapsed;
    let rewards_dec = rewards.set_precision(6)?; // 设置6位小数精度
    
    Ok(Response::new()
        .add_attribute("action", "claim_rewards")
        .add_attribute("sender", info.sender)
        .add_attribute("amount", rewards_dec.to_string()))
}

注意事项

  1. 所有运算都会进行溢出检查,如果发生溢出会返回错误
  2. Decimal类型默认使用18位小数精度
  3. 在智能合约中使用时,注意gas消耗
  4. 除法运算需要特别注意分母为零的情况

cosmwasm-bignumber为区块链智能合约提供了可靠的高精度数值计算能力,特别适合金融类合约和需要精确计算的场景。

回到顶部