Smart Contract Development Pipeline
The Hybrid Framework enables Rust developers to write safe, efficient smart contracts using RISC-V architecture while maintaining full EVM compatibility. Contracts leverage Rust's type safety and performance characteristics to create robust blockchain applications.
Key Features:- RISC-V smart contract execution on EVM chains
- Rust-based development with type safety
- Solidity-like storage abstractions
- Two-stage compilation process
- Comprehensive error handling
Project Structure
Required Cargo.toml Configuration
Every Hybrid Framework contract must follow a specific project structure:
[package]
name = "my-contract"
version = "0.1.0"
edition = "2021"
[features]
default = []
deploy = []
interface-only = []
[[bin]]
name = "runtime"
path = "src/lib.rs"
[[bin]]
name = "deploy"
path = "src/lib.rs"
required-features = ["deploy"]
[dependencies]
hybrid-derive = { path = "../hybrid-derive" }
hybrid-contract = { path = "../hybrid-contract" }default: Standard contract featuresdeploy: Deployment-specific code pathsinterface-only: Interface generation without implementation
runtime: Handles normal contract function calls after deploymentdeploy: Executes during contract deployment and initialization
The contract discovery system validates these requirements automatically, performing comprehensive checks including feature validation, binary target validation, and dependency resolution.
Development Workflow
The contract development process follows a structured workflow:
Step-by-Step Process
-
Initialize Project
cargo hybrid new my-contract -
Define Storage Structure
- Create storage struct with required fields
- Use
Slot<T>andMapping<K, V>types
-
Implement Contract Trait
- Add
#[contract]attribute - Implement contract functions
- Add
-
Validate Syntax
cargo hybrid check -
Build Contract
cargo hybrid build- Compiles runtime binary
- Compiles deploy binary
- Generates bytecode with 0xff prefix
-
Deploy Contract
cargo hybrid deploy -
Test Contract Functions
- Verify deployment
- Test contract interactions
Contract Implementation
Basic Contract Structure
#![no_std]
#![no_main]
use hybrid_contract::*;
use hybrid_contract::hstd::{Slot, Mapping};
// Storage structure
struct MyTokenStorage {
total_supply: Slot<U256>,
balances: Mapping<Address, U256>,
allowances: Mapping<Address, Mapping<Address, U256>>,
}
// Contract implementation
#[contract]
impl MyTokenStorage {
fn call(&mut self) {
let sig = msg_sig();
match sig {
[0xa9, 0x05, 0x9c, 0xbb] => self.balance_of(),
[0x23, 0xb8, 0x72, 0xdd] => self.transfer(),
_ => revert(),
}
}
}
// Entry point
#[entry]
fn main() -> ! {
let mut contract = MyTokenStorage::default();
contract.call();
}Key Components
- Storage Structure: Defines persistent contract state
- #[contract] Attribute: Marks the main contract implementation
- Function Dispatch: Routes calls based on function signatures
- Entry Point: Main function that initializes and runs the contract
Runtime Library
The hybrid-contract crate provides essential runtime components for smart contract development.
Storage Abstractions
The hstd module offers Solidity-like storage types:
- Single storage slots for any ABI-encodable type
- Direct storage access for simple values
- Key-value mappings with automatic key derivation
- Supports nested mappings
- Efficient storage layout
Both abstractions use sload and sstore system calls for blockchain storage interaction.
Environment Access
Access blockchain environment information through dedicated functions:
Block Informationblock_number() // Current block number
block_timestamp() // Block timestamp
base_fee() // Base fee per gas
chain_id() // Chain identifiergas_price() // Transaction gas price
origin() // Transaction originatormsg_sender() // Current caller address
msg_value() // Value sent with call
msg_data() // Call data
msg_sig() // Function signatureSystem Call Interface
Core system calls provide EVM compatibility:
| Function | EVM Opcode | Description |
|---|---|---|
sload(key) | SLOAD | Read from storage |
sstore(key, value) | SSTORE | Write to storage |
msg_sender() | CALLER | Get caller address |
msg_value() | CALLVALUE | Get sent value |
keccak256(offset, size) | KECCAK256 | Hash computation |
return_riscv(addr, size) | RETURN | Return from contract |
Compilation Pipeline
The Hybrid Framework uses a two-stage compilation process that generates specialized bytecode for each execution phase.
Compilation Flow
-
Runtime Compilation
- Compiles contract logic without deploy features
- Optimized for post-deployment execution
- Smaller bytecode size
-
Deploy Compilation
- Includes deployment-specific initialization
- Compiled with
deployfeature flag - Executes only during contract creation
-
Bytecode Generation
- Combines runtime and deploy binaries
- Prepends 0xff prefix to signal RISC-V execution
- Final format:
[0xff] + [deploy_bytecode]
Runtime vs Deploy Binary
The deploy feature flag controls compilation paths:
- Runtime Binary: Handles normal contract function calls after deployment
- Deploy Binary: Executes during contract deployment and initialization
This separation allows deployment-specific initialization logic without bloating the runtime binary.
Bytecode Format
[0xff] + [deploy_bytecode]The 0xff prefix signals to the Hybrid VM that this is RISC-V bytecode rather than native EVM bytecode, triggering the appropriate execution path in the dual-VM system.
Memory Layout
Hybrid contracts execute in a carefully designed memory environment that provides EVM compatibility while running on RISC-V.
Memory Organization
Contracts use a structured memory layout that mirrors EVM conventions:
- Low Memory: Reserved for EVM scratch space
- Stack Region: Function call stack
- Heap Region: Dynamic allocations
- Storage Interface: Maps to blockchain storage
The runtime uses a custom linker script to ensure proper memory layout and deterministic behavior across all contract executions.
Error Handling
The runtime includes comprehensive error handling mechanisms to ensure contract safety and debuggability.
Panic Handler
- Converts Rust panics to contract reverts
- Includes panic messages in revert data
- Maintains blockchain determinism
- Improves debugging experience
Deterministic Allocation
- Bump allocator ensures consistent memory usage
- No system allocator dependencies
- Predictable gas costs
- Reproducible execution
System Call Safety
- All EVM interactions validated through system calls
- Type-safe interfaces prevent common errors
- Compile-time checks for storage access
- Runtime validation for dynamic operations
Additional Resources
For more detailed information, refer to:
- Compilation Pipeline: Architecture and optimization details
- Procedural Macros: Code generation and macro expansion
- Contract Runtime Library: Complete API reference
Getting Started
To begin developing with the Hybrid Framework:
- Install the Hybrid toolchain
- Create a new project:
cargo hybrid new my-contract - Implement your contract logic
- Build and deploy:
cargo hybrid build && cargo hybrid deploy