Skip to content

Commit

Permalink
Merge branch 'master' into hal3e/provider-on-chain-api
Browse files Browse the repository at this point in the history
  • Loading branch information
hal3e committed Oct 19, 2022
2 parents f4140a6 + 1de9504 commit fdf638d
Show file tree
Hide file tree
Showing 13 changed files with 155 additions and 67 deletions.
9 changes: 9 additions & 0 deletions docs/src/contracts/interacting-with-contracts.md
Original file line number Diff line number Diff line change
Expand Up @@ -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).
46 changes: 30 additions & 16 deletions examples/contracts/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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()
Expand All @@ -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()
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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();

Expand Down Expand Up @@ -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?;
Expand Down Expand Up @@ -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?;
Expand Down Expand Up @@ -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(())
}

Expand All @@ -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
Expand Down Expand Up @@ -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]);
Expand Down Expand Up @@ -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());
Expand Down Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion examples/cookbook/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
24 changes: 12 additions & 12 deletions examples/types/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -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(())
}
Expand All @@ -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(())
Expand All @@ -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
Expand Down Expand Up @@ -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(())
Expand All @@ -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(())
Expand Down
3 changes: 1 addition & 2 deletions packages/fuels-abigen-macro/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(),
);
}
Expand Down
3 changes: 1 addition & 2 deletions packages/fuels-core/src/code_gen/abigen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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),*]}
}

Expand Down
98 changes: 80 additions & 18 deletions packages/fuels-types/src/bech32.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@ macro_rules! bech32type {
}

impl $i {
pub fn new<T: Into<Bytes32>>(hrp: &str, hash: T) -> Self {
pub fn new<T: Into<[u8; 32]>>(hrp: &str, hash: T) -> Self {
Self {
hrp: hrp.to_string(),
hash: hash.into(),
hash: Bytes32::from(hash.into()),
}
}

Expand Down Expand Up @@ -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());
}
}
}
}
7 changes: 4 additions & 3 deletions packages/fuels/tests/bindings.rs
Original file line number Diff line number Diff line change
@@ -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]
Expand Down
Loading

0 comments on commit fdf638d

Please sign in to comment.