Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Plutus and Extended UTxO

Plutus and Extended UTxO

VIDEO: https://www.youtube.com/watch?v=TFezjgwuw8Y

This presentation was part of PlutusFest 2018 and introduces the design and architecture of the Plutus Platform, a Haskell-based environment and toolchain for developing contracts for the Cardano blockchain. The key features are its use of a standard purely functional programming language (instead of inventing a new language, which appears to be the popular approach), being based on a ledger-architecture that resembles a functional data flow graph (UTxO ledger, rather than an account-based ledger), and its tight integration and co-development of on-chain code (executed by block producing nodes) and off-chain code (executed on client machines).

See https://testnet.iohkdev.io/plutus/ for an online environment to write and test Plutus code and https://github.com/input-output-hk/plutus/ for the code.

Manuel Chakravarty

December 11, 2018
Tweet

More Decks by Manuel Chakravarty

Other Decks in Technology

Transcript

  1. PLUTUS What is Plutus? Innovative development and execution platform for

    distributed contract applications on Cardano SL & CL.
  2. PLUTUS input output typed function safe usage :: ⍺ ::

    β local reasoning type-directed design
  3. PLUTUS input output typed function safe usage :: ⍺ ::

    β local reasoning type-directed design advanced testing & verification
  4. PLUTUS core Plutus Core not a bytecode not a classic

    virtual machine typed FP calculus abstract machine interpreter
  5. PLUTUS core Plutus Core small, powerful & based on peer-reviewed

    science not a bytecode not a classic virtual machine typed FP calculus abstract machine interpreter
  6. PLUTUS Input Output ν: Validator x: Value ρ: Redeemer ν(ρ)

    ≟ True ν: Validator x: Value ρ: Redeemer core core core core
  7. PLUTUS Input Output ν: Validator x: Value ρ: Redeemer ν(ρ)

    ≟ True ν: Validator x: Value ρ: Redeemer δ: Data core core core core core
  8. PLUTUS Input Output ν: Validator x: Value ρ: Redeemer ν(ρ)

    ≟ True ν: Validator x: Value ρ: Redeemer δ: Data σ: State core core core core core
  9. PLUTUS Input Output ν: Validator x: Value ρ: Redeemer ν(ρ)

    ≟ True ν: Validator x: Value ρ: Redeemer ν(ρ, δ, σ, x) ≟ True δ: Data σ: State core core core core core
  10. PLUTUS ν: Validator x: Value ρ: Redeemer ν(ρ, δ, σ,

    x) ≟ True δ: Data σ: State Extended UTxO core core core
  11. PLUTUS ν: Validator x: Value ρ: Redeemer ν(ρ, δ, σ,

    x) ≟ True δ: Data σ: State Extended UTxO Preserves the superior structure of UTxO ledgers core core core
  12. PLUTUS ν: Validator x: Value ρ: Redeemer ν(ρ, δ, σ,

    x) ≟ True δ: Data σ: State Extended UTxO Preserves the superior structure of UTxO ledgers Greatly increases the expressive power of scripts core core core
  13. PLUTUS Extended UTxO Preserves the superior structure of UTxO ledgers

    Greatly increases the expressive power of scripts
  14. PLUTUS Extended UTxO Preserves the superior structure of UTxO ledgers

    Greatly increases the expressive power of scripts data flows with value
  15. PLUTUS Extended UTxO Preserves the superior structure of UTxO ledgers

    Greatly increases the expressive power of scripts data flows with value scripts have an identity
  16. PLUTUS Extended UTxO Preserves the superior structure of UTxO ledgers

    Greatly increases the expressive power of scripts data flows with value scripts have an identity invariants across transaction chains
  17. PLUTUS Simple crowdfunding 1. Payment into campaign until a payment

    deadline 2. If funding goal reached, campaign owner can collect funds
  18. PLUTUS Simple crowdfunding 1. Payment into campaign until a payment

    deadline 2. If funding goal reached, campaign owner can collect funds 3. If funding goal not reached, refunds can be obtained by contributors
  19. PLUTUS Simple crowdfunding 1. Payment into campaign until a payment

    deadline 2. If funding goal reached, campaign owner can collect funds 3. If funding goal not reached, refunds can be obtained by contributors 4. If campaign owner does not collect by collection deadline, contributors can also obtain refunds
  20. PLUTUS 1. Payment into campaign until a payment deadline 2.

    If funding goal reached, campaign owner can collect funds 3. If funding goal not reached, refunds can be obtained by contributors 4. If campaign owner does not collect by collection deadline, contributors can also obtain refunds
  21. PLUTUS 1. Payment into campaign until a payment deadline 2.

    If funding goal reached, campaign owner can collect funds 3. If funding goal not reached, refunds can be obtained by contributors 4. If campaign owner does not collect by collection deadline, contributors can also obtain refunds pragma solidity ^0.4.6; contract WinnerTakesAll { uint minimumEntryFee; uint public deadlineProjects; uint public deadlineCampaign; uint public winningFunds; address public winningAddress; struct Project { address addr; string name; string url; uint funds; bool initialized; } … Solidity (on-chain)
  22. PLUTUS pragma solidity ^0.4.6; contract WinnerTakesAll { uint minimumEntryFee; uint

    public deadlineProjects; uint public deadlineCampaign; uint public winningFunds; address public winningAddress; struct Project { address addr; string name; string url; uint funds; bool initialized; } … Solidity (on-chain) var Web3 = require('web3'); var web3 = new Web3(); web3.setProvider(new web3.providers.HttpProvider(”http:… var accounts = web3.eth.accounts; accounts.forEach(function(v) { $(”#supportFrom”).append(”<opt… $(”#projectAddr”).append(”<opt… }); var compiled = web3.eth.compile.so… var code = compiled.code; var abi = compiled.info.abiDefinit… var contract = web3.eth.contract(a… … JavaScript (off-chain) +
  23. PLUTUS pragma solidity ^0.4.6; contract WinnerTakesAll { uint minimumEntryFee; uint

    public deadlineProjects; uint public deadlineCampaign; uint public winningFunds; address public winningAddress; struct Project { address addr; string name; string url; uint funds; bool initialized; } … Solidity var Web3 = require('web3'); var web3 = new Web3(); web3.setProvider(new web3.providers.HttpProvider(”http:… var accounts = web3.eth.accounts; accounts.forEach(function(v) { $(”#supportFrom”).append(”<opt… $(”#projectAddr”).append(”<opt… }); var compiled = web3.eth.compile.so… var code = compiled.code; var abi = compiled.info.abiDefinit… var contract = web3.eth.contract(a… … JavaScript
  24. PLUTUS pragma solidity ^0.4.6; contract WinnerTakesAll { uint minimumEntryFee; uint

    public deadlineProjects; uint public deadlineCampaign; uint public winningFunds; address public winningAddress; struct Project { address addr; string name; string url; uint funds; bool initialized; } … Solidity var Web3 = require('web3'); var web3 = new Web3(); web3.setProvider(new web3.providers.HttpProvider(”http:… var accounts = web3.eth.accounts; accounts.forEach(function(v) { $(”#supportFrom”).append(”<opt… $(”#projectAddr”).append(”<opt… }); var compiled = web3.eth.compile.so… var code = compiled.code; var abi = compiled.info.abiDefinit… var contract = web3.eth.contract(a… … JavaScript off-chain (wallet) on-chain (transaction)
  25. PLUTUS pragma solidity ^0.4.6; contract WinnerTakesAll { uint minimumEntryFee; uint

    public deadlineProjects; uint public deadlineCampaign; uint public winningFunds; address public winningAddress; struct Project { address addr; string name; string url; uint funds; bool initialized; } … Solidity var Web3 = require('web3'); var web3 = new Web3(); web3.setProvider(new web3.providers.HttpProvider(”http:… var accounts = web3.eth.accounts; accounts.forEach(function(v) { $(”#supportFrom”).append(”<opt… $(”#projectAddr”).append(”<opt… }); var compiled = web3.eth.compile.so… var code = compiled.code; var abi = compiled.info.abiDefinit… var contract = web3.eth.contract(a… … JavaScript off-chain (wallet) on-chain (transaction) two-level (staged) programming model JavaScript Solidity
  26. PLUTUS Haskell (Plutus Tx) Haskell off-chain (wallet) on-chain (transaction) two-level

    (staged) programming model meta programming integrated compact
  27. PLUTUS Haskell (Plutus Tx) Haskell off-chain (wallet) on-chain (transaction) two-level

    (staged) programming model meta programming integrated compact robust
  28. PLUTUS contribute :: Campaign -> Value -> MockWallet () contribute

    campaign value = do when (value <= 0) $ throwOtherError "Must contribute a positive value" Haskell
  29. PLUTUS contribute :: Campaign -> Value -> MockWallet () contribute

    campaign value = do when (value <= 0) $ throwOtherError "Must contribute a positive value" ownPK <- ownPubKey Haskell
  30. PLUTUS contribute :: Campaign -> Value -> MockWallet () contribute

    campaign value = do when (value <= 0) $ throwOtherError "Must contribute a positive value" ownPK <- ownPubKey tx <- payToScript Haskell
  31. PLUTUS contribute :: Campaign -> Value -> MockWallet () contribute

    campaign value = do when (value <= 0) $ throwOtherError "Must contribute a positive value" ownPK <- ownPubKey tx <- payToScript (Ledger.scriptAddress (contributionScript campaign)) Haskell
  32. PLUTUS contribute :: Campaign -> Value -> MockWallet () contribute

    campaign value = do when (value <= 0) $ throwOtherError "Must contribute a positive value" ownPK <- ownPubKey tx <- payToScript (Ledger.scriptAddress (contributionScript campaign)) value Haskell
  33. PLUTUS contribute :: Campaign -> Value -> MockWallet () contribute

    campaign value = do when (value <= 0) $ throwOtherError "Must contribute a positive value" ownPK <- ownPubKey tx <- payToScript (Ledger.scriptAddress (contributionScript campaign)) value DataScript (Ledger.lifted ownPK) Haskell
  34. PLUTUS contribute :: Campaign -> Value -> MockWallet () contribute

    campaign value = do when (value <= 0) $ throwOtherError "Must contribute a positive value" ownPK <- ownPubKey tx <- payToScript (Ledger.scriptAddress (contributionScript campaign)) value DataScript (Ledger.lifted ownPK) register (refundTrigger campaign) (refundHandler (Ledger.hashTx tx) campaign) contributionScript :: Campaign -> ValidatorScript Haskell
  35. PLUTUS contributionScript :: Campaign -> ValidatorScript contributionScript campaign = ValidatorScript

    (validator `apply` campaign) where validator = Ledger.fromCompiledCode $$(PlutusTx.compile [|| (\Campaign{..} action contrib tx -> Plutus Tx Haskell
  36. PLUTUS contributionScript :: Campaign -> ValidatorScript contributionScript campaign = ValidatorScript

    (validator `apply` campaign) where validator = Ledger.fromCompiledCode $$(PlutusTx.compile [|| (\Campaign{..} action contrib tx -> let PendingTx ps outs _ _ (Height h) _ _ = tx Plutus Tx Haskell
  37. PLUTUS contributionScript :: Campaign -> ValidatorScript contributionScript campaign = ValidatorScript

    (validator `apply` campaign) where validator = Ledger.fromCompiledCode $$(PlutusTx.compile [|| (\Campaign{..} action contrib tx -> let PendingTx ps outs _ _ (Height h) _ _ = tx isValid = case action of Plutus Tx Haskell
  38. PLUTUS contributionScript :: Campaign -> ValidatorScript contributionScript campaign = ValidatorScript

    (validator `apply` campaign) where validator = Ledger.fromCompiledCode $$(PlutusTx.compile [|| (\Campaign{..} action contrib tx -> let PendingTx ps outs _ _ (Height h) _ _ = tx isValid = case action of Refund -> h > collectionDeadline && Plutus Tx Haskell
  39. PLUTUS contributionScript :: Campaign -> ValidatorScript contributionScript campaign = ValidatorScript

    (validator `apply` campaign) where validator = Ledger.fromCompiledCode $$(PlutusTx.compile [|| (\Campaign{..} action contrib tx -> let PendingTx ps outs _ _ (Height h) _ _ = tx isValid = case action of Refund -> h > collectionDeadline && contributorOnly outs && Plutus Tx Haskell
  40. PLUTUS contributionScript :: Campaign -> ValidatorScript contributionScript campaign = ValidatorScript

    (validator `apply` campaign) where validator = Ledger.fromCompiledCode $$(PlutusTx.compile [|| (\Campaign{..} action contrib tx -> let PendingTx ps outs _ _ (Height h) _ _ = tx isValid = case action of Refund -> h > collectionDeadline && contributorOnly outs && $$(txSignedBy) tx contrib Plutus Tx Haskell
  41. PLUTUS contributionScript :: Campaign -> ValidatorScript contributionScript campaign = ValidatorScript

    (validator `apply` campaign) where validator = Ledger.fromCompiledCode $$(PlutusTx.compile [|| (\Campaign{..} action contrib tx -> let PendingTx ps outs _ _ (Height h) _ _ = tx isValid = case action of Refund -> h > collectionDeadline && contributorOnly outs && $$(txSignedBy) tx contrib Collect -> h > deadline && Plutus Tx Haskell
  42. PLUTUS contributionScript :: Campaign -> ValidatorScript contributionScript campaign = ValidatorScript

    (validator `apply` campaign) where validator = Ledger.fromCompiledCode $$(PlutusTx.compile [|| (\Campaign{..} action contrib tx -> let PendingTx ps outs _ _ (Height h) _ _ = tx isValid = case action of Refund -> h > collectionDeadline && contributorOnly outs && $$(txSignedBy) tx contrib Collect -> h > deadline && h <= collectionDeadline && Plutus Tx Haskell
  43. PLUTUS contributionScript :: Campaign -> ValidatorScript contributionScript campaign = ValidatorScript

    (validator `apply` campaign) where validator = Ledger.fromCompiledCode $$(PlutusTx.compile [|| (\Campaign{..} action contrib tx -> let PendingTx ps outs _ _ (Height h) _ _ = tx isValid = case action of Refund -> h > collectionDeadline && contributorOnly outs && $$(txSignedBy) tx contrib Collect -> h > deadline && h <= collectionDeadline && totalInputs >= target && Plutus Tx Haskell
  44. PLUTUS contributionScript :: Campaign -> ValidatorScript contributionScript campaign = ValidatorScript

    (validator `apply` campaign) where validator = Ledger.fromCompiledCode $$(PlutusTx.compile [|| (\Campaign{..} action contrib tx -> let PendingTx ps outs _ _ (Height h) _ _ = tx isValid = case action of Refund -> h > collectionDeadline && contributorOnly outs && $$(txSignedBy) tx contrib Collect -> h > deadline && h <= collectionDeadline && totalInputs >= target && $$(txSignedBy) p campaignOwner Plutus Tx Haskell
  45. PLUTUS contributionScript :: Campaign -> ValidatorScript contributionScript campaign = ValidatorScript

    (validator `apply` campaign) where validator = Ledger.fromCompiledCode $$(PlutusTx.compile [|| (\Campaign{..} action contrib tx -> let PendingTx ps outs _ _ (Height h) _ _ = tx isValid = case action of Refund -> h > collectionDeadline && contributorOnly outs && $$(txSignedBy) tx contrib Collect -> h > deadline && h <= collectionDeadline && totalInputs >= target && $$(txSignedBy) p campaignOwner in $$(P.errorIfNot) isValid ||]) Plutus Tx Haskell
  46. PLUTUS contribute :: Campaign -> Value -> MockWallet () contribute

    campaign value = do when (value <= 0) $ throwOtherError "Must contribute a positive value" ownPK <- ownPubKey tx <- payToScript (Ledger.scriptAddress (contributionScript campaign)) value DataScript (Ledger.lifted ownPK) register (refundTrigger campaign) (refundHandler (Ledger.hashTx tx) campaign) contributionScript :: Campaign -> ValidatorScript contributionScript campaign = ValidatorScript (validator `apply` campaign) where validator = Ledger.fromCompiledCode $$(PlutusTx.compile [|| (\Campaign{..} action contrib tx -> let PendingTx ps outs _ _ (Height h) _ _ = tx isValid = case action of Refund -> h > collectionDeadline && contributorOnly outs && $$(txSignedBy) tx contrib Collect -> h > deadline && h <= collectionDeadline && totalInputs >= target && $$(txSignedBy) p campaignOwner in $$(P.errorIfNot) isValid ||]) off-chain on-chain
  47. PLUTUS contribute :: Campaign -> Value -> MockWallet () contribute

    campaign value = do when (value <= 0) $ throwOtherError "Must contribute a positive value" ownPK <- ownPubKey tx <- payToScript (Ledger.scriptAddress (contributionScript campaign)) value DataScript (Ledger.lifted ownPK) register (refundTrigger campaign) (refundHandler (Ledger.hashTx tx) campaign) contributionScript :: Campaign -> ValidatorScript contributionScript campaign = ValidatorScript (validator `apply` campaign) where validator = Ledger.fromCompiledCode $$(PlutusTx.compile [|| (\Campaign{..} action contrib tx -> let PendingTx ps outs _ _ (Height h) _ _ = tx isValid = case action of Refund -> h > collectionDeadline && contributorOnly outs && $$(txSignedBy) tx contrib Collect -> h > deadline && h <= collectionDeadline && totalInputs >= target && $$(txSignedBy) p campaignOwner in $$(P.errorIfNot) isValid ||]) core off-chain on-chain
  48. PLUTUS contribute :: Campaign -> Value -> MockWallet () contribute

    campaign value = do when (value <= 0) $ throwOtherError "Must contribute a positive value" ownPK <- ownPubKey tx <- payToScript (Ledger.scriptAddress (contributionScript campaign)) value DataScript (Ledger.lifted ownPK) register (refundTrigger campaign) (refundHandler (Ledger.hashTx tx) campaign) contributionScript :: Campaign -> ValidatorScript contributionScript campaign = ValidatorScript (validator `apply` campaign) where validator = Ledger.fromCompiledCode $$(PlutusTx.compile [|| (\Campaign{..} action contrib tx -> let PendingTx ps outs _ _ (Height h) _ _ = tx isValid = case action of Refund -> h > collectionDeadline && contributorOnly outs && $$(txSignedBy) tx contrib Collect -> h > deadline && h <= collectionDeadline && totalInputs >= target && $$(txSignedBy) p campaignOwner in $$(P.errorIfNot) isValid ||]) core core off-chain on-chain
  49. PLUTUS contribute :: Campaign -> Value -> MockWallet () contribute

    campaign value = do when (value <= 0) $ throwOtherError "Must contribute a positive value" ownPK <- ownPubKey tx <- payToScript (Ledger.scriptAddress (contributionScript campaign)) value DataScript (Ledger.lifted ownPK) register (refundTrigger campaign) (refundHandler (Ledger.hashTx tx) campaign) contributionScript :: Campaign -> ValidatorScript contributionScript campaign = ValidatorScript (validator `apply` campaign) where validator = Ledger.fromCompiledCode $$(PlutusTx.compile [|| (\Campaign{..} action contrib tx -> let PendingTx ps outs _ _ (Height h) _ _ = tx isValid = case action of Refund -> h > collectionDeadline && contributorOnly outs && $$(txSignedBy) tx contrib Collect -> h > deadline && h <= collectionDeadline && totalInputs >= target && $$(txSignedBy) p campaignOwner in $$(P.errorIfNot) isValid ||]) core core off-chain on-chain