neo_solidity/cli/cli_parts/
cli_deploy.rs

1fn ensure_deploy_stub(metadata: &mut ContractMetadata) -> Result<(), CompileError> {
2    const DEPLOY_NAME: &str = "_deploy";
3
4    if metadata.methods.iter().any(|m| m.name == DEPLOY_NAME) {
5        return Ok(());
6    }
7
8    let constructors: Vec<&FunctionMetadata> = metadata
9        .methods
10        .iter()
11        .filter(|function| matches!(function.kind, FunctionKind::Constructor))
12        .collect();
13
14    if constructors.len() > 1 {
15        return Err(CompileError::Message(
16            "multiple constructors are not supported".to_string(),
17        ));
18    }
19
20    // Parameterised constructors are supported via `_deploy(data, update)`.
21    // When the Solidity constructor requires arguments, `data` is treated as an array
22    // of constructor args. Tooling commonly passes this as a JSON-encoded array string
23    // (e.g., `[7]`); the injected deploy prologue attempts StdLib.jsonDeserialize, then
24    // StdLib.deserialize (for StdLib.serialize(...) bytes), and finally falls back to
25    // using `data` as-is if native calls throw.
26
27    let deploy_params = vec![
28        ParameterMetadata {
29            name: Some("data".to_string()),
30            ty: "Any".to_string(),
31            neo_type: Some(NeoType::Any),
32            storage: None,
33        },
34        ParameterMetadata {
35            name: Some("update".to_string()),
36            ty: "bool".to_string(),
37            neo_type: Some(NeoType::Boolean),
38            storage: None,
39        },
40    ];
41
42    let signature = format!(
43        "{}_({},{})",
44        DEPLOY_NAME, deploy_params[0].ty, deploy_params[1].ty
45    );
46    let mut hasher = Keccak256::new();
47    hasher.update(signature.as_bytes());
48    let digest = hasher.finalize();
49    let mut selector = [0u8; 4];
50    selector.copy_from_slice(&digest[..4]);
51
52    metadata.methods.push(FunctionMetadata {
53        name: DEPLOY_NAME.to_string(),
54        neo_name: DEPLOY_NAME.to_string(),
55        kind: FunctionKind::Regular,
56        parameters: deploy_params,
57        return_parameters: vec![],
58        state_mutability: StateMutability::NonPayable,
59        visibility: VisibilityKind::Public,
60        offset: 0,
61        body: None,
62        selector,
63        is_virtual: false,
64        is_override: false,
65        documentation: NatspecDoc::default(),
66    });
67
68    Ok(())
69}