Skip to main content

Deploy Smart Contracts (Go)

This guide shows the core steps to deploy a ULVM smart contract using the ULedger Go SDK.

You will:

  1. Load a wallet (the signer)
  2. Read your compiled contract (.wat or .wasm)
  3. Create a transaction session to a node
  4. Submit a DEPLOY_SMART_CONTRACT transaction
info

On many chains, your wallet must be registered on-chain (TX_CREATE_WALLET) before it can deploy contracts. If you get REJECTED_BY_UNAUTHORIZED, register the wallet first.


1. Prerequisites

You need:

  • nodeEndpoint (example: http://localhost:8080)
  • blockchainId
  • A wallet that can sign transactions
  • Your contract source file:
    • auction.wat (text), or
    • auction.wasm (binary — encoding depends on node rules)

Use the .ukey file from the wallet tutorial:

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

3. Read the contract source code

Option A: Deploy a .wat file (text)

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

Option B: Deploy a .wasm file (binary)

Your node may expect raw bytes, hex, or base64. A common approach is base64:

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

Use the format your node expects for DEPLOY_SMART_CONTRACT.


4. Pick a contract address (this goes in To)

In the Go SDK transaction input, To is required.

For deploy transactions, To is typically treated as the contract address (the place the contract “lives” on-chain).

Here’s a simple helper that generates a random 32-byte hex string:

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. Create a transaction session

This call fetches /health (to get nodeId) and checks /blockchains.

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

6. Build the exact ULTransactionInput and deploy

Your Go struct is:

type ULTransactionInput struct {
BlockchainId string
To string
From string
Payload string
SenderSignature string
PayloadType string
Suggestor string
SenderTimestamp time.Time
PayloadRoot string
KeyType crypto.KeyType
}

For deploy, you only need to set these fields manually:

  • BlockchainId
  • To (contract address)
  • Payload (your contract source)
  • PayloadType (must be DEPLOY_SMART_CONTRACT.String())

Everything else is filled by GenerateTransaction().

input := transaction.ULTransactionInput{
BlockchainId: blockchainId,
To: contractAddress,
Payload: contractSource,
PayloadType: transaction.DEPLOY_SMART_CONTRACT.String(),
}

Now submit:

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 ID:", tx.TransactionId)
fmt.Println("Status:", tx.Status)
fmt.Println("Output:", tx.Output)
fmt.Println("Contract Address (To):", contractAddress)

What GenerateTransaction() does for you (deploy case)

Based on your transaction_session.go:

  • Sets input.Suggestor = nodeId (from /health)
  • Sets input.SenderTimestamp = now (UTC)
  • Sets input.From = session.wallet.Address (because it’s not TX_CREATE_WALLET)
  • Sets input.KeyType = session.wallet.GetKey().GetType()
  • Computes input.PayloadRoot using GetUnboundCommitment(...) for deploy/upgrade/create/alter wallet
  • Signs commitment and fills input.SenderSignature
  • POSTs to: POST {nodeEndpoint}/blockchains/{blockchainId}/transactions

7. Next step: Invoke the contract

To call your deployed contract, you’ll submit an INVOKE_SMART_CONTRACT transaction.

Continue to: Invoke Smart Contracts (Go) (next guide).