rhai-bigint
A Rhai scripting engine plugin providing seamless, arbitrary-precision BigInt arithmetic.
Why this exists
By default, the Rhai scripting engine limits integers to 64-bit (or 128-bit via feature flags). When building financial applications, cryptography tools, or Web3 indexers, values frequently exceed these limits (e.g., 1 ETH = $10^{18}$ Wei).
Naively casting these large numbers to floating-point (f64) results in catastrophic precision loss (IEEE 754 limits). Casting them to strings preserves the value, but breaks the ability to use native math operators inside the user's scripts.
rhai-bigint solves this by injecting num_bigint::BigInt directly into the Rhai memory space and overloading the standard math and comparison operators. Users get the native ergonomics of standard operators, while the engine guarantees 100% lossless precision under the hood.
Features
- Constructs
BigIntfrom integers (i64), floats (rhai::FLOAT, truncated toward zero), and strings. - Overloads standard arithmetic operators (
+,-,*,/,%,**). - Overloads unary negation (
-). - Overloads bitwise operators (
&,|,^,<<,>>). - Overloads comparison operators (
==,!=,>,>=,<,<=). - Converts
BigIntback to a decimal string (to_string), hex string (to_hex), or float (to_float). - Provides
to_bigint()as a method on integers and floats for ergonomic conversion:42.to_bigint(),1.5.to_bigint().
Installation
Add via Cargo
Manual Configuration
Add the following to your Cargo.toml:
[]
= "1.22.2"
= "0.1.8"
Feature Flags
sync: Enablesrhai/syncsupport. Turn this on if your Rhai engine requires thread-safe types (e.g., when evaluating scripts across a Tokio thread pool).
Usage
1. Registering the Package in Rust
Using the plugin is as simple as registering the package with your Rhai Engine.
use Engine;
use Package;
use BigIntPackage;
2. Scripting Examples
Once registered, your users can write natural, ergonomic scripts.
Basic Arithmetic
let a = ; // from integer
let b = ; // from string
// let a = parse_bigint(1.5); // from float — truncates toward zero, so this equals 1
let sum = a + b;
let diff = b - a;
let prod = a * b;
let quotient = b / a;
let remainder = b % a;
let power = a ** 3; // exponentiation — exponent must be a non-negative integer
let negative = -a;
// Bitwise operators (two's complement semantics)
let and_result = a & ;
let or_result = a | ;
let xor_result = a ^ ;
let left_shift = a << 8; // shift amount must be a non-negative integer
let right_shift = a >> 2;
Comparisons
let price = ;
let threshold = ;
if price >= threshold
Bridging Rust and Rhai
If you are writing a host application and need to inject a BigInt into a script's Scope, you can use the Dynamic wrapper:
use ;
use BigInt;
use BigIntPackage;
let mut engine = new;
new.register_into_engine;
let mut scope = new;
// Inject a massive number from Rust into the Rhai scope
let my_rust_bigint = parse_bytes.unwrap;
scope.push;
// The script can interact with it natively
let script = "balance > parse_bigint(100)";
let is_rich: bool = engine.eval_with_scope.unwrap;
Related Crates
- rhai-evm — Complements
rhai-bigintwith EVM-specific helpers: denomination constructors (ether(),gwei(),usdc()), Keccak-256 hashing, EIP-55 address utilities, and lossless conversion fromalloy-primitivestypes (U256,I256) intoBigInt.
License
- MIT license (http://opensource.org/licenses/MIT)