> ## Documentation Index
> Fetch the complete documentation index at: https://developers.stellar.org/llms.txt
> Use this file to discover all available pages before exploring further.

# Invoke a contract function in a transaction using SDKs

> Use the Stellar SDK to create, simulate, and assemble a transaction.

This is a simple example using the Stellar SDK to create, simulate, and then assemble a Stellar transaction which invokes an `increment` function of the [auth example contract](https://developers.stellar.org/docs/build/smart-contracts/example-contracts/auth.md).

> [tab] JavaScript
>
> > [!TIP]
> >
> > Please go to [the project homepage](https://github.com/stellar/js-stellar-sdk) of JavaScript SDK to learn how to install it.
>
> First, upload the bytes of [the example contract](https://developers.stellar.org/docs/build/smart-contracts/example-contracts/auth.md) onto the blockchain using [Stellar CLI](https://developers.stellar.org/docs/tools/cli/stellar-cli.md). This is called "install" because, from the perspective of the blockchain itself, this contract has been installed.
>
> ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
> stellar contract build
> stellar contract upload --wasm target/wasm32v1-none/release/test_auth_contract.wasm --network testnet
> ```
>
> This will return a hash; save that, you'll use it soon. For this example, we will use `bc7d436bab44815c03956b344dc814fac3ef60e9aca34c3a0dfe358fcef7527f`.
>
> No contract has yet been deployed with this hash. In Soroban, you can have many Smart Contracts which all reference the same Wasm hash, defining their behavior. We'll do that from the following JavaScript code itself.
>
> ```ts theme={"theme":{"light":"github-light","dark":"github-dark"}}
> import { Keypair } from "@stellar/stellar-sdk"
> import { Client, basicNodeSigner } from "@stellar/stellar-sdk/contract"
> import { Server } from "@stellar/stellar-sdk/rpc"
>
> // As mentioned, we are using Testnet for this example
> const rpcUrl = "https://soroban-testnet.stellar.org"
> const networkPassphrase = "Test SDF Network ; September 2015"
> const wasmHash = "bc7d436bab44815c03956b344dc814fac3ef60e9aca34c3a0dfe358fcef7527f"
>
> /**
>  * Generate a random keypair and fund it
>  */
> async function generateFundedKeypair() {
>   const keypair = Keypair.random();
>   const server = new Server(rpcUrl);
>   await server.requestAirdrop(keypair.publicKey());
>   return keypair
> }
>
> (async () => {
>   // The source account will be used to sign and send the transaction.
>   const sourceKeypair = await generateFundedKeypair()
>
>   // If you are using a browser, you can pass in `signTransaction` from your
>   // Wallet extension such as Varial. If you're using Node, you can use
>   // `signTransaction` from `basicNodeSigner`.
>   const { signTransaction } = basicNodeSigner(sourceKeypair, networkPassphrase)
>
>   // This constructs and simulates a deploy transaction. Once we sign and send
>   // this below, it will create a brand new smart contract instance that
>   // references the wasm we uploaded with the CLI.
>   const deployTx = await Client.deploy(
>     null, // if the contract has a `__constructor` function, its arguments go here
>     {
>       networkPassphrase,
>       rpcUrl,
>       wasmHash,
>       publicKey: sourceKeypair.publicKey(),
>       signTransaction,
>     }
>   )
>   // Like other `Client` methods, `deploy` returns an `AssembledTransaction`,
>   // which wraps logic for signing, sending, and awaiting completion of the
>   // transaction. Once that all completes, the `result` of this transaction
>   // will contain the final `Client` instance, which we can use to invoke
>   // methods on the new contract. Here we are using JS destructuring to get the
>   // `result` key from the object returned by `signAndSend`, and put it in a
>   // local variable called `client`.
>   const { result: client } = await deployTx.signAndSend()
>
>   ...
> ```
>
> > [!TIP]
> >
> > **Client from existing Contract**
> >
> > If you don't need to deploy a contract, and instead already know a deployed contract's ID, you can instantiate a Client for it directly. This uses similar arguments to the ones to `Client.deploy` above, with the addition of `contractId`:
> >
> > ```diff theme={"theme":{"light":"github-light","dark":"github-dark"}}
> > -const deployTx = await Client.deploy(
> > -  null,
> > -  {
> > +const client = await Client.from({
> > +  contractId: "C123abc…",
> >    networkPassphrase,
> >    rpcUrl,
> >    wasmHash,
> >    publicKey: sourceKeypair.publicKey(),
> >    signTransaction,
> >  })
> > ```
>
> Now that we instantiated a `client`, we can use it to call methods on the contract. Picking up where we left off:
>
> ```ts theme={"theme":{"light":"github-light","dark":"github-dark"}}
>   ...
>
>   // This will construct and simulate an `increment` transaction. Since the
>   // `auth` contract requires that this transaction be signed, we will need to
>   // call `signAndSend` on it, like we did with `deployTx` above.
>   const incrementTx = await client.increment({
>     user: sourceKeypair.publicKey(), // who needs to sign
>     value: 1, // how much to increment by
>   })
>
>   // For calls that don't need to be signed, you can get the `result` of their
>   // simulation right away, on a call like `client.increment()` above.
>   const { result } = await incrementTx.signAndSend()
>
>   // Now you can do whatever you need to with the `result`, which in this case
>   // contains the new value of the incrementor/counter.
>   console.log("New incremented value:", result)
> })();
> ```

> [tab] Python
>
> > [!TIP]
> >
> > Please go to [the project homepage](https://github.com/StellarCN/py-stellar-base) of Python SDK to learn how to install it.
> >
> > In addition, Python provides a lot of example code, which you can find [here](https://github.com/StellarCN/py-stellar-base/tree/main/examples).
>
> ```py theme={"theme":{"light":"github-light","dark":"github-dark"}}
> import time
>
> from stellar_sdk import Keypair, Network, SorobanServer, TransactionBuilder, scval
> from stellar_sdk import xdr as stellar_xdr
> from stellar_sdk.exceptions import PrepareTransactionException
> from stellar_sdk.soroban_rpc import GetTransactionStatus, SendTransactionStatus
>
> secret = "SAAPYAPTTRZMCUZFPG3G66V4ZMHTK4TWA6NS7U4F7Z3IMUD52EK4DDEV"
> rpc_server_url = "https://soroban-testnet.stellar.org:443"
> network_passphrase = Network.TESTNET_NETWORK_PASSPHRASE
>
> # Here we will use a deployed instance of the `increment` example contract.
> contract_id = "CDOGJBJMRVVXW5K3UJ5BGVJ5RSQXQB4UFVQYVFOIARC2UYXSEPF4YAVR"
> # The source account will be used to sign and send the transaction.
> source_keypair = Keypair.from_secret(secret)
> # Configure SorobanClient to use the `stellar-rpc` instance of your choosing.
> soroban_server = SorobanServer(rpc_server_url)
> # Transactions require a valid sequence number (which varies from one account to another).
> # We fetch this sequence number from the RPC server.
> source = soroban_server.load_account(source_keypair.public_key)
>
> tx = (
>     # The transaction begins as pretty standard. The source account, minimum fee,
>     # and network passphrase are provided.
>     TransactionBuilder(source, network_passphrase, base_fee=100)
>     # This transaction will be valid for the next 30 seconds
>     .set_timeout(30)
>     # The invocation of the `increment` function of our contract is added to the transaction.
>     .append_invoke_contract_function_op(
>         contract_id=contract_id,
>         function_name="increment",
>         parameters=[scval.to_address(source_keypair.public_key), scval.to_uint32(5)],
>     ).build()
> )
>
> print(f"builtTransaction: {tx.to_xdr()}")
>
> try:
>     # We use the RPC server to "prepare" the transaction. This simulating the
>     # transaction, discovering the soroban data, and updating the
>     # transaction to include that soroban data. If you know the soroban data ahead of
>     # time, you could manually use `set_soroban_data` and skip this step.
>     tx = soroban_server.prepare_transaction(tx)
> except PrepareTransactionException as e:
>     print(f"Prepare Transaction Failed: {e.simulate_transaction_response}")
>     raise e
>
> # Sign the transaction with the source account's keypair.
> tx.sign(source_keypair)
>
> # Let's see the base64-encoded XDR of the transaction we just built.
> print(f"Signed prepared transaction XDR: {tx.to_xdr()}")
>
> # Submit the transaction to the Stellar-RPC server. The RPC server will
> # then submit the transaction into the network for us. Then we will have to
> # wait, polling `get_transaction` until the transaction completes.
> send_transaction_data = soroban_server.send_transaction(tx)
> print(f"Sent transaction: {send_transaction_data}")
> if send_transaction_data.status != SendTransactionStatus.PENDING:
>     print(send_transaction_data.error_result_xdr)
>     raise Exception("Send transaction failed")
>
> while True:
>     print("Waiting for transaction to be confirmed...")
>     # Poll `get_transaction` until the status is not "NOT_FOUND"
>     get_transaction_data = soroban_server.get_transaction(send_transaction_data.hash)
>     if get_transaction_data.status != GetTransactionStatus.NOT_FOUND:
>         break
>     time.sleep(3)
>
> print(f"getTransaction response: {get_transaction_data}")
>
> if get_transaction_data.status == GetTransactionStatus.SUCCESS:
>     # The transaction was successful, so we can extract the `result_meta_xdr`
>     transaction_meta = stellar_xdr.TransactionMeta.from_xdr(
>         get_transaction_data.result_meta_xdr
>     )
>     result = transaction_meta.v3.soroban_meta.return_value
>     # Find the return value from the contract and return it
>     print(f"Transaction result: {scval.from_uint32(result)}")
> else:
>     # The transaction failed, so we can extract the `result_xdr`
>     print(f"Transaction failed: {get_transaction_data.result_xdr}")
>     raise Exception("Transaction failed")
> ```

> [tab] Java
>
> > [!TIP]
> >
> > Please go to [the project homepage](https://github.com/lightsail-network/java-stellar-sdk) of Java SDK to learn how to install it.
>
> ```java theme={"theme":{"light":"github-light","dark":"github-dark"}}
> import org.stellar.sdk.KeyPair;
> import org.stellar.sdk.Network;
> import org.stellar.sdk.SorobanServer;
> import org.stellar.sdk.Transaction;
> import org.stellar.sdk.TransactionBuilder;
> import org.stellar.sdk.TransactionBuilderAccount;
> import org.stellar.sdk.exception.AccountNotFoundException;
> import org.stellar.sdk.exception.PrepareTransactionException;
> import org.stellar.sdk.exception.SorobanRpcException;
> import org.stellar.sdk.operations.InvokeHostFunctionOperation;
> import org.stellar.sdk.responses.sorobanrpc.GetTransactionResponse;
> import org.stellar.sdk.responses.sorobanrpc.SendTransactionResponse;
> import org.stellar.sdk.scval.Scv;
> import org.stellar.sdk.xdr.SCVal;
> import org.stellar.sdk.xdr.TransactionMeta;
>
> import java.io.IOException;
> import java.util.List;
>
> public class Example {
>     public static void main(String[] args) throws SorobanRpcException, IOException, InterruptedException {
>         // The source account will be used to sign and send the transaction.
>         KeyPair sourceKeypair = KeyPair.fromSecretSeed("SAAPYAPTTRZMCUZFPG3G66V4ZMHTK4TWA6NS7U4F7Z3IMUD52EK4DDEV");
>
>         // Configure SorobanClient to use the `stellar-rpc` instance of your choosing.
>         SorobanServer sorobanServer = new SorobanServer("https://soroban-testnet.stellar.org");
>
>         // Here we will use a deployed instance of the `increment` example contract.
>         String contractAddress = "CDOGJBJMRVVXW5K3UJ5BGVJ5RSQXQB4UFVQYVFOIARC2UYXSEPF4YAVR";
>
>         // Transactions require a valid sequence number (which varies from one account to
>         // another). We fetch this sequence number from the RPC server.
>         TransactionBuilderAccount sourceAccount = null;
>         try {
>             sourceAccount = sorobanServer.getAccount(sourceKeypair.getAccountId());
>         } catch (AccountNotFoundException e) {
>             throw new RuntimeException("Account not found, please activate it first");
>         }
>
>         // The invocation of the `increment` function.
>         InvokeHostFunctionOperation operation = InvokeHostFunctionOperation.invokeContractFunctionOperationBuilder(contractAddress, "increment",
>                 List.of(
>                         Scv.toAddress(sourceAccount.getAccountId()),
>                         Scv.toUint32(5)
>                 )
>         ).build();
>
>         // Create a transaction with the source account and the operation we want to invoke.
>         Transaction transaction = new TransactionBuilder(sourceAccount, Network.TESTNET)
>                 .addOperation(operation) // The invocation of the `increment` function of our contract is added to the transaction.
>                 .setTimeout(30) // This transaction will be valid for the next 30 seconds
>                 .setBaseFee(100)  // The base fee is 100 stroops (0.00001 XLM)
>                 .build();
>
>         // We use the RPC server to "prepare" the transaction. This simulating the
>         // transaction, discovering the soroban data, and updating the
>         // transaction to include that soroban data. If you know the soroban data ahead of
>         // time, you could manually use `setSorobanData` and skip this step.
>         try {
>             transaction = sorobanServer.prepareTransaction(transaction);
>         } catch (PrepareTransactionException e) {
>             // You should handle the error here
>             System.out.println("Prepare Transaction Failed: " + e.getMessage());
>             throw new RuntimeException(e);
>         }
>
>         // Sign the transaction with the source account's keypair.
>         transaction.sign(sourceKeypair);
>
>         // Let's see the base64-encoded XDR of the transaction we just built.
>         System.out.println("Signed prepared transaction XDR: " + transaction.toEnvelopeXdrBase64());
>
>         // Submit the transaction to the Stellar-RPC server. The RPC server will then
>         // submit the transaction into the network for us. Then we will have to wait,
>         // polling `getTransaction` until the transaction completes.
>         SendTransactionResponse response = sorobanServer.sendTransaction(transaction);
>         if (!SendTransactionResponse.SendTransactionStatus.PENDING.equals(response.getStatus())) {
>             throw new RuntimeException("Sending transaction failed");
>         }
>
>         // Poll `getTransaction` until the status is not "NOT_FOUND"
>         GetTransactionResponse getTransactionResponse;
>         while (true) {
>             System.out.println("Waiting for transaction confirmation...");
>             // See if the transaction is complete
>             getTransactionResponse = sorobanServer.getTransaction(response.getHash());
>             if (!GetTransactionResponse.GetTransactionStatus.NOT_FOUND.equals(getTransactionResponse.getStatus())) {
>                 break;
>             }
>             // Wait one second
>             Thread.sleep(1000);
>         }
>
>         System.out.println("Get transaction response: " + getTransactionResponse);
>
>         if (GetTransactionResponse.GetTransactionStatus.SUCCESS.equals(getTransactionResponse.getStatus())) {
>             // The transaction was successful, so we can extract the `resultMetaXdr`
>             TransactionMeta transactionMeta = TransactionMeta.fromXdrBase64(getTransactionResponse.getResultMetaXdr());
>             SCVal result = transactionMeta.getV3().getSorobanMeta().getReturnValue();
>             long parsedResult = Scv.fromUint32(result);
>             System.out.println("Transaction result: " + parsedResult);
>         } else {
>             // The transaction failed, so we can extract the `resultXdr`
>             System.out.println("Transaction failed: " + getTransactionResponse.getResultXdr());
>         }
>     }
> }
> ```

> [tab] Rust
>
> > [!TIP]
> >
> > Please go to [the project homepage](https://github.com/rahul-soshte/rs-soroban-client) of Rust Soroban Client Library to learn how to install it.
> >
> > Other examples can be found in the [`examples/`](https://github.com/rahul-soshte/rs-soroban-client/tree/main/examples) folder of the repository.
>
> First, deploy [the example contract](https://developers.stellar.org/docs/build/smart-contracts/example-contracts/auth.md) onto the blockchain using [Stellar CLI](https://developers.stellar.org/docs/tools/cli/stellar-cli.md).
>
> ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
> stellar contract build
> stellar contract deploy --wasm ./target/wasm32v1-none/release/soroban_auth_contract.wasm --network testnet
> ```
>
> This will return a contract ID, in the following example we will use `CBU3OHKZ2BHOHK5VMG3HBWIW3PBQHZLNMHNJUGM23W5NBFA75JMMWAVT`.
>
> ```rust theme={"theme":{"light":"github-light","dark":"github-dark"}}
> use std::time::Duration;
>
> use soroban_client::{
>     account::{Account, AccountBehavior},
>     address::{Address, AddressTrait},
>     contract::{ContractBehavior, Contracts},
>     keypair::{Keypair, KeypairBehavior},
>     network::{NetworkPassphrase, Networks},
>     soroban_rpc::TransactionStatus,
>     transaction::{TransactionBehavior, TransactionBuilder, TransactionBuilderBehavior},
>     Options, Server,
> };
>
> #[tokio::main]
> pub async fn main() -> Result<(), Box<dyn std::error::Error>> {
>     let server_url = "https://soroban-testnet.stellar.org";
>     let server = Server::new(server_url, Options::default())?;
>
>     let source_keypair = Keypair::random()?;
>     let source_public_key = &source_keypair.public_key();
>     let signers = [source_keypair];
>
>     // Get account information from server
>     let account_data = server.request_airdrop(source_public_key).await?;
>     let mut source_account = Account::new(source_public_key, &account_data.sequence_number())?;
>
>     // Calling the increment method of the contract
>     let contract_addr = "CBU3OHKZ2BHOHK5VMG3HBWIW3PBQHZLNMHNJUGM23W5NBFA75JMMWAVT";
>     let contract = Contracts::new(contract_addr).unwrap();
>     let tx = TransactionBuilder::new(&mut source_account, Networks::testnet(), None)
>         .fee(1000u32)
>         .add_operation(contract.call(
>             "increment",
>             Some(vec![
>                 Address::account(signers[0].raw_public_key())?.to_sc_val()?,
>                 3u32.into(),
>             ]),
>         ))
>         .build();
>
>     // Preparing the transaction, this will call `server.simulate_transaction` and
>     // `assemble_transaction` to enhance the transaction with the soroban data and auths
>     let ptxr = server.prepare_transaction(&tx).await;
>     let mut ptx = match ptxr {
>         Ok(p) => p,
>         Err(e) => {
>             // Manage errors here
>             return Err(e.into());
>         }
>     };
>
>     // Sign the transaction with the source account
>     ptx.sign(&signers);
>
>     println!("> Calling increment on contract {contract_addr}",);
>     let response = server.send_transaction(ptx).await?;
>
>     let hash = &response.hash;
>     println!(">> Tx hash: {hash}");
>     let counter: u32 = match server.wait_transaction(hash, Duration::from_secs(15)).await {
>         Ok(tx_result) if tx_result.status == TransactionStatus::Success => {
>             // On success we can extract the returned value
>             let (_meta, ret_val) = tx_result.to_result_meta().expect("No result meta");
>             ret_val
>                 .expect("None returned value")
>                 .try_into()
>                 .expect("Return value is not u32")
>         }
>         _ => {
>             return Err("Failed to create contract".into());
>         }
>     };
>     println!(">> Counter: {counter}",);
>     println!();
>
>     Ok(())
> }
> ```
