Skip to content

Instantly share code, notes, and snippets.

@dino-
Last active March 23, 2021 18:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dino-/d411a8e031e398101ad3220717e32f9b to your computer and use it in GitHub Desktop.
Save dino-/d411a8e031e398101ad3220717e32f9b to your computer and use it in GitHub Desktop.
Plutus Playground Smart Contract
import Control.Monad ( void )
import Data.Aeson ( FromJSON, ToJSON )
import qualified Data.Text as T
import GHC.Generics ( Generic )
import Language.Plutus.Contract
import Language.PlutusTx as PlutusTx
import Language.PlutusTx.Prelude
import Ledger
import Ledger.Ada as Ada
import Ledger.Constraints as Constraints
import Ledger.Typed.Scripts as Scripts
import Playground.Contract
import Schema
import Wallet.Emulator.Wallet
data SplitData = SplitData
{ recipient1 :: PubKeyHash -- ^ First recipient of the funds
, recipient2 :: PubKeyHash -- ^ Second recipient of the funds
, amount :: Ada -- ^ How much Ada we want to lock
}
deriving stock (Show, Generic)
-- For a 'real' application use 'makeIsDataIndexed' to ensure the output is stable over time
-- PlutusTx.unstableMakeIsData ''SplitData
PlutusTx.makeIsData ''SplitData
PlutusTx.makeLift ''SplitData
validateSplit :: SplitData -> () -> ValidatorCtx -> Bool
validateSplit SplitData { recipient1, recipient2, amount } _ ValidatorCtx { valCtxTxInfo } =
let half = Ada.divide amount 2 in
Ada.fromValue (valuePaidTo valCtxTxInfo recipient1) >= half &&
Ada.fromValue (valuePaidTo valCtxTxInfo recipient2) >= (amount - half)
data Split
instance Scripts.ScriptType Split where
type instance RedeemerType Split = ()
type instance DatumType Split= SplitData
splitInstance :: Scripts.ScriptInstance Split
splitInstance = Scripts.validator @Split
$$(PlutusTx.compile [|| validateSplit ||])
$$(PlutusTx.compile [|| wrap ||]) where
wrap = Scripts.wrapValidator @SplitData @()
data LockArgs = LockArgs
{ recipient1Wallet :: Wallet
, recipient2Wallet :: Wallet
, totalAda :: Ada
}
deriving stock (Show, Generic)
deriving anyclass (ToJSON, FromJSON, ToSchema)
type SplitSchema = BlockchainActions
.\/ Endpoint "lock" LockArgs
.\/ Endpoint "unlock" LockArgs
lock :: Contract SplitSchema T.Text LockArgs
lock = endpoint @"lock"
unlock :: Contract SplitSchema T.Text LockArgs
unlock = endpoint @"unlock"
mkSplitData :: LockArgs -> SplitData
mkSplitData LockArgs { recipient1Wallet, recipient2Wallet, totalAda } =
let convert :: Wallet -> PubKeyHash
convert = pubKeyHash . walletPubKey
in
SplitData
{ recipient1 = convert recipient1Wallet
, recipient2 = convert recipient2Wallet
, amount = totalAda
}
lockFunds :: SplitData -> Contract SplitSchema T.Text ()
lockFunds s@SplitData { amount } = do
logInfo $ "Locking " <> show amount
let tx = Constraints.mustPayToTheScript s (Ada.toValue amount)
void $ submitTxConstraints splitInstance tx
unlockFunds :: SplitData -> Contract SplitSchema T.Text ()
unlockFunds SplitData { recipient1, recipient2, amount } = do
let contractAddress = (Ledger.scriptAddress (Scripts.validatorScript splitInstance))
utxos <- utxoAt contractAddress
let half = Ada.divide amount 2
tx =
collectFromScript utxos ()
<> Constraints.mustPayToPubKey recipient1 (Ada.toValue half)
<> Constraints.mustPayToPubKey recipient2 (Ada.toValue $ amount - half)
void $ submitTxConstraintsSpending splitInstance utxos tx
endpoints :: Contract SplitSchema T.Text ()
endpoints = (lock >>= lockFunds . mkSplitData) `select` (unlock >>= unlockFunds . mkSplitData)
mkSchemaDefinitions ''SplitSchema
$(mkKnownCurrencies [])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment