> ## 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.

# Upload WebAssembly (Wasm) bytecode using code

> Upload the Wasm of the contract using js-stellar-sdk.

## Install WebAssembly (Wasm) bytecode using code

This process uploads the contract code to the Stellar Testnet in a transaction, the uploaded Wasm blob is a [contract source](https://github.com/stellar/stellar-protocol/blob/master/core/cap-0046-02.md#contract-source), which can be thought of as a 'class' of a contract. Multiple [instances of a contract can be deployed](https://developers.stellar.org/docs/build/guides/conventions/deploy-contract.md) which share the same source, but have their own state.

## Prerequisites

Before you begin, ensure you have the following installed to compile a smart contract:

1. [Rust](https://www.rust-lang.org) and Cargo (for compiling smart contracts)
2. The [Stellar CLI](https://github.com/stellar/stellar-cli)

## Initialize and build a sample Rust contract

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
stellar contract init hello-world
cd hello-world

# use rust compiler to compile Rust project into a WebAssembly (Wasm) dynamic library (cdylib).
stellar contract build
# cargo rustc --manifest-path=contracts/hello_world/Cargo.toml --crate-type=cdylib --target=wasm32v1-none --release
```

We are initializing the default `hello_world` contract in [soroban\_examples](https://github.com/stellar/soroban-examples) to the directory `hello-world`. You may use the `-w` option to create with another example like `account`.

After building the contract for release, the generated .wasm file is at the path `hello-word/target/wasm32v1-none/release/hello_world.wasm`

## Upload Wasm to the Stellar blockchain

We can use one of the [client SDKs](https://developers.stellar.org/docs/tools/sdks/client-sdks.md), install necessary dependencies for your chosen programming language:

* JavaScript SDK: [Node.js](https://nodejs.org/en) and npm
* Python SDK: [pip](https://pip.pypa.io/en/stable/installation)

Create a new directory for your project and navigate into it:

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
mkdir install-wasm
cd install-wasm
```

### Running the install script

Different programming languages can be used to upload the `.wasm` file, its SHA256 hash is used for deploying the contract.

**JavaScript**

This guide will walk you through installing the Wasm of the contract using the JavaScript SDK: [js-stellar-sdk](https://github.com/stellar/js-stellar-sdk).

Create a new Node.js project with a JavaScript file, and install necessary dependencies:

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
touch index.js
npm init es6 -y
npm install @stellar/stellar-sdk fs
```

Run the script with `node index.js`, it reads the Wasm file, gets account details, and uploads the contract in a transaction:

```javascript theme={"theme":{"light":"github-light","dark":"github-dark"}}
// Import necessary modules in your JavaScript file:
import * as StellarSDK from "@stellar/stellar-sdk";
import fs from "fs";

async function uploadWasm(filePath) {
  // reads the compiled Wasm file to buffer
  const bytecode = fs.readFileSync(filePath);

  // retrieves account details from the network
  const account = await server.getAccount(sourceKeypair.publicKey());

  // installs the bytecode with a `uploadContractWasm` Stellar operation wrapped in a transaction sent to the network
  const operation = StellarSDK.Operation.uploadContractWasm({ wasm: bytecode });
  return await buildAndSendTransaction(account, operation);
}

// constructs a transaction, signs it, and submits it to the network, handling any necessary retries for transaction confirmation.
async function buildAndSendTransaction(account, operations) {
  const transaction = new StellarSDK.TransactionBuilder(account, {
    fee: StellarSDK.BASE_FEE,
    networkPassphrase: StellarSDK.Networks.TESTNET,
  })
    .addOperation(operations)
    .setTimeout(30)
    .build();

  const tx = await server.prepareTransaction(transaction);
  tx.sign(sourceKeypair);

  console.log("Submitting transaction...");
  let response = await server.sendTransaction(tx);
  const hash = response.hash;
  console.log(`Transaction hash: ${hash}`);
  console.log("Awaiting confirmation...");

  while (true) {
    response = await server.getTransaction(hash);
    if (response.status !== "NOT_FOUND") {
      break;
    }
    await new Promise((resolve) => setTimeout(resolve, 1000));
  }

  if (response.status === "SUCCESS") {
    console.log("Transaction successful.");
    return response;
  } else {
    console.log("Transaction failed.");
    throw new Error("Transaction failed");
  }
}

// Upload contract to the testnet
const server = new StellarSDK.rpc.Server(
  "https://soroban-testnet.stellar.org:443",
);
// Replace `Your_Secret_Key`
const sourceKeypair = StellarSDK.Keypair.fromSecret("Your_Secret_Key");
// Adjust this path as necessary
const wasmFilePath = "../target/wasm32v1-none/release/hello_world.wasm";

try {
  let uploadResponse = await uploadWasm(wasmFilePath);
  const byteArray = uploadResponse.returnValue.bytes();
  const wasmHash = byteArray.toString("hex");
  console.log(`Wasm hash: ${wasmHash}`);
} catch (error) {
  console.error(error);
}
```

**Python**

This guide will walk you through installing the Wasm of the contract using the Python SDK: [py-stellar-base](https://stellar-sdk.readthedocs.io/en/soroban).

Create a new Python script, and install the necessary dependencies:

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
touch install.py
pip install stellar-sdk
```

Run the script with `python3 install.py`, it reads the Wasm file, gets account details, and uploads the contract in a transaction:

```py theme={"theme":{"light":"github-light","dark":"github-dark"}}
import asyncio
import time
from stellar_sdk import Keypair, Network, SorobanServer, TransactionBuilder, xdr as stellar_xdr
from stellar_sdk.exceptions import PrepareTransactionException
from stellar_sdk.soroban_rpc import GetTransactionStatus
import hashlib


def print_wasm_hash(wasm_bytes):
    # Create a SHA256 hash object
    sha256_hash = hashlib.sha256()

    # Update the hash object with the WASM bytes
    sha256_hash.update(wasm_bytes)

    # Get the digest and convert it to a stellar_sdk.xdr.Hash object
    hash_bytes = sha256_hash.digest()
    xdr_hash = stellar_xdr.Hash(hash_bytes)
    hash_hex_str = xdr_hash.hash.hex()
    print(f"Wasm Hash: {hash_hex_str}")


async def upload_wasm(file_path):
    # Read the compiled Wasm file
    with open(file_path, 'rb') as file:
        wasm_bytes = file.read()

    # Retrieve account details from the network
    account = server.load_account(source_keypair.public_key)

    # print wasm hash for later deployment
    print_wasm_hash(wasm_bytes)

    # Install the bytes with an 'uploadContractWasm' Stellar operation
    return await build_and_send_transaction(account, wasm_bytes)


async def build_and_send_transaction(account, bytes):
    transaction = (
        TransactionBuilder(
            source_account=account,
            network_passphrase=Network.TESTNET_NETWORK_PASSPHRASE,
        )
        .append_upload_contract_wasm_op(bytes)
        .set_timeout(30)
        .build()
    )

    print("Preparing transaction...")
    try:
        tx = server.prepare_transaction(transaction)
    except PrepareTransactionException as e:
        print(f"Got exception: {e}")
        return None

    tx.sign(source_keypair)

    print("Submitting transaction...")
    response = server.send_transaction(tx)
    hash = response.hash
    print(f"Transaction hash: {hash}")
    print("Awaiting confirmation...")

    while True:
        response = server.get_transaction(hash)
        if response.status != GetTransactionStatus.NOT_FOUND:
            break
        time.sleep(1)

    if response.status == GetTransactionStatus.SUCCESS:
        print("Transaction successful.")
        return response
    else:
        print("Transaction failed.")
        raise Exception("Transaction failed")

# Upload contract to the testnet
server = SorobanServer("https://soroban-testnet.stellar.org:443")
# Replace 'Your_Secret_Key' with your actual secret key
source_keypair = Keypair.from_secret("Your_Secret_Key")
# Adjust this path as necessary
wasm_file_path = "../target/wasm32v1-none/release/hello_world.wasm"


async def main():
    try:
      await upload_wasm(wasm_file_path)
    except Exception as error:
        print(f"Error: {error}")

# Run the main function
asyncio.run(main())
```

**Rust**

This guide will walk you through uploading the Wasm of the contract using the Rust SDK: [rs-soroban-client](https://github.com/rahul-soshte/rs-soroban-client).

Create a new Cargo project, and install the necessary dependencies:

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
cargo init
cargo add soroban_client
cargo add tokio -F macros,full
```

Copy the code below into `src/main.rs` then run the program with `cargo run`, it reads the Wasm file, gets account details, and uploads the contract in a transaction:

```rust theme={"theme":{"light":"github-light","dark":"github-dark"}}
use std::time::Duration;

use soroban_client::{
    account::{Account, AccountBehavior},
    keypair::{Keypair, KeypairBehavior},
    network::{NetworkPassphrase, Networks},
    operation::Operation,
    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())?;

    // Adjust this path as necessary
    let wasm_file_path = "../target/wasm32v1-none/release/hello_world.wasm";

    // Read the wasm file
    let wasm_bytes = std::fs::read(wasm_file_path)?;

    // Build the xdr::HostFunction::UploadContractWasm operation
    let upload_wasm_op = Operation::new()
        .upload_wasm(&wasm_bytes, None)
        .expect("Cannot create upload_wasm operation");

    // Replace Your_Secret_Key with your actual secret key
    let source_keypair = Keypair::from_secret("Your_Secret_Key")?;
    let source_public_key = &source_keypair.public_key();

    // Get account information from server
    let account_data = server.get_account(source_public_key).await?;

    // Build the Account to use in the transaction
    let mut source_account = Account::new(source_public_key, &account_data.sequence_number())?;

    // Build the operation
    let tx = TransactionBuilder::new(&mut source_account, Networks::testnet(), None)
        .fee(1000u32)
        .add_operation(upload_wasm_op)
        .build();

    let mut ptx = server.prepare_transaction(&tx).await?;
    ptx.sign(&[source_keypair]);

    println!("> Uploading WASM executable");
    let response = server.send_transaction(ptx).await?;

    let hash = &response.hash;
    println!(">> Tx hash: {hash}");
    let wasm_hash = match server.wait_transaction(hash, Duration::from_secs(15)).await {
        Ok(tx_result) if tx_result.status == TransactionStatus::Success => {
            let (_meta, ret_val) = tx_result.to_result_meta().expect("No meta found");
            if let Some(scval) = ret_val {
                let bytes: Vec<u8> = scval.try_into().expect("Cannot convert ScVal to Vec<u8>");
                *bytes.last_chunk::<32>().expect("Not 32 bytes")
            } else {
                return Err(">> None return value".into());
            }
        }
        _ => {
            println!(">> Failed to upload the WASM executable");
            return Err(">> Failed to upload the wasm".into());
        }
    };
    let hex_wasm_hash: String = wasm_hash.iter().map(|b| format!("{:02x}", b)).collect();
    println!(">> Wasm hash: {hex_wasm_hash}");
    println!();

    Ok(())
}
```

Replace `"Your_Secret_Key"` with your actual secret key.

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
stellar keys generate --global hello --network testnet
stellar keys show hello
```

The Stellar CLI can be used to generate identities, e.g. `hello`, and show its secret key.

> [!TIP]
>
> Ensure that you handle secret and private keys securely in production environments and never expose them in your code repositories.

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
Submitting transaction...
Transaction hash: cef7a63667fe5b0ddcde5562d90e0a40bc04c69616916d1d7fa74a8571bbd82f
Awaiting confirmation...
Transaction successful.
Wasm hash: 275405755441e4be59555bb5c5fd81e84ed21659015d8f3594796c1cf3f380db
```

The returned upload transaction hash can be viewed with online tools: [stellar.expert/explorer/testnet/tx/cef7a63667fe5b0ddcde5562d90e0a40bc04c69616916d1d7fa74a8571bbd82f](https://stellar.expert/explorer/testnet/tx/cef7a63667fe5b0ddcde5562d90e0a40bc04c69616916d1d7fa74a8571bbd82f)

[Uploaded contracts are stored in ContractCodeEntry ledger entries.](https://github.com/stellar/stellar-protocol/blob/master/core/cap-0046-02.md#uploading-wasm-sources-using-invokehostfunctionop) These entries are keyed by the hash of the Wasm used to upload them.

You may use the Wasm hash for deployment with the Stellar CLI:

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
stellar contract deploy \
    --source-account hello \
    --network testnet \
    --wasm-hash 275405755441e4be59555bb5c5fd81e84ed21659015d8f3594796c1cf3f380db
# CC6NAQE3ZHRQV3NPQB3F3NYEFBAMEABA4KQTM6A2V5V7PBR5H3UEU3MW
```

View the deployed contract using the returned identifier with online tools: [stellar.expert/explorer/testnet/contract/CC6NAQE3ZHRQV3NPQB3F3NYEFBAMEABA4KQTM6A2V5V7PBR5H3UEU3MW](https://stellar.expert/explorer/testnet/contract/CC6NAQE3ZHRQV3NPQB3F3NYEFBAMEABA4KQTM6A2V5V7PBR5H3UEU3MW)
