How 3DPass Achieves EVM Compatibility: Technical Architecture Explained
3DPass achieves full EVM compatibility by embedding the pallet‑evm runtime module powered by SputnikVM, implementing deterministic address translation between Substrate H256 and Ethereum H160 formats, and exposing standard Ethereum JSON‑RPC endpoints through the Frontier framework.
The 3DPass blockchain is built on Substrate yet offers native support for unmodified Ethereum smart contracts. By bridging the gap between Substrate's native runtime and the Ethereum Virtual Machine, 3DPass allows Solidity developers to deploy existing dApps while maintaining access to Substrate-native features like on-chain identity and asset management.
Core Architecture Components
The EVM integration relies on several interconnected pallets and mapping layers that translate between Ethereum and Substrate paradigms.
pallet-evm Runtime Integration
At the heart of 3DPass EVM compatibility lies the pallet‑evm configured in runtime/src/lib.rs. This pallet embeds the SputnikVM engine to execute Ethereum bytecode directly within the Substrate runtime. The configuration defines critical parameters including the Runner trait implementation, gas-to-weight conversion ratios, and the EVM ChainId.
The runtime implements pallet_evm::Config for Runtime at line 1534 of runtime/src/lib.rs, specifying how contract calls and creations are dispatched through the Runner::call and Runner::create methods.
Deterministic Address Mapping
3DPass uses HashedAddressMapping<BlakeTwo256> to establish a bi-directional mapping between Substrate native accounts (AccountId as H256) and Ethereum addresses (H160). This deterministic hashing ensures every Substrate account automatically possesses a corresponding EVM address, enabling seamless cross-platform token transfers and asset interactions.
The mapping type is declared in runtime/src/lib.rs at line 41:
type AddressMapping = HashedAddressMapping<BlakeTwo256>;
Chain Configuration and Identity
Beyond the execution engine, 3DPass configures Ethereum-compatible network parameters to ensure compatibility with standard tooling.
Chain ID and Network Parameters
The pallet_evm_chain_id pallet configures the network identifier that MetaMask, ethers.js, and other Ethereum tools use to identify the 3DPass chain. This configuration appears in runtime/src/lib.rs at line 1511 as impl pallet_evm_chain_id::Config for Runtime {}.
Block Hash and Fee Handling
For full Ethereum RPC compatibility, 3DPass implements pallet_ethereum::EthereumBlockHashMapping to handle blockHash queries, and integrates the BaseFee pallet for EIP-1559-compliant dynamic fee calculations. These components ensure that Ethereum clients receive expected responses when querying historical blocks or estimating gas costs.
The BlockHashMapping type is defined in runtime/src/lib.rs at line 38.
Precompiles: Bridging Solidity and Substrate
Precompiles expose native Substrate functionality as Ethereum-compatible contract addresses, allowing Solidity code to interact with native pallets.
FrontierPrecompiles Implementation
The FrontierPrecompiles<R> type aggregates standard Ethereum precompiles (SHA-256, RIPEMD-160, etc.) alongside custom 3DPass-specific precompiles. This collection bridges Substrate pallets—such as identity, assets, and proxy modules—to Solidity contracts via deterministic address calls.
Custom precompiles are registered in runtime/src/precompiles.rs, with individual implementations located in precompiles/*/src/lib.rs directories (e.g., precompiles/identity/src/lib.rs).
Accessing Substrate Features from Solidity
Developers can call Substrate-native functions directly from Solidity by targeting specific precompile addresses. For example, the Identity precompile at 0x00000000000000000000000000000000000405 exposes pallet_identity functionality:
interface IIdentity {
function setIdentity(address who, bytes calldata info) external;
}
contract Registry {
IIdentity constant ID = IIdentity(address(0x00000000000000000000000000000000000405));
function register(bytes calldata info) external {
ID.setIdentity(msg.sender, info);
}
}
When this contract executes, the EVM routes the call through the Identity precompile implementation back to the Substrate runtime.
RPC Layer and Transaction Lifecycle
The frontier/rpc-core crate provides the translation layer between Ethereum JSON-RPC calls and Substrate extrinsics.
Transaction Processing Pipeline
When a user submits an Ethereum transaction via eth_sendRawTransaction, the RPC handler defined in frontier/rpc-core/src/eth.rs decodes the raw bytes, validates nonces and gas limits using logic from primitives/evm/src/validation.rs, and dispatches the call through the configured pallet_evm runner.
The transaction lifecycle functions call_evm and create_evm in runtime/src/lib.rs (around line 2078) handle the final execution, applying gas metering and state transitions according to Ethereum rules while recording changes to Substrate storage.
Practical Implementation Examples
Sending Transactions via Ethereum Tooling
You can interact with 3DPass using standard Ethereum libraries like ethers.js:
const { ethers } = require('ethers');
const provider = new ethers.JsonRpcProvider('http://localhost:9944');
const wallet = new ethers.Wallet('<PRIVATE_KEY>', provider);
async function send() {
const tx = {
to: '0x1234...abcd',
value: ethers.parseEther('0.01')
};
const receipt = await wallet.sendTransaction(tx);
console.log('Tx hash:', receipt.hash);
}
send();
The RPC endpoint processes this through frontier/rpc-core before reaching the EVM pallet at runtime/src/lib.rs.
Converting Between Address Formats
For runtime developers working in Rust, converting between Substrate accounts and EVM addresses uses the configured mapping:
use pallet_evm::AddressMapping;
let substrate_account: <Runtime as frame_system::Config>::AccountId = ...;
let evm_address: sp_core::H160 =
<Runtime as pallet_evm::Config>::AddressMapping::into_account_id(substrate_account);
This conversion utilizes the same HashedAddressMapping<BlakeTwo256> logic applied to all cross-vm interactions.
Summary
- 3DPass integrates
pallet‑evmwith SputnikVM to execute unmodified Ethereum bytecode within the Substrate runtime viaruntime/src/lib.rs. - Deterministic address mapping through
HashedAddressMapping<BlakeTwo256>ensures every SubstrateH256account maps to a unique EthereumH160address. - Frontier precompiles bridge Solidity contracts to native Substrate pallets like identity and assets through specialized contract addresses.
- EIP‑1559 compatibility is achieved through the
BaseFeepallet andEthereumBlockHashMappingfor complete Ethereum RPC parity. - Standard Ethereum tooling works out-of-the-box via the
frontier/rpc-coretranslation layer that converts JSON-RPC calls to Substrate extrinsics.
Frequently Asked Questions
How does 3DPass convert Substrate addresses to Ethereum addresses?
3DPass uses the HashedAddressMapping<BlakeTwo256> type defined in runtime/src/lib.rs to deterministically hash Substrate AccountId (32-byte H256) values into Ethereum-compatible H160 addresses. This ensures every native account automatically has a corresponding EVM address without manual registration.
Can I use MetaMask to interact with 3DPass?
Yes. 3DPass exposes standard Ethereum JSON-RPC endpoints through the frontier/rpc-core implementation, allowing MetaMask to connect using the network's Chain ID configured in the pallet_evm_chain_id pallet. Transactions signed in MetaMask are processed by the same validation logic found in primitives/evm/src/validation.rs.
What precompiles are available on 3DPass?
3DPass includes standard Ethereum precompiles plus custom extensions for Substrate pallets. The FrontierPrecompiles type in runtime/src/precompiles.rs aggregates these, including implementations for identity management, batch calls, and asset transfers located in the precompiles/ directory.
How are gas fees calculated in 3DPass EVM transactions?
The network implements EIP-1559 fee mechanics using the BaseFee pallet alongside gas-to-weight mappings defined in the pallet_evm configuration. This allows Ethereum-compatible fee estimation while converting gas costs to Substrate weight units for block execution limits.
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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →