Saltar al contenido principal

Desplegar Smart Contracts (Go)

Esta guía muestra los pasos principales para desplegar un smart contract ULVM compilado usando el ULedger Go SDK.

Vas a:

  1. Cargar un wallet (el firmante)
  2. Leer tu contrato compilado (.wat o .wasm)
  3. Crear una UL_TransactionSession hacia un node
  4. Enviar una transacción DEPLOY_SMART_CONTRACT
info

Antes de desplegar contratos en la mayoría de las redes, tu wallet debe estar registrado on-chain (TX_CREATE_WALLET).
Si el despliegue falla con errores de autorización, registra tu wallet primero.


1. Requisitos previos​

Necesitas:

  • Un endpoint de node (puedes usar un endpoint de testnet: https://tn-w-3.uledger.net/)
  • Un blockchainId
  • Un wallet con el que puedas firmar
  • Un archivo de contrato compilado:
    • contract.wat (texto), o
    • contract.wasm (binario)

2. Cargar un wallet (enfoque recomendado)​

Recomendado: cargar desde un archivo .ukey creado por el flujo de wallet del SDK.

w, err := wallet.LoadFromFile("./wallets/my_wallet.ukey", "")
if err != nil {
return fmt.Errorf("load wallet: %w", err)
}

Evita codificar claves privadas directamente en los ejemplos. Usa archivos .ukey o variables de entorno.


3. Leer el archivo del contrato​

Si despliegas .wat (texto)​

watBytes, err := os.ReadFile("./auction.wat")
if err != nil {
return fmt.Errorf("read contract file: %w", err)
}
sourceCode := string(watBytes)

Si despliegas .wasm (binario)​

La mayoría de los payloads de transacción son cadenas de texto, por lo que un enfoque común es usar base64:

wasmBytes, err := os.ReadFile("./auction.wasm")
if err != nil {
return fmt.Errorf("read contract file: %w", err)
}
sourceCode := base64.StdEncoding.EncodeToString(wasmBytes)

Si tu red espera texto WAT o WASM en base64 depende de la configuración del node.


4. Elegir una dirección de contrato​

Muchas cadenas tratan la dirección del contrato como un valor explícito (pasado como To).

Un valor predeterminado simple y seguro es una cadena hex aleatoria de 32 bytes:

func randomHex32() (string, error) {
b := make([]byte, 32)
if _, err := rand.Read(b); err != nil {
return "", err
}
return hex.EncodeToString(b), nil
}
contractAddress, err := randomHex32()
if err != nil {
return fmt.Errorf("generate contract address: %w", err)
}

5. Crear una sesión de transacción​

session, err := transaction.NewUL_TransactionSession(nodeEndpoint, w)
if err != nil {
return fmt.Errorf("create session: %w", err)
}

NewUL_TransactionSession normalmente realiza llamadas iniciales al node (como /health) y prepara la sesión para firmar y enviar transacciones.


6. Construir y enviar la transacción de despliegue​

Esta es la "lógica principal":

input := transaction.ULTransactionInput{
BlockchainId: blockchainId,
From: w.Address, // dirección del wallet firmante
To: contractAddress, // donde vivirá el contrato
Payload: sourceCode, // texto WAT o WASM en base64
PayloadType: transaction.DEPLOY_SMART_CONTRACT.String(),
}

tx, err := session.GenerateTransaction(input)
if err != nil {
return fmt.Errorf("deploy contract: %w", err)
}

if tx.TransactionId == "" {
return fmt.Errorf("deploy returned empty transaction id")
}

fmt.Println("Deploy TX:", tx.TransactionId)
fmt.Println("Status:", tx.Status)
fmt.Println("Output:", tx.Output)
fmt.Println("Contract address:", contractAddress)

Qué esperar como respuesta​

  • tx.TransactionId = identificador de la transacción
  • tx.Status = SUBMITTED, ACCEPTED, o REJECTED
  • tx.Output = SUCCESS o un motivo de rechazo

7. Siguiente paso: Invocar el contrato​

Una vez desplegado, puedes llamar al contrato con una transacción INVOKE_SMART_CONTRACT.

Continúa en: Invocar Smart Contracts (Go).