Instalar WebAssembly (Wasm) bytecode usando código
Este proceso sube el código del contrato a la Stellar Testnet en una transacción, el blob Wasm subido es una fuente de contrato, que se puede pensar como una 'clase' de un contrato. Varias instancias de un contrato pueden ser desplegadas que comparten la misma fuente, pero tienen su propio estado. Varios instancias de un contrato pueden ser desplegadas que comparten la misma fuente, pero tienen su propio estado.
Requisitos previos
Antes de comenzar, asegúrate de tener lo siguiente instalado para compilar un contrato inteligente:
- Rust y Cargo (para compilar contratos inteligentes)
- El Stellar CLI
Inicializar y construir un contrato Rust de muestra
soroban contract init hello-world
cd hello-world
# use rust compiler to compile Rust project into a WebAssembly (Wasm) dynamic library (cdylib).
soroban contract build
# cargo rustc --manifest-path=contracts/hello_world/Cargo.toml --crate-type=cdylib --target=wasm32-unknown-unknown --release
Estamos inicializando el contrato hello_world
por defecto en soroban_examples al directorio hello-world
. Puedes usar la opción -w
para crear con otro ejemplo como account
.
Después de construir el contrato para su lanzamiento, el archivo .wasm generado está en la ruta hello-word/target/wasm32-unknown-unknown/release/hello_world.wasm
Subir Wasm a la blockchain Stellar
Podemos usar uno de los SDKs, instala las dependencias necesarias para tu lenguaje de programación elegido:
Crea un nuevo directorio para tu proyecto y navega dentro de él:
mkdir install-wasm
cd install-wasm
Ejecutando el script de instalación
Se pueden usar diferentes lenguajes de programación para subir el archivo .wasm
, su hash SHA256 se utiliza para desplegar el contrato.
- JavaScript
- Python
Esta guía te guiará a través de la instalación del Wasm del contrato usando el SDK de JavaScript: js-stellar-sdk.
Crea un nuevo proyecto Node.js con un archivo JavaScript, y instala las dependencias necesarias:
touch index.js
npm init es6 -y
npm install @stellar/stellar-sdk fs
Ejecuta el script con node index.js
, lee el archivo Wasm, obtiene los detalles de la cuenta y sube el contrato en una transacción:
// 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.SorobanRpc.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/wasm32-unknown-unknown/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);
}
Esta guía te guiará a través de la instalación del Wasm del contrato usando el SDK de Python: py-stellar-base.
Crea un nuevo script en Python y instala las dependencias necesarias:
touch install.py
pip install stellar-sdk
Ejecuta el script con python3 install.py
, lee el archivo Wasm, obtiene los detalles de la cuenta y sube el contrato en una transacción:
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/wasm32-unknown-unknown/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())
Reemplaza "Your_Secret_Key"
con tu clave secreta real.
stellar keys generate --global hello --network testnet
stellar keys show hello
El Stellar CLI se puede usar para generar identidades, por ejemplo, hello
, y mostrar su clave secreta.
Asegúrate de manejar las claves secretas y privadas de manera segura en ambientes de producción y nunca las expongas en tus repositorios de código.
Submitting transaction...
Transaction hash: cef7a63667fe5b0ddcde5562d90e0a40bc04c69616916d1d7fa74a8571bbd82f
Awaiting confirmation...
Transaction successful.
Wasm hash: 275405755441e4be59555bb5c5fd81e84ed21659015d8f3594796c1cf3f380db
El hash de la transacción de carga devuelta se puede ver con herramientas en línea: stellar.expert/explorer/testnet/tx/cef7a63667fe5b0ddcde5562d90e0a40bc04c69616916d1d7fa74a8571bbd82f
Los contratos subidos se almacenan en entradas de ledger ContractCodeEntry. Estas entradas están indexadas por el hash del Wasm usado para subirlos.
Puedes usar el hash del Wasm para el despliegue con el Stellar CLI:
stellar contract deploy \
--source hello \
--network testnet \
--wasm-hash 275405755441e4be59555bb5c5fd81e84ed21659015d8f3594796c1cf3f380db
# CC6NAQE3ZHRQV3NPQB3F3NYEFBAMEABA4KQTM6A2V5V7PBR5H3UEU3MW
Visualiza el contrato desplegado usando el identificador devuelto con herramientas en línea: stellar.expert/explorer/testnet/contract/CC6NAQE3ZHRQV3NPQB3F3NYEFBAMEABA4KQTM6A2V5V7PBR5H3UEU3MW
Guías en esta categoría:
📄️ Instalar y desplegar un contrato inteligente con código
Instalar y desplegar un contrato inteligente con código
📄️ Instalar WebAssembly (Wasm) bytecode usando código
Instalar el Wasm del contrato usando js-stellar-sdk
📄️ Invocar una función de contrato en una transacción Stellar utilizando SDKs
Usar el SDK de Stellar para crear, simular y ensamblar una transacción
📄️ guía del método RPC simulateTransaction
guía de ejemplos y tutoriales de simulateTransaction
📄️ Enviar una transacción a Stellar RPC utilizando el SDK de JavaScript
Usar un mecanismo de bucle para enviar una transacción a la RPC