Saltar al contenido principal

Smart Contract Development with Soroban and Hardhat

In this tutorial, we will discover the similarities in smart contract deployment by examining workflows with Soroban and Hardhat. We will dive into the intricacies of each framework, learn to write secure and efficient smart contract code, and harness the power of Rust and Soroban to create customized contract logic.

Table of Contents

  1. Soroban and Hardhat Comparison
  2. Hardhat vs Soroban SDKs
  3. Using Rust and Soroban for Smart Contract Development
  4. Vault Contract Deployment and Interaction

Soroban and Hardhat Comparison

Introduction

Soroban and Hardhat are both frameworks that enable developers to build, test, and deploy smart contracts. In this section, we will delve into the similarities and distinctions between these two frameworks.

Soroban Framework

Soroban es un marco basado en Rust diseñado para desarrollar contratos inteligentes en la red Stellar. Diseñado como un marco ligero, con herramientas para admitir a los desarrolladores, Soroban permite a los desarrolladores crear contratos inteligentes a través de un flujo de trabajo simple e intuitivo.

Hardhat

Hardhat sirve como un entorno de desarrollo para compilar, desplegar, probar y depurar contratos inteligentes para la EVM. Asiste a los desarrolladores en la gestión y automatización de tareas recurrentes inherentes a la construcción de contratos inteligentes.

Similaridades

Soroban y Hardhat son marcos potentes diseñados para agilizar el proceso de construir, probar y desplegar contratos inteligentes. Equipadas con una suite integral de herramientas, estos marcos facilitan el desarrollo de contratos inteligentes y su despliegue en sus respectivas máquinas virtuales.

Diferencias

Soroban, con su diseño ligero, ofrece a los desarrolladores una plataforma excepcional para escribir contratos inteligentes basados en Rust y desplegarlos sin esfuerzo en la red Stellar. En contraste, Hardhat sirve principalmente como un entorno de desarrollo diseñado para la Máquina Virtual de Ethereum, proporcionando un enfoque y audiencia objetivo diferentes.

Hardhat vs. Soroban SDKs

Hardhat ofrece un flujo de trabajo optimizado para desplegar contratos inteligentes en la Máquina Virtual de Ethereum, con componentes clave como ethers.js, scripts, y testing desempeñando roles cruciales.

Por otro lado, Soroban presenta una alternativa convincente, con potentes SDKs que facilitan el desarrollo y despliegue de contratos inteligentes. En la próxima sección, profundizaremos en los SDKs de Soroban, comparando los componentes de Hardhat y destacando las ventajas únicas que cada plataforma aporta.

Ethers.js

Ethers.js es una biblioteca de JavaScript ampliamente utilizada diseñada para la interacción sin problemas con la EVM. Ofrece una interfaz amigable que simplifica la conexión a nodos de Ethereum, la gestión de cuentas y el envío de transacciones. Además, Ethers.js proporciona una API robusta para la comunicación eficiente con contratos inteligentes. Esta biblioteca es un componente central del marco Hardhat y puede ser importada en scripts para agilizar el despliegue de contratos inteligentes.

const { ethers } = require("hardhat");

async function main() {
const [deployer] = await ethers.getSigners();

console.log("Deploying contracts with the account:", deployer.address);
}

Soroban Client

Soroban ofrece una biblioteca comparable, stellar-sdk, que permite la interacción sin problemas con contratos inteligentes desplegados en la red Stellar. Esta biblioteca proporciona una API de capa de red integral para métodos RPC de Stellar, así como la API tradicional de Horizon, simplificando el proceso de construcción y firma de transacciones. Además, stellar-sdk agiliza la comunicación con instancias RPC y admite enviar transacciones o consultar el estado de la red con facilidad.

Scripts

Los scripts de Hardhat agilizan la automatización de tareas rutinarias, como desplegar y gestionar contratos inteligentes. Los desarrolladores pueden crear estos scripts usando JavaScript o TypeScript, adaptándose a su estilo de programación preferido. Se almacenan en el directorio scripts de un proyecto Hardhat y pueden ejecutarse utilizando el comando npx hardhat run.

// scripts/deploy.js

async function main() {
// Compile and deploy the smart contract
const MyContract = await ethers.getContractFactory("MyContract");
const myContract = await MyContract.deploy();

console.log("MyContract deployed to:", myContract.address);
}

main()
.then(() => process.exit(0))
.catch((error) => {
console.error(error);
process.exit(1);
});

Soroban Scripts

Soroban ofrece una amplia colección de SDKs que incluyen capacidades de scripting, asegurando un flujo de trabajo fluido para desplegar y gestionar contratos inteligentes. Los desarrolladores pueden automatizar tareas como compilar, desplegar e interactuar con contratos inteligentes utilizando una variedad de SDKs que admiten scripting en lenguajes como JavaScript, TypeScript, Python, y otros.

# This example shows how to deploy a compiled contract to the Stellar network.
# https://github.com/stellar/soroban-quest/blob/main/quests/6-asset-interop/py-scripts/deploy-contract.py

import time

from stellar_sdk import Network, Keypair, TransactionBuilder
from stellar_sdk import xdr as stellar_xdr
from stellar_sdk.soroban import SorobanServer
from stellar_sdk.soroban.soroban_rpc import TransactionStatus

# TODO: You need to replace the following parameters according to the actual situation
secret = "SAAPYAPTTRZMCUZFPG3G66V4ZMHTK4TWA6NS7U4F7Z3IMUD52EK4DDEV"
rpc_server_url = "https://soroban-testnet.stellar.org"
network_passphrase = Network.TESTNET_NETWORK_PASSPHRASE
contract_file_path = "/path/to/compiled/soroban_contract.wasm"

kp = Keypair.from_secret(secret)
soroban_server = SorobanServer(rpc_server_url)

print("installing contract...")
source = soroban_server.load_account(kp.public_key)

# with open(contract_file_path, "rb") as f:
# contract_bin = f.read()

tx = (
TransactionBuilder(source, network_passphrase)
.set_timeout(300)
.append_install_contract_code_op(
contract=contract_file_path, # the path to the contract, or binary data
source=kp.public_key,
)
.build()
)
...

Testing

Hardhat proporciona un marco de pruebas que permite a los desarrolladores escribir pruebas para sus contratos inteligentes. Estas pruebas pueden escribirse en JavaScript o TypeScript y ejecutarse utilizando el comando npx hardhat test.

// test/my-contract.js

const { expect } = require("chai");

describe("MyContract", function () {
it("Should return the correct name", async function () {
const MyContract = await ethers.getContractFactory("MyContract");
const myContract = await MyContract.deploy();

await myContract.deployed();
expect(await myContract.name()).to.equal("MyContract");
});
});

Soroban Testing

Soroban permite a los usuarios aprovechar el poder del marco de pruebas de Rust para escribir pruebas para sus contratos inteligentes. Estas pruebas pueden escribirse en Rust y ejecutarse usando el comando cargo test.

#![cfg(test)]

use super::*;
use soroban_sdk::{vec, Env, Symbol, symbol_short};

#[test]
fn test() {
let env = Env::default();
let contract_id = env.register_contract(None, HelloContract);
let client = HelloContractClient::new(&env, &contract_id);

let words = client.hello(&symbol_short!("Dev"));
assert_eq!(
words,
vec![&env, symbol_short!("Hello"), symbol_short!("Dev"),]
);
}

En resumen, mientras Hardhat proporciona un excelente entorno para desplegar contratos inteligentes en la EVM, el marco basado en Rust de Soroban ofrece ventajas significativas en términos de rendimiento, lo que lo convierte en una opción ideal para construir contratos inteligentes seguros y eficientes.

Desarrollar Contratos Inteligentes con Rust y Soroban

Introducción

Ahora que hemos examinado el flujo de trabajo de despliegue con Hardhat, exploremos el desarrollo y despliegue de contratos inteligentes con Rust y Soroban. La principal ventaja de utilizar Soroban es su capacidad para aprovechar las características de seguridad y rendimiento de Rust, lo que lo convierte en una excelente opción para desarrollar contratos inteligentes seguros y eficientes.

Hemos aprendido que los contratos inteligentes son contratos autoejecutables que pueden programarse para hacer cumplir automáticamente las reglas y regulaciones de un acuerdo particular. Son un componente central de las aplicaciones descentralizadas (dApps) y la tecnología blockchain. En esta sección, aprenderemos cómo usar Rust y Soroban para desarrollar y desplegar lógica de contrato inteligente personalizada.

Configuración

Si aún no has configurado el entorno de desarrollo para Soroban, puedes comenzar siguiendo los pasos en la Página de Configuración.

Este proyecto requiere el uso del archivo soroban_token_contract.wasm que necesitarás importar manualmente.

Primero, necesitarás clonar la etiqueta v22.0.1 del repositorio soroban-examples:

git clone -b v22.0.1 https://github.com/stellar/soroban-examples

Luego, navega al directorio soroban-examples/token

cd soroban-examples/token

A continuación, construye el contrato Token usando el siguiente comando:

soroban contract build

Esto construirá el archivo soroban_token_contract.wasm que necesitarás importar en tu proyecto. El archivo soroban_token_contract.wasm se encuentra en el directorio soroban-examples/target/wasm32-unknown-unknown/release.

soroban-examples
├── target
│ └── wasm32-unknown-unknown
│ └── release
│ └── soroban_token_contract.wasm
└──

Una vez que tengamos el Token, vamos a crear un nuevo contrato inteligente que lo use.

Escribir un Contrato Inteligente

Comencemos escribiendo un ejemplo simple de un contrato de vault que permite a los usuarios depositar fondos y retirar sus fondos con rendimiento generado.

Aquí hay un desglose de la mecánica del contrato

  • Las acciones son creadas cuando un usuario realiza un depósito.
  • El protocolo DeFi utiliza los depósitos de los usuarios para generar rendimiento.
  • El usuario quema acciones para retirar sus tokens + rendimiento.

En una nueva terminal, vamos a crear un nuevo proyecto en Rust ejecutando el siguiente comando:

cargo new --lib vault

Esto creará un nuevo proyecto de Rust llamado vault.

Ahora vamos a agregar el archivo soroban_token_contract.wasm al proyecto vault. Para hacer esto, podemos arrastrar y soltar el archivo en el directorio del proyecto vault.

vault-project

A continuación, necesitaremos agregar el SDK de Soroban como una dependencia. Para hacer esto, abre el archivo Cargo.toml en tu proyecto y asegúrate de que coincide con lo siguiente:

[package]
name = "vault"
version = "0.0.0"
edition = "2021"
publish = false

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

[dependencies]
soroban-sdk = { version = "20.0.0" }
num-integer = { version = "0.1.45", default-features = false, features = ["i128"] }

[dev_dependencies]
soroban-sdk = { version = "20.0.0", 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

En este proyecto necesitaremos crear 3 archivos:

  • src/lib.rs - Aquí es donde escribiremos nuestra lógica de contrato inteligente de vault.
  • src/test.rs - Aquí es donde escribiremos nuestras pruebas.
  • src/token.rs - Este archivo hereda el contrato de token que importamos anteriormente. También es donde escribiremos nuestra lógica de creación de tokens.

Para interactuar con el contrato de token, utilizaremos una interfaz incorporada que puedes encontrar en la pestaña token_interface.rs. Esta interfaz incluye las funciones initialize y mint que utilizaremos para crear y acuñar tokens para usar en nuestro contrato de vault. Si quieres ver el código completo del contrato de token, puedes verlo aquí.

#![cfg(test)]
extern crate std;

use crate::{token, VaultClient};

use soroban_sdk::{
symbol_short,
testutils::{Address as _, AuthorizedFunction, AuthorizedInvocation},
Address, BytesN, Env, IntoVal,
};

fn create_token_contract<'a>(e: &Env, admin: &Address) -> token::Client<'a> {
token::Client::new(e, &e.register_stellar_asset_contract_v2(admin.clone()).address())
}

fn create_vault_contract<'a>(
e: &Env,
token_wasm_hash: &BytesN<32>,
token: &Address,
) -> VaultClient<'a> {
let vault = VaultClient::new(e, &e.register_contract(None, crate::Vault {}));
vault.initialize(token_wasm_hash, token);
vault
}

fn install_token_wasm(e: &Env) -> BytesN<32> {
soroban_sdk::contractimport!(file = "./soroban_token_contract.wasm");
e.deployer().upload_contract_wasm(WASM)
}

#[test]
fn test() {
let e = Env::default();
e.mock_all_auths();

let admin1 = Address::random(&e);

let token = create_token_contract(&e, &admin1);

let user1 = Address::random(&e);

let vault = create_vault_contract(&e, &install_token_wasm(&e), &token.address);

let contract_share = token::Client::new(&e, &vault.share_id());

let token_share = token::Client::new(&e, &contract_share.address);

token.mint(&user1, &200);
assert_eq!(token.balance(&user1), 200);
token.mint(&vault.address, &100);
assert_eq!(token.balance(&vault.address), 100);

vault.deposit(&user1, &100);
assert_eq!(
e.auths(),
std::vec![(
user1.clone(),
AuthorizedInvocation {
function: AuthorizedFunction::Contract((
vault.address.clone(),
symbol_short!("deposit"),
(&user1, 100_i128).into_val(&e)
)),
sub_invocations: std::vec![AuthorizedInvocation {
function: AuthorizedFunction::Contract((
token.address.clone(),
symbol_short!("transfer"),
(&user1, &vault.address, 100_i128).into_val(&e)
)),
sub_invocations: std::vec![]
}]
}
)]
);

assert_eq!(token_share.balance(&user1), 100);
assert_eq!(token_share.balance(&vault.address), 0);
assert_eq!(token.balance(&user1), 100);
assert_eq!(token.balance(&vault.address), 200);

e.budget().reset_unlimited();
vault.withdraw(&user1, &100);
assert_eq!(
e.auths(),
std::vec![(
user1.clone(),
AuthorizedInvocation {
function: AuthorizedFunction::Contract((
vault.address.clone(),
symbol_short!("withdraw"),
(&user1, 100_i128).into_val(&e)
)),
sub_invocations: std::vec![AuthorizedInvocation {
function: AuthorizedFunction::Contract((
token_share.address.clone(),
symbol_short!("transfer"),
(&user1, &vault.address, 100_i128).into_val(&e)
)),
sub_invocations: std::vec![]
}]
}
)]
);
assert_eq!(token.balance(&user1), 201);
assert_eq!(token_share.balance(&user1), 0);
assert_eq!(token.balance(&vault.address), 99);
assert_eq!(token_share.balance(&vault.address), 0);
}

Now that we've added these files to our project, let's break down what happens in the lib.rs file above and discover how "yield" is generated from our vault contract

Primero, echemos un vistazo a lo que sucede cuando un usuario deposita tokens en el contrato de vault.

fn deposit(e: Env, from: Address, amount: i128) {
// Depositor needs to authorize the deposit
from.require_auth();

let token = token::Client::new(&e, &get_token(&e));

token.transfer(&from, &e.current_contract_address(), &amount);

// Now calculate how many new vault shares to mint
let balance = get_token_balance(&e);

let shares = amount;

mint_shares(&e, from, shares);
put_reserve(&e, balance + shares);
}
  • La función deposit es llamada por el depositante para depositar tokens en el contrato de vault.
  • El método transfer de la instancia token_client transfiere tokens del depositante al contrato de vault.
  • El saldo actual de tokens y el total de acciones emitidas por el contrato de vault se obtienen utilizando las funciones get_token_balance y get_total_shares, respectivamente.
  • mint_shares se llama para emitir nuevas acciones al depositante y actualiza el total de acciones emitidas por el contrato de vault.
  • put_reserve almacena el saldo actual de tokens en una ubicación reservada.

Si el usuario llamara al método deposit con 100 tokens, sucedería lo siguiente:

  • 100 tokens se transferirían del depositante al contrato de vault.
  • El saldo actual de tokens se almacenaría en una ubicación reservada.
  • El total de acciones emitidas por el contrato de vault se actualizaría a 100.
  • 100 acciones se emitirían al depositante.

Ahora veamos qué sucede cuando un usuario retira tokens del vault.

fn withdraw(e: Env, to: Address, amount: i128) -> i128 {
to.require_auth();

// First transfer the vault shares that need to be redeemed
let share_token_client = token::Client::new(&e, &get_token_share(&e));
share_token_client.transfer(&to, &e.current_contract_address(), &amount);

// Calculate total amount including yield
let total_amount = amount + (amount / 100);

let token_client = token::Client::new(&e, &get_token(&e));
token_client.transfer(&e.current_contract_address(), &to, &total_amount);

let balance = get_token_balance(&e);
let balance_shares = get_balance_shares(&e);

burn_shares(&e, balance_shares);
put_reserve(&e, balance); // Update the reserve with the actual balance

total_amount
}
  • La función withdraw es llamada por el retirador para retirar tokens del contrato de vault.
  • El método transfer de la instancia share_token_client transfiere acciones del retirador al contrato de vault.
  • El método transfer_token de la instancia token_client transfiere tokens del contrato de vault al retirador.
  • burn_shares se llama para quemar las acciones que fueron transferidas al contrato de vault.
  • put_reserve almacena el saldo actual de tokens en una ubicación reservada.
  • Devuelve el total de tokens retirados por el usuario.

Nota : En la función de retirada, notarás que la cantidad de transferencia se define como &(&amount + (&amount / &100)). Este es un cálculo de rendimiento simple que asume que el rendimiento es el 1% de la cantidad que se está retirando. Sin embargo, es importante notar que este es un enfoque muy simplista y puede no ser adecuado para sistemas de producción. En realidad, los cálculos de rendimiento son más complejos e involucran varios factores como condiciones de mercado, gestión de riesgos y tarifas.

Si el usuario llamara al método withdraw con 100 acciones, sucedería lo siguiente:

  • 100 acciones se transferirían del retirador al contrato de vault.
  • El saldo actual de tokens se almacenaría en una ubicación reservada.
  • 100 acciones se quemarían.
  • 100 + (100/100) tokens se transferirían del contrato de vault al retirador.

Testing

Para probar el contrato de vault, podemos simplemente ejecutar el siguiente comando en nuestra terminal desde el directorio de nuestro contrato de vault:

#cd vault
cargo test

Esto ejecutará las pruebas que hemos escrito en el archivo src/test.rs.

running 1 test
test test::test ... ok

Despliegue e Interacción del Contrato de Vault

Ahora que tenemos un contrato de vault operativo, podemos desplegarlo en una red e interactuar con él.

Esta sección requiere que tengas un Keypair financiado para usar con el Testnet de Stellar. Puedes crear y financiar uno usando el Stellar Lab.

A continuación, encontrarás una serie de comandos que te ayudarán a construir, desplegar e interactuar con los contratos de vault y de token. Puedes usarlos para seguir mientras pasamos por el proceso de construir, desplegar e interactuar con los contratos. Puede serte útil mantener estos comandos en un directorio scripts en tu proyecto. De esta manera, puedes ejecutarlos fácilmente desde tu terminal.

Nota : Si decides usar scripts, asegúrate de verificar tus rutas de importación.

soroban contract build

Primero, necesitamos construir el contrato de vault. Podemos hacer esto ejecutando el script build.sh desde nuestro directorio de vault.

##cd vault
soroban contract build

A continuación, necesitamos desplegar el contrato de token. Podemos hacer esto ejecutando el script deploy_token.sh.

soroban contract deploy \
--wasm soroban_token_contract.wasm \
--source <SECRET_KEY> \
--rpc-url https://soroban-testnet.stellar.org:443 \
--network-passphrase 'Test SDF Network ; September 2015'

Deberíamos recibir una salida con el ID del contrato de token. Necesitaremos este ID para el siguiente paso.

CBYMG7OPIT67AG4S2FZU7LAYCXUSXEHRGHLDE6H26VCVWNOV7QUQTGNU

A continuación, necesitamos inicializar el contrato de token. Podemos hacer esto ejecutando el script initialize_token.sh.

soroban contract invoke \
--id <TOKEN_CONTRACT_ID> \
--source <SECRET_KEY> \
--rpc-url https://soroban-testnet.stellar.org:443 \
--network-passphrase 'Test SDF Network ; September 2015' \
-- \
initialize \
--admin <USER_ADDRESS> \
--decimal 18 \
--name <TOKEN_NAME> \
--symbol <TOKEN_SYMBOL>

A continuación, necesitamos desplegar el contrato de vault. Podemos hacer esto ejecutando el script deploy_vault.sh.

soroban contract deploy \
--wasm target/wasm32-unknown-unknown/release/vault.wasm \
--source <SECRET_KEY> \
--rpc-url https://soroban-testnet.stellar.org:443 \
--network-passphrase 'Test SDF Network ; September 2015'

Deberíamos recibir una salida con el ID del contrato del vault. Necesitaremos este ID para el siguiente paso.

CBBPLE6TGYOMO5HUF2AMYLSYYXM2VYZVAVYI5QCCM5OCFRZPBE2XA53F

Ahora necesitamos obtener el hash Wasm del contrato del token. Podemos hacer esto ejecutando el script get_token_wasm_hash.sh.

soroban contract install \
--wasm soroban_token_contract.wasm \
--source <SECRET_KEY> \
--rpc-url https://soroban-testnet.stellar.org:443 \
--network-passphrase 'Test SDF Network ; September 2015'

Deberíamos recibir el hash Wasm del contrato del token.

6b7e4bfbf47157a12e24e564efc1f9ac237e7ae6d7056b6c2ab47178b9e7a510

Ahora necesitamos inicializar el contrato del vault. Podemos hacer esto ejecutando el script initialize_vault.sh y pasando el ID del contrato del token y el hash Wasm del contrato del token.

soroban contract invoke \
--id <VAULT_CONTRACT_ID> \
--source <SECRET_KEY> \
--rpc-url https://soroban-testnet.stellar.org:443 \
--network-passphrase 'Test SDF Network ; September 2015' \
-- \
initialize \
--token_wasm_hash 6b7e4bfbf47157a12e24e564efc1f9ac237e7ae6d7056b6c2ab47178b9e7a510 \
--token <TOKEN_CONTRACT_ADDRESS>

Después de recibir que la transacción ha sido enviada, mintamos algunos tokens a ambas nuestras cuentas de usuario y direcciones del contrato del vault. Podemos hacer esto ejecutando el script mint.sh.

soroban contract invoke \
--id <TOKEN_CONTRACT_ID> \
--source <SECRET_KEY> \
--rpc-url https://soroban-testnet.stellar.org:443 \
--network-passphrase 'Test SDF Network ; September 2015' \
-- \
mint \
--to <USER_OR_VAULT_ADDRESS> \
--amount 100

Después de enviar la transacción, podemos verificar el saldo de la cuenta. Podemos hacer esto ejecutando el script balance.sh.

soroban contract invoke \
--id <TOKEN_CONTRACT_ID> \
--source <SECRET_KEY> \
--rpc-url https://soroban-testnet.stellar.org:443 \
--network-passphrase 'Test SDF Network ; September 2015' \
-- \
balance \
--id <USER_ADDRESS>

Deberíamos recibir una salida con el saldo de la cuenta.

100

Ahora podemos depositar algunos tokens en nuestro vault. Podemos hacer esto ejecutando el script deposit.sh.

soroban contract invoke \
--id <VAULT_CONTRACT_ID> \
--source <ACCOUNT_SECRET_KEY> \
--rpc-url https://soroban-testnet.stellar.org:443 \
--network-passphrase 'Test SDF Network ; September 2015' \
-- \
deposit \
--from <USER_ADDRESS> \
--amount 100

Después de enviar la transacción, podemos verificar las reservas del vault. Podemos hacer esto ejecutando el script reserves.sh.

soroban contract invoke \
--id <VAULT_CONTRACT_ID> \
--source <SECRET_KEY> \
--rpc-url https://soroban-testnet.stellar.org:443 \
--network-passphrase 'Test SDF Network ; September 2015' \
-- \
get_rsrvs

Deberíamos recibir una salida con las reservas del vault.

"200"

100 de la depósito y 100 de la mint.

Ahora podemos retirar algunos tokens del vault. Podemos hacer esto ejecutando el script withdraw.sh.

soroban contract invoke \
--id <VAULT_CONTRACT_ID> \
--source <SECRET_KEY> \
--rpc-url https://soroban-testnet.stellar.org:443 \
--network-passphrase 'Test SDF Network ; September 2015' \
-- \
withdraw \
--to <USER_ADDRESS> \
--amount 100

Deberíamos recibir una salida con el monto de la retirada.

"100"

Ahora es un buen momento para verificar nuestro saldo de cuenta de nuevo. Podemos hacer esto ejecutando el script balance.sh.

Deberíamos ver que nuestro saldo ha aumentado el monto que retiramos más el rendimiento (monto/100) o %1 de nuestro monto de retiro.

101

Y finalmente, podemos verificar las reservas del vault de nuevo. Podemos hacer esto ejecutando el script get_rsrv.sh.

Deberíamos ver que las reservas del vault han disminuido por el monto que retiramos + rendimiento.

"99"

¡Y ahí lo tienes! ¡Has desplegado e interactuado con éxito con el contrato del vault!

Es importante notar que este no es un contrato listo para producción y solo está destinado a demostrar las capacidades de la plataforma de contratos inteligentes Soroban. ¡Esperamos ver contratos de rendimiento mucho más complejos desplegados con Soroban en el futuro, y esperamos que tú seas parte de ello!

¿Te fue útil esta página?