SafeMath and u256 Usage
This document explains the implementation and usage of SafeMath for the u256 data type, focusing on its importance in avoiding overflows and underflows in blockchain smart contracts.
Why Use SafeMath?
When working with unsigned integers like u256, overflows and underflows can lead to critical bugs or vulnerabilities in your smart contracts. SafeMath mitigates these risks by adding checks for these conditions during arithmetic operations.
Importing SafeMath
To start using SafeMath, include the necessary imports in your AssemblyScript code:
import { SafeMath } from "@btc-vision/btc-runtime/runtime";
import { u128, u256 } from "as-bignum/assembly";
Available Methods
SafeMath provides a comprehensive suite of arithmetic operations for u256, u128, and smaller unsigned integers (u64). Below is a list of the most commonly used methods:
Addition
- Method:
SafeMath.add(a: u256, b: u256): u256 - Description: Adds two
u256values safely, throwing an error if an overflow occurs. - Example:
let a: u256 = u256.fromU32(1000);
let b: u256 = u256.fromU32(2000);
let sum: u256 = SafeMath.add(a, b); // Result: 3000
Subtraction
- Method:
SafeMath.sub(a: u256, b: u256): u256 - Description: Subtracts one
u256value from another, throwing an error if an underflow occurs. - Example:
let a: u256 = u256.fromU32(5000);
let b: u256 = u256.fromU32(3000);
let difference: u256 = SafeMath.sub(a, b); // Result: 2000
Multiplication
- Method:
SafeMath.mul(a: u256, b: u256): u256 - Description: Multiplies two
u256values safely, throwing an error if an overflow occurs. - Example:
let a: u256 = u256.fromU32(10);
let b: u256 = u256.fromU32(20);
let product: u256 = SafeMath.mul(a, b); // Result: 200
Division
- Method:
SafeMath.div(a: u256, b: u256): u256 - Description: Divides one
u256value by another, throwing an error if a division by zero occurs. - Example:
let a: u256 = u256.fromU32(100);
let b: u256 = u256.fromU32(5);
let quotient: u256 = SafeMath.div(a, b); // Result: 20
Modulo
- Method:
SafeMath.mod(a: u256, b: u256): u256 - Description: Computes the remainder of
adivided byb, throwing an error ifbis zero. - Example:
let a: u256 = u256.fromU32(10);
let b: u256 = u256.fromU32(3);
let remainder: u256 = SafeMath.mod(a, b); // Result: 1
Advanced Methods
Exponentiation
- Method:
SafeMath.pow(base: u256, exponent: u256): u256 - Description: Computes
baseraised to the power ofexponentsafely. - Example:
let base: u256 = u256.fromU32(2);
let exponent: u256 = u256.fromU32(10);
let result: u256 = SafeMath.pow(base, exponent); // Result: 1024
Logarithm (Approximate)
- Method:
SafeMath.approximateLog2(x: u256): u256 - Description: Approximates the binary logarithm (
log2) of au256value. - Example:
let x: u256 = u256.fromU32(1024);
let log2: u256 = SafeMath.approximateLog2(x); // Result: 10
Best Practices
- Avoid native operations (
+,-,*,/) to ensure safety. - Even with SafeMath, ensure the inputs are within the expected range to prevent logical errors.
- For performance-critical code, use unchecked arithmetic only when absolutely safe and well-documented.