-
Notifications
You must be signed in to change notification settings - Fork 31
Home
Welcome to the plutus-nix wiki!
- Vesting Module
- Parameterized Vesting Module
- Time Utilities (CGTime)
- Address Utilities (CGPlutusUtils)
- Glossary of Terms
The Vesting module implements a simple on-chain vesting contract that releases funds to a beneficiary only after a deadline.
-
mkVestingValidator :: VestingDatum -> () -> ScriptContext -> Bool- Core validator logic: checks signature and deadline.
-
mkWrappedVestingValidator :: BuiltinData -> BuiltinData -> BuiltinData -> ()- Wraps
mkVestingValidatorfor compilation.
- Wraps
-
validator :: Validator- The compiled validator script.
-
saveVal :: IO ()- Writes the validator to a
.plutusfile.
- Writes the validator to a
-
vestingAddressBech32 :: Network -> String- Returns the on-chain address in Bech32 format.
-
printVestingDatumJSON :: PubKeyHash -> String -> IO ()- Serializes a
VestingDatumto JSON for testing.
- Serializes a
import Vesting
import Utilities (Network(..))
main :: IO ()
main = do
-- Save the validator
saveVal
-- Print the address for testnet
putStrLn $ vestingAddressBech32 Testnet
-- Prepare a datum JSON
let beneficiary = "659ad08ff..."
deadlineISO = "2025-06-01T00:00:00Z"
printVestingDatumJSON beneficiary deadlineISOParameterizedVesting generalizes Vesting by parameterizing the script with VestingParams.
-
mkParameterizedVestingValidator :: VestingParams -> () -> () -> ScriptContext -> Bool- Checks
txSignedByand deadline for given parameters.
- Checks
-
mkWrappedParameterizedVestingValidator :: VestingParams -> BuiltinData -> BuiltinData -> BuiltinData -> ()- Wraps the parameterized validator for compilation.
-
validator :: VestingParams -> Validator- Produces a validator for specific parameters.
-
fromHexPKH :: String -> PubKeyHash- Converts a hex string to a
PubKeyHash.
- Converts a hex string to a
-
saveVal :: VestingParams -> IO ()- Writes the parameterized validator to a file.
import ParameterizedVesting
main :: IO ()
main = do
let params = VestingParams
{ beneficiary = fromHexPKH "659ad08ff..."
, deadline = 1717406400 -- POSIXTime
}
saveVal params
putStrLn "Parameterized vesting validator saved."The CGTime module provides conversions and helpers between UTCTime, POSIXTime, and ISO‑8601.
utcToPOSIX :: UTCTime -> POSIXTimeiso8601ToPOSIX :: String -> Maybe POSIXTimeposixToUTC :: POSIXTime -> UTCTimeposixToISO8601 :: POSIXTime -> StringgetUTCNow :: IO UTCTimegetPOSIXNow :: IO POSIXTimegetISO8601Now :: IO StringgetTimeTriple :: IO (UTCTime,POSIXTime,String)addSeconds :: NominalDiffTime -> UTCTime -> UTCTimeaddDaysUTC :: Integer -> UTCTime -> UTCTimediffSeconds :: UTCTime -> UTCTime -> NominalDiffTimeaddSecondsPOSIX :: NominalDiffTime -> POSIXTime -> POSIXTimeaddDaysPOSIX :: Integer -> POSIXTime -> POSIXTimediffSecondsPOSIX :: POSIXTime -> POSIXTime -> NominalDiffTimeformatUTC :: String -> UTCTime -> StringparseUTC :: String -> String -> Maybe UTCTimegetLocalISO8601 :: IO String
import CGTime
import Data.Time.Clock (getCurrentTime)
main :: IO ()
main = do
t <- getUTCNow
print $ utcToPOSIX t
print $ posixToISO8601 1714810800
print =<< getISO8601NowCGPlutusUtils lets you go between Bech32 addresses and PubKeyHash.
bech32ToPubKeyHash :: String -> Either String PubKeyHashpkhToAddrB32 :: String -> Word8 -> String -> Either String StringpkhToAddrB32Opt :: Maybe String -> Maybe Word8 -> String -> Either String StringpkhToAddrB32Testnet :: String -> Either String StringpkhToAddrB32Mainnet :: String -> Either String String
import CGPlutusUtils
main :: IO ()
main = do
let hex = "659ad08ff173857842dc6f8..."
case pkhToAddrB32Testnet hex of
Left err -> putStrLn $ "Error: " ++ err
Right addr -> putStrLn $ "Address: " ++ addr
print $ bech32ToPubKeyHash addrBech32: A human-readable encoding for addresses.
PubKeyHash: A 28-byte hash of a public key used to identify wallets.
POSIXTime: Seconds since Unix epoch (1970‑01‑01 UTC).
UTCTime: Coordinated Universal Time representation in Haskell.
HRP: Human‑Readable Part of a Bech32 string, indicates network.
GADT: Generalized Algebraic Data Type, a Haskell feature for precise typing.
Datum: On-chain data attached to UTxOs.
Validator: A script that checks whether a transaction is allowed.
On-chain: Code that runs in the blockchain’s validation.
Off-chain: Code that runs in a user’s wallet or backend.
CGTime: Coxygen Global Time module
CGPlutusUtils: Coxygen Global Plutus Utils module
This section shows how to add and run Cabal tests for every module.
Edit wspace.cabal to include a test-suite component:
test-suite wspace-tests
type: exitcode-stdio-1.0
hs-source-dirs: tests
main-is: Spec.hs
build-depends:
base >=4.14 && <4.15,
wspace,
utilities,
tasty,
tasty-hunit,
QuickCheck
default-language: Haskell2010import Test.Tasty
import Test.Tasty.HUnit
import Vesting
main :: IO ()
main = defaultMain tests
tests :: TestTree
tests = testGroup "Vesting Module Tests"
[ testCase "Validator rejects before deadline" $
mkVestingValidator ... @?= False
, testCase "Validator accepts after deadline" $
mkVestingValidator ... @?= True
]import Test.Tasty
import Test.Tasty.HUnit
import ParameterizedVesting
main = defaultMain tests
tests = testGroup "Parameterized Vesting Tests"
[ testCase "FromHexPKH parses valid hex" $
fromHexPKH "659ad..." @?= expectedPKH
]import Test.Tasty
import Test.Tasty.HUnit
import CGTime
main = defaultMain tests
tests = testGroup "CGTime Tests"
[ testCase "ISO8601 to POSIX roundtrip" $
let tStr = "2025-05-04T00:00:00Z"
in iso8601ToPOSIX tStr >>= -> posixToISO8601 t @?= tStr
]import Test.Tasty
import Test.Tasty.HUnit
import CGPlutusUtils
main = defaultMain tests
tests = testGroup "CGPlutusUtils Tests"
[ testCase "Bech32 → PKH → Bech32 roundtrip" $
let hex = "659ad08ff..."
in do
addr <- pkhToAddrB32Testnet hex
Right pkh <- return $ bech32ToPubKeyHash addr
pkh @?= Crypto.PubKeyHash (Builtins.toBuiltin (fst $ B16.decode (C.pack hex)))
]cabal test