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:
- Cargar un wallet (el firmante)
- Leer tu contrato compilado (
.wato.wasm) - Crear una
UL_TransactionSessionhacia un node - Enviar una transacción
DEPLOY_SMART_CONTRACT
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), ocontract.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
.ukeyo 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óntx.Status=SUBMITTED,ACCEPTED, oREJECTEDtx.Output=SUCCESSo 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).