@@ -3,18 +3,19 @@ use crate::{
3
3
op:: call:: {
4
4
missing_contracts:: determine_missing_contracts,
5
5
parser:: { param_type_val_to_token, token_to_string} ,
6
- CallResponse , Either ,
6
+ Abi , CallData , CallResponse , Either ,
7
7
} ,
8
8
} ;
9
9
use anyhow:: { anyhow, bail, Result } ;
10
- use fuel_abi_types:: abi:: { program :: ProgramABI , unified_program:: UnifiedProgramABI } ;
10
+ use fuel_abi_types:: abi:: unified_program:: UnifiedProgramABI ;
11
11
use fuels:: {
12
12
accounts:: ViewOnlyAccount ,
13
13
programs:: calls:: {
14
14
receipt_parser:: ReceiptParser ,
15
15
traits:: { ContractDependencyConfigurator , TransactionTuner } ,
16
16
ContractCall ,
17
17
} ,
18
+ types:: tx_status:: TxStatus ,
18
19
} ;
19
20
use fuels_core:: {
20
21
codec:: {
@@ -29,7 +30,7 @@ use fuels_core::{
29
30
ContractId ,
30
31
} ,
31
32
} ;
32
- use std:: { collections:: HashMap , path:: PathBuf } ;
33
+ use std:: { collections:: HashMap , path:: PathBuf , str :: FromStr } ;
33
34
use url:: Url ;
34
35
35
36
/// Calls a contract function with the given parameters
@@ -46,20 +47,19 @@ pub async fn call_function(
46
47
caller,
47
48
call_parameters,
48
49
gas,
49
- output,
50
+ mut output,
50
51
external_contracts,
51
52
..
52
53
} = cmd;
53
54
54
55
// Load ABI (already provided in the operation)
55
56
let abi_str = super :: load_abi ( & abi) . await ?;
56
- let parsed_abi: ProgramABI = serde_json:: from_str ( & abi_str) ?;
57
- let unified_program_abi = UnifiedProgramABI :: from_counterpart ( & parsed_abi) ?;
57
+ let abi = Abi :: from_str ( & abi_str) . map_err ( |e| anyhow ! ( "Failed to parse ABI: {}" , e) ) ?;
58
58
59
59
let cmd:: call:: FuncType :: Selector ( selector) = function;
60
60
61
61
let ( encoded_data, output_param) =
62
- prepare_contract_call_data ( & unified_program_abi , & selector, & function_args) ?;
62
+ prepare_contract_call_data ( & abi . unified , & selector, & function_args) ?;
63
63
64
64
// Setup connection to node
65
65
let ( wallet, tx_policies, base_asset_id) = super :: setup_connection ( & node, caller, & gas) . await ?;
@@ -84,8 +84,10 @@ pub async fn call_function(
84
84
85
85
// Setup variable output policy and log decoder
86
86
let variable_output_policy = VariableOutputPolicy :: Exactly ( call_parameters. amount as usize ) ;
87
- let error_codes = unified_program_abi
87
+ let error_codes = abi
88
+ . unified
88
89
. error_codes
90
+ . as_ref ( )
89
91
. map_or ( HashMap :: new ( ) , |error_codes| {
90
92
error_codes
91
93
. iter ( )
@@ -193,7 +195,7 @@ pub async fn call_function(
193
195
} ;
194
196
195
197
// Display the script JSON when verbosity level is 2 or higher (vv)
196
- let script = if cmd. verbosity >= 2 {
198
+ let script_json = if cmd. verbosity >= 2 {
197
199
let script_json = serde_json:: to_value ( & script) . unwrap ( ) ;
198
200
forc_tracing:: println_label_green (
199
201
"transaction script:\n " ,
@@ -204,10 +206,28 @@ pub async fn call_function(
204
206
None
205
207
} ;
206
208
209
+ let abi_map = HashMap :: from ( [ ( contract_id, abi) ] ) ;
210
+
207
211
// Process transaction results
208
- let receipts = tx_status
209
- . take_receipts_checked ( Some ( & log_decoder) )
210
- . map_err ( |e| anyhow ! ( "Failed to take receipts: {e}" ) ) ?;
212
+ let receipts = match tx_status. clone ( ) . take_receipts_checked ( Some ( & log_decoder) ) {
213
+ Ok ( receipts) => receipts,
214
+ Err ( e) => {
215
+ // Print receipts when an error occurs and verbosity is high enough
216
+ super :: print_receipts_and_trace (
217
+ tx_status. total_gas ( ) ,
218
+ & tx_status. clone ( ) . take_receipts ( ) ,
219
+ cmd. verbosity ,
220
+ & abi_map,
221
+ & mut output,
222
+ ) ?;
223
+ match tx_status {
224
+ TxStatus :: Failure ( e) | TxStatus :: PreconfirmationFailure ( e) => {
225
+ bail ! ( "Failed to process transaction; reason: {:#?}" , e. reason) ;
226
+ }
227
+ _ => bail ! ( "Failed to process transaction: {:#?}" , e) ,
228
+ }
229
+ }
230
+ } ;
211
231
212
232
// Parse the result based on output format
213
233
let mut receipt_parser = ReceiptParser :: new ( & receipts, DecoderConfig :: default ( ) ) ;
@@ -230,18 +250,21 @@ pub async fn call_function(
230
250
} ;
231
251
232
252
// Process and return the final output
233
- let program_abi = sway_core:: asm_generation:: ProgramABI :: Fuel ( parsed_abi) ;
234
253
let mut call_response = super :: process_transaction_output (
235
- & receipts ,
254
+ tx_status ,
236
255
& tx_hash. to_string ( ) ,
237
- & program_abi,
238
- Some ( result) ,
239
256
& mode,
240
257
& node,
241
258
cmd. verbosity ,
259
+ & mut output,
260
+ Some ( CallData {
261
+ contract_id,
262
+ abis : abi_map,
263
+ result,
264
+ } ) ,
242
265
) ?;
243
266
if cmd. verbosity >= 2 {
244
- call_response. script = script ;
267
+ call_response. script_json = script_json ;
245
268
}
246
269
247
270
Ok ( call_response)
@@ -855,7 +878,7 @@ pub mod tests {
855
878
. await
856
879
. unwrap_err( )
857
880
. to_string( )
858
- . contains( "PanicInstruction { reason: NotEnoughBalance" ) ) ;
881
+ . contains( "Failed to process transaction; reason: \" NotEnoughBalance\" " ) ) ;
859
882
assert_eq ! ( get_contract_balance( id, provider. clone( ) ) . await , 1 ) ;
860
883
861
884
// contract call transfer funds to another address
0 commit comments