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}