fuels_programs/calls/
script_call.rs

1use std::{collections::HashSet, fmt::Debug};
2
3use fuel_tx::{ContractId, Output};
4use fuels_core::types::{
5    bech32::Bech32ContractId,
6    errors::{error, Result},
7    input::Input,
8};
9use itertools::chain;
10
11use crate::calls::utils::{generate_contract_inputs, generate_contract_outputs, sealed};
12
13#[derive(Debug, Clone)]
14/// Contains all data relevant to a single script call
15pub struct ScriptCall {
16    pub script_binary: Vec<u8>,
17    pub encoded_args: Result<Vec<u8>>,
18    pub inputs: Vec<Input>,
19    pub outputs: Vec<Output>,
20    pub external_contracts: Vec<Bech32ContractId>,
21}
22
23impl ScriptCall {
24    pub fn with_outputs(mut self, outputs: Vec<Output>) -> Self {
25        self.outputs = outputs;
26        self
27    }
28
29    pub fn with_inputs(mut self, inputs: Vec<Input>) -> Self {
30        self.inputs = inputs;
31        self
32    }
33
34    pub(crate) fn prepare_inputs_outputs(&self) -> Result<(Vec<Input>, Vec<Output>)> {
35        let contract_ids: HashSet<ContractId> = self
36            .external_contracts
37            .iter()
38            .map(|bech32| bech32.into())
39            .collect();
40        let num_of_contracts = contract_ids.len();
41
42        let inputs = chain!(generate_contract_inputs(contract_ids), self.inputs.clone(),).collect();
43
44        // Note the contract_outputs need to come first since the
45        // contract_inputs are referencing them via `output_index`. The node
46        // will, upon receiving our request, use `output_index` to index the
47        // `inputs` array we've sent over.
48        let outputs = chain!(
49            generate_contract_outputs(num_of_contracts),
50            self.outputs.clone(),
51        )
52        .collect();
53
54        Ok((inputs, outputs))
55    }
56
57    pub(crate) fn compute_script_data(&self) -> Result<Vec<u8>> {
58        self.encoded_args
59            .as_ref()
60            .map(|b| b.to_owned())
61            .map_err(|e| error!(Codec, "cannot encode script call arguments: {e}"))
62    }
63}
64
65impl sealed::Sealed for ScriptCall {}