1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
use multiversx_sc::api::ESDT_TRANSFER_FUNC_NAME;
use crate::{
tx_execution::builtin_function_mocks::builtin_func_trait::BuiltinFunctionEsdtTransferInfo,
tx_mock::{BlockchainUpdate, TxCache, TxInput, TxResult},
};
use super::{
super::builtin_func_trait::BuiltinFunction,
transfer_common::{
execute_transfer_builtin_func, extract_transfer_info, ParsedTransferBuiltinFunCall,
RawEsdtTransfer,
},
};
pub struct ESDTTransfer;
impl BuiltinFunction for ESDTTransfer {
fn name(&self) -> &str {
ESDT_TRANSFER_FUNC_NAME
}
fn extract_esdt_transfers(&self, tx_input: &TxInput) -> BuiltinFunctionEsdtTransferInfo {
if let Ok(parsed_tx) = try_parse_input(tx_input) {
extract_transfer_info(parsed_tx)
} else {
BuiltinFunctionEsdtTransferInfo::empty(tx_input)
}
}
fn execute(&self, tx_input: TxInput, tx_cache: TxCache) -> (TxResult, BlockchainUpdate) {
match try_parse_input(&tx_input) {
Ok(parsed_tx) => {
execute_transfer_builtin_func(parsed_tx, self.name(), tx_input, tx_cache)
},
Err(message) => {
let err_result = TxResult::from_vm_error(message);
(err_result, BlockchainUpdate::empty())
},
}
}
}
fn try_parse_input(tx_input: &TxInput) -> Result<ParsedTransferBuiltinFunCall, &'static str> {
if tx_input.args.len() < 2 {
return Err("ESDTTransfer too few arguments");
}
let token_identifier = tx_input.args[0].clone();
let value_bytes = tx_input.args[1].clone();
let func_name = tx_input.func_name_from_arg_index(2);
let args = if tx_input.args.len() > 2 {
tx_input.args[3..].to_vec()
} else {
Vec::new()
};
Ok(ParsedTransferBuiltinFunCall {
destination: tx_input.to.clone(),
raw_esdt_transfers: vec![RawEsdtTransfer {
token_identifier,
nonce_bytes: Vec::new(),
value_bytes,
}],
func_name,
args,
})
}