From 046cb1a97948003d8a83daff7cb06fccc9f1cd9a Mon Sep 17 00:00:00 2001 From: Tupui <23188539+tupui@users.noreply.github.com> Date: Thu, 1 Aug 2024 23:22:09 +0200 Subject: [PATCH 1/9] Structure for cross contract convention guide --- .../guides/conventions/cross-contract.mdx | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 docs/build/guides/conventions/cross-contract.mdx diff --git a/docs/build/guides/conventions/cross-contract.mdx b/docs/build/guides/conventions/cross-contract.mdx new file mode 100644 index 000000000..5ab1e1146 --- /dev/null +++ b/docs/build/guides/conventions/cross-contract.mdx @@ -0,0 +1,29 @@ +--- +title: Making Cross Contract Calls +description: Call a smart contract from within another smart contract +--- + +As with developing software in any language, developing a Soroban smart contract with a rich feature set can be a challenging and time-consuming task. Thankfully, someone else might already have solved part of your issues or build components which could be reused. The open source community is vibrant and Stellar's community does not disappoint. + +There are two kind of dependencies which can be introduced in a Soroban smart contract. + +1. Other Rust crates can be used (provided that they are compatible with Soroban's [Rust dialect](../../../learn/encyclopedia/contract-development/rust-dialect.mdx)); +2. Other smart contract can be used. This is referred to as a [Cross-Contract](../../../learn/encyclopedia/contract-development/contract-interactions/cross-contract.mdx) call. + +In the following, we will see how other contracts can be leveraged from within another contract. + +## Setup + + +## Making a cross contract call + +## Handling responses + +## Keeping up to date + + +## Examples + +See the following full example: + +- [Cross Contract Calls](../../smart-contracts/example-contracts/cross-contract-call.mdx) shows how to create two contracts and call one from each other. From b1b1691db49da61bcbbbe829905e2c5a15634d07 Mon Sep 17 00:00:00 2001 From: Tupui <23188539+tupui@users.noreply.github.com> Date: Fri, 2 Aug 2024 01:14:08 +0200 Subject: [PATCH 2/9] Deps section --- docs/build/guides/conventions/cross-contract.mdx | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/docs/build/guides/conventions/cross-contract.mdx b/docs/build/guides/conventions/cross-contract.mdx index 5ab1e1146..29f121dd4 100644 --- a/docs/build/guides/conventions/cross-contract.mdx +++ b/docs/build/guides/conventions/cross-contract.mdx @@ -12,8 +12,15 @@ There are two kind of dependencies which can be introduced in a Soroban smart co In the following, we will see how other contracts can be leveraged from within another contract. -## Setup +## Contract as a dependency +While finding a contract is out of scope for this guide, there are a few place to be on a lookout. Most project and dApp are publicly disclosing on their website the address of their Soroban smart contract. With this information, a [block explorer](../../../tools/developer-tools/block-explorers.mdx) is a powerful tool to understand how a contract is being used. Some explorer also allow to download the compiled contract as a WASM file. There are also projects providing a link to access the code itself. + +:::info[Contract address] + +In order to depend on a project, we at least need to know the contract address of the contract to depend on. + +::: ## Making a cross contract call From 5787f784179ece4203208f9b1a77e18ff2c2f29a Mon Sep 17 00:00:00 2001 From: Tupui <23188539+tupui@users.noreply.github.com> Date: Fri, 2 Aug 2024 01:14:33 +0200 Subject: [PATCH 3/9] Last words section --- docs/build/guides/conventions/cross-contract.mdx | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/docs/build/guides/conventions/cross-contract.mdx b/docs/build/guides/conventions/cross-contract.mdx index 29f121dd4..a80785dc5 100644 --- a/docs/build/guides/conventions/cross-contract.mdx +++ b/docs/build/guides/conventions/cross-contract.mdx @@ -26,8 +26,13 @@ In order to depend on a project, we at least need to know the contract address o ## Handling responses -## Keeping up to date +## On depending on another contract +Congratulations, now you can effectively leverage the whole Soroban ecosystem and it's diversity of smart contracts. There are one last point to discuss before closing up: dependability. + +As with calling any smart contract in the first place, depending on an external smart contract should be done with care. It is well advised to do your own research and analysis on the contract you would want to use. As contracts can be updated without their address changing, it is important to pay close attention to any change on the underlying code. + +Besides this security consideration, upgrading a contract is an integrand part of a contract's life cycle. New features are added, bugs are being fixed, and public API changes. Here as well, it is important to observe any development on these contract as to ensure a continuity of operation of your own contract. ## Examples From 0585c60cbdb2e2d112ab2c6b7838d8ecd51cfe78 Mon Sep 17 00:00:00 2001 From: Tupui <23188539+tupui@users.noreply.github.com> Date: Fri, 2 Aug 2024 02:11:05 +0200 Subject: [PATCH 4/9] Add handling resp --- .../guides/conventions/cross-contract.mdx | 36 +++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/docs/build/guides/conventions/cross-contract.mdx b/docs/build/guides/conventions/cross-contract.mdx index a80785dc5..6c06e089c 100644 --- a/docs/build/guides/conventions/cross-contract.mdx +++ b/docs/build/guides/conventions/cross-contract.mdx @@ -26,16 +26,48 @@ In order to depend on a project, we at least need to know the contract address o ## Handling responses +In the examples above, we have used `env.invoke_contract` and `client.some_function`. In both cases, if there is an issue with the underlying contract call, the contract will panic. This might be a valid approach, but in some cases we want to catch errors and handle them depending on the outcome. This to forward a custom error message, or even trigger an alternative code path. + +Enters `try_`. By using `env.try_invoke_contract` or `client.try_some_function`, underlying errors won't make the contract panic. Instead, errors will be wrapped and can be handled. Example if we wanted to default to 0 in case of an error: + +```rust +client.try_add(&x, &y).unwrap_or(Ok(0)).unwrap() +``` + +Of course, we could have a far more complex error handling by leveraging the `match` statement: + +```rust +match client.try_add(&x, &y) { + // the contract returned a value + Ok(Ok(number)) => todo!("do something with the number returned"), + Ok(Err(ConversionError)) => todo!("got a value back, but it wasn't a number like we expected"), + + // the contract errored + Err(Ok(Error::AnError)) => todo!("do something when an error occurs that the contract included in its contract spec"), + Err(Err(status)) => todo!("do something when an unrecognized error, or system error, occurs"), +} +``` + ## On depending on another contract Congratulations, now you can effectively leverage the whole Soroban ecosystem and it's diversity of smart contracts. There are one last point to discuss before closing up: dependability. As with calling any smart contract in the first place, depending on an external smart contract should be done with care. It is well advised to do your own research and analysis on the contract you would want to use. As contracts can be updated without their address changing, it is important to pay close attention to any change on the underlying code. +:::tip[Contract WASM] + +The WASM can be fetched by using the [Stellar CLI](../../../tools/developer-tools/cli). This can serve as a quick way to e.g. automate a hash check in a continuous integration system. Though such check would not provide strong on-chain guarantees. But one could build a contract for that! + +```bash +stellar contract fetch --id C... --network ... > contract.wasm +``` + +::: + Besides this security consideration, upgrading a contract is an integrand part of a contract's life cycle. New features are added, bugs are being fixed, and public API changes. Here as well, it is important to observe any development on these contract as to ensure a continuity of operation of your own contract. ## Examples -See the following full example: +See the following full example with tests: -- [Cross Contract Calls](../../smart-contracts/example-contracts/cross-contract-call.mdx) shows how to create two contracts and call one from each other. +- [Cross Contract Calls](../../smart-contracts/example-contracts/cross-contract-call.mdx) shows how to create two contracts, deploy them and then how to call one from the other. From bef625dc18786ead22eb43e304ac71d219c4bfb7 Mon Sep 17 00:00:00 2001 From: Tupui <23188539+tupui@users.noreply.github.com> Date: Fri, 2 Aug 2024 02:11:25 +0200 Subject: [PATCH 5/9] Add cross contract call --- .../guides/conventions/cross-contract.mdx | 49 +++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/docs/build/guides/conventions/cross-contract.mdx b/docs/build/guides/conventions/cross-contract.mdx index 6c06e089c..cc43f4046 100644 --- a/docs/build/guides/conventions/cross-contract.mdx +++ b/docs/build/guides/conventions/cross-contract.mdx @@ -24,6 +24,55 @@ In order to depend on a project, we at least need to know the contract address o ## Making a cross contract call +Once we know which function to call and which arguments to use, there are mainly two ways to make a cross contract call: we can either load the WASM or call the contract. + +Let's start with only using a contract's address. In this example, we have an external contract which has a public function named `add_with` which takes two u32 as input values to, well, sum them. + +```rust +#[contract] +pub struct ContractB; + +#[contractimpl] +impl ContractB { + pub fn add_with(env: Env, contract: Address, x: u32, y: u32) -> u32 { + env.invoke_contract(&contract, symbol_short!("add"), vec![&env, x.to_val(), y.to_val()]) + } +} +``` + +Only using the contract comes with its own challenges. Because we don't have access to the WASM code, we don't have any typing inference and have to manually convert function inputs to `Val`. If we want more tools to help us, we can actually load the WASM code in the contract. This allows us to pass normal types without the need for manual conversions from our side. Behind the scene, this way of doing is simply a convenient wrapper around `env.invoke_contract`. + +```rust +mod contract_a { + soroban_sdk::contractimport!( + file = "soroban_contract_a.wasm" + ); +} + +#[contract] +pub struct ContractB; + +#[contractimpl] +impl ContractB { + pub fn add_with(env: Env, contract: Address, x: u32, y: u32) -> u32 { + let client = contract_a::Client::new(&env, &contract); + client.add(&x, &y) + } +} +``` + +Although we have access to the WASM, we still need a contract address because there could be multiple contract deployed on-chain which would use the same underlying code. This can be of importance if for instance the function that you need requires access to stored values from other users. + +:::tip[Address and WASM] + +Thanks to the presence of the Rust bindings of the external contract, we can also use any public enum of the contract as if we would have defined them within our own contract. + +```rust +client::ContractAEnum::SomeField +``` + +::: + ## Handling responses In the examples above, we have used `env.invoke_contract` and `client.some_function`. In both cases, if there is an issue with the underlying contract call, the contract will panic. This might be a valid approach, but in some cases we want to catch errors and handle them depending on the outcome. This to forward a custom error message, or even trigger an alternative code path. From 37b7c2fd616cc65f6d21e708e0ab3f26e315e961 Mon Sep 17 00:00:00 2001 From: Tupui <23188539+tupui@users.noreply.github.com> Date: Fri, 2 Aug 2024 02:14:34 +0200 Subject: [PATCH 6/9] Add public API section --- docs/build/guides/conventions/cross-contract.mdx | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/docs/build/guides/conventions/cross-contract.mdx b/docs/build/guides/conventions/cross-contract.mdx index cc43f4046..a41d299e5 100644 --- a/docs/build/guides/conventions/cross-contract.mdx +++ b/docs/build/guides/conventions/cross-contract.mdx @@ -22,6 +22,14 @@ In order to depend on a project, we at least need to know the contract address o ::: +## Public API + +All public functions of a contract can be called. Here as well, using a network explorer can be helpful as some propose to see the Rust interphase of a contract. Bindings can also be generated using the CLI: + +``` +stellar contract bindings rust --network --contract-id ... --output-dir ... +``` + ## Making a cross contract call Once we know which function to call and which arguments to use, there are mainly two ways to make a cross contract call: we can either load the WASM or call the contract. From 37b3dbd43ccf6c59797e48905dd75894c4c83390 Mon Sep 17 00:00:00 2001 From: Bri <92327786+briwylde08@users.noreply.github.com> Date: Mon, 5 Aug 2024 12:59:01 -0600 Subject: [PATCH 7/9] editorial & formatting --- .../guides/conventions/cross-contract.mdx | 48 +++++++++---------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/docs/build/guides/conventions/cross-contract.mdx b/docs/build/guides/conventions/cross-contract.mdx index a41d299e5..173e3b82e 100644 --- a/docs/build/guides/conventions/cross-contract.mdx +++ b/docs/build/guides/conventions/cross-contract.mdx @@ -1,40 +1,40 @@ --- -title: Making Cross Contract Calls +title: Making cross-contract calls description: Call a smart contract from within another smart contract --- As with developing software in any language, developing a Soroban smart contract with a rich feature set can be a challenging and time-consuming task. Thankfully, someone else might already have solved part of your issues or build components which could be reused. The open source community is vibrant and Stellar's community does not disappoint. -There are two kind of dependencies which can be introduced in a Soroban smart contract. +There are two kinds of dependencies that can be introduced in a Soroban smart contract: 1. Other Rust crates can be used (provided that they are compatible with Soroban's [Rust dialect](../../../learn/encyclopedia/contract-development/rust-dialect.mdx)); -2. Other smart contract can be used. This is referred to as a [Cross-Contract](../../../learn/encyclopedia/contract-development/contract-interactions/cross-contract.mdx) call. +2. Other smart contract can be used. This is referred to as a [cross-contract call](../../../learn/encyclopedia/contract-development/contract-interactions/cross-contract.mdx). -In the following, we will see how other contracts can be leveraged from within another contract. +In the following, we will see how contracts can be leveraged from within another contract. ## Contract as a dependency -While finding a contract is out of scope for this guide, there are a few place to be on a lookout. Most project and dApp are publicly disclosing on their website the address of their Soroban smart contract. With this information, a [block explorer](../../../tools/developer-tools/block-explorers.mdx) is a powerful tool to understand how a contract is being used. Some explorer also allow to download the compiled contract as a WASM file. There are also projects providing a link to access the code itself. +While finding a contract is out of scope for this guide, there are a few place to be on the lookout. Most projects and dApps publicly disclose the address of their Soroban smart contract on their website. With this information, a [block explorer](../../../tools/developer-tools/block-explorers.mdx) is a powerful tool to understand how a contract is being used. Some explorers also allow you to download the compiled contract as a Wasm file. There are also projects that provide a link to access the code itself. :::info[Contract address] -In order to depend on a project, we at least need to know the contract address of the contract to depend on. +To depend on a project, we need to know the contract address of the contract to depend on. ::: ## Public API -All public functions of a contract can be called. Here as well, using a network explorer can be helpful as some propose to see the Rust interphase of a contract. Bindings can also be generated using the CLI: +All public functions of a contract can be called. Using a network explorer can be helpful as some propose to see the Rust interphase of a contract. Bindings can also be generated using the CLI: ``` stellar contract bindings rust --network --contract-id ... --output-dir ... ``` -## Making a cross contract call +## Making a cross-contract call -Once we know which function to call and which arguments to use, there are mainly two ways to make a cross contract call: we can either load the WASM or call the contract. +Once we know which function to call and which arguments to use, there are two main ways to make a cross-contract call: we can either load the Wasm or call the contract. -Let's start with only using a contract's address. In this example, we have an external contract which has a public function named `add_with` which takes two u32 as input values to, well, sum them. +Let's start by using only a contract's address. In this example, we have an external contract with a public function named `add_with` which takes two u32 as input values to sum them. ```rust #[contract] @@ -48,7 +48,7 @@ impl ContractB { } ``` -Only using the contract comes with its own challenges. Because we don't have access to the WASM code, we don't have any typing inference and have to manually convert function inputs to `Val`. If we want more tools to help us, we can actually load the WASM code in the contract. This allows us to pass normal types without the need for manual conversions from our side. Behind the scene, this way of doing is simply a convenient wrapper around `env.invoke_contract`. +Only using the contract comes with its own challenges. Because we don't have access to the Wasm code, we don't have any typing inference and have to manually convert function inputs to `Val`. If we want more tools to help us, we can load the Wasm code in the contract. This allows us to pass normal types without needing manual conversions from our side. Behind the scenes, this way of doing it is simply a convenient wrapper around `env.invoke_contract`. ```rust mod contract_a { @@ -69,11 +69,11 @@ impl ContractB { } ``` -Although we have access to the WASM, we still need a contract address because there could be multiple contract deployed on-chain which would use the same underlying code. This can be of importance if for instance the function that you need requires access to stored values from other users. +Although we have access to the Wasm, we still need a contract address because there could be multiple contracts deployed on-chain that use the same underlying code. This can be of importance if, for instance, the function that you need requires access to stored values from other users. -:::tip[Address and WASM] +:::tip[Address and Wasm] -Thanks to the presence of the Rust bindings of the external contract, we can also use any public enum of the contract as if we would have defined them within our own contract. +Thanks to the Rust bindings of the external contract, we can also use any public enum of the contract as if we would have defined them within our own contract. ```rust client::ContractAEnum::SomeField @@ -83,15 +83,15 @@ client::ContractAEnum::SomeField ## Handling responses -In the examples above, we have used `env.invoke_contract` and `client.some_function`. In both cases, if there is an issue with the underlying contract call, the contract will panic. This might be a valid approach, but in some cases we want to catch errors and handle them depending on the outcome. This to forward a custom error message, or even trigger an alternative code path. +In the examples above, we have used `env.invoke_contract` and `client.some_function`. In both cases, if there is an issue with the underlying contract call, the contract will panic. This might be a valid approach, but in some cases we want to catch errors and handle them depending on the outcome. This is to forward a custom error message, or even triggers an alternative code path. -Enters `try_`. By using `env.try_invoke_contract` or `client.try_some_function`, underlying errors won't make the contract panic. Instead, errors will be wrapped and can be handled. Example if we wanted to default to 0 in case of an error: +Enter `try_`. By using `env.try_invoke_contract` or `client.try_some_function`, underlying errors won't make the contract panic. Instead, errors will be wrapped and can be handled. For example if we wanted to default to 0 in case of an error: ```rust client.try_add(&x, &y).unwrap_or(Ok(0)).unwrap() ``` -Of course, we could have a far more complex error handling by leveraging the `match` statement: +Of course, we could have far more complex error handling by leveraging the `match` statement: ```rust match client.try_add(&x, &y) { @@ -105,15 +105,15 @@ match client.try_add(&x, &y) { } ``` -## On depending on another contract +## Depending on another contract -Congratulations, now you can effectively leverage the whole Soroban ecosystem and it's diversity of smart contracts. There are one last point to discuss before closing up: dependability. +Congratulations, now you can effectively leverage the whole Soroban ecosystem and its myriad of smart contracts. There is one last point to discuss before closing up: **dependability**. -As with calling any smart contract in the first place, depending on an external smart contract should be done with care. It is well advised to do your own research and analysis on the contract you would want to use. As contracts can be updated without their address changing, it is important to pay close attention to any change on the underlying code. +As with calling any smart contract, depending on an external smart contract should be done with care. It is advisable to do your own research and analysis on the contract you want to use. As contracts can be updated without their address changing, it is important to pay close attention to any changes in the underlying code. -:::tip[Contract WASM] +:::tip[Contract Wasm] -The WASM can be fetched by using the [Stellar CLI](../../../tools/developer-tools/cli). This can serve as a quick way to e.g. automate a hash check in a continuous integration system. Though such check would not provide strong on-chain guarantees. But one could build a contract for that! +The Wasm can be fetched by using the [Stellar CLI](../../../tools/developer-tools/cli). This can serve as a quick way to (for example) automate a hash check in a continuous integration system. However, such a check would not provide strong on-chain guarantees, but one could build a contract for that! ```bash stellar contract fetch --id C... --network ... > contract.wasm @@ -121,10 +121,10 @@ stellar contract fetch --id C... --network ... > contract.wasm ::: -Besides this security consideration, upgrading a contract is an integrand part of a contract's life cycle. New features are added, bugs are being fixed, and public API changes. Here as well, it is important to observe any development on these contract as to ensure a continuity of operation of your own contract. +Besides this security consideration, upgrading a contract is an integral part of a contract's lifecycle. New features are added, bugs are fixed, and public API changes are made. Here as well, it is important to observe any development on these contract to ensure the continuous operation of your own contract. ## Examples See the following full example with tests: -- [Cross Contract Calls](../../smart-contracts/example-contracts/cross-contract-call.mdx) shows how to create two contracts, deploy them and then how to call one from the other. +- [Cross-contract calls](../../smart-contracts/example-contracts/cross-contract-call.mdx) shows how to create two contracts, deploy them, and then how to call one from the other. From 0017c02f50511b9ebfb9d3d00a1fd9db2c43057e Mon Sep 17 00:00:00 2001 From: Pamphile Roy <23188539+tupui@users.noreply.github.com> Date: Mon, 12 Aug 2024 22:02:41 +0200 Subject: [PATCH 8/9] Apply suggestions from code review Co-authored-by: Elliot Voris --- docs/build/guides/conventions/cross-contract.mdx | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/build/guides/conventions/cross-contract.mdx b/docs/build/guides/conventions/cross-contract.mdx index 173e3b82e..bba75b625 100644 --- a/docs/build/guides/conventions/cross-contract.mdx +++ b/docs/build/guides/conventions/cross-contract.mdx @@ -3,7 +3,7 @@ title: Making cross-contract calls description: Call a smart contract from within another smart contract --- -As with developing software in any language, developing a Soroban smart contract with a rich feature set can be a challenging and time-consuming task. Thankfully, someone else might already have solved part of your issues or build components which could be reused. The open source community is vibrant and Stellar's community does not disappoint. +As with developing software in any language, developing a Stellar smart contract with a rich feature set can be a challenging and time-consuming task. Thankfully, someone else might already have solved part of your issues or build components which could be reused. The open source community is vibrant and Stellar's community does not disappoint. There are two kinds of dependencies that can be introduced in a Soroban smart contract: @@ -24,9 +24,9 @@ To depend on a project, we need to know the contract address of the contract to ## Public API -All public functions of a contract can be called. Using a network explorer can be helpful as some propose to see the Rust interphase of a contract. Bindings can also be generated using the CLI: +All public functions of a contract can be called. Using a network explorer can be helpful as some propose to see the Rust interface of a contract. Bindings can also be generated using the CLI: -``` +```bash stellar contract bindings rust --network --contract-id ... --output-dir ... ``` @@ -34,7 +34,7 @@ stellar contract bindings rust --network --contract-id ... --output-dir ... Once we know which function to call and which arguments to use, there are two main ways to make a cross-contract call: we can either load the Wasm or call the contract. -Let's start by using only a contract's address. In this example, we have an external contract with a public function named `add_with` which takes two u32 as input values to sum them. +Let's start by using only a contract's address. In this example, we have an external contract with a public function named `add_with` which takes two `u32` as input values to sum them. ```rust #[contract] @@ -113,7 +113,7 @@ As with calling any smart contract, depending on an external smart contract shou :::tip[Contract Wasm] -The Wasm can be fetched by using the [Stellar CLI](../../../tools/developer-tools/cli). This can serve as a quick way to (for example) automate a hash check in a continuous integration system. However, such a check would not provide strong on-chain guarantees, but one could build a contract for that! +The Wasm can be fetched by using the [Stellar CLI](../../../tools/developer-tools/cli/README.mdx). This can serve as a quick way to (for example) automate a hash check in a continuous integration system. However, such a check would not provide strong on-chain guarantees, but one could build a contract for that! ```bash stellar contract fetch --id C... --network ... > contract.wasm @@ -121,7 +121,7 @@ stellar contract fetch --id C... --network ... > contract.wasm ::: -Besides this security consideration, upgrading a contract is an integral part of a contract's lifecycle. New features are added, bugs are fixed, and public API changes are made. Here as well, it is important to observe any development on these contract to ensure the continuous operation of your own contract. +Besides this security consideration, upgrading a contract is an integral part of a contract's lifecycle. New features are added, bugs are fixed, and public API changes are made. Here as well, it is important to observe any development on these contracts to ensure the continuous operation of your own contract. ## Examples From c3e33bf49ded496d4c5dcd1219fe99c38d5d02fe Mon Sep 17 00:00:00 2001 From: Tupui <23188539+tupui@users.noreply.github.com> Date: Mon, 12 Aug 2024 22:05:32 +0200 Subject: [PATCH 9/9] Convert other occurrences of Soroban smart contract --- docs/build/guides/conventions/cross-contract.mdx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/build/guides/conventions/cross-contract.mdx b/docs/build/guides/conventions/cross-contract.mdx index bba75b625..4d69293ef 100644 --- a/docs/build/guides/conventions/cross-contract.mdx +++ b/docs/build/guides/conventions/cross-contract.mdx @@ -5,7 +5,7 @@ description: Call a smart contract from within another smart contract As with developing software in any language, developing a Stellar smart contract with a rich feature set can be a challenging and time-consuming task. Thankfully, someone else might already have solved part of your issues or build components which could be reused. The open source community is vibrant and Stellar's community does not disappoint. -There are two kinds of dependencies that can be introduced in a Soroban smart contract: +There are two kinds of dependencies that can be introduced in a Stellar smart contract: 1. Other Rust crates can be used (provided that they are compatible with Soroban's [Rust dialect](../../../learn/encyclopedia/contract-development/rust-dialect.mdx)); 2. Other smart contract can be used. This is referred to as a [cross-contract call](../../../learn/encyclopedia/contract-development/contract-interactions/cross-contract.mdx). @@ -14,7 +14,7 @@ In the following, we will see how contracts can be leveraged from within another ## Contract as a dependency -While finding a contract is out of scope for this guide, there are a few place to be on the lookout. Most projects and dApps publicly disclose the address of their Soroban smart contract on their website. With this information, a [block explorer](../../../tools/developer-tools/block-explorers.mdx) is a powerful tool to understand how a contract is being used. Some explorers also allow you to download the compiled contract as a Wasm file. There are also projects that provide a link to access the code itself. +While finding a contract is out of scope for this guide, there are a few place to be on the lookout. Most projects and dApps publicly disclose the address of their Stellar smart contract on their website. With this information, a [block explorer](../../../tools/developer-tools/block-explorers.mdx) is a powerful tool to understand how a contract is being used. Some explorers also allow you to download the compiled contract as a Wasm file. There are also projects that provide a link to access the code itself. :::info[Contract address]