Skip to content

Instantly share code, notes, and snippets.

@lucamarrocco
Created January 10, 2023 00:40
Show Gist options
  • Save lucamarrocco/012b416e1d53679b4fa87de73a3ac4e8 to your computer and use it in GitHub Desktop.
Save lucamarrocco/012b416e1d53679b4fa87de73a3ac4e8 to your computer and use it in GitHub Desktop.
import qualified Cardano.Chain.UTxO as UTxO
import qualified Ledger
import qualified Ledger.Ada as Ada
import qualified Ledger.Value as Value
import qualified Plutus.Contract as Contract
import qualified Plutus.Contract.State as State
import qualified Plutus.Contract.Typed as Typed
-- | This is the state of our contract.
data TokenState = TokenState
{ owner :: Ledger.PubKey
, value :: Value.Value Ada
, locked :: Bool
}
-- | Initialize the contract with an owner and a value.
init :: Ledger.PubKey -> Value.Value Ada -> TokenState
init owner value = TokenState
{ owner = owner
, value = value
, locked = False
}
-- | Lock the token.
lock :: TokenState -> TokenState
lock state = state { locked = True }
-- | Unlock the token.
unlock :: TokenState -> TokenState
unlock state = state { locked = False }
-- | Transfer the token to a new owner.
transfer :: Ledger.PubKey -> TokenState -> TokenState
transfer newOwner state = state { owner = newOwner }
-- | Check if the current transaction is signed by the owner of the token.
checkOwner :: TokenState -> UTxO.Tx -> Bool
checkOwner state tx = UTxO.txSender tx == owner state
-- | The contract entry point.
token :: State.Contract TokenState
token = State.wrap do
-- Check if the token is locked
locked <- Contract.getField locked
-- If the token is not locked, allow the owner to lock or transfer it
if not locked then do
-- Check if the current transaction is signed by the owner of the token
owner <- Contract.getField owner
tx <- Ledger.getTransaction
Contract.assert (checkOwner owner tx)
-- Get the input event
evt <- Contract.getEvent
-- Handle the input event
case evt of
-- Lock the token
"lock" -> do
Contract.putField lock
Contract.commit
-- Transfer the token to a new owner
"transfer" -> do
-- Get the new owner from the input data
newOwner <- Contract.getData >>= Ledger.pubKeyFromBytes
-- Transfer the token to the new owner
Contract.putField (transfer newOwner)
Contract.commit
-- If the token is locked, only allow the owner to unlock it
else do
-- Check if the current transaction is signed by the owner of the token
owner <- Contract.getField owner
tx <- Ledger.getTransaction
Contract.assert (checkOwner owner tx)
-- Unlock the token
Contract.putField unlock
Contract.commit
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment