Skip to main content

move_neovm/
lib.rs

1// Copyright (c) 2025 R3E Network
2// Licensed under the MIT License
3
4//! Move Bytecode to NeoVM Translator
5//!
6//! This crate provides a minimal Move bytecode → WASM translator to feed the
7//! wasm-neovm pipeline. The lowering is experimental and does not cover the
8//! full Move semantics yet.
9//!
10//! # Pipeline
11//!
12//! ```text
13//! Move Source → Move Compiler → Move Bytecode → move-neovm → WASM → wasm-neovm → NEF
14//! ```
15//!
16//! # Usage
17//!
18//! ```rust,ignore
19//! use move_neovm::{parse_move_bytecode, translate_to_wasm};
20//!
21//! // Parse Move bytecode
22//! let module = parse_move_bytecode(&bytecode)?;
23//!
24//! // Translate to WASM
25//! let wasm = translate_to_wasm(&module)?;
26//!
27//! // Then use wasm-neovm to generate NEF
28//! ```
29//!
30//! # Challenges
31//!
32//! Move has unique features that don't map directly to WASM/NeoVM:
33//! - Linear resource types (no copy/drop without ability)
34//! - Module system with publishing semantics
35//! - Global typed storage model
36//!
37//! These require runtime emulation or compile-time transformation.
38
39pub mod bytecode;
40pub mod runtime;
41pub mod translator;
42
43pub use bytecode::{
44    parse_move_bytecode, validate_move_bytecode, BytecodeVersion, FieldDef, FunctionDef,
45    MoveModule, MoveOpcode, StructDef, TypeTag,
46};
47pub use runtime::{global_storage_key, signer_to_checkwitness, ResourceError, ResourceTracker};
48pub use translator::translate_to_wasm;
49
50use anyhow::Result;
51
52/// Translation result containing WASM module bytes
53pub struct MoveTranslation {
54    /// Generated WASM module bytes
55    pub wasm: Vec<u8>,
56    /// Module metadata
57    pub metadata: MoveModuleMetadata,
58}
59
60/// Metadata about the translated Move module
61#[derive(Debug, Clone, Default)]
62pub struct MoveModuleMetadata {
63    /// Module name
64    pub name: String,
65    /// Exported functions
66    pub functions: Vec<String>,
67    /// Resource types defined
68    pub resources: Vec<String>,
69}
70
71/// Translate Move bytecode to WASM
72///
73/// # Arguments
74/// * `bytecode` - Raw Move bytecode bytes
75/// * `module_name` - Name for the output module
76///
77/// # Returns
78/// Translation result containing WASM bytes and metadata
79pub fn translate_move_to_wasm(bytecode: &[u8], module_name: &str) -> Result<MoveTranslation> {
80    // Parse the Move bytecode
81    let module = parse_move_bytecode(bytecode)?;
82
83    // Translate to WASM
84    let wasm = translate_to_wasm(&module)?;
85
86    // Collect metadata
87    let metadata = MoveModuleMetadata {
88        name: module_name.to_string(),
89        functions: module
90            .functions
91            .iter()
92            .filter(|f| f.is_public || f.is_entry)
93            .map(|f| f.name.clone())
94            .collect(),
95        resources: module
96            .structs
97            .iter()
98            .filter(|s| s.abilities.is_resource())
99            .map(|s| s.name.clone())
100            .collect(),
101    };
102
103    Ok(MoveTranslation { wasm, metadata })
104}
105
106/// Check if the given bytes appear to be valid Move bytecode
107pub fn is_move_bytecode(bytes: &[u8]) -> bool {
108    validate_move_bytecode(bytes)
109}
110
111#[cfg(test)]
112mod tests {
113    use super::*;
114
115    #[test]
116    fn test_is_move_bytecode() {
117        // Valid Move magic
118        assert!(is_move_bytecode(&[
119            0xa1, 0x1c, 0xeb, 0x0b, 0x00, 0x00, 0x00, 0x00
120        ]));
121
122        // Invalid - WASM magic
123        assert!(!is_move_bytecode(&[0x00, 0x61, 0x73, 0x6d]));
124    }
125}