From 1de9504ddb14df6008464775086c92c7cb743f11 Mon Sep 17 00:00:00 2001 From: Ahmed Mujkic <32431923+MujkicA@users.noreply.github.com> Date: Wed, 19 Oct 2022 12:32:59 +0200 Subject: [PATCH] feat!: Enforce Bech32 type-safety on contract instance creation (#622) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Changes contract instantiation to accept a `Bech32ContractId` instead of a string. Co-authored-by: Halil Beglerović Co-authored-by: iqdecay Co-authored-by: Rodrigo Araújo Co-authored-by: Ahmed Sagdati <37515857+segfault-magnet@users.noreply.github.com> --- .../contracts/interacting-with-contracts.md | 9 ++ examples/contracts/src/lib.rs | 46 ++++++--- examples/cookbook/src/lib.rs | 2 +- examples/types/src/lib.rs | 24 ++--- packages/fuels-abigen-macro/src/lib.rs | 3 +- packages/fuels-core/src/code_gen/abigen.rs | 3 +- packages/fuels-types/src/bech32.rs | 98 +++++++++++++++---- packages/fuels/tests/bindings.rs | 7 +- packages/fuels/tests/contracts.rs | 6 +- packages/fuels/tests/from_token.rs | 7 +- packages/fuels/tests/providers.rs | 6 +- packages/fuels/tests/storage.rs | 4 +- packages/fuels/tests/types.rs | 7 +- 13 files changed, 155 insertions(+), 67 deletions(-) diff --git a/docs/src/contracts/interacting-with-contracts.md b/docs/src/contracts/interacting-with-contracts.md index ed921a2ecb..95b14580d3 100644 --- a/docs/src/contracts/interacting-with-contracts.md +++ b/docs/src/contracts/interacting-with-contracts.md @@ -4,3 +4,12 @@ If you already have a deployed contract and want to call its methods using the S ```rust,ignore {{#include ../../../examples/contracts/src/lib.rs:deployed_contracts}} +``` + +The above example assumes that your contract id string is encoded in the bech32m format. You can recognize it by the human-readable-part "fuel" followed by the separator "1". However, when using other Fuel tools, you might end up with a hex-encoded contract id string. In that case, you can create your contract instance as follows: + +```rust,ignore +{{#include ../../../examples/contracts/src/lib.rs:deployed_contracts_hex}} +``` + +You can learn more about the Fuel SDK bech32 types [here](../types/bech32.md). diff --git a/examples/contracts/src/lib.rs b/examples/contracts/src/lib.rs index 4ac71e8378..975f5f947a 100644 --- a/examples/contracts/src/lib.rs +++ b/examples/contracts/src/lib.rs @@ -56,7 +56,7 @@ mod tests { // ANCHOR: use_deployed_contract // This is an instance of your contract which you can use to make calls to your functions - let contract_instance = MyContract::new(contract_id.to_string(), wallet); + let contract_instance = MyContract::new(contract_id, wallet); let response = contract_instance .methods() @@ -121,7 +121,7 @@ mod tests { .await?; // ANCHOR: contract_call_cost_estimation - let contract_instance = MyContract::new(contract_id.to_string(), wallet); + let contract_instance = MyContract::new(contract_id, wallet); let tolerance = 0.0; let transaction_cost = contract_instance @@ -201,7 +201,7 @@ mod tests { .await?; println!("Contract deployed @ {contract_id_1}"); - let contract_instance_1 = MyContract::new(contract_id_1.to_string(), wallets[0].clone()); + let contract_instance_1 = MyContract::new(contract_id_1, wallets[0].clone()); let response = contract_instance_1 .methods() @@ -221,7 +221,7 @@ mod tests { .await?; println!("Contract deployed @ {contract_id_2}"); - let contract_instance_2 = MyContract::new(contract_id_2.to_string(), wallets[1].clone()); + let contract_instance_2 = MyContract::new(contract_id_2, wallets[1].clone()); let response = contract_instance_2 .methods() @@ -255,7 +255,7 @@ mod tests { println!("Contract deployed @ {contract_id}"); // ANCHOR: instantiate_contract // ANCHOR: tx_parameters - let contract_methods = MyContract::new(contract_id.to_string(), wallet.clone()).methods(); + let contract_methods = MyContract::new(contract_id.clone(), wallet.clone()).methods(); // ANCHOR_END: instantiate_contract // In order: gas_price, gas_limit, and maturity @@ -287,7 +287,7 @@ mod tests { .await?; // This is an async call, `.await` for it. // ANCHOR: call_parameters - let contract_methods = MyContract::new(contract_id.to_string(), wallet.clone()).methods(); + let contract_methods = MyContract::new(contract_id, wallet.clone()).methods(); let tx_params = TxParameters::default(); @@ -332,7 +332,7 @@ mod tests { ) .await?; println!("Contract deployed @ {contract_id}"); - let contract_methods = MyContract::new(contract_id.to_string(), wallet.clone()).methods(); + let contract_methods = MyContract::new(contract_id.clone(), wallet.clone()).methods(); // ANCHOR: simulate // you would mint 100 coins if the transaction wasn't simulated let counter = contract_methods.mint_coins(100).simulate().await?; @@ -369,7 +369,7 @@ mod tests { StorageConfiguration::default(), ) .await?; - let contract_methods = TestContract::new(contract_id.to_string(), wallet).methods(); + let contract_methods = TestContract::new(contract_id, wallet).methods(); // ANCHOR: good_practice let response = contract_methods.increment_counter(162).call().await?; @@ -404,14 +404,28 @@ mod tests { MyContract, "packages/fuels/tests/contracts/contract_test/out/debug/contract_test-abi.json" ); - let wallet = launch_provider_and_get_wallet().await; - // Your contract ID as a String. - let contract_id = - "fuel1vkm285ypjesypw7vhdlhnty3kjxxx4efckdycqh3ttna4xvmxtfs6murwy".to_string(); + let wallet_original = launch_provider_and_get_wallet().await; + + let wallet = wallet_original.clone(); + // Your bech32m encoded contract ID. + let contract_id: Bech32ContractId = + "fuel1vkm285ypjesypw7vhdlhnty3kjxxx4efckdycqh3ttna4xvmxtfs6murwy" + .parse() + .expect("Invalid ID"); let connected_contract_instance = MyContract::new(contract_id, wallet); // You can now use the `connected_contract_instance` just as you did above! // ANCHOR_END: deployed_contracts + + let wallet = wallet_original; + // ANCHOR: deployed_contracts_hex + let contract_id: ContractId = + "0x65b6a3d081966040bbccbb7f79ac91b48c635729c59a4c02f15ae7da999b32d3" + .parse() + .expect("Invalid ID"); + let connected_contract_instance = MyContract::new(contract_id.into(), wallet); + // ANCHOR_END: deployed_contracts_hex + Ok(()) } @@ -434,7 +448,7 @@ mod tests { ) .await?; - let contract_methods = MyContract::new(contract_id.to_string(), wallet.clone()).methods(); + let contract_methods = MyContract::new(contract_id, wallet.clone()).methods(); // ANCHOR: call_params_gas // Set the transaction `gas_limit` to 1000 and `gas_forwarded` to 200 to specify that the @@ -474,7 +488,7 @@ mod tests { .await?; // ANCHOR: multi_call_prepare - let contract_methods = MyContract::new(contract_id.to_string(), wallet.clone()).methods(); + let contract_methods = MyContract::new(contract_id, wallet.clone()).methods(); let call_handler_1 = contract_methods.initialize_counter(42); let call_handler_2 = contract_methods.get_array([42; 2]); @@ -522,7 +536,7 @@ mod tests { ) .await?; - let contract_methods = MyContract::new(contract_id.to_string(), wallet.clone()).methods(); + let contract_methods = MyContract::new(contract_id, wallet.clone()).methods(); // ANCHOR: multi_call_cost_estimation let mut multi_call_handler = MultiContractCallHandler::new(wallet.clone()); @@ -569,7 +583,7 @@ mod tests { // ANCHOR: connect_wallet // Create contract instance with wallet_1 - let contract_instance = MyContract::new(contract_id.to_string(), wallet_1.clone()); + let contract_instance = MyContract::new(contract_id, wallet_1.clone()); // Perform contract call with wallet_2 let response = contract_instance diff --git a/examples/cookbook/src/lib.rs b/examples/cookbook/src/lib.rs index 46e960259b..69a6ef8a9b 100644 --- a/examples/cookbook/src/lib.rs +++ b/examples/cookbook/src/lib.rs @@ -43,7 +43,7 @@ mod tests { ) .await?; - let contract_methods = MyContract::new(contract_id.to_string(), wallet.clone()).methods(); + let contract_methods = MyContract::new(contract_id.clone(), wallet.clone()).methods(); // ANCHOR_END: liquidity_deploy // ANCHOR: liquidity_deposit diff --git a/examples/types/src/lib.rs b/examples/types/src/lib.rs index d8c5deab71..efad645c94 100644 --- a/examples/types/src/lib.rs +++ b/examples/types/src/lib.rs @@ -25,8 +25,8 @@ mod tests { assert_eq!([1u8; 32], *b256); // From a hex string. - let hex_string = "0x0000000000000000000000000000000000000000000000000000000000000000"; - let b256 = Bytes32::from_str(hex_string).expect("failed to create Bytes32 from string"); + let hex_str = "0x0000000000000000000000000000000000000000000000000000000000000000"; + let b256 = Bytes32::from_str(hex_str).expect("failed to create Bytes32 from string"); assert_eq!([0u8; 32], *b256); // ANCHOR_END: bytes32 @@ -35,8 +35,8 @@ mod tests { let b256_hex_string = format!("{:#x}", b256); // ANCHOR_END: bytes32_format - assert_eq!(hex_string[2..], b256_string); - assert_eq!(hex_string, b256_hex_string); + assert_eq!(hex_str[2..], b256_string); + assert_eq!(hex_str, b256_hex_string); Ok(()) } @@ -59,8 +59,8 @@ mod tests { assert_eq!([1u8; 32], *address); // From a string. - let hex_string = "0x0000000000000000000000000000000000000000000000000000000000000000"; - let address = Address::from_str(hex_string).expect("failed to create Address from string"); + let hex_str = "0x0000000000000000000000000000000000000000000000000000000000000000"; + let address = Address::from_str(hex_str).expect("failed to create Address from string"); assert_eq!([0u8; 32], *address); // ANCHOR_END: address Ok(()) @@ -81,9 +81,9 @@ mod tests { let _bech32_address = Bech32Address::new(hrp, my_hash); // From a string. - let string = "fuel1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqsx2mt2"; + let address = "fuel1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqsx2mt2"; let bech32_address = - Bech32Address::from_str(string).expect("failed to create Bech32 address from string"); + Bech32Address::from_str(address).expect("failed to create Bech32 address from string"); assert_eq!([0u8; 32], *bech32_address.hash()); // From Address @@ -117,8 +117,8 @@ mod tests { assert_eq!([1u8; 32], *asset_id); // From a string. - let hex_string = "0x0000000000000000000000000000000000000000000000000000000000000000"; - let asset_id = AssetId::from_str(hex_string).expect("failed to create AssetId from string"); + let hex_str = "0x0000000000000000000000000000000000000000000000000000000000000000"; + let asset_id = AssetId::from_str(hex_str).expect("failed to create AssetId from string"); assert_eq!([0u8; 32], *asset_id); // ANCHOR_END: asset_id Ok(()) @@ -142,9 +142,9 @@ mod tests { assert_eq!([1u8; 32], *contract_id); // From a string. - let hex_string = "0x0000000000000000000000000000000000000000000000000000000000000000"; + let hex_str = "0x0000000000000000000000000000000000000000000000000000000000000000"; let contract_id = - ContractId::from_str(hex_string).expect("failed to create ContractId from string"); + ContractId::from_str(hex_str).expect("failed to create ContractId from string"); assert_eq!([0u8; 32], *contract_id); // ANCHOR_END: contract_id Ok(()) diff --git a/packages/fuels-abigen-macro/src/lib.rs b/packages/fuels-abigen-macro/src/lib.rs index 431c93c522..7b7092c560 100644 --- a/packages/fuels-abigen-macro/src/lib.rs +++ b/packages/fuels-abigen-macro/src/lib.rs @@ -110,8 +110,7 @@ pub fn setup_contract_test(input: TokenStream) -> TokenStream { Salt::from([#(#salt),*]), ) .await - .expect("Failed to deploy the contract") - .to_string(), + .expect("Failed to deploy the contract"), #wallet_name.clone(), ); } diff --git a/packages/fuels-core/src/code_gen/abigen.rs b/packages/fuels-core/src/code_gen/abigen.rs index b35771c174..0ba950f4fb 100644 --- a/packages/fuels-core/src/code_gen/abigen.rs +++ b/packages/fuels-core/src/code_gen/abigen.rs @@ -128,8 +128,7 @@ impl Abigen { } impl #name { - pub fn new(contract_id: String, wallet: WalletUnlocked) -> Self { - let contract_id = Bech32ContractId::from_str(&contract_id).expect("Invalid contract id"); + pub fn new(contract_id: Bech32ContractId, wallet: WalletUnlocked) -> Self { Self { contract_id, wallet, logs_lookup: vec![#(#log_id_param_type_pairs),*]} } diff --git a/packages/fuels-types/src/bech32.rs b/packages/fuels-types/src/bech32.rs index e6c3e5f25f..5f070621e1 100644 --- a/packages/fuels-types/src/bech32.rs +++ b/packages/fuels-types/src/bech32.rs @@ -20,10 +20,10 @@ macro_rules! bech32type { } impl $i { - pub fn new>(hrp: &str, hash: T) -> Self { + pub fn new>(hrp: &str, hash: T) -> Self { Self { hrp: hrp.to_string(), - hash: hash.into(), + hash: Bytes32::from(hash.into()), } } @@ -114,32 +114,94 @@ mod test { #[test] fn test_new() { let pubkey_hash = [ - 48, 101, 49, 52, 48, 102, 48, 55, 48, 100, 49, 97, 102, 117, 51, 57, 49, 50, 48, 54, - 48, 98, 48, 100, 48, 56, 49, 53, 48, 52, 49, 52, + 107, 50, 223, 89, 84, 225, 186, 222, 175, 254, 253, 44, 15, 197, 229, 148, 220, 255, + 55, 19, 170, 227, 221, 24, 183, 217, 102, 98, 75, 1, 0, 39, ]; - let expected_address = Address::new(pubkey_hash); - let bech32_addr = &Bech32Address::new(FUEL_BECH32_HRP, Bytes32::new(pubkey_hash)); - let plain_addr: Address = bech32_addr.into(); + { + // Create from Bytes32 + let bech32_addr = &Bech32Address::new(FUEL_BECH32_HRP, Bytes32::new(pubkey_hash)); + let bech32_cid = &Bech32ContractId::new(FUEL_BECH32_HRP, Bytes32::new(pubkey_hash)); - assert_eq!(plain_addr, expected_address); + assert_eq!(*bech32_addr.hash(), pubkey_hash); + assert_eq!(*bech32_cid.hash(), pubkey_hash); + } + + { + // Create from ContractId + let bech32_addr = &Bech32Address::new(FUEL_BECH32_HRP, ContractId::new(pubkey_hash)); + let bech32_cid = &Bech32ContractId::new(FUEL_BECH32_HRP, ContractId::new(pubkey_hash)); + + assert_eq!(*bech32_addr.hash(), pubkey_hash); + assert_eq!(*bech32_cid.hash(), pubkey_hash); + } + + { + // Create from Address + let bech32_addr = &Bech32Address::new(FUEL_BECH32_HRP, Address::new(pubkey_hash)); + let bech32_cid = &Bech32ContractId::new(FUEL_BECH32_HRP, Address::new(pubkey_hash)); + + assert_eq!(*bech32_addr.hash(), pubkey_hash); + assert_eq!(*bech32_cid.hash(), pubkey_hash); + } } #[test] fn test_from_str() { - let pubkey_hash = [ - 48, 101, 49, 52, 48, 102, 48, 55, 48, 100, 49, 97, 102, 117, 51, 57, 49, 50, 48, 54, - 48, 98, 48, 100, 48, 56, 49, 53, 48, 52, 49, 52, + let pubkey_hashes = [ + [ + 107, 50, 223, 89, 84, 225, 186, 222, 175, 254, 253, 44, 15, 197, 229, 148, 220, + 255, 55, 19, 170, 227, 221, 24, 183, 217, 102, 98, 75, 1, 0, 39, + ], + [ + 49, 83, 18, 64, 150, 242, 119, 146, 83, 184, 84, 96, 160, 212, 110, 69, 81, 34, + 101, 86, 182, 99, 62, 68, 44, 28, 40, 26, 131, 21, 221, 64, + ], + [ + 48, 101, 49, 52, 48, 102, 48, 55, 48, 100, 49, 97, 102, 117, 51, 57, 49, 50, 48, + 54, 48, 98, 48, 100, 48, 56, 49, 53, 48, 52, 49, 52, + ], ]; - - let bech32_contract_id = &Bech32ContractId::from_str( + let bech32m_encodings = [ + "fuel1dved7k25uxadatl7l5kql309jnw07dcn4t3a6x9hm9nxyjcpqqns50p7n2", + "fuel1x9f3ysyk7fmey5ac23s2p4rwg4gjye2kke3nu3pvrs5p4qc4m4qqwx56k3", "fuel1xpjnzdpsvccrwvryx9skvafn8ycnyvpkxp3rqeps8qcn2vp5xy6qu7yyz7", - ) - .unwrap(); - let plain_contract_id: ContractId = bech32_contract_id.into(); + ]; - let expected_contract_id = ContractId::new(pubkey_hash); + for (b32m_e, pbkh) in bech32m_encodings.iter().zip(pubkey_hashes) { + let bech32_contract_id = &Bech32ContractId::from_str(b32m_e).unwrap(); + assert_eq!(*bech32_contract_id.hash(), pbkh); + } - assert_eq!(plain_contract_id, expected_contract_id); + for (b32m_e, pbkh) in bech32m_encodings.iter().zip(pubkey_hashes) { + let bech32_contract_id = &Bech32Address::from_str(b32m_e).unwrap(); + assert_eq!(*bech32_contract_id.hash(), pbkh); + } + } + + #[test] + fn test_from_invalid_bech32_string() { + { + let expected = [ + Error::from(bech32::Error::InvalidChecksum), + Error::from(bech32::Error::InvalidChar('b')), + Error::from(bech32::Error::MissingSeparator), + ]; + let invalid_bech32 = [ + "fuel1x9f3ysyk7fmey5ac23s2p4rwg4gjye2kke3nu3pvrs5p4qc4m4qqwx32k3", + "fuel1xpjnzdpsvccrwvryx9skvafn8ycnyvpkxp3rqeps8qcn2vp5xy6qu7yyb7", + "fuelldved7k25uxadatl7l5kql309jnw07dcn4t3a6x9hm9nxyjcpqqns50p7n2", + ]; + + for (b32m_e, e) in invalid_bech32.iter().zip(expected.iter()) { + let result = &Bech32ContractId::from_str(b32m_e).expect_err("should error"); + assert_eq!(result.to_string(), e.to_string()); + } + + for (b32m_e, e) in invalid_bech32.iter().zip(expected) { + let result = &Bech32Address::from_str(b32m_e).expect_err("should error"); + assert_eq!(result.to_string(), e.to_string()); + } + } } } diff --git a/packages/fuels/tests/bindings.rs b/packages/fuels/tests/bindings.rs index a9c7a8f597..13f2b33177 100644 --- a/packages/fuels/tests/bindings.rs +++ b/packages/fuels/tests/bindings.rs @@ -1,11 +1,12 @@ use fuels::core::abi_encoder::ABIEncoder; use fuels::prelude::*; use sha2::{Digest, Sha256}; -use std::slice; +use std::{slice, str::FromStr}; -pub fn null_contract_id() -> String { +pub fn null_contract_id() -> Bech32ContractId { // a bech32 contract address that decodes to ~[0u8;32] - String::from("fuel1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqsx2mt2") + Bech32ContractId::from_str("fuel1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqsx2mt2") + .unwrap() } #[tokio::test] diff --git a/packages/fuels/tests/contracts.rs b/packages/fuels/tests/contracts.rs index b7fec4274d..47f55cac06 100644 --- a/packages/fuels/tests/contracts.rs +++ b/packages/fuels/tests/contracts.rs @@ -473,7 +473,7 @@ async fn test_output_variable_estimation() -> Result<(), Error> { let (wallets, addresses, mint_asset_id, contract_id) = setup_output_variable_estimation_test().await?; - let contract_instance = MyContract::new(contract_id.to_string(), wallets[0].clone()); + let contract_instance = MyContract::new(contract_id, wallets[0].clone()); let contract_methods = contract_instance.methods(); let amount = 1000; @@ -525,7 +525,7 @@ async fn test_output_variable_estimation_default_attempts() -> Result<(), Error> let (wallets, addresses, mint_asset_id, contract_id) = setup_output_variable_estimation_test().await?; - let contract_instance = MyContract::new(contract_id.to_string(), wallets[0].clone()); + let contract_instance = MyContract::new(contract_id, wallets[0].clone()); let contract_methods = contract_instance.methods(); let amount = 1000; @@ -554,7 +554,7 @@ async fn test_output_variable_estimation_multicall() -> Result<(), Error> { let (wallets, addresses, mint_asset_id, contract_id) = setup_output_variable_estimation_test().await?; - let contract_instance = MyContract::new(contract_id.to_string(), wallets[0].clone()); + let contract_instance = MyContract::new(contract_id, wallets[0].clone()); let contract_methods = contract_instance.methods(); let amount = 1000; diff --git a/packages/fuels/tests/from_token.rs b/packages/fuels/tests/from_token.rs index 42724a3adc..a3e4fcfa05 100644 --- a/packages/fuels/tests/from_token.rs +++ b/packages/fuels/tests/from_token.rs @@ -1,8 +1,11 @@ +use std::str::FromStr; + use fuels::prelude::*; -pub fn null_contract_id() -> String { +pub fn null_contract_id() -> Bech32ContractId { // a bech32 contract address that decodes to ~[0u8;32] - String::from("fuel1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqsx2mt2") + Bech32ContractId::from_str("fuel1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqsx2mt2") + .unwrap() } #[tokio::test] diff --git a/packages/fuels/tests/providers.rs b/packages/fuels/tests/providers.rs index 09ec6ac1ce..521cb8554f 100644 --- a/packages/fuels/tests/providers.rs +++ b/packages/fuels/tests/providers.rs @@ -33,7 +33,7 @@ async fn test_provider_launch_and_connect() -> Result<(), Error> { ) .await?; - let contract_instance_connected = MyContract::new(contract_id.to_string(), wallet.clone()); + let contract_instance_connected = MyContract::new(contract_id.clone(), wallet.clone()); let response = contract_instance_connected .methods() @@ -43,7 +43,7 @@ async fn test_provider_launch_and_connect() -> Result<(), Error> { assert_eq!(42, response.value); wallet.set_provider(launched_provider); - let contract_instance_launched = MyContract::new(contract_id.to_string(), wallet); + let contract_instance_launched = MyContract::new(contract_id, wallet); let response = contract_instance_launched .methods() @@ -461,7 +461,7 @@ async fn testnet_hello_world() -> Result<(), Error> { ) .await?; - let contract_methods = MyContract::new(contract_id.to_string(), wallet.clone()).methods(); + let contract_methods = MyContract::new(contract_id, wallet.clone()).methods(); let response = contract_methods .initialize_counter(42) // Build the ABI call diff --git a/packages/fuels/tests/storage.rs b/packages/fuels/tests/storage.rs index ec4f39fd88..f763f87340 100644 --- a/packages/fuels/tests/storage.rs +++ b/packages/fuels/tests/storage.rs @@ -29,7 +29,7 @@ async fn test_storage_initialization() -> Result<(), Error> { .await?; // ANCHOR_END: manual_storage - let contract_instance = MyContract::new(contract_id.to_string(), wallet.clone()); + let contract_instance = MyContract::new(contract_id, wallet.clone()); let result = contract_instance .methods() @@ -70,7 +70,7 @@ async fn test_init_storage_automatically() -> Result<(), Error> { Bytes32::from_str("f383b0ce51358be57daa3b725fe44acdb2d880604e367199080b4379c41bb6ed") .unwrap(); - let contract_methods = MyContract::new(contract_id.to_string(), wallet.clone()).methods(); + let contract_methods = MyContract::new(contract_id, wallet.clone()).methods(); let value = contract_methods .get_value_b256(Bits256(*key1)) diff --git a/packages/fuels/tests/types.rs b/packages/fuels/tests/types.rs index 4f7005e9dc..74e512acbc 100644 --- a/packages/fuels/tests/types.rs +++ b/packages/fuels/tests/types.rs @@ -1,9 +1,10 @@ use fuels::prelude::*; use std::str::FromStr; -pub fn null_contract_id() -> String { +pub fn null_contract_id() -> Bech32ContractId { // a bech32 contract address that decodes to ~[0u8;32] - String::from("fuel1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqsx2mt2") + Bech32ContractId::from_str("fuel1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqsx2mt2") + .unwrap() } #[tokio::test] @@ -98,7 +99,7 @@ async fn call_with_structs() -> Result<(), Error> { ) .await?; - let contract_methods = MyContract::new(contract_id.to_string(), wallet).methods(); + let contract_methods = MyContract::new(contract_id, wallet).methods(); let response = contract_methods .initialize_counter(counter_config) // Build the ABI call