Skip to content

Instantly share code, notes, and snippets.

@diaspogift
Last active December 17, 2020 21:38
Show Gist options
  • Save diaspogift/0a901f8aa8a4c7e71742531b6626b285 to your computer and use it in GitHub Desktop.
Save diaspogift/0a901f8aa8a4c7e71742531b6626b285 to your computer and use it in GitHub Desktop.
Plutus Playground Smart Contract
-- This is a starter contract, based on the Game contract,
-- containing the bare minimum required scaffolding.
--
-- What you should change to something more suitable for
-- your use case:
-- * The DataScript type
-- * The Redeemer type
--
-- And add function implementations (and rename them to
-- something suitable) for the endpoints:
-- * publish
-- * redeem
import qualified Language.PlutusTx as PlutusTx
import Language.PlutusTx.Prelude
import Ledger (Address, DataScript (DataScript), PendingTx, PubKey,
RedeemerScript (RedeemerScript), TxId, ValidatorScript (ValidatorScript),
applyScript, compileScript, hashTx, lifted, pendingTxValidRange,
scriptAddress, valueSpent)
import qualified Ledger.Interval as Interval
import Ledger.Slot (Slot, SlotRange)
import qualified Ledger.Validation as V
import Ledger.Value (Value)
import qualified Ledger.Value as Value
import Playground.Contract
import Wallet (EventHandler (EventHandler), EventTrigger, MonadWallet, andT,
collectFromScript, collectFromScriptTxn, fundsAtAddressGeqT, logMsg,
ownPubKey, payToScript, register, slotRangeT)
import qualified Wallet as W
import Wallet.Emulator (Wallet)
import qualified Wallet.Emulator as EM
type Quorum = Integer
type TransferId = Integer
data SentStatus = Sent | NotSent deriving (Generic, ToJSON, FromJSON, ToSchema)
PlutusTx.makeLift ''SentStatus
greeting :: String
greeting = "Hello world!"
data Transfer = Transfer {
transferId :: TransferId
, amount :: Value
, payTo :: PubKey
, approvalsCount :: Integer
, sent :: SentStatus
, approvalPairs :: [(PubKey, Bool)]
} deriving (Generic, ToJSON, FromJSON, ToSchema)
PlutusTx.makeLift ''Transfer
data MultiSigWallet = MultiSigWallet {
approvers :: [PubKey]
, requestedTransfers :: [Transfer]
, quorum :: Quorum
} deriving (Generic, ToJSON, FromJSON, ToSchema)
PlutusTx.makeLift ''MultiSigWallet
data MSWalletAction = Request | Fund
deriving (Generic, ToJSON, FromJSON, ToSchema)
PlutusTx.makeLift ''MSWalletAction
type MultiSigWalletValidator = PubKey -> MultiSigWallet -> PendingTx -> Bool
mswValidatoScript :: MultiSigWallet -> ValidatorScript
mswValidatoScript msw = ValidatorScript $ Ledger.applyScript validator (Ledger.lifted msw)
where
validator =
$$(Ledger.compileScript [||
\(msw :: MultiSigWallet) (dataScript :: ()) (redeemerScript :: () )(_ :: PendingTx) -> ()
||])
mkMultiSigWallet :: [PubKey] -> Quorum -> Value -> Wallet -> MultiSigWallet
mkMultiSigWallet apprs qrm seedFund ownerWallet =
MultiSigWallet {
approvers = EM.walletPubKey ownerWallet : apprs
, requestedTransfers = []
, quorum = qrm
}
type Counter = Integer
helloAction :: MonadWallet m => Counter -> m ()
helloAction _ = W.logMsg "in helloAction ..."
requestTransfer :: MonadWallet m => MultiSigWallet -> Value -> m ()
requestTransfer msw amountRequested = do
pk <- ownPubKey
let checked = elem pk (approvers msw)
case checked of
True -> logMsg "run requestion logic - happy branch"
False -> logMsg "run requestion logic - sad branch"
contractAddress :: MultiSigWallet -> Address
contractAddress msw = Ledger.scriptAddress $ mswValidatoScript msw
contribute :: MonadWallet m => MultiSigWallet -> Value -> m ()
contribute msw value = do
ownPK <- ownPubKey
let dataScript = DataScript $ Ledger.lifted ownPK
range = W.defaultSlotRange
tx <- payToScript range (contractAddress msw) value dataScript
logMsg "Contribution submited"
--register refundTrigger $ refundHandler msw (Ledger.hashTx tx)
collect :: MonadWallet m => MultiSigWallet -> m ()
collect msw = do
logMsg "collecting contributions ..."
let redeemerScript = RedeemerScript $ Ledger.lifted ()
range = W.interval 10 15
collectFromScript range (mswValidatoScript msw) redeemerScript
watchContract :: MonadWallet m => MultiSigWallet -> m ()
watchContract msw = W.startWatching $ contractAddress msw
$(mkFunctions ['helloAction, 'contribute,'collect, 'watchContract])
[0,[{"wallets":[{"simulatorWalletWallet":{"getWallet":1},"simulatorWalletBalance":{"getValue":[[{"unCurrencySymbol":""},[[{"unTokenName":""},10]]]]}},{"simulatorWalletWallet":{"getWallet":2},"simulatorWalletBalance":{"getValue":[[{"unCurrencySymbol":""},[[{"unTokenName":""},10]]]]}}],"signatures":[{"functionName":"helloAction","argumentSchema":[{"tag":"FormSchemaInt"}]},{"functionName":"contribute","argumentSchema":[{"contents":[["approvers",{"contents":[["getPubKey",{"tag":"FormSchemaString"}]],"tag":"FormSchemaArray"}],["requestedTransfers",{"contents":[["transferId",{"tag":"FormSchemaInt"}],["amount",{"tag":"FormSchemaValue"}],["payTo",{"contents":[["getPubKey",{"tag":"FormSchemaString"}]],"tag":"FormSchemaObject"}],["approvalsCount",{"tag":"FormSchemaInt"}],["sent",{"contents":["Sent","NotSent"],"tag":"FormSchemaRadio"}],["approvalPairs",{"contents":[{"contents":[["getPubKey",{"tag":"FormSchemaString"}]],"tag":"FormSchemaObject"},{"tag":"FormSchemaBool"}],"tag":"FormSchemaArray"}]],"tag":"FormSchemaArray"}],["quorum",{"tag":"FormSchemaInt"}]],"tag":"FormSchemaObject"},{"tag":"FormSchemaValue"}]},{"functionName":"collect","argumentSchema":[{"contents":[["approvers",{"contents":[["getPubKey",{"tag":"FormSchemaString"}]],"tag":"FormSchemaArray"}],["requestedTransfers",{"contents":[["transferId",{"tag":"FormSchemaInt"}],["amount",{"tag":"FormSchemaValue"}],["payTo",{"contents":[["getPubKey",{"tag":"FormSchemaString"}]],"tag":"FormSchemaObject"}],["approvalsCount",{"tag":"FormSchemaInt"}],["sent",{"contents":["Sent","NotSent"],"tag":"FormSchemaRadio"}],["approvalPairs",{"contents":[{"contents":[["getPubKey",{"tag":"FormSchemaString"}]],"tag":"FormSchemaObject"},{"tag":"FormSchemaBool"}],"tag":"FormSchemaArray"}]],"tag":"FormSchemaArray"}],["quorum",{"tag":"FormSchemaInt"}]],"tag":"FormSchemaObject"}]},{"functionName":"watchContract","argumentSchema":[{"contents":[["approvers",{"contents":[["getPubKey",{"tag":"FormSchemaString"}]],"tag":"FormSchemaArray"}],["requestedTransfers",{"contents":[["transferId",{"tag":"FormSchemaInt"}],["amount",{"tag":"FormSchemaValue"}],["payTo",{"contents":[["getPubKey",{"tag":"FormSchemaString"}]],"tag":"FormSchemaObject"}],["approvalsCount",{"tag":"FormSchemaInt"}],["sent",{"contents":["Sent","NotSent"],"tag":"FormSchemaRadio"}],["approvalPairs",{"contents":[{"contents":[["getPubKey",{"tag":"FormSchemaString"}]],"tag":"FormSchemaObject"},{"tag":"FormSchemaBool"}],"tag":"FormSchemaArray"}]],"tag":"FormSchemaArray"}],["quorum",{"tag":"FormSchemaInt"}]],"tag":"FormSchemaObject"}]},{"functionName":"payToWallet_","argumentSchema":[{"tag":"FormSchemaValue"},{"contents":[["getWallet",{"tag":"FormSchemaInt"}]],"tag":"FormSchemaObject"}]}],"currencies":[{"knownTokens":[{"unTokenName":""}],"hash":"","friendlyName":"Ada"}],"actions":[]}]]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment