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

# Getting Started with Rust and Solidity

> Explore the fundamentals of Solidity and Rust Syntax, Data Types, and Basic Constructs.

In this tutorial, we'll explore Rust and Solidity, two powerful programming languages. Rust, a systems programming language, is renowned for its safety, concurrency, and performance features, which can be advantageous when building smart contracts. On the other hand, Solidity is a high-level language specifically designed for creating smart contracts on the Ethereum Virtual Machine. This section aims to provide a high-level overview of the similarities and differences between the two languages.

## Table of Contents

1. [Solidity Syntax, Data Types, and Basic Constructs](#solidity-syntax)
2. [Rust Syntax, Data Types, and Ownership Model](#rust-syntax)
3. [Writing and Interacting With Simple Smart Contracts](#writing-and-interacting-with-simple-smart-contracts)

### Solidity Syntax

Solidity is a programming language designed specifically for creating smart contracts on the Ethereum Virtual Machine (EVM). It has a syntax similar to JavaScript and supports a variety of data types and constructs.

```solidity theme={"theme":{"light":"github-light","dark":"github-dark"}}
pragma solidity ^0.8.0;

contract HelloWorld {
  function sayHello() public pure returns (string memory) {
    return "Hello, World!";
  }
}
```

### Data Types

Solidity supports various data types, such as:

* Boolean: `bool`
* Integer: `int` (signed) and `uint` (unsigned)
* Address: `address`
* String: `string`
* Bytes: `bytes` (dynamic-size) and `bytes32` (fixed-size)
* Arrays: dynamic-size or fixed-size and can be declared with various types.
* Structs: `struct`
* Enums: `enum`
* Mapping: `mapping`

Here are examples of implementations for each data type:

```solidity theme={"theme":{"light":"github-light","dark":"github-dark"}}
pragma solidity ^0.8.0;

contract DataTypesExample {
    // Boolean
    bool public isCompleted = false;

    // Integer (signed and unsigned)
    int256 public signedInteger = -10;
    uint256 public unsignedInteger = 10;

    // Address
    address public userAddress = 0x742d35Cc6634C0532925a3b844Bc454e4438f44e;

    // String
    string public greeting = "Hello, World!";

    // Bytes (dynamic-size and fixed-size)
    bytes public dynamicBytes = "hello, solidity";
    bytes32 public fixedBytes = "hello, solidity";

    // Arrays (dynamic-size and fixed-size)
    uint[] public dynamicArray = [1, 2, 3];
    uint[5] public fixedArray = [1, 2, 3, 4, 5];

    address[] public dynamicAddressArray = [0xd41d1744871f42Bb724D777A2d0Bf53FB43a0040, 0x1f514ae9834aEAF6c2c3eb6D20E27e865F419010];
    address[3] public fixedAddressArray = [0xC90cd0D820D6dc447B3cD9545185B046873786A6, 0x401997E856CE51e0D4A8f26ce64952313BEA0E25, 0x221d3b9821f3Cc49B42E7dd487E2a6d1b3ed0E05];

    bool[] public dynamicBoolArray = [true, false, true];
    bool[2] public fixedBoolArray = [true, false];

    // Struct
    struct Person {
        string name;
        uint age;
    }
    Person public person = Person("Alice", 30);

    // Enums
    enum Status { Open, Closed, Pending }
    Status public currentStatus = Status.Open;
    Status public nextStatus = Status.Closed;
    Status public previousStatus = Status.Pending;

    // Mapping
    mapping(address => uint) public balances;

    constructor() {
        balances[msg.sender] = 100;
    }
}
```

### Basic Constructs

Some of the basic constructs in Solidity include:

1. `Variables`: Declared with a data type and an identifier.
2. `Functions`: Defined with the `function` keyword.
3. `Modifiers`: Used to modify functions' behavior.
4. `Events`: Used to log changes in the contract state.
5. `Inheritance`: Solidity supports single and multiple inheritance.

We will explore some of these constructs in more detail in the next article, [Advanced Solidity Concepts](https://developers.stellar.org/docs/learn/migrate/evm/solidity-and-rust-advanced-concepts.md#advanced-solidity-concepts).

### Rust Syntax

Rust is a programming language that is well-suited for building smart contracts due to its emphasis on safety, concurrency, and performance. It enforces strict ownership and borrowing rules to prevent data races and other common bugs.

```rust theme={"theme":{"light":"github-light","dark":"github-dark"}}
fn main() {
    println!("Hello, world!");
}
```

### Data Types

The [Soroban Rust SDK](https://docs.rs/soroban-sdk/latest/soroban_sdk/index.html) supports a variety of [Built-In Types](https://developers.stellar.org/docs/learn/fundamentals/contract-development/types/built-in-types.md) which consist of both Primitive and [Custom Types](https://developers.stellar.org/docs/learn/fundamentals/contract-development/types/custom-types.md), such as:

#### Primitive Data Types

* 32-bit Integers: signed (`i32`) and unsigned (`u32`)
* 64-bit Integers: signed (`i64`) and unsigned (`u64`)
* 128-bit Integers: signed (`i128`) and unsigned (`u128`)
* Bool (`bool`)
* Bytes, Strings (`Bytes`, `BytesN`): byte arrays and strings that can be passed to contracts and stores
* Vec (`Vec`): sequential and indexable growable collection type
* Map (`Map`): ordered key-value dictionary
* Address (`Address`): universal opaque identifier used in contracts
* String (`String`): a contiguous growable array type containing u8s and requires an env to be passed in
* Symbol:

  * (`Symbol::new`): small efficient strings up to 32 characters in length and requires an env to be passed in
  * (`symbol_short!`) small efficient strings up to 9 characters in length

  Both are limited to the characters `a-zA-Z0-9_` and are encoded into 64-bit integers.

#### Custom Data Types

* `Structs` (with Named Fields): A custom type consisting of named fields stored on the ledger as a `map` of key-value pairs.
* `Structs` (with Unnamed Fields): A custom type consisting of unnamed fields stored on the ledger as a vector of values.
* `Enum` (Unit and Tuple Variants): A custom type consisting of unit and tuple variants stored on the ledger as a two-element vector, with the first element being the name of the variant and the second being the value.
* `Enum` (Integer Variants): A custom type consisting of integer variants stored on the ledger as the `u32` value.

The following are examples of implementations for each data type:

```rust theme={"theme":{"light":"github-light","dark":"github-dark"}}
// Integer (signed and unsigned)
let unsigned_32_bit: u32 = 42;
let signed_32_bit: i32 = -42;
let unsigned_64_bit: u64 = 42;
let signed_64_bit: i64 = -42;
let unsigned_128_bit: u128 = 42;
let signed_128_bit: i128 = -42;

// Boolean
let boolean: bool = true;

// String
let msg: &str = "Hello";
String::from_slice(&env, msg)

// Symbols (short and new)
let symbol_short = symbol_short!("Sample"); // up to 9 chars
// env is &Env
let symbol_new = Symbol::new(env, "SampleSymbolExpression");

// Bytes (Bytes and BytesN)
let bytes = Bytes::from_slice(&env, &[1; 32]);
let bytes_n = BytesN::from_array(&env, &[0; 32]);

// Vec
let vec = vec![&env, 0, 1, 2, 3];

// Map
let map = map![&env, (2, 20), (1, 10)];

// Address
let address = Address::from_str(&env, "G...");

// Struct (named fields)
pub struct State {
    pub count: u32,
    pub last_incr: u32,
}

struct Tuple(u32, String);

// Struct (unnamed fields)
pub struct State(pub u32, pub u32);

// Enum (unit and tuple variants)
pub enum Enum {
    A,
    B(u32),
}

// Enum (integer variants)
pub enum Enum {
    A = 0,
    B = 1,
}
```

### A Brief Introduction to Modules, Macros, Structs, Traits, and Attribute Macros

In this section, we will provide a concise introduction to some fundamental concepts in Rust: `Modules`, `Macros`, `Structs`, `Traits`, and `Attribute Macros`.

These concepts are essential for understanding and writing efficient Rust code, and they will assist you on your journey as a smart contract developer.

#### 1. Modules

Modules in Rust are used to organize and separate code into different namespaces. They enable better code organization, reusability, and encapsulation. To define a module, use the `mod` keyword followed by a block containing the module's contents.

```rust theme={"theme":{"light":"github-light","dark":"github-dark"}}
mod my_module {
    pub fn my_function() {
        println!("Hello from my_module!");
    }
}
```

#### 2. Macros

[Macros](https://doc.rust-lang.org/book/ch19-06-macros.html) in Rust are powerful tools that allow you to do metaprogramming, enabling you to build chunks of reusable code at compile time.

There are two basic types: [declarative](https://doc.rust-lang.org/book/ch19-06-macros.html#declarative-macros-with-macro_rules-for-general-metaprogramming) and [procedural](https://doc.rust-lang.org/book/ch19-06-macros.html#procedural-macros-for-generating-code-from-attributes) macros. The most common is the declarative macro, or plain "macro", which is defined with `macro_rules!`

```rust theme={"theme":{"light":"github-light","dark":"github-dark"}}
macro_rules! my_macro {
    () => {
        println!("Hello from my_macro!");
    };
}

fn main() {
    my_macro!();
}
```

#### 3. Structs

Structs are custom data types in Rust that enable you to bundle data together. They provide a way to define and create more complex data structures.

```rust theme={"theme":{"light":"github-light","dark":"github-dark"}}
struct MyStruct {
    field1: i32,
    field2: String,
}

fn main() {
    let my_instance = MyStruct {
        field1: 42,
        field2: String::from("Hello"),
    };
}
```

#### 4. Traits

Traits in Rust define a shared set of behaviors that types can then either use as-is (default implementations) or implement themselves. They can be thought of as interfaces in other languages. Traits are defined with the `trait` keyword, and their methods can be implemented for different types using the `impl` keyword.

```rust theme={"theme":{"light":"github-light","dark":"github-dark"}}
trait MyTrait {
    fn my_method(&self);
}

struct MyStruct;

impl MyTrait for MyStruct {
    fn my_method(&self) {
        println!("Hello from MyTrait's my_method!");
    }
}
```

#### 5. Attribute Macros

Attribute macros in Rust are a form of procedural macros that enable you to define custom attributes for various language elements such as functions, structs, and enums. They can modify or generate code based on the annotated items.

```rust theme={"theme":{"light":"github-light","dark":"github-dark"}}
// To use an attribute macro, first import it with `use`
use my_attribute_macro::my_attribute;

// Then apply the attribute to an element in your code
#[my_attribute]
fn my_function() {
    println!("Hello from my_function!");
}
```

During your smart contract developer journey, you will frequently encounter the attribute macro [`#[contractimpl]`](https://docs.rs/soroban-sdk/latest/soroban_sdk/index.html) which exports publicly accessible functions to the Soroban environment.

Functions that are publicly accessible in the implementation are invocable by other contracts, or directly by transactions, when deployed.

```rust theme={"theme":{"light":"github-light","dark":"github-dark"}}
#[contractimpl]
impl HelloContract {
    pub fn hello(env: Env, to: Symbol) -> Vec<Symbol> {
        vec![&env, symbol_short!("Hello"), to]
    }
}
```

### Ownership Model

Rust enforces [**strict ownership rules**](https://doc.rust-lang.org/book/ch04-00-understanding-ownership.html) to manage memory and resources:

* Each value has a single owner.
* When the owner goes out of scope, the value is automatically deallocated.
* [`Borrowing`](https://doc.rust-lang.org/book/ch04-02-references-and-borrowing.html): Values can be borrowed as immutable or mutable references.
* [`Lifetimes`](https://doc.rust-lang.org/rust-by-example/scope/lifetime.html): Used to ensure that references remain valid.

### Smart Contract Dialect

Contract development in Rust involves certain restrictions due to either unavailable features in the deployment environment or high runtime costs. Thus, the code written for contracts can be seen as a distinct *dialect* of Rust, focusing on deterministic behavior and minimized code size.

To learn more about Rust's Contract Dialect, check out the [Contract Rust Dialect Page](https://developers.stellar.org/docs/learn/fundamentals/contract-development/rust-dialect.md).

## Writing and Interacting with Simple Smart Contracts

In this section, we'll learn how to write and interact with simple smart contracts in Solidity and Rust.

### Writing a Smart Counter in Solidity

Here's an example of a simple Solidity smart contract for a counter:

```solidity theme={"theme":{"light":"github-light","dark":"github-dark"}}
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.0;

contract Counter {
    uint256 private _count;

    function getCount() public view returns (uint256) {
        return _count;
    }

    function increment() public {
        _count += 1;
    }
}
```

Let's break down the layout of the code line by line:

```solidity theme={"theme":{"light":"github-light","dark":"github-dark"}}
// SPDX-License-Identifier: UNLICENSED
```

This is a comment that identifies the [license](https://docs.soliditylang.org/en/v0.8.19/layout-of-source-files.html#spdx-license-identifier) for the code. It's not required for the code to run, but it's good practice to include licensing information.

```solidity theme={"theme":{"light":"github-light","dark":"github-dark"}}
pragma solidity ^0.8.0;
```

This specifies the version of Solidity that this code was written for. In this case, it's version `0.8.0` or higher.

```solidity theme={"theme":{"light":"github-light","dark":"github-dark"}}
contract Counter {}
```

This defines a new Solidity contract called `Counter`.

```solidity theme={"theme":{"light":"github-light","dark":"github-dark"}}
uint256 private _count;
```

This is a [`private variable`](https://docs.soliditylang.org/en/v0.8.19/cheatsheet.html#function-visibility-specifiers) called `_count` of type `uint256` (unsigned integer). This variable will be used to store the current value of the counter. It is marked as `private`, which means it can only be accessed from within the contract.

```solidity theme={"theme":{"light":"github-light","dark":"github-dark"}}
function getCount() public view returns (uint256) {
    return _count;
}
```

This is a function called `getCount()` that returns the current value of the counter. The function is marked as `public`, which means it can be called from outside the contract. The `view` keyword indicates that this function doesn't modify the state of the contract. The `returns` keyword specifies the return type of the function.

```solidity theme={"theme":{"light":"github-light","dark":"github-dark"}}
function increment() public {
    _count += 1;
}
```

This is a function called `increment()` that increments the counter by 1. It doesn't return anything, but it modifies the state of the contract. Like `getCount()`, it's marked as `public`, which means it can be called from both inside and outside the contract.

### Interacting with the Solidity Smart Counter

We can interact with the smart contract using the `Remix IDE`. To do so, follow these steps:

1. Click the following link to [open the Gist in Remix](https://remix.ethereum.org/#version=soljson-v0.8.18+commit.87f61d96.js\&optimize=false\&runs=200\&gist=416ab15a6beed9d91cf2f615625ffe48\&lang=en\&evmVersion=null).

2. Navigate to the `Counter.sol` file in the file explorer.

![Counter](https://mintcdn.com/stellardevelopmentfoundation/hmWBKBicbGG4DTu6/img/migrating/counter.png?fit=max\&auto=format\&n=hmWBKBicbGG4DTu6\&q=85\&s=261336569b22eda35e98e685c9db7ad3)

3. Press `Ctrl/Cmd + s` to compile the contract.
4. Navigate to the `Deploy & Run Transactions` tab and click the `Deploy` button.

![Deploy](https://mintcdn.com/stellardevelopmentfoundation/hmWBKBicbGG4DTu6/img/migrating/deploy-counter.png?fit=max\&auto=format\&n=hmWBKBicbGG4DTu6\&q=85\&s=abc9dd8a6e1e60a468207d277c4c7a59)

The contract should appear under the `Deployed Contracts` tab:

![Deployed](https://mintcdn.com/stellardevelopmentfoundation/hmWBKBicbGG4DTu6/img/migrating/deployed-contracts.png?fit=max\&auto=format\&n=hmWBKBicbGG4DTu6\&q=85\&s=19f435050158ad878c6ac109d5083044)

5. Click the `increment` button to increment the counter.
6. Click the `getCount` button to get the current count.

![Increment](https://mintcdn.com/stellardevelopmentfoundation/hmWBKBicbGG4DTu6/img/migrating/increment.png?fit=max\&auto=format\&n=hmWBKBicbGG4DTu6\&q=85\&s=01a138509eb936affcee23c49a275289)

Up to this point, we've covered the basics of writing, deploying to a sandbox EVM, and interacting with a simple smart contract using Solidity. In the following section, we will extend our knowledge by learning how to achieve the same outcomes using Rust.

### Writing a Smart Counter in Rust

In this section, we'll create a Rust program that simulates the functionality of the Counter smart contract. Here's an example of a simple counter in Rust:

```rust theme={"theme":{"light":"github-light","dark":"github-dark"}}
#![no_std]
use soroban_sdk::{contractimpl, log, Env, Symbol};

const COUNTER: Symbol = symbol_short!("COUNTER");

#[contract]
pub struct IncrementContract;

#[contractimpl]
impl IncrementContract {
    /// Increment increments an internal counter, and returns the value.
    pub fn increment(env: Env) -> u32 {
        // Get the current count.
        let mut count: u32 = env.storage().instance().get(&COUNTER).unwrap_or(0); // If no value set, assume 0.
        log!(&env, "count: {}", count);

        // Increment the count.
        count += 1;

        // Save the count.
        env.storage().instance().set(&COUNTER, &count);

        // Return the count to the caller.
        count
    }

    /// get_count returns the current value of the counter.
    pub fn get_count(env: Env) -> u32 {
        env.storage().instance().get(&COUNTER).unwrap_or(0)
    }
}
```

This code is an implementation of a smart contract written in Rust using the [`Soroban Rust SDK`](../../../tools/sdks/contract-sdks#soroban-rust-sdk), a Rust-based smart contract development toolkit developed by the [Stellar Development Foundation (SDF)](https://stellar.org/foundation). The Soroban Rust SDK provides a powerful set of tools for writing smart contracts that run on the Soroban Virtual Machine.

Here's a line-by-line explanation of what the code is doing:

```rust theme={"theme":{"light":"github-light","dark":"github-dark"}}
#![no_std]
```

This is a Rust attribute that tells the Rust compiler not to link the [Rust standard library](https://doc.rust-lang.org/std). The standard library is extensive, and when deploying Soroban applications, we want to streamline the process as much as possible. By using `no_std`, we establish a leaner, "barebones" starting point for projects, encompassing only the Rust core and a few other essential components, rather than the full breadth of the standard library.

```rust theme={"theme":{"light":"github-light","dark":"github-dark"}}
use soroban_sdk::{contractimpl, log, Env, Symbol};
```

This code imports necessary items from the Soroban Rust SDK for writing a smart contract. The `contractimpl` [macro](https://doc.rust-lang.org/book/ch19-06-macros.html) is used to implement the smart contract, while the `log` macro is used for logging messages. The `Env` struct represents the environment the contract is executing in, and the `Symbol` type is a small, efficient string type.

```rust theme={"theme":{"light":"github-light","dark":"github-dark"}}
const COUNTER: Symbol = symbol_short!("COUNTER");
```

This creates a new `Symbol` value with the string "COUNTER". The constant `COUNTER` is then used as a key to identify the count value stored in the contract `storage`.

```rust theme={"theme":{"light":"github-light","dark":"github-dark"}}
#[contract]
pub struct IncrementContract;
```

This defines a public struct, `IncrementContract`, which will contain the implementation of the smart contract.

```rust theme={"theme":{"light":"github-light","dark":"github-dark"}}
#[contractimpl]
impl IncrementContract {}
```

This is a macro that implements the `IncrementContract` struct as a smart contract.

As previously noted, the `#[contractimpl]` attribute exports public functions to the Soroban environment. Meaning, these functions become accessible within the implementation and can be invoked by other contracts or directly by transactions upon deployment.

```rust theme={"theme":{"light":"github-light","dark":"github-dark"}}
pub fn increment(env: Env) -> u32 {}
```

This is a public function called `increment` that takes an `Env` struct as an argument and returns a `u32`. `Env` is the environment the contract is executing in, and `u32` is the type of value returned by the function.

```rust theme={"theme":{"light":"github-light","dark":"github-dark"}}
let mut count: u32 = env.storage().instance().get(&COUNTER).unwrap_or(0)); // If no value set, assume 0.
```

In this line of code, a mutable variable named `count` of type unsigned 32-bit integer (`u32`) is being created. The storage environment is accessed using `env.storage()`, and the value associated with the key `COUNTER` is retrieved using the `get` method. If there is no value set for the key `COUNTER`, a default value of 0 is used.

```rust theme={"theme":{"light":"github-light","dark":"github-dark"}}
log!(&env, "count: {}", count);
```

This logs the current count using the `log` macro provided by the Soroban Rust SDK.

```rust theme={"theme":{"light":"github-light","dark":"github-dark"}}
count += 1;
```

This increments the count by 1.

```rust theme={"theme":{"light":"github-light","dark":"github-dark"}}
env.storage().instance().set(&COUNTER, &count);
```

This saves the updated count back to the contract storage using the `set` method on the storage object.

```rust theme={"theme":{"light":"github-light","dark":"github-dark"}}
count
```

This returns the updated count to the caller of the function.

```rust theme={"theme":{"light":"github-light","dark":"github-dark"}}
pub fn get_count(env: Env) -> u32 {}
```

This is a public function called `get_count` that takes an `Env` struct as an argument and returns a `u32`. Once more we see the `Env` which is the environment the contract is executing in, and `u32` as the type of the value returned by the function.

```rust theme={"theme":{"light":"github-light","dark":"github-dark"}}
env.storage().instance().get(&COUNTER).unwrap_or(0)
```

This is a repeat of the code we saw earlier, which retrieves the value associated with the key `COUNTER` from the contract storage. If there is no value set for the key `COUNTER`, a default value of 0 is used. Finally, the `unwrap()` method is called to extract the actual value from the `Ok` wrapper, which is then returned to the caller of the function.

Now that we have written our smart contract, it's time to explore how we can interact with it using the [Stellar CLI](https://developers.stellar.org/docs/tools/cli/stellar-cli.md), one of many robust [Developer Tools](https://developers.stellar.org/docs/tools/developer-tools) available. This powerful command-line tool allows us to interact with the Soroban Virtual Machine from a local machine, providing us with an efficient and flexible way to manage our smart contract.

### Interacting with the Rust Smart Counter

To interact with the Rust counter, create a new Rust library using the cargo new command.

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
cargo new --lib increment
```

Once the project is created, replace the `src/lib.rs` file with the [code example above](#writing-a-smart-counter-in-rust).

```rust theme={"theme":{"light":"github-light","dark":"github-dark"}}
// Remember to replace your lib.rs file with the code example above.
// This is just a reference to point you in the right direction.
#[contractimpl]
impl IncrementContract {...}
```

Then, add the following dependencies to the `Cargo.toml` file:

```toml theme={"theme":{"light":"github-light","dark":"github-dark"}}
[package]
name = "increment"
version = "0.1.0"
edition = "2021"

[lib]
crate-type = ["cdylib"]

[features]
testutils = ["soroban-sdk/testutils"]

[dependencies]
soroban-sdk = "27"

[dev-dependencies]
soroban-sdk = { version = "27", features = ["testutils"] }

[profile.release]
opt-level = "z"
overflow-checks = true
debug = 0
strip = "symbols"
debug-assertions = false
panic = "abort"
codegen-units = 1
lto = true

[profile.release-with-logs]
inherits = "release"
debug-assertions = true
```

> *Note*: For a detailed explanation of the `Cargo.toml` configuration used in this tutorial, check out the [Hello World Example](https://developers.stellar.org/docs/build/smart-contracts/getting-started/hello-world.md).

Next, build the project using the `stellar contract build` command.

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
cd increment
stellar contract build
```

The compiled contract will be located in the `target/wasm32v1-none/release` directory.

To interact with the contract, we can use the `stellar contract invoke` command from the `stellar-cli` tool. Here's an example of invoking the `increment` function on a contract with ID 1:

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
stellar contract invoke \
    --wasm target/wasm32v1-none/release/increment.wasm \
    --id 1 \
    -- \
    increment
```

The output should be the current value of the counter, which in this case is:

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
1
```

You can use the same `stellar contract invoke` command to increment the counter multiple times.

To get the current value of the counter, you can use the following command:

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
stellar contract invoke \
    --wasm target/wasm32v1-none/release/increment.wasm \
    --id 1 \
    -- \
    get_count
```

The output should be the current value of the counter, assuming the counter has been incremented 3 times, the output will be:

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
3
```

And that's it! You've learned how to write and interact with simple smart contracts in Solidity and Rust. In the upcoming sections, we'll learn about advanced smart contract concepts, the similarities and differences between Solidity and Rust, and how to develop and deploy smart contracts with Soroban.
