testnumbat_wasm_debug/testdenali_step/
sc_deploy.rs

1use testnumbat_wasm::types::Address;
2use testdenali::{TxDeploy, TxExpect};
3
4use crate::{
5    execute_helper_functions::*, execute_tx, AsyncCallTxData, BlockchainMock, BlockchainMockError,
6    ContractMap, TxContext, TxInput, TxOutput, TxResult,
7};
8
9pub fn execute(
10    state: &mut BlockchainMock,
11    contract_map: &ContractMap<TxContext>,
12    tx_id: &str,
13    tx: &TxDeploy,
14    expect: &Option<TxExpect>,
15) {
16    let tx_input = TxInput {
17        from: tx.from.value.into(),
18        to: Address::zero(),
19        call_value: tx.call_value.value.clone(),
20        dcdt_value: tx.dcdt_value.value.clone(),
21        dcdt_token_identifier: tx.dcdt_token_identifier.value.clone(),
22        func_name: b"init".to_vec(),
23        args: tx
24            .arguments
25            .iter()
26            .map(|scen_arg| scen_arg.value.clone())
27            .collect(),
28        gas_limit: tx.gas_limit.value,
29        gas_price: tx.gas_price.value,
30        tx_hash: generate_tx_hash_dummy(tx_id),
31    };
32    state.increase_nonce(&tx_input.from);
33    let (tx_result, _) = sc_create(tx_input, &tx.contract_code.value, state, contract_map).unwrap();
34    if let Some(tx_expect) = expect {
35        check_tx_output(tx_id, tx_expect, &tx_result);
36    }
37}
38
39pub fn sc_create(
40    tx_input: TxInput,
41    contract_path: &[u8],
42    state: &mut BlockchainMock,
43    contract_map: &ContractMap<TxContext>,
44) -> Result<(TxResult, Option<AsyncCallTxData>), BlockchainMockError> {
45    let from = tx_input.from.clone();
46    let to = tx_input.to.clone();
47    let call_value = tx_input.call_value.clone();
48    let blockchain_info = state.create_tx_info(&to);
49
50    state.subtract_tx_payment(&from, &call_value)?;
51    state.subtract_tx_gas(&from, tx_input.gas_limit, tx_input.gas_price);
52
53    let dcdt_token_identifier = tx_input.dcdt_token_identifier.clone();
54    let dcdt_value = tx_input.dcdt_value.clone();
55    let dcdt_used = !dcdt_token_identifier.is_empty() && dcdt_value > 0u32.into();
56
57    if dcdt_used {
58        state.substract_dcdt_balance(&from, &dcdt_token_identifier, &dcdt_value)
59    }
60
61    let tx_context = TxContext::new(blockchain_info, tx_input.clone(), TxOutput::default());
62    let mut tx_output = execute_tx(tx_context, contract_path, contract_map);
63
64    if tx_output.result.result_status == 0 {
65        let new_address = state.create_account_after_deploy(
66            &tx_input,
67            tx_output.contract_storage,
68            contract_path.to_vec(),
69        );
70        state.send_balance(
71            &new_address,
72            tx_output.send_balance_list.as_slice(),
73            &mut tx_output.result.result_logs,
74        )?;
75    } else {
76        state.increase_balance(&from, &call_value);
77
78        if dcdt_used {
79            state.increase_dcdt_balance(&from, &dcdt_token_identifier, &dcdt_value);
80        }
81    }
82
83    Ok((tx_output.result, tx_output.async_call))
84}