neo-decompiler 0.11.0

Neo N3 NEF decompiler: parse, disassemble, lift bytecode to high-level pseudocode and C# skeletons, with a CLI, JSON reports, and optional WebAssembly bindings.
Documentation
use serde::Serialize;
use serde_json::Value;

use crate::manifest::{
    ContractManifest, ManifestPermissionContract, ManifestPermissionMethods, ManifestTrusts,
};

#[derive(Debug, Clone, Serialize)]
pub(super) struct ManifestSummary {
    name: String,
    supported_standards: Vec<String>,
    features: serde_json::Map<String, Value>,
    groups: Vec<GroupSummary>,
    methods: usize,
    events: usize,
    permissions: Vec<PermissionSummary>,
    trusts: Option<TrustSummary>,
    abi: AbiSummary,
    #[serde(skip_serializing_if = "Option::is_none")]
    extra: Option<Value>,
}

#[derive(Debug, Clone, Serialize)]
struct GroupSummary {
    pubkey: String,
    signature: String,
}

#[derive(Debug, Clone, Serialize)]
struct PermissionSummary {
    contract: PermissionContractSummary,
    methods: PermissionMethodsSummary,
}

#[derive(Debug, Clone, Serialize)]
#[serde(tag = "type", content = "value")]
enum PermissionContractSummary {
    Wildcard(String),
    Hash(String),
    Group(String),
    Other(Value),
}

#[derive(Debug, Clone, Serialize)]
#[serde(tag = "type", content = "value")]
enum PermissionMethodsSummary {
    Wildcard(String),
    Methods(Vec<String>),
}

#[derive(Debug, Clone, Serialize)]
#[serde(tag = "type", content = "value")]
enum TrustSummary {
    Wildcard(String),
    Contracts(Vec<String>),
    Other(Value),
}

#[derive(Debug, Clone, Serialize)]
struct AbiSummary {
    methods: Vec<MethodSummary>,
    events: Vec<EventSummary>,
}

#[derive(Debug, Clone, Serialize)]
struct MethodSummary {
    name: String,
    parameters: Vec<ParameterSummary>,
    return_type: String,
    safe: bool,
    offset: Option<i32>,
}

#[derive(Debug, Clone, Serialize)]
struct EventSummary {
    name: String,
    parameters: Vec<ParameterSummary>,
}

#[derive(Debug, Clone, Serialize)]
struct ParameterSummary {
    name: String,
    ty: String,
}

pub(super) fn summarize_manifest(manifest: &ContractManifest) -> ManifestSummary {
    ManifestSummary {
        name: manifest.name.clone(),
        supported_standards: manifest.supported_standards.clone(),
        features: manifest.features.clone(),
        groups: manifest
            .groups
            .iter()
            .map(|group| GroupSummary {
                pubkey: group.pubkey.clone(),
                signature: group.signature.clone(),
            })
            .collect(),
        methods: manifest.abi.methods.len(),
        events: manifest.abi.events.len(),
        permissions: manifest
            .permissions
            .iter()
            .map(|permission| PermissionSummary {
                contract: PermissionContractSummary::from(&permission.contract),
                methods: PermissionMethodsSummary::from(&permission.methods),
            })
            .collect(),
        trusts: manifest.trusts.as_ref().map(TrustSummary::from),
        extra: manifest.extra.clone(),
        abi: AbiSummary {
            methods: manifest
                .abi
                .methods
                .iter()
                .map(|method| MethodSummary {
                    name: method.name.clone(),
                    parameters: method
                        .parameters
                        .iter()
                        .map(ParameterSummary::from)
                        .collect(),
                    return_type: method.return_type.clone(),
                    safe: method.safe,
                    offset: method.offset,
                })
                .collect(),
            events: manifest
                .abi
                .events
                .iter()
                .map(|event| EventSummary {
                    name: event.name.clone(),
                    parameters: event
                        .parameters
                        .iter()
                        .map(ParameterSummary::from)
                        .collect(),
                })
                .collect(),
        },
    }
}

impl From<&crate::manifest::ManifestParameter> for ParameterSummary {
    fn from(param: &crate::manifest::ManifestParameter) -> Self {
        Self {
            name: param.name.clone(),
            ty: param.kind.clone(),
        }
    }
}

impl From<&ManifestPermissionContract> for PermissionContractSummary {
    fn from(contract: &ManifestPermissionContract) -> Self {
        match contract {
            ManifestPermissionContract::Wildcard(value) => {
                PermissionContractSummary::Wildcard(value.clone())
            }
            ManifestPermissionContract::Hash { hash } => {
                PermissionContractSummary::Hash(hash.clone())
            }
            ManifestPermissionContract::Group { group } => {
                PermissionContractSummary::Group(group.clone())
            }
            ManifestPermissionContract::Other(value) => {
                PermissionContractSummary::Other(value.clone())
            }
        }
    }
}

impl From<&ManifestPermissionMethods> for PermissionMethodsSummary {
    fn from(methods: &ManifestPermissionMethods) -> Self {
        match methods {
            ManifestPermissionMethods::Wildcard(value) => {
                PermissionMethodsSummary::Wildcard(value.clone())
            }
            ManifestPermissionMethods::Methods(list) => {
                PermissionMethodsSummary::Methods(list.clone())
            }
        }
    }
}

impl From<&ManifestTrusts> for TrustSummary {
    fn from(trusts: &ManifestTrusts) -> Self {
        match trusts {
            ManifestTrusts::Wildcard(value) => TrustSummary::Wildcard(value.clone()),
            ManifestTrusts::Contracts(values) => TrustSummary::Contracts(values.clone()),
            ManifestTrusts::Other(value) => TrustSummary::Other(value.clone()),
        }
    }
}