Desplegar un contrato a partir de bytecode Wasm instalado usando un contrato desplegador
Descripción general
Esta guía te lleva a través del proceso de desplegar un contrato inteligente a partir de bytecode Wasm instalado usando un contrato desplegador. Cubriremos la configuración de tu entorno, la carga de bytecode Wasm y el despliegue e inicialización de un contrato de forma atómica.
Requisitos previos:
- Conocimiento básico del lenguaje de programación Rust. Para refrescarte en Rust, visita Rustlings o El libro de Rust.
- Familiaridad con contratos inteligentes Stellar
- Cargo instalado, Stellar CLI y SDK de Soroban
Configuración del entorno
El ejemplo de desplegador demuestra cómo desplegar contratos usando un contrato.
- Clona el repositorio de ejemplos de Soroban:
git clone -b v20.2.0 https://github.com/stellar/soroban-examples
- Navega al ejemplo de desplegador:
cd soroban-examples/deployer/deployer
Para que este ejemplo funcione, debes navegar a deployer/contracts
y deployer/deployer
y ejecutar el comando stellar contract build
en cada directorio para generar los archivos de destino.
- Ejecuta pruebas:
En el deployer/deployer
, ejecuta el siguiente comando:
cargo test
Deberías ver la salida indicando que las pruebas pasaron:
running 2 tests
test test::test_deploy_from_contract ... ok
test test::test_deploy_from_address ... ok
Descripción del código
#[contract]
pub struct Deployer;
#[contractimpl]
impl Deployer {
/// Deploy the contract Wasm and after deployment invoke the init function
/// of the contract with the given arguments.
///
/// This has to be authorized by `deployer` (unless the `Deployer` instance
/// itself is used as deployer). This way the whole operation is atomic
/// and it's not possible to frontrun the contract initialization.
///
/// Returns the contract address and result of the init function.
pub fn deploy(
env: Env,
deployer: Address,
wasm_hash: BytesN<32>,
salt: BytesN<32>,
init_fn: Symbol,
init_args: Vec<Val>,
) -> (Address, Val) {
// Skip authorization if deployer is the current contract.
if deployer != env.current_contract_address() {
deployer.require_auth();
}
// Deploy the contract using the uploaded Wasm with given hash.
let deployed_address = env
.deployer()
.with_address(deployer, salt)
.deploy(wasm_hash);
// Invoke the init function with the given arguments.
let res: Val = env.invoke_contract(&deployed_address, &init_fn, init_args);
// Return the contract ID of the deployed contract and the result of
// invoking the init result.
(deployed_address, res)
}
}
Cómo funciona
El contrato desplegador proporciona un mecanismo para desplegar otros contratos de manera segura y determinista. Asegura que el despliegue esté autorizado por la dirección de desplegador especificada y admite la inicialización atómica del contrato recién desplegado. Esto garantiza que el contrato esté correctamente inicializado inmediatamente después del despliegue, previniendo cualquier problema potencial con contratos no inicializados.
Desglose de funciones
env: Env
: El objeto Env representa el entorno de ejecución del contrato actual. Proporciona métodos para interactuar con la blockchain y otros contratos, así como realizar varias operaciones.deployer: Address
: La dirección de la entidad que está solicitando el despliegue del contrato. Esta dirección se utilizará para autorizar el despliegue.wasm_hash: BytesN<32>
: El hash del bytecode Wasm del contrato que se va a desplegar y que debe estar ya instalado y en el ledger. Este hash se utiliza para identificar de manera única el código del contrato.salt: BytesN<32>
: Un valor único utilizado para derivar la dirección del contrato desplegado. La misma combinación de dirección del desplegador y sal siempre producirá la misma dirección de contrato desplegado, asegurando direcciones de contrato deterministas.init_fn: Symbol
: El nombre de la función de inicialización que se llamará en el contrato recién desplegado.init_args: Vec<Val>
: Un vector de argumentos, especificados como objetos{type: value}
, que se pasarán a la función de inicialización del contrato desplegado.
Pasos de la función
if deployer != env.current_contract_address() {
deployer.require_auth();
}
La función verifica si la dirección deployer
es la misma que la dirección del contrato actual. Si no lo es, requiere autorización de la dirección del desplegador para asegurar que el desplegador ha permitido este despliegue.
let deployed_address = env
.deployer()
.with_address(deployer, salt)
.deploy(wasm_hash);
- Usa el método
env.deployer()
para crear un objeto desplegador. with_address(deployer, salt)
especifica la dirección del desplegador y la sal para derivar la nueva dirección del contrato.deploy(wasm_hash)
despliega el contrato usando el hash de bytecode Wasm proporcionado y devuelve la dirección del contrato recién desplegado.
let res: Val = env.invoke_contract(&deployed_address, &init_fn, init_args);
- Invoca la función de inicialización especificada (
init_fn
) en el contrato recién desplegado (deployed_address
), pasando los argumentos de inicialización proporcionados (init_args
). - El resultado de esta llamada a la función se almacena en
res
.
(deployed_address, res)
Devuelve una tupla que contiene la dirección del contrato recién desplegado y el resultado de la función de inicialización.
Construir los contratos
Para construir el contrato en un archivo .wasm
, usa el comando stellar contract build
. Este comando construye tanto el contrato desplegador como el contrato de prueba.
stellar contract build
Ambos archivos .wasm
deberían encontrarse en ambos directorios de destino del contrato después de construir ambos contratos:
target/wasm32-unknown-unknown/release/soroban_deployer_contract.wasm
target/wasm32-unknown-unknown/release/soroban_deployer_test_contract.wasm
Ejecutar el contrato
Antes de desplegar el contrato de prueba con el desplegador, instala el bytecode Wasm del contrato de prueba usando el comando install
. El comando install
imprimirá el hash derivado del archivo Wasm que debe ser utilizado por el desplegador.
stellar contract install \
--wasm contract/target/wasm32-unknown-unknown/release/soroban_deployer_test_contract.wasm \
--source-account alice \
--network testnet
Al desplegar un contrato inteligente en la red, debes especificar una identidad que se utilizará para firmar las transacciones. Cambia la identidad alice
por la tuya.
El comando imprime el hash en formato hexadecimal. Se verá algo así como 6bc6d975ef99c057231481c40f69f4c2a8a89ac56e8826ef0378f8e5c6abc4be
.
También necesitamos desplegar el contrato Deployer
:
stellar contract deploy \
--wasm deployer/target/wasm32-unknown-unknown/release/soroban_deployer_contract.wasm \
--source alice \
--network testnet
Esto devolverá la dirección del desplegador. Por ejemplo: CDKYZMA3OXR54YAHOQ5D4EWDFDT3ZNKKRYKQT7MGPWH22ZVD2DX2BJID
.
Luego, el contrato desplegador puede ser invocado con el valor hash de Wasm anterior.
stellar contract invoke \
--id CDKYZMA3OXR54YAHOQ5D4EWDFDT3ZNKKRYKQT7MGPWH22ZVD2DX2BJID \
--source alice \
--network testnet \
-- \
deploy \
--deployer CDKYZMA3OXR54YAHOQ5D4EWDFDT3ZNKKRYKQT7MGPWH22ZVD2DX2BJID \
--salt 123 \
--wasm_hash 6bc6d975ef99c057231481c40f69f4c2a8a89ac56e8826ef0378f8e5c6abc4be \
--init_fn init \
--init_args '[{"u32":8}]'
reemplaza alice
con tu propia identidad
La invocación del contrato desplegador devolverá la dirección del contrato (por ejemplo: CCTVFX6BFTQHTGAHA5TY4YZQJRUKRE2RRNUTGVBNKE3PJF5C7CI53APY
) del contrato de prueba que se ha desplegado recientemente.
Invoca el contrato de prueba desplegado usando la dirección devuelta del comando anterior.
stellar contract invoke \
--id CCTVFX6BFTQHTGAHA5TY4YZQJRUKRE2RRNUTGVBNKE3PJF5C7CI53APY \
--source alice \
--network testnet \
-- \
value
Deberías recibir algo como la siguiente salida:
8
Guías en esta categoría:
📄️ Usar __check_auth de maneras interesantes
Dos guías que explican cómo usar __check_auth
📄️ Hacer llamadas entre contratos
Llamar a un contrato inteligente desde otro contrato inteligente
📄️ Desplegar un contrato a partir de bytecode Wasm instalado usando un contrato desplegador
Desplegar un contrato a partir de bytecode Wasm instalado usando un contrato desplegador
📄️ Desplegar un SAC para un activo Stellar utilizando código
Desplegar un SAC para un activo Stellar utilizando el SDK de Javascript
📄️ Organizar errores de contrato con un tipo de enumeración de errores
Gestionar y comunicar errores de contrato utilizando una estructura de enumeración almacenada como valores de Estado
📄️ Extender el TTL de un contrato desplegado con código
Cómo extender el TTL del código Wasm de un contrato desplegado
📄️ Actualizando el bytecode de Wasm para un contrato desplegado
Actualizar el bytecode de Wasm para un contrato desplegado
📄️ Escribir metadatos para tu contrato
Usa el contractmeta! macro en Rust SDK para escribir metadatos en contratos Wasm