Plutus.V1.Ledger.Address

  • 1. 📜 Overview

  • 2. 🔧 Language Extensions and Imports

  • 3. 🗄️ Data Structures

    • 3.1 🆕 newtype Example

    • 3.2 🔤 type Synonym Example

    • 3.3 📦 data Type Example

    • 3.4 🏠 Address Data Type

  • 4. ⚙️ Functions

    • 4.1 🔑 pubKeyHashAddress

    • 4.2 🔍 toPubKeyHash

    • 4.3 📜 toValidatorHash

    • 4.4 🏷️ scriptHashAddress

    • 4.5 🎰 stakingCredential

  • 5. 🤝 Typeclass Instances

  • 6. 📚 Glossary


1 📜 Overview

This tutorial walks through a Plutus Address script in Haskell:

  • Defines a custom Address data type with payment and staking credentials.

  • Implements helper functions to build and query addresses.

  • Shows how to derive instances for on-chain data (IsData) and lifting.

  • Explains language extensions, imports, and related typeclasses.

It also illustrates basic newtype, type synonym, and data definitions for comparison.


2 🔧 Language Extensions and Imports

{-# LANGUAGE DerivingStrategies #-}
{-# LANGUAGE DeriveAnyClass    #-}
{-# LANGUAGE TemplateHaskell   #-}
{-# LANGUAGE OverloadedStrings #-}
{-# INLINABLE          #-}
  • DerivingStrategies: chooses between stock and anyclass for deriving.

  • DeriveAnyClass: allows deriving classes like NFData.

  • TemplateHaskell: used by PlutusTx.makeIsDataIndexed and makeLift for on-chain code.

  • OverloadedStrings: for convenient string literals in Prettyprinter.

  • INLINABLE pragma**: marks functions for on-chain compilation and optimization.

Imports:

import Control.DeepSeq (NFData)
import GHC.Generics    (Generic)
import PlutusTx        qualified
import PlutusTx.Bool   qualified as PlutusTx
import PlutusTx.Eq     qualified as PlutusTx
import Prettyprinter

import Plutus.V1.Ledger.Credential (Credential(..), StakingCredential)
import Plutus.V1.Ledger.Crypto
import Plutus.V1.Ledger.Scripts
  • NFData, Generic: for strict evaluation and generic deriving.

  • PlutusTx modules: on-chain utilities (Bool, Eq, makeIsDataIndexed, makeLift).

  • Prettyprinter: for human-readable Pretty instance.

  • Ledger.Credential, Crypto, Scripts: on-chain ledger types (PubKeyHash, ValidatorHash, Credential).


3 🗄️ Data Structures

Below are examples of the three Haskell type definitions, followed by our Address.

3.1 🆕 newtype Example

-- A wrapper for integers with special semantics
newtype MyInt = MyInt Int
    deriving (Eq, Show)

-- Usage:
let x = MyInt 5
print x           -- outputs: MyInt 5
  • Inputs: Int value

  • Processing: none (zero-cost wrapper)

  • Output: MyInt

3.2 🔤 type Synonym Example

-- Alias for readability
type Username = String

-- Usage:
let user :: Username
    user = "alice"
  • Inputs/Outputs: identical to String, just renamed.

3.3 📦 data Type Example

-- A sum type representing shapes
data Shape = Circle Double | Rectangle Double Double
    deriving (Eq, Show)

-- Usage:
let c = Circle 2.0
let r = Rectangle 3.0 4.0
  • Inputs: Double parameters

  • Processing: none at construction

  • Outputs: Shape value

3.4 🏠 Address Data Type

-- | Address with payment and optional staking credential
data Address = Address
    { addressCredential        :: Credential
    , addressStakingCredential :: Maybe StakingCredential
    }
    deriving stock (Eq, Ord, Show, Generic)
    deriving anyclass (NFData)
  • Fields:

    • addressCredential: on-chain Credential (either a public key or script)

    • addressStakingCredential: optional StakingCredential

  • Derivations:

    • Eq, Ord, Show, Generic via stock

    • NFData via anyclass

Example Usage:

import Plutus.V1.Ledger.Credential (PubKeyCredential(..))
import Plutus.V1.Ledger.Crypto     (PubKeyHash)

let pkh = PubKeyHash "abcdef..."
let addr = Address (PubKeyCredential pkh) Nothing
print addr

4 ⚙️ Functions

Each function below is marked {-# INLINABLE #-} for on-chain use.

4.1 🔑 pubKeyHashAddress

{-# INLINABLE pubKeyHashAddress #-}
-- | Construct an address locked by a public key hash
pubKeyHashAddress :: PubKeyHash -> Address
pubKeyHashAddress pkh = Address (PubKeyCredential pkh) Nothing
  • Inputs: PubKeyHash

  • Processing: wraps into PubKeyCredential, sets no staking

  • Output: Address

Example:

let myAddr = pubKeyHashAddress somePubKeyHash

4.2 🔍 toPubKeyHash

{-# INLINABLE toPubKeyHash #-}
-- | Extract the public key hash, if present
toPubKeyHash :: Address -> Maybe PubKeyHash
toPubKeyHash (Address (PubKeyCredential k) _) = Just k
toPubKeyHash _                                = Nothing
  • Inputs: Address

  • Processing: pattern match on Credential

  • Output: Maybe PubKeyHash

Examples:

toPubKeyHash (pubKeyHashAddress pkh) == Just pkh
toPubKeyHash (scriptHashAddress vh)   == Nothing

4.3 📜 toValidatorHash

{-# INLINABLE toValidatorHash #-}
-- | Extract the validator hash, if any
toValidatorHash :: Address -> Maybe ValidatorHash
toValidatorHash (Address (ScriptCredential k) _) = Just k
toValidatorHash _                                = Nothing
  • Inputs: Address

  • Processing: pattern match on ScriptCredential

  • Output: Maybe ValidatorHash

Example:

toValidatorHash (scriptHashAddress someVH) == Just someVH

4.4 🏷️ scriptHashAddress

{-# INLINABLE scriptHashAddress #-}
-- | Construct an address locked by a script validator hash
scriptHashAddress :: ValidatorHash -> Address
scriptHashAddress vh = Address (ScriptCredential vh) Nothing
  • Inputs: ValidatorHash

  • Processing: wraps into ScriptCredential, no staking

  • Output: Address

Example:

let scriptAddr = scriptHashAddress myValidatorHash

4.5 🎰 stakingCredential

{-# INLINABLE stakingCredential #-}
-- | Retrieve staking credential, if any
stakingCredential :: Address -> Maybe StakingCredential
stakingCredential (Address _ s) = s
  • Inputs: Address

  • Processing: field projection

  • Output: Maybe StakingCredential

Example:

stakingCredential addr == Nothing

5 🤝 Typeclass Instances

instance Pretty Address where
    pretty (Address cred stakingCred) =
        let staking = maybe "no staking credential" pretty stakingCred in
        pretty cred <+> parens staking
  • Class: Pretty from Prettyprinter

  • Method: pretty :: a -> Doc ann

  • Behavior: prints the payment credential and staking in parentheses.

instance PlutusTx.Eq Address where
    {-# INLINABLE (==) #-}
    Address c1 s1 == Address c2 s2 =
        c1 PlutusTx.== c2 PlutusTx.&& s1 PlutusTx.== s2
  • Class: Eq from PlutusTx, used on-chain

  • Method: (==) must be INLINABLE

On-chain Derivation:

PlutusTx.makeIsDataIndexed ''Address [('Address,0)]
PlutusTx.makeLift     ''Address
  • makeIsDataIndexed: generates IsData instance with constructor index

  • makeLift: allows lifting Haskell values into on-chain code


6 📚 Glossary

  • Address: On-chain identifier combining payment & staking credentials.

  • Credential: Either PubKeyCredential PubKeyHash or ScriptCredential ValidatorHash.

  • StakingCredential: Optional credential for staking rewards.

  • PubKeyHash: Hash of a public key.

  • ValidatorHash: Hash of a validator script.

  • INLINABLE: GHC pragma making function available for specialization.

  • makeIsDataIndexed: Template Haskell for on-chain data serialization.

  • makeLift: Template Haskell for lifting to on-chain.

  • newtype: Zero-cost wrapper around a single field type.

  • type: Synonym for another type.

  • data: Defines a new algebraic data type.

  • NFData: Class for deep evaluation (rnf).

  • Pretty: Class for pretty-printing values.

Last updated