Asset Contract Address Format for Local Assets on 3DPass: Technical Specification

Local asset contracts on 3DPass utilize a deterministic 20-byte EVM address format comprising a 4-byte prefix (0xFBFBFBFA), 12 bytes of zero padding, and a 4-byte big-endian AssetId to uniquely identify native assets within the Ethereum Virtual Machine.

The 3DPass blockchain facilitates seamless interoperability between its Substrate-based runtime and EVM-compatible clients through a specialized addressing scheme for local assets. Understanding the asset contract address format for local assets on 3DPass is critical for developers integrating ERC-20 compatible tokens, as it enables deterministic contract derivation from native AssetId values.

Anatomy of the Local Asset Address Structure

Local assets on 3DPass follow a rigid 20-byte address schema that combines identification metadata with the native asset identifier:


0xFBFBFBFA0000000000000000xxxxxxxx

The format decomposes into three distinct segments:

  • Prefix (4 bytes) – 0xFBFBFBFA (the constant LOCAL_ASSET_PRECOMPILE_ADDRESS_PREFIX) signals that the address belongs to the local ERC-20 asset precompile set rather than foreign assets or standard contracts.
  • Padding (12 bytes) – Zero-filled bytes (000000000000) required to fill the standard EVM address space between the prefix and the asset identifier.
  • Asset ID (4 bytes) – The asset's AssetId encoded as a big-endian u32, occupying the final four bytes of the address.

When an EVM call targets such an address, the runtime extracts the last 4 bytes as the asset identifier and routes the call to the Erc20AssetsPrecompileSet configured for local assets.

Source Code Implementation

The conversion logic and prefix definitions reside in the 3DPass runtime, specifically within the precompiles and core runtime modules.

Prefix Definition in precompiles.rs

In runtime/src/precompiles.rs, the 4-byte prefix is declared as a constant byte array that marks addresses as local asset precompiles:

// Lines 64-70 in runtime/src/precompiles.rs
pub const LOCAL_ASSET_PRECOMPILE_ADDRESS_PREFIX: &[u8; 4] = &[251, 251, 251, 250];
// Hexadecimal representation: 0xFBFBFBFA

This prefix distinguishes local assets from foreign asset precompiles and standard EVM contracts within the 3DPass runtime.

Address Conversion Logic in lib.rs

The Runtime structure in runtime/src/lib.rs implements the AccountIdAssetIdConversion trait to handle bidirectional translation between Substrate AssetId values and EVM-compatible H160 addresses.

Extracting Asset IDs (account_to_asset_id, lines 100-115):

// Validates the prefix and extracts the u32 AssetId from the trailing bytes
fn account_to_asset_id(account: AccountId) -> Option<(Vec<u8>, AssetId)>

This function verifies that the first 4 bytes of the provided H160 address match LOCAL_ASSET_PRECOMPILE_ADDRESS_PREFIX, then reads the final 4 bytes as the AssetId.

Building Addresses (asset_id_to_account, lines 119-126):

// Constructs the 20-byte address by concatenating:
// 1. The 4-byte prefix
// 2. 12 bytes of zero padding  
// 3. The 4-byte big-endian AssetId
fn asset_id_to_account(prefix: &[u8], asset_id: AssetId) -> AccountId

Practical Code Examples

Generating a Contract Address from an Asset ID

To calculate the EVM contract address for local asset ID 42:

use runtime::{asset_id_to_account, LOCAL_ASSET_PRECOMPILE_ADDRESS_PREFIX};

let asset_id: u32 = 42;
let prefix = LOCAL_ASSET_PRECOMPILE_ADDRESS_PREFIX; // &[251, 251, 251, 250]
let address = asset_id_to_account(prefix, asset_id);

// Result: 0xFBFBFBFA00000000000000002A
// (where 0x2A is 42 in big-endian hexadecimal)

Parsing an Address to Extract the Asset ID

To validate an incoming address and retrieve the corresponding native asset identifier:

use runtime::account_to_asset_id;
use sp_core::H160;

let address: H160 = "0xFBFBFBFA00000000000000002A".parse().unwrap();

if let Some((prefix, asset_id)) = account_to_asset_id(address.into()) {
    // prefix == &[251, 251, 251, 250]
    // asset_id == 42u32
}

EVM Routing and Precompile Execution

When the 3DPass EVM receives a transaction targeting an address starting with 0xFBFBFBFA, the runtime:

  1. Validates the 20-byte address length
  2. Confirms the 4-byte prefix matches LOCAL_ASSET_PRECOMPILE_ADDRESS_PREFIX
  3. Extracts the trailing 4 bytes as a big-endian u32 asset identifier
  4. Routes the call to the Erc20AssetsPrecompileSet implementation for local assets

This deterministic routing allows standard Ethereum tooling such as MetaMask or Web3.js to interact with native 3DPass assets using seemingly standard ERC-20 contract addresses.

Summary

  • Local asset addresses are 20-byte EVM addresses with the deterministic structure: prefix (4) + padding (12) + asset_id (4).
  • The prefix 0xFBFBFBFA is defined as LOCAL_ASSET_PRECOMPILE_ADDRESS_PREFIX in runtime/src/precompiles.rs (lines 64-70).
  • Bidirectional conversion is handled by account_to_asset_id and asset_id_to_account in runtime/src/lib.rs (lines 100-126).
  • Asset identifiers are encoded as big-endian u32 values in the final 4 bytes, supporting IDs from 0 to 4,294,967,295.
  • The format enables seamless interaction from standard EVM clients while maintaining native runtime integration.

Frequently Asked Questions

What is the exact hex prefix for 3DPass local asset contracts?

The prefix is 0xFBFBFBFA, defined in runtime/src/precompiles.rs as the byte array &[251, 251, 251, 250]. This constant occupies the first 4 bytes of every local asset contract address and tells the runtime to treat the target as a local ERC-20 precompile.

How is the asset ID encoded within the address?

The asset ID is encoded as a big-endian unsigned 32-bit integer (u32) occupying the final 4 bytes of the 20-byte address. For example, asset ID 42 (0x0000002A) appears as 0000002A in the trailing bytes, resulting in the full address 0xFBFBFBFA00000000000000002A.

Where is the address conversion logic implemented in the 3DPass codebase?

The conversion logic is implemented in runtime/src/lib.rs within the Runtime type's implementation of AccountIdAssetIdConversion. Specifically, account_to_asset_id (lines 100-115) handles address parsing, while asset_id_to_account (lines 119-126) handles address construction. The prefix constant is defined separately in runtime/src/precompiles.rs.

Can I interact with local assets using standard Ethereum wallets?

Yes. Because local asset addresses are valid 20-byte EVM addresses (H160), wallets like MetaMask, Trust Wallet, or hardware wallets can send transactions to them. The 3DPass runtime automatically detects the 0xFBFBFBFA prefix and routes the call to the appropriate native asset through the Erc20AssetsPrecompileSet, allowing standard ERC-20 functions like transfer, balanceOf, and approve to work transparently.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →