Utilities
Blake3 hashing and native DEX precompiles on the Lux EVM.
Overview
In addition to cryptographic signature and key encapsulation precompiles, the Lux EVM provides utility precompiles for high-performance hashing and native on-chain trading.
Blake3 Hash
A precompile for the Blake3 cryptographic hash function. Blake3 is significantly faster than keccak256 and SHA-256 while providing equivalent security.
| Property | Value |
|---|---|
| Address | 0x0500000000000000000000000000000000000004 |
| Input | Arbitrary-length data to hash |
| Output | 32-byte Blake3 digest |
| Gas Cost | 30 + 6 per 64-byte block |
Why Blake3?
- Speed -- Blake3 is ~5x faster than keccak256 in software, making it cheaper for large inputs
- Tree hashing -- Blake3 supports incremental and parallel hashing natively
- Standardization -- Used by many modern cryptographic protocols and file systems
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
contract Blake3Hasher {
address constant BLAKE3 = 0x0500000000000000000000000000000000000004;
function hash(bytes memory data) external view returns (bytes32) {
(bool success, bytes memory result) = BLAKE3.staticcall(data);
require(success, "Blake3 hash failed");
return bytes32(result);
}
}Gas Comparison for Hashing
| Function | Gas (32 bytes) | Gas (1 KB) | Gas (32 KB) |
|---|---|---|---|
| keccak256 | 36 | 294 | 9,030 |
| SHA-256 (precompile) | 72 | 420 | 12,204 |
| Blake3 (precompile) | 33 | 126 | 3,102 |
For contracts that hash large amounts of data (Merkle trees, data availability proofs), Blake3 provides significant gas savings.
import { createPublicClient, http, toHex } from 'viem'
import { lux } from 'viem/chains'
const client = createPublicClient({
chain: lux,
transport: http(),
})
const BLAKE3_ADDRESS = '0x0500000000000000000000000000000000000004'
const result = await client.call({
to: BLAKE3_ADDRESS,
data: toHex(new TextEncoder().encode('Hello, post-quantum world')),
})
console.log('Blake3 hash:', result.data)DEX Precompile
A native on-chain decentralized exchange built into the Lux EVM. The DEX precompile provides atomic token swaps without requiring external smart contract deployments.
| Property | Value |
|---|---|
| Address | 0x0000000000000000000000000000000000009010 |
| Operations | Create pool, add/remove liquidity, swap |
| Gas Cost | Varies by operation |
Operations
The DEX precompile uses function selectors encoded in the first 4 bytes of calldata:
| Selector | Function | Description |
|---|---|---|
0x01 | createPool | Create a new trading pair |
0x02 | addLiquidity | Add liquidity to a pool |
0x03 | removeLiquidity | Remove liquidity from a pool |
0x04 | swap | Execute a token swap |
0x05 | getQuote | Get a swap quote (view) |
0x06 | getPool | Get pool info (view) |
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
interface ILuxDEX {
function createPool(address tokenA, address tokenB, uint24 fee) external returns (address pool);
function addLiquidity(address pool, uint256 amountA, uint256 amountB, uint256 minLP) external returns (uint256 lpTokens);
function removeLiquidity(address pool, uint256 lpTokens, uint256 minA, uint256 minB) external returns (uint256 amountA, uint256 amountB);
function swap(address pool, address tokenIn, uint256 amountIn, uint256 minAmountOut) external returns (uint256 amountOut);
function getQuote(address pool, address tokenIn, uint256 amountIn) external view returns (uint256 amountOut);
function getPool(address tokenA, address tokenB, uint24 fee) external view returns (address pool);
}
contract DEXExample {
ILuxDEX constant DEX = ILuxDEX(0x0000000000000000000000000000000000009010);
function swapTokens(
address pool,
address tokenIn,
uint256 amountIn,
uint256 minOut
) external returns (uint256) {
return DEX.swap(pool, tokenIn, amountIn, minOut);
}
}Router Precompile
The Router precompile provides multi-hop swap routing across DEX pools, finding optimal paths for token swaps.
| Property | Value |
|---|---|
| Address | 0x0000000000000000000000000000000000009012 |
| Operations | Multi-hop swap, route discovery |
| Gas Cost | Varies by path length |
Operations
| Selector | Function | Description |
|---|---|---|
0x01 | swapExactIn | Swap exact input amount through a path |
0x02 | swapExactOut | Swap to get exact output amount |
0x03 | findBestPath | Find optimal swap path (view) |
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
interface ILuxRouter {
function swapExactIn(
address[] calldata path,
uint24[] calldata fees,
uint256 amountIn,
uint256 minAmountOut,
address recipient,
uint256 deadline
) external returns (uint256 amountOut);
function swapExactOut(
address[] calldata path,
uint24[] calldata fees,
uint256 amountOut,
uint256 maxAmountIn,
address recipient,
uint256 deadline
) external returns (uint256 amountIn);
function findBestPath(
address tokenIn,
address tokenOut,
uint256 amountIn
) external view returns (address[] memory path, uint24[] memory fees, uint256 amountOut);
}
contract RouterExample {
ILuxRouter constant ROUTER = ILuxRouter(0x0000000000000000000000000000000000009012);
function swapWithBestRoute(
address tokenIn,
address tokenOut,
uint256 amountIn,
uint256 minAmountOut
) external returns (uint256) {
// Find the best path
(address[] memory path, uint24[] memory fees, ) = ROUTER.findBestPath(
tokenIn, tokenOut, amountIn
);
// Execute the swap
return ROUTER.swapExactIn(
path, fees, amountIn, minAmountOut, msg.sender, block.timestamp + 300
);
}
}The DEX and Router precompiles are distinct from external DEX deployments (like Uniswap forks). Being precompiles, they execute at native speed with lower gas costs than equivalent Solidity implementations. However, they share the same pool state, so liquidity added via the precompile is accessible via the Router and vice versa.
Is this guide helpful?