numbat_wasm_debug/
builtin_func_exec.rs

1use numbat_wasm::types::Address;
2use num_bigint::BigUint;
3
4use crate::*;
5
6const DCDT_TRANSFER_FUNC: &[u8] = b"DCDTTransfer";
7const SET_USERNAME_FUNC: &[u8] = b"SetUserName";
8
9pub fn try_execute_builtin_function(
10    tx_input: &TxInput,
11    state: &mut BlockchainMock,
12) -> Option<TxResult> {
13    match tx_input.func_name.as_slice() {
14        DCDT_TRANSFER_FUNC => Some(execute_dcdt_transfer(tx_input, state)),
15        SET_USERNAME_FUNC => Some(execute_set_username(tx_input, state)),
16        _ => None,
17    }
18}
19
20fn execute_dcdt_transfer(tx_input: &TxInput, state: &mut BlockchainMock) -> TxResult {
21    let from = tx_input.from.clone();
22    let to = tx_input.to.clone();
23    let dcdt_token_identifier = tx_input.dcdt_token_identifier.clone();
24    let dcdt_value = tx_input.dcdt_value.clone();
25
26    state.substract_dcdt_balance(&from, &dcdt_token_identifier, &dcdt_value);
27    state.increase_dcdt_balance(&to, &dcdt_token_identifier, &dcdt_value);
28    TxResult {
29        result_status: 0,
30        result_message: Vec::new(),
31        result_values: Vec::new(),
32        result_logs: vec![dcdt_transfer_event_log(
33            from,
34            to,
35            dcdt_token_identifier,
36            &dcdt_value,
37        )],
38    }
39}
40
41pub fn dcdt_transfer_event_log(
42    from: Address,
43    to: Address,
44    dcdt_token_identifier: Vec<u8>,
45    dcdt_value: &BigUint,
46) -> TxLog {
47    let nonce_topic = Vec::<u8>::new();
48    TxLog {
49        address: from,
50        endpoint: b"DCDTTransfer".to_vec(),
51        topics: vec![
52            dcdt_token_identifier,
53            nonce_topic,
54            dcdt_value.to_bytes_be(),
55            to.to_vec(),
56        ],
57        data: vec![],
58    }
59}
60
61fn execute_set_username(tx_input: &TxInput, state: &mut BlockchainMock) -> TxResult {
62    assert_eq!(tx_input.args.len(), 1, "SetUserName expects 1 argument");
63    if state.try_set_username(&tx_input.to, tx_input.args[0].as_slice()) {
64        TxResult::empty()
65    } else {
66        TxResult {
67            result_status: 10,
68            result_message: b"username already set".to_vec(),
69            result_values: Vec::new(),
70            result_logs: Vec::new(),
71        }
72    }
73}