Skip to content

Instantly share code, notes, and snippets.

@ThasianX
Last active October 6, 2021 06:24
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 ThasianX/598a7913101944ff02a30fca15a4884f to your computer and use it in GitHub Desktop.
Save ThasianX/598a7913101944ff02a30fca15a4884f 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 Ledger
import qualified Ledger.Ada as Ada
import qualified Ledger.Constraints as Constraints
import qualified Ledger.Typed.Scripts as Scripts
import Plutus.Contract
import qualified PlutusTx as PlutusTx
import PlutusTx.Prelude
import qualified Prelude as Haskell
import Schema
import Wallet.Emulator.Wallet
import Playground.Contract
data SplitData =
SplitData
{ recipient1 :: PubKeyHash
, recipient2 :: PubKeyHash
, amount :: Ada
}
deriving stock (Haskell.Show, Generic)
PlutusTx.unstableMakeIsData ''SplitData
PlutusTx.makeLift ''SplitData
validateSplit :: SplitData -> () -> ScriptContext -> Bool
validateSplit SplitData{recipient1, recipient2, amount} _ ScriptContext{scriptContextTxInfo} =
let half = Ada.divide amount 2 in
Ada.fromValue (valuePaidTo scriptContextTxInfo recipient1) >= half &&
Ada.fromValue (valuePaidTo scriptContextTxInfo recipient2) >= (amount - half)
data Split
instance Scripts.ValidatorTypes Split where
type instance RedeemerType Split = ()
type instance DatumType Split = SplitData
splitValidator :: Scripts.TypedValidator Split
splitValidator = Scripts.mkTypedValidator @Split
$$(PlutusTx.compile [|| validateSplit ||])
$$(PlutusTx.compile [|| wrap ||]) where
wrap = Scripts.wrapValidator @SplitData @()
data LockArgs =
LockArgs
{ recipient1Wallet :: WalletNumber
, recipient2Wallet :: WalletNumber
, totalAda :: Ada
}
deriving stock (Haskell.Show, Generic)
deriving anyclass (ToJSON, FromJSON, ToSchema)
type SplitSchema =
Endpoint "lock" LockArgs
.\/ Endpoint "unlock" LockArgs
lock :: Promise () SplitSchema T.Text ()
lock = endpoint @"lock" (lockFunds . mkSplitData)
unlock :: Promise () SplitSchema T.Text ()
unlock = endpoint @"unlock" (unlockFunds . mkSplitData)
mkSplitData :: LockArgs -> SplitData
mkSplitData LockArgs{recipient1Wallet, recipient2Wallet, totalAda} =
let convert :: Wallet -> PubKeyHash
convert = pubKeyHash . walletPubKey
in
SplitData
{ recipient1 = convert (fromWalletNumber recipient1Wallet)
, recipient2 = convert (fromWalletNumber recipient2Wallet)
, amount = totalAda
}
lockFunds :: SplitData -> Contract () SplitSchema T.Text ()
lockFunds s@SplitData{amount} = do
logInfo $ "Locking " <> Haskell.show amount
let tx = Constraints.mustPayToTheScript s (Ada.toValue amount)
void $ submitTxConstraints splitValidator tx
unlockFunds :: SplitData -> Contract () SplitSchema T.Text ()
unlockFunds SplitData{recipient1, recipient2, amount} = do
let contractAddress = Scripts.validatorAddress splitValidator
utxos <- utxosAt 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 splitValidator utxos tx
endpoints :: Contract () SplitSchema T.Text ()
endpoints = selectList [lock, unlock]
mkSchemaDefinitions ''SplitSchema
$(mkKnownCurrencies [])
[0,[{"simulationWallets":[{"simulatorWalletWallet":{"getWallet":1},"simulatorWalletBalance":{"getValue":[[{"unCurrencySymbol":""},[[{"unTokenName":""},100000000]]]]}},{"simulatorWalletWallet":{"getWallet":2},"simulatorWalletBalance":{"getValue":[[{"unCurrencySymbol":""},[[{"unTokenName":""},100000000]]]]}}],"simulationName":"Simulation 1","simulationId":1,"simulationActions":[{"caller":{"getWallet":1},"argumentValues":{"endpointDescription":{"getEndpointDescription":"lock"},"argument":{"contents":[["recipient1Wallet",{"contents":[["getWallet",{"s":1,"e":0,"c":[1],"tag":"FormIntegerF"}]],"tag":"FormObjectF"}],["recipient2Wallet",{"contents":[["getWallet",{"s":1,"e":0,"c":[2],"tag":"FormIntegerF"}]],"tag":"FormObjectF"}],["totalAda",{"contents":[["getLovelace",{"s":1,"e":4,"c":[10000],"tag":"FormIntegerF"}]],"tag":"FormObjectF"}]],"tag":"FormObjectF"}},"tag":"CallEndpoint"},{"blocks":10,"tag":"AddBlocks"},{"caller":{"getWallet":2},"argumentValues":{"endpointDescription":{"getEndpointDescription":"unlock"},"argument":{"contents":[["recipient1Wallet",{"contents":[["getWallet",{"s":1,"e":0,"c":[1],"tag":"FormIntegerF"}]],"tag":"FormObjectF"}],["recipient2Wallet",{"contents":[["getWallet",{"s":1,"e":0,"c":[2],"tag":"FormIntegerF"}]],"tag":"FormObjectF"}],["totalAda",{"contents":[["getLovelace",{"s":1,"e":4,"c":[10000],"tag":"FormIntegerF"}]],"tag":"FormObjectF"}]],"tag":"FormObjectF"}},"tag":"CallEndpoint"},{"blocks":10,"tag":"AddBlocks"}]}]]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment