From f791733433436f75cdef8a34195a98c4ed7d28b2 Mon Sep 17 00:00:00 2001 From: Jordan Millar Date: Fri, 17 Jun 2022 08:12:49 -0500 Subject: [PATCH 01/15] Modify PReferenceScript and SReferenceScript to accept a Maybe ScriptHash so we can construct the redeemer pointer map in the case of minting reference scripts where we don't have direct access to the script. --- cardano-api/src/Cardano/Api.hs | 1 + cardano-api/src/Cardano/Api/Script.hs | 8 ++++---- cardano-api/src/Cardano/Api/Value.hs | 2 +- cardano-api/src/Cardano/Api/ValueParser.hs | 1 + 4 files changed, 7 insertions(+), 5 deletions(-) diff --git a/cardano-api/src/Cardano/Api.hs b/cardano-api/src/Cardano/Api.hs index 6441ae9ae48..820add43765 100644 --- a/cardano-api/src/Cardano/Api.hs +++ b/cardano-api/src/Cardano/Api.hs @@ -117,6 +117,7 @@ module Cardano.Api ( AssetId(..), Value, parseValue, + policyId, selectAsset, valueFromList, valueToList, diff --git a/cardano-api/src/Cardano/Api/Script.hs b/cardano-api/src/Cardano/Api/Script.hs index f1a5f7c5076..f3eb81df947 100644 --- a/cardano-api/src/Cardano/Api/Script.hs +++ b/cardano-api/src/Cardano/Api/Script.hs @@ -728,13 +728,13 @@ data WitCtx witctx where -- or to mint tokens. This datatype encapsulates this concept. data PlutusScriptOrReferenceInput lang = PScript (PlutusScript lang) - | PReferenceScript TxIn + | PReferenceScript TxIn (Maybe ScriptHash) deriving (Eq, Show) data SimpleScriptOrReferenceInput lang = SScript (SimpleScript lang) - | SReferenceScript TxIn + | SReferenceScript TxIn (Maybe ScriptHash) deriving (Eq, Show) -- | A /use/ of a script within a transaction body to witness that something is @@ -812,9 +812,9 @@ scriptWitnessScript (SimpleScriptWitness langInEra version (SScript script)) = scriptWitnessScript (PlutusScriptWitness langInEra version (PScript script) _ _ _) = Just $ ScriptInEra langInEra (PlutusScript version script) -scriptWitnessScript (SimpleScriptWitness _ _ (SReferenceScript _)) = +scriptWitnessScript (SimpleScriptWitness _ _ (SReferenceScript _ _)) = Nothing -scriptWitnessScript (PlutusScriptWitness _ _ (PReferenceScript _) _ _ _) = +scriptWitnessScript (PlutusScriptWitness _ _ (PReferenceScript _ _) _ _ _) = Nothing -- ---------------------------------------------------------------------------- diff --git a/cardano-api/src/Cardano/Api/Value.hs b/cardano-api/src/Cardano/Api/Value.hs index 351df627801..7cbf41385d6 100644 --- a/cardano-api/src/Cardano/Api/Value.hs +++ b/cardano-api/src/Cardano/Api/Value.hs @@ -144,7 +144,7 @@ quantityToLovelace :: Quantity -> Lovelace quantityToLovelace (Quantity x) = Lovelace x -newtype PolicyId = PolicyId ScriptHash +newtype PolicyId = PolicyId { unPolicyId :: ScriptHash } deriving stock (Eq, Ord) deriving (Show, IsString, ToJSON, FromJSON) via UsingRawBytesHex PolicyId diff --git a/cardano-api/src/Cardano/Api/ValueParser.hs b/cardano-api/src/Cardano/Api/ValueParser.hs index 1d8c29f5dfb..501408e4128 100644 --- a/cardano-api/src/Cardano/Api/ValueParser.hs +++ b/cardano-api/src/Cardano/Api/ValueParser.hs @@ -1,6 +1,7 @@ module Cardano.Api.ValueParser ( parseValue , assetName + , policyId ) where import Prelude From afe32ed76de8c82e7e816a7d8cf86bfd768e2004 Mon Sep 17 00:00:00 2001 From: Jordan Millar Date: Fri, 17 Jun 2022 08:54:34 -0500 Subject: [PATCH 02/15] Wire up remaining parsing options for minting, certifying and withdrawing reference scripts --- cardano-cli/src/Cardano/CLI/Shelley/Output.hs | 2 +- .../src/Cardano/CLI/Shelley/Parsers.hs | 253 ++++++++++-------- 2 files changed, 142 insertions(+), 113 deletions(-) diff --git a/cardano-cli/src/Cardano/CLI/Shelley/Output.hs b/cardano-cli/src/Cardano/CLI/Shelley/Output.hs index b0c600ed143..8d0fa9e0e2e 100644 --- a/cardano-cli/src/Cardano/CLI/Shelley/Output.hs +++ b/cardano-cli/src/Cardano/CLI/Shelley/Output.hs @@ -284,7 +284,7 @@ renderScriptCosts eUnitPrices scriptMapping executionCostMapping = Left err -> Left (PlutusScriptCostErrExecError sWitInd (Just scriptHash) err) : accum -- TODO: Create a new sum type to encapsulate the fact that we can also -- have a txin and render the txin in the case of reference scripts. - Just (AnyScriptWitness (PlutusScriptWitness _ _ (PReferenceScript _refTxIn) _ _ _)) -> + Just (AnyScriptWitness (PlutusScriptWitness _ _ (PReferenceScript _refTxIn _) _ _ _)) -> case eExecUnits of Right execUnits -> case calculateExecutionUnitsLovelace eUnitPrices execUnits of diff --git a/cardano-cli/src/Cardano/CLI/Shelley/Parsers.hs b/cardano-cli/src/Cardano/CLI/Shelley/Parsers.hs index 4662402767f..6c23eed73d4 100644 --- a/cardano-cli/src/Cardano/CLI/Shelley/Parsers.hs +++ b/cardano-cli/src/Cardano/CLI/Shelley/Parsers.hs @@ -229,74 +229,10 @@ pScriptFor name (Just deprecated) help = <> Opt.internal ) -pReferenceScriptWitnessFiles - :: WitCtx witctx - -> BalanceTxExecUnits -- ^ Use the @execution-units@ flag. - -> Parser (ScriptWitnessFiles witctx) -pReferenceScriptWitnessFiles witctx autoBalanceExecUnits = - toReferenceScriptWitnessFiles - <$> pReferenceTxIn - <*> (simpleWit <|> pPWitness) - - - where - pPWitness = - (,,,) <$> pPlutusScriptLanguage - <*> (Just <$> pScriptDatumOrFile "reference-tx-in" witctx) - <*> (Just <$> pScriptRedeemerOrFile "reference-tx-in") - <*> (case autoBalanceExecUnits of - AutoBalance -> pure $ Just (ExecutionUnits 0 0) - ManualBalance -> Just <$> pExecutionUnits "reference-tx-in") - - simpleWit - :: Parser ( AnyScriptLanguage - , Maybe (ScriptDatumOrFile witctx) - , Maybe ScriptRedeemerOrFile - , Maybe ExecutionUnits - ) - simpleWit = - (,,,) <$> pSimpleScriptLang - <*> pure Nothing - <*> pure Nothing - <*> pure Nothing - - pPlutusScriptLanguage :: Parser AnyScriptLanguage - pPlutusScriptLanguage = - Opt.flag' (AnyScriptLanguage $ PlutusScriptLanguage PlutusScriptV2) - ( Opt.long "plutus-script-v2" - <> Opt.help "Specify a plutus script v2 reference script." - ) - - pSimpleScriptLang :: Parser AnyScriptLanguage - pSimpleScriptLang = - Opt.flag' (AnyScriptLanguage $ SimpleScriptLanguage SimpleScriptV2) - ( Opt.long "simple-script" - <> Opt.help "Specify a simple script reference script. \ - \See documentation at doc/reference/simple-scripts.md" - ) - - toReferenceScriptWitnessFiles - :: TxIn - -> ( AnyScriptLanguage - , Maybe (ScriptDatumOrFile witctx) - , Maybe ScriptRedeemerOrFile - , Maybe ExecutionUnits - ) - -> ScriptWitnessFiles witctx - toReferenceScriptWitnessFiles txin (sLang, mD, mR, mE) = - case sLang of - AnyScriptLanguage (SimpleScriptLanguage _) -> - SimpleReferenceScriptWitnessFiles txin sLang - AnyScriptLanguage (PlutusScriptLanguage _) -> - case (mD, mR, mE) of - (Just d, Just r, Just e) -> PlutusReferenceScriptWitnessFiles txin sLang d r e - (_,_,_) -> panic "toReferenceScriptWitnessFiles: Should not be possible" - - -pReferenceTxIn :: Parser TxIn -pReferenceTxIn = +pReferenceTxIn :: String -> Parser TxIn +pReferenceTxIn prefix = Opt.option (readerFromParsecParser parseTxIn) - ( Opt.long "tx-in-reference" + ( Opt.long (prefix ++ "tx-in-reference") <> Opt.metavar "TX-IN" <> Opt.help "TxId#TxIx - Specify a reference input. The reference input may or may not have\ \ a plutus reference script attached." @@ -364,16 +300,16 @@ pScriptDatumOrFile scriptFlagPrefix witctx = (scriptFlagPrefix ++ "-datum") "The script datum, in JSON syntax." "The script datum, in the given JSON file.") <|> - pInlineDatumPresent scriptFlagPrefix + pInlineDatumPresent WitCtxMint -> pure NoScriptDatumOrFileForMint WitCtxStake -> pure NoScriptDatumOrFileForStake - -pInlineDatumPresent :: String -> Parser (ScriptDatumOrFile WitCtxTxIn) -pInlineDatumPresent scriptFlagPrefix = - flag' InlineDatumPresentAtTxIn - ( long (scriptFlagPrefix ++ "-inline-datum-present") - <> Opt.help "Inline datum present at transaction input." - ) + where + pInlineDatumPresent :: Parser (ScriptDatumOrFile WitCtxTxIn) + pInlineDatumPresent = + flag' InlineDatumPresentAtTxIn + ( long (scriptFlagPrefix ++ "-inline-datum-present") + <> Opt.help "Inline datum present at transaction input." + ) pScriptDataOrFile :: String -> String -> String -> Parser ScriptDataOrFile pScriptDataOrFile dataFlagPrefix helpTextForValue helpTextForFile = @@ -1501,17 +1437,21 @@ pCertificateFile balanceExecUnits = Opt.strOption (Opt.long "certificate" <> Opt.internal) ) ) - <*> optional (pScriptWitnessFiles - WitCtxStake - balanceExecUnits - "certificate" Nothing - "the use of the certificate.") + <*> optional (pCertifyingScriptOrReferenceScriptWit balanceExecUnits) where - helpText = "Filepath of the certificate. This encompasses all \ - \types of certificates (stake pool certificates, \ - \stake key certificates etc). Optionally specify a script witness." - - + pCertifyingScriptOrReferenceScriptWit + :: BalanceTxExecUnits -> Parser (ScriptWitnessFiles WitCtxStake) + pCertifyingScriptOrReferenceScriptWit bExecUnits = + pScriptWitnessFiles + WitCtxStake + balanceExecUnits + "certificate" Nothing + "the use of the certificate." <|> + pPlutusStakeReferenceScriptWitnessFiles "certificate-" bExecUnits + + helpText = "Filepath of the certificate. This encompasses all \ + \types of certificates (stake pool certificates, \ + \stake key certificates etc). Optionally specify a script witness." pPoolMetadataFile :: Parser PoolMetadataFile pPoolMetadataFile = @@ -1578,21 +1518,47 @@ pWithdrawal balance = <> Opt.metavar "WITHDRAWAL" <> Opt.help helpText ) - <*> optional (pScriptWitnessFiles - WitCtxStake - balance - "withdrawal" Nothing - "the withdrawal of rewards.") + <*> optional pWithdrawalScriptOrReferenceScriptWit where - helpText = "The reward withdrawal as StakeAddress+Lovelace where \ - \StakeAddress is the Bech32-encoded stake address \ - \followed by the amount in Lovelace. Optionally specify \ - \a script witness." - - parseWithdrawal :: Parsec.Parser (StakeAddress, Lovelace) - parseWithdrawal = - (,) <$> parseStakeAddress <* Parsec.char '+' <*> parseLovelace - + pWithdrawalScriptOrReferenceScriptWit :: Parser (ScriptWitnessFiles WitCtxStake) + pWithdrawalScriptOrReferenceScriptWit = + pScriptWitnessFiles + WitCtxStake + balance + "withdrawal" Nothing + "the withdrawal of rewards." <|> + pPlutusStakeReferenceScriptWitnessFiles "withdrawal-" balance + + helpText = "The reward withdrawal as StakeAddress+Lovelace where \ + \StakeAddress is the Bech32-encoded stake address \ + \followed by the amount in Lovelace. Optionally specify \ + \a script witness." + + parseWithdrawal :: Parsec.Parser (StakeAddress, Lovelace) + parseWithdrawal = + (,) <$> parseStakeAddress <* Parsec.char '+' <*> parseLovelace + +pPlutusStakeReferenceScriptWitnessFiles + :: String + -> BalanceTxExecUnits -- ^ Use the @execution-units@ flag. + -> Parser (ScriptWitnessFiles WitCtxStake) +pPlutusStakeReferenceScriptWitnessFiles prefix autoBalanceExecUnits = + PlutusReferenceScriptWitnessFiles + <$> pReferenceTxIn prefix + <*> pPlutusScriptLanguage prefix + <*> pure NoScriptDatumOrFileForStake + <*> pScriptRedeemerOrFile (prefix ++ "reference-tx-in") + <*> (case autoBalanceExecUnits of + AutoBalance -> pure (ExecutionUnits 0 0) + ManualBalance -> pExecutionUnits $ prefix ++ "reference-tx-in") + <*> pure Nothing + +pPlutusScriptLanguage :: String -> Parser AnyScriptLanguage +pPlutusScriptLanguage prefix = + Opt.flag' (AnyScriptLanguage $ PlutusScriptLanguage PlutusScriptV2) + ( Opt.long (prefix ++ "plutus-script-v2") + <> Opt.help "Specify a plutus script v2 reference script." + ) pUpdateProposalFile :: Parser UpdateProposalFile pUpdateProposalFile = @@ -2109,15 +2075,51 @@ pTxIn balance = <> Opt.metavar "TX-IN" <> Opt.help "TxId#TxIx" ) - <*> optional pPlutusScriptOrReferenceInputWitness + <*> optional (pPlutusReferenceScriptWitness balance <|> + pSimpleReferenceSpendingScriptWitess <|> + pEmbeddedPlutusScriptWitness + ) where - pPlutusScriptOrReferenceInputWitness :: Parser (ScriptWitnessFiles WitCtxTxIn) - pPlutusScriptOrReferenceInputWitness = - pScriptWitnessFiles WitCtxTxIn balance + pSimpleReferenceSpendingScriptWitess :: Parser (ScriptWitnessFiles WitCtxTxIn) + pSimpleReferenceSpendingScriptWitess = + createSimpleReferenceScriptWitnessFiles + <$> pReferenceTxIn "simple-script-" + where + createSimpleReferenceScriptWitnessFiles + :: TxIn + -> ScriptWitnessFiles WitCtxTxIn + createSimpleReferenceScriptWitnessFiles refTxIn = + let simpleLang = AnyScriptLanguage (SimpleScriptLanguage SimpleScriptV2) + in SimpleReferenceScriptWitnessFiles refTxIn simpleLang Nothing + + pPlutusReferenceScriptWitness :: BalanceTxExecUnits -> Parser (ScriptWitnessFiles WitCtxTxIn) + pPlutusReferenceScriptWitness autoBalanceExecUnits = + createPlutusReferenceScriptWitnessFiles + <$> pReferenceTxIn "spending-" + <*> pPlutusScriptLanguage "spending-" + <*> pScriptDatumOrFile "spending-reference-tx-in" WitCtxTxIn + <*> pScriptRedeemerOrFile "spending-reference-tx-in" + <*> (case autoBalanceExecUnits of + AutoBalance -> pure (ExecutionUnits 0 0) + ManualBalance -> pExecutionUnits "spending-reference-tx-in") + where + createPlutusReferenceScriptWitnessFiles + :: TxIn + -> AnyScriptLanguage + -> ScriptDatumOrFile WitCtxTxIn + -> ScriptRedeemerOrFile + -> ExecutionUnits + -> ScriptWitnessFiles WitCtxTxIn + createPlutusReferenceScriptWitnessFiles refIn sLang sDatum sRedeemer execUnits = + PlutusReferenceScriptWitnessFiles refIn sLang sDatum sRedeemer execUnits Nothing + + pEmbeddedPlutusScriptWitness :: Parser (ScriptWitnessFiles WitCtxTxIn) + pEmbeddedPlutusScriptWitness = + pScriptWitnessFiles + WitCtxTxIn + balance "tx-in" (Just "txin") - "the spending of the transaction input." <|> - pReferenceScriptWitnessFiles WitCtxTxIn balance - + "the spending of the transaction input." pTxInCollateral :: Parser TxIn pTxInCollateral = @@ -2251,16 +2253,43 @@ pMintMultiAsset balanceExecUnits = <> Opt.metavar "VALUE" <> Opt.help helpText ) - <*> some (pScriptWitnessFiles - WitCtxMint - balanceExecUnits - "mint" (Just "minting") - "the minting of assets for a particular policy Id." - ) + <*> some (pMintingScriptOrReferenceScriptWit balanceExecUnits) where + pMintingScriptOrReferenceScriptWit + :: BalanceTxExecUnits -> Parser (ScriptWitnessFiles WitCtxMint) + pMintingScriptOrReferenceScriptWit bExecUnits = + pScriptWitnessFiles + WitCtxMint + balanceExecUnits + "mint" (Just "minting") + "the minting of assets for a particular policy Id." <|> + pPlutusMintReferenceScriptWitnessFiles bExecUnits + + pPlutusMintReferenceScriptWitnessFiles + :: BalanceTxExecUnits -> Parser (ScriptWitnessFiles WitCtxMint) + pPlutusMintReferenceScriptWitnessFiles autoBalanceExecUnits = + PlutusReferenceScriptWitnessFiles + <$> pReferenceTxIn "mint-" + <*> pPlutusScriptLanguage "mint-" + <*> pure NoScriptDatumOrFileForMint + <*> pScriptRedeemerOrFile "mint-reference-tx-in" + <*> (case autoBalanceExecUnits of + AutoBalance -> pure (ExecutionUnits 0 0) + ManualBalance -> pExecutionUnits "mint-reference-tx-in") + <*> (Just <$> pPolicyId) + helpText = "Mint multi-asset value(s) with the multi-asset cli syntax. \ \You must specify a script witness." +pPolicyId :: Parser PolicyId +pPolicyId = + Opt.option (readerFromParsecParser policyId) + ( Opt.long "policy-id" + <> Opt.metavar "HASH" + <> Opt.help "Policy id of minting script." + ) + + pInvalidBefore :: Parser SlotNo pInvalidBefore = SlotNo <$> From e1a7f4f7fd0344663e957edbcb1cf273b6d30e79 Mon Sep 17 00:00:00 2001 From: Jordan Millar Date: Fri, 17 Jun 2022 09:21:31 -0500 Subject: [PATCH 03/15] Modify `runBuildRaw` and `runBuild` to accept reference inputs from withdrawing, certifying and minting reference scripts --- .../Cardano/CLI/Shelley/Run/Transaction.hs | 144 ++++++++++++------ 1 file changed, 100 insertions(+), 44 deletions(-) diff --git a/cardano-cli/src/Cardano/CLI/Shelley/Run/Transaction.hs b/cardano-cli/src/Cardano/CLI/Shelley/Run/Transaction.hs index d2f86caf54f..8225e7b9b4c 100644 --- a/cardano-cli/src/Cardano/CLI/Shelley/Run/Transaction.hs +++ b/cardano-cli/src/Cardano/CLI/Shelley/Run/Transaction.hs @@ -395,11 +395,11 @@ runTxBuildRaw (AnyCardanoEra era) outputFormat (TxBodyFile fpath) = do let referenceInputsWithWits = [ (input, wit) - | (_, wit@(Just (PlutusReferenceScriptWitnessFiles input _ _ _ _))) + | (_, wit@(Just (PlutusReferenceScriptWitnessFiles input _ _ _ _ _))) <- inputsAndScripts ] ++ [(input, wit) - | (_, wit@(Just (SimpleReferenceScriptWitnessFiles input _))) + | (_, wit@(Just (SimpleReferenceScriptWitnessFiles input _ _))) <- inputsAndScripts ] @@ -409,7 +409,7 @@ runTxBuildRaw (AnyCardanoEra era) <*> validateTxInsCollateral era inputsCollateral <*> validateTxInsReference - era referenceInputsWithWits readOnlyRefIns + era referenceInputsWithWits withdrawals certFiles mValue readOnlyRefIns <*> validateTxOuts era txouts <*> validateTxTotalCollateral era mTotCollateral <*> validateTxReturnCollateral era mReturnCollateral @@ -488,15 +488,27 @@ runTxBuild (AnyCardanoEra era) (AnyConsensusModeParams cModeParams) networkId mS consensusMode = consensusModeOnly cModeParams dummyFee = Just $ Lovelace 0 inputsThatRequireWitnessing = [input | (input,_) <- txins] + referenceInputs = map fst referenceInputsWithWits ++ readOnlyRefIns ++ mintingRefInputs + mintingRefInputs = case mValue of + Nothing -> [] + Just (_, wits) -> + [ input + | (PlutusReferenceScriptWitnessFiles input _ _ _ _ _) + <- wits + ] ++ + [input + | SimpleReferenceScriptWitnessFiles input _ _ + <- wits + ] + referenceInputsWithWits = [ (input, wit) - | (_, wit@(Just (PlutusReferenceScriptWitnessFiles input _ _ _ _))) + | (_, wit@(Just (PlutusReferenceScriptWitnessFiles input _ _ _ _ _))) <- txins ] ++ [(input, wit) - | (_, wit@(Just (SimpleReferenceScriptWitnessFiles input _))) + | (_, wit@(Just (SimpleReferenceScriptWitnessFiles input _ _))) <- txins ] - referenceInputs = map fst referenceInputsWithWits ++ readOnlyRefIns case (consensusMode, cardanoEraStyle era) of (CardanoMode, ShelleyBasedEra sbe) -> do @@ -504,7 +516,8 @@ runTxBuild (AnyCardanoEra era) (AnyConsensusModeParams cModeParams) networkId mS TxBodyContent <$> validateTxIns era txins <*> validateTxInsCollateral era txinsc - <*> validateTxInsReference era referenceInputsWithWits readOnlyRefIns + <*> validateTxInsReference + era referenceInputsWithWits withdrawals certFiles mValue readOnlyRefIns <*> validateTxOuts era txouts <*> validateTxTotalCollateral era mtotcoll <*> validateTxReturnCollateral era mReturnCollateral @@ -520,7 +533,6 @@ runTxBuild (AnyCardanoEra era) (AnyConsensusModeParams cModeParams) networkId mS <*> validateTxUpdateProposal era mUpdatePropFile <*> validateTxMintValue era mValue <*> validateTxScriptValidity era mScriptValidity - eInMode <- case toEraInMode era CardanoMode of Just result -> return result Nothing -> @@ -688,31 +700,57 @@ validateTxInsCollateral era txins = Nothing -> txFeatureMismatch era TxFeatureCollateral Just supported -> return (TxInsCollateral supported txins) -validateTxInsReference :: forall era. CardanoEra era - -> [(TxIn, Maybe (ScriptWitnessFiles WitCtxTxIn))] - -> [TxIn] -- ^ Read only reference inputs - -> ExceptT ShelleyTxCmdError IO (TxInsReference BuildTx era) -validateTxInsReference _ [] [] = return TxInsReferenceNone -validateTxInsReference era txins readOnlyRefIns = +validateTxInsReference + :: forall era. CardanoEra era + -> [(TxIn, Maybe (ScriptWitnessFiles WitCtxTxIn))] + -- ^ We are only interested in inputs witnessed by reference inputs. + -> [(StakeAddress, Lovelace, Maybe (ScriptWitnessFiles WitCtxStake))] + -- ^ We are only interested in withdrawals witnessed by reference inputs. + -> [(CertificateFile, Maybe (ScriptWitnessFiles WitCtxStake))] + -- ^ We are only interested in certificates witnessed by reference inputs. + -> Maybe (Value, [ScriptWitnessFiles WitCtxMint]) + -- ^ We are only interested in the minting values witnessed by reference inputs. + -> [TxIn] -- ^ Read only reference inputs + -> ExceptT ShelleyTxCmdError IO (TxInsReference BuildTx era) +validateTxInsReference _ [] [] [] Nothing [] = return TxInsReferenceNone +validateTxInsReference era txins withdrawals certFiles mMintWitnesses readOnlyRefIns = case refInsScriptsAndInlineDatsSupportedInEra era of Nothing -> txFeatureMismatch era TxFeatureReferenceInputs Just supp -> do - final <- mapM convert txins - return $ TxInsReference supp $ readOnlyRefIns ++ catMaybes final + txinsWitByRefInputs <- mapM (getWitnessingReferenceInput . snd) txins + + withdrawalsWitByRefInputs + <- mapM (\(_, _, mSwit) -> getWitnessingReferenceInput mSwit) withdrawals + + certsWitByRefInputs <- mapM (getWitnessingReferenceInput . snd) certFiles + + valuesWitByRefInputs + <- case mMintWitnesses of + Nothing -> return [] + Just (_, mintWitnesses) -> + mapM (getWitnessingReferenceInput . Just) mintWitnesses + + return . TxInsReference supp + . catMaybes $ concat [ txinsWitByRefInputs + , withdrawalsWitByRefInputs + , certsWitByRefInputs + , valuesWitByRefInputs + , map Just readOnlyRefIns + ] where - convert - :: (TxIn, Maybe (ScriptWitnessFiles WitCtxTxIn)) + getWitnessingReferenceInput + :: Maybe (ScriptWitnessFiles witctx) -> ExceptT ShelleyTxCmdError IO (Maybe TxIn) - convert (_, mScriptWitnessFiles) = + getWitnessingReferenceInput mScriptWitnessFiles = case mScriptWitnessFiles of Just scriptWitnessFiles -> do sWit <- createScriptWitness era scriptWitnessFiles case sWit of - PlutusScriptWitness _ _ (PReferenceScript refIn) _ _ _ -> + PlutusScriptWitness _ _ (PReferenceScript refIn _) _ _ _ -> return $ Just refIn PlutusScriptWitness _ _ PScript{} _ _ _ -> return Nothing - SimpleScriptWitness _ _ (SReferenceScript refIn) -> + SimpleScriptWitness _ _ (SReferenceScript refIn _) -> return $ Just refIn SimpleScriptWitness _ _ SScript{} -> return Nothing @@ -1025,12 +1063,17 @@ validateTxScriptValidity era (Just scriptValidity) = Nothing -> txFeatureMismatch era TxFeatureScriptValidity Just supported -> pure $ TxScriptValidity supported scriptValidity +-- TODO: Currently we specify the policyId with the '--mint' option on the cli +-- and we added a separate '--policy-id' parser that parses the policy id for the +-- given reference input (since we don't have the script in this case). To avoid asking +-- for the policy id twice (in the build command) we can potentially query the UTxO and +-- access the script (and therefore the policy id). validateTxMintValue :: forall era. CardanoEra era -> Maybe (Value, [ScriptWitnessFiles WitCtxMint]) -> ExceptT ShelleyTxCmdError IO (TxMintValue BuildTx era) validateTxMintValue _ Nothing = return TxMintNone -validateTxMintValue era (Just (val, scriptWitnessFiles)) = +validateTxMintValue era (Just (val, scriptWitnessFiles)) = do case multiAssetSupportedInEra era of Left _ -> txFeatureMismatch era TxFeatureMintValue Right supported -> do @@ -1042,9 +1085,8 @@ validateTxMintValue era (Just (val, scriptWitnessFiles)) = -- The set (and map) of policy ids for which we have witnesses: witnesses <- mapM (createScriptWitness era) scriptWitnessFiles let witnessesProvidedMap :: Map PolicyId (ScriptWitness WitCtxMint era) - witnessesProvidedMap = - Map.fromList [ (\(Just pid, w) -> (pid, w)) (scriptWitnessPolicyId witness, witness) - | witness <- witnesses ] + witnessesProvidedMap = Map.fromList $ gatherMintingWitnesses witnesses + witnessesProvidedSet = Map.keysSet witnessesProvidedMap -- Check not too many, nor too few: @@ -1053,23 +1095,36 @@ validateTxMintValue era (Just (val, scriptWitnessFiles)) = return (TxMintValue supported val (BuildTxWith witnessesProvidedMap)) where - validateAllWitnessesProvided witnessesNeeded witnessesProvided - | null witnessesMissing = return () - | otherwise = left (ShelleyTxCmdPolicyIdsMissing witnessesMissing) - where - witnessesMissing = Set.elems (witnessesNeeded Set.\\ witnessesProvided) - - validateNoUnnecessaryWitnesses witnessesNeeded witnessesProvided - | null witnessesExtra = return () - | otherwise = left (ShelleyTxCmdPolicyIdsExcess witnessesExtra) - where - witnessesExtra = Set.elems (witnessesProvided Set.\\ witnessesNeeded) + gatherMintingWitnesses + :: [ScriptWitness WitCtxMint era] + -> [(PolicyId, ScriptWitness WitCtxMint era)] + gatherMintingWitnesses [] = [] + gatherMintingWitnesses (sWit : rest) = + case scriptWitnessPolicyId sWit of + Nothing -> gatherMintingWitnesses rest + Just pid -> (pid, sWit) : gatherMintingWitnesses rest + + validateAllWitnessesProvided witnessesNeeded witnessesProvided + | null witnessesMissing = return () + | otherwise = left (ShelleyTxCmdPolicyIdsMissing witnessesMissing) + where + witnessesMissing = Set.elems (witnessesNeeded Set.\\ witnessesProvided) + + validateNoUnnecessaryWitnesses witnessesNeeded witnessesProvided + | null witnessesExtra = return () + | otherwise = left (ShelleyTxCmdPolicyIdsExcess witnessesExtra) + where + witnessesExtra = Set.elems (witnessesProvided Set.\\ witnessesNeeded) scriptWitnessPolicyId :: ScriptWitness witctx era -> Maybe PolicyId -scriptWitnessPolicyId witness = - case scriptWitnessScript witness of - Just (ScriptInEra _ script) -> Just $ scriptPolicyId script - Nothing -> Nothing +scriptWitnessPolicyId (SimpleScriptWitness _ version (SScript script)) = + Just . scriptPolicyId $ SimpleScript version script +scriptWitnessPolicyId (SimpleScriptWitness _ _ (SReferenceScript _ mPid)) = + PolicyId <$> mPid +scriptWitnessPolicyId (PlutusScriptWitness _ version (PScript script) _ _ _) = + Just . scriptPolicyId $ PlutusScript version script +scriptWitnessPolicyId (PlutusScriptWitness _ _ (PReferenceScript _ mPid) _ _ _) = + PolicyId <$> mPid createScriptWitness :: CardanoEra era @@ -1120,7 +1175,7 @@ createScriptWitness era (PlutusScriptWitnessFiles createScriptWitness era (PlutusReferenceScriptWitnessFiles refTxIn anyScrLang@(AnyScriptLanguage anyScriptLanguage) - datumOrFile redeemerOrFile execUnits) = do + datumOrFile redeemerOrFile execUnits mPid) = do case refInsScriptsAndInlineDatsSupportedInEra era of Nothing -> left $ ShelleyTxCmdReferenceScriptsNotSupportedInEra $ getIsCardanoEraConstraint era (AnyCardanoEra era) @@ -1139,12 +1194,12 @@ createScriptWitness era (PlutusReferenceScriptWitnessFiles refTxIn return $ PlutusScriptWitness sLangInEra version - (PReferenceScript refTxIn) + (PReferenceScript refTxIn (unPolicyId <$> mPid)) datum redeemer execUnits Nothing -> left $ ShelleyTxCmdScriptLanguageNotSupportedInEra anyScrLang (anyCardanoEra era) createScriptWitness era (SimpleReferenceScriptWitnessFiles refTxIn - anyScrLang@(AnyScriptLanguage anyScriptLanguage)) = do + anyScrLang@(AnyScriptLanguage anyScriptLanguage) mPid) = do case refInsScriptsAndInlineDatsSupportedInEra era of Nothing -> left $ ShelleyTxCmdReferenceScriptsNotSupportedInEra $ getIsCardanoEraConstraint era (AnyCardanoEra era) @@ -1153,7 +1208,8 @@ createScriptWitness era (SimpleReferenceScriptWitnessFiles refTxIn Just sLangInEra -> case languageOfScriptLanguageInEra sLangInEra of SimpleScriptLanguage v -> - return . SimpleScriptWitness sLangInEra v $ SReferenceScript refTxIn + return . SimpleScriptWitness sLangInEra v + $ SReferenceScript refTxIn (unPolicyId <$> mPid) PlutusScriptLanguage{} -> panic "createScriptWitness: Should not be possible to specify a plutus script" Nothing -> From a6934eb0c14053c1a3d34e446ffb9c627498bd90 Mon Sep 17 00:00:00 2001 From: Jordan Millar Date: Fri, 17 Jun 2022 09:42:50 -0500 Subject: [PATCH 04/15] Modify ScriptWitnessFiles to accept a Maybe PolicyId when using minting reference scripts --- cardano-cli/src/Cardano/CLI/Types.hs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/cardano-cli/src/Cardano/CLI/Types.hs b/cardano-cli/src/Cardano/CLI/Types.hs index 5d8d41042da..1ef07fea844 100644 --- a/cardano-cli/src/Cardano/CLI/Types.hs +++ b/cardano-cli/src/Cardano/CLI/Types.hs @@ -53,8 +53,8 @@ import Data.Word (Word64) import qualified Cardano.Chain.Slotting as Byron import Cardano.Api (AddressAny, AnyScriptLanguage, EpochNo, ExecutionUnits, Hash, - InAnyCardanoEra, PaymentKey, ScriptData, SlotNo (SlotNo), Tx, TxIn, Value, - WitCtxMint, WitCtxStake, WitCtxTxIn) + InAnyCardanoEra, PaymentKey, PolicyId, ScriptData, SlotNo (SlotNo), Tx, TxIn, + Value, WitCtxMint, WitCtxStake, WitCtxTxIn) import qualified Cardano.Ledger.Crypto as Crypto @@ -293,17 +293,20 @@ data ScriptWitnessFiles witctx where -> ExecutionUnits -> ScriptWitnessFiles witctx + -- TODO: Need to figure out how to exclude PlutusV1 scripts at the type level PlutusReferenceScriptWitnessFiles :: TxIn -> AnyScriptLanguage -> ScriptDatumOrFile witctx -> ScriptRedeemerOrFile -> ExecutionUnits + -> Maybe PolicyId -- ^ For minting reference scripts -> ScriptWitnessFiles witctx SimpleReferenceScriptWitnessFiles :: TxIn -> AnyScriptLanguage + -> Maybe PolicyId -- ^ For minting reference scripts -> ScriptWitnessFiles witctx From 4ebe8ee89a0a36f83e39d6cabc42119f8865ae27 Mon Sep 17 00:00:00 2001 From: Jordan Millar Date: Fri, 17 Jun 2022 09:43:49 -0500 Subject: [PATCH 05/15] Update babbage-script-example.md to include how to use minting reference scrtips Add an example Plutus V2 minting script at scripts/plutus/scripts/v2/minting-script.plutus Update example-babbage-script-usage.sh to utilize a minting reference script --- .../plutus/babbage-script-example.md | 66 ++++++++++++------- .../plutus/example-babbage-script-usage.sh | 52 ++++++++++----- .../plutus/scripts/v2/minting-script.plutus | 5 ++ 3 files changed, 84 insertions(+), 39 deletions(-) create mode 100644 scripts/plutus/scripts/v2/minting-script.plutus diff --git a/doc/reference/plutus/babbage-script-example.md b/doc/reference/plutus/babbage-script-example.md index cecf1c6d055..036d7ed9d74 100644 --- a/doc/reference/plutus/babbage-script-example.md +++ b/doc/reference/plutus/babbage-script-example.md @@ -14,7 +14,7 @@ In the case where we are not using a reference input to reference another transa ### An example of using a Plutus V2 reference script -Below is an example that shows how to use a Plutus spending script and an inline datum. Here we discuss a [shell script example of how to use a reference script to spend a tx input](scripts/plutus/example-babbage-script-usage.sh). This is a step-by-step process involving: +Below is an example that shows how to use a reference Plutus spending script with an inline datum and a reference minting script. Here we discuss a [shell script example of how to use a reference script to spend a tx input and a reference minting script to mint tokens](scripts/plutus/example-babbage-script-usage.sh). This is a step-by-step process involving: + the creation of the `Required Redeemer` Plutus txin script + the creation of the `Required Redeemer` Plutus script at a transaction output (creation of the reference script) @@ -22,8 +22,9 @@ Below is an example that shows how to use a Plutus spending script and an inline + sending ada to the Plutus script address + spending ada at the Plutus script address using the Plutus reference script + creating a read only reference tx output ++ the creation of the reference [minting script](scripts/plutus/scripts/v2) at a transaction output. -In this example we will use the [Required Redeemer](scripts/plutus/scripts/v2/required-redeemer.plutus) Plutus spending script. In order to execute a reference Plutus spending script, we require the following: +In this example we will use the [Required Redeemer](scripts/plutus/scripts/v2/required-redeemer.plutus) Plutus spending script and a [minting script](scripts/plutus/scripts/v2). In order to execute a reference Plutus spending script, we require the following: - Collateral tx input(s) - these are provided and are forfeited in the event the Plutus script fails to execute. - A Plutus tx output. This is the tx output that sits at the Plutus script address. @@ -31,7 +32,7 @@ In this example we will use the [Required Redeemer](scripts/plutus/scripts/v2/re - An inline datum at the Plutus tx output. The Plutus spending script requires an inline datum or datum hash and in this case we are using an inline datum. - A read only reference input with an inline datum. -#### Creating the `Required Redeemer` Plutus spending script +#### Creating the `Required Redeemer` Plutus spending script and the minting script The plutus-example executable will automagically generate several Plutus scripts in the CLI-compatible text envelope format. @@ -45,7 +46,7 @@ cd plutus-apps/plutus-example cabal run exe:plutus-example ``` -This will output `required-redeemer.plutus` in the `generated-plutus-scripts/v2` dir. +This will output `required-redeemer.plutus` and `minting-script.plutus` in the `generated-plutus-scripts/v2` dir. #### Setting up a local Babbage node cluster @@ -75,13 +76,15 @@ cardano-cli transaction build \ --testnet-magic 42 \ --change-address "$utxoaddr" \ --tx-in "$txin" \ - --tx-out "$readonlyaddress+$lovelaceattxindiv5" \ + --tx-out "$readonlyaddress+$lovelaceattxindiv6" \ --tx-out-inline-datum-file "$datumfilepath" \ --tx-out "$utxoaddr+$lovelace" \ - --tx-out "$plutusscriptaddr+$lovelace" \ + --tx-out "$plutusspendingscriptaddr+$lovelace" \ --tx-out-inline-datum-file "$datumfilepath" \ - --tx-out "$dummyaddress+$lovelaceattxindiv5" \ - --tx-out-reference-script-file "$plutusscriptinuse" \ + --tx-out "$dummyaddress+$lovelaceattxindiv6" \ + --tx-out-reference-script-file "$plutusspendingscript" \ + --tx-out "$addressformintingrefscript+$lovelaceattxindiv6" \ + --tx-out-reference-script-file "$plutusmintingscript" \ --protocol-params-file "$WORK/pparams.json" \ --out-file "$WORK/create-datum-output.body" ``` @@ -92,7 +95,7 @@ Firstly, we are sending ada and an inline datum to the plutus script address. Th ```bash ... ---tx-out "$plutusscriptaddr+$lovelace" \ +--tx-out "$plutusspendingscriptaddr+$lovelace" \ --tx-out-inline-datum-file "$datumfilepath" \ ... ``` @@ -103,8 +106,8 @@ Secondly, we are creating a reference script at a tx output: ```bash ... ---tx-out "$dummyaddress+$lovelaceattxindiv5" \ ---tx-out-reference-script-file "$plutusscriptinuse" \ +--tx-out "$dummyaddress+$lovelaceattxindiv6" \ +--tx-out-reference-script-file "$plutusspendingscript" \ ... ``` @@ -114,11 +117,20 @@ Thirdly, we are preparing a txout to be used as a read only reference input: ```bash ... ---tx-out "$readonlyaddress+$lovelaceattxindiv5" \ +--tx-out "$readonlyaddress+$lovelaceattxindiv6" \ --tx-out-inline-datum-file "$datumfilepath" \ ... ``` +Fourthly, we create the minting reference script at a tx output: + +```bash +... +--tx-out "$addressformintingrefscript+$lovelaceattxindiv6" \ +--tx-out-reference-script-file "$plutusmintingscript" \ +... +``` + We sign and then submit as usual: ```bash @@ -130,17 +142,22 @@ cardano-cli transaction sign \ ``` -#### Spending ada at the script address +#### Spending ada at the script address and minting tokens Now that there is ada at our script address, we must construct the appropriate transaction in order to spend it. Because we are using the `build` command, we should only note the following: `$plutusutxotxin` - This is the tx input that sits at the Plutus script address (NB: It has a datum hash). -`tx-in-reference` - This specifies the reference input you are using to witness a transaction input. -`plutus-script-v2`- This specifies the version of the reference script at the reference input. -`reference-tx-in-inline-datum-present` - This indicates that we are using an inline datum which exists at the utxo we are trying to spend (the utxo at the Plutus script address). -`reference-tx-in-redeemer-file` - This is the redeemer to be used with the reference script. +`spending-tx-in-reference` - This specifies the reference input you are using to witness a transaction input. +`spending-plutus-script-v2`- This specifies the version of the reference script at the reference input. +`spending-reference-tx-in-inline-datum-present` - This indicates that we are using an inline datum which exists at the utxo we are trying to spend (the utxo at the Plutus script address). +`spending-reference-tx-in-redeemer-file` - This is the redeemer to be used with the reference script. `read-only-tx-in-reference` - This is a non-witnessing reference input. This will only be exposed in the Plutus script context. +`mint-tx-in-reference` - This specifies the reference input you are using to mint tokens. +`mint-plutus-script-v2` - This specifies the version of the reference script at the reference input. +`mint-reference-tx-in-redeemer-file` - This is the redeemer to be used with the reference script. +`policy-id` - Because we do not have direct access to the minting script we must specify the policy id. + ```bash cardano-cli transaction build \ @@ -153,11 +170,16 @@ cardano-cli transaction build \ --tx-in-collateral "$txinCollateral" \ --out-file "$WORK/test-alonzo-ref-script.body" \ --tx-in "$plutuslockedutxotxin" \ - --tx-in-reference "$plutusreferencescripttxin" \ - --plutus-script-v2 \ - --reference-tx-in-inline-datum-present \ - --reference-tx-in-redeemer-file "$redeemerfilepath" \ - --tx-out "$dummyaddress2+10000000" \ + --spending-tx-in-reference "$plutusreferencescripttxin" \ + --spending-plutus-script-v2 \ + --spending-reference-tx-in-inline-datum-present \ + --spending-reference-tx-in-redeemer-file "$redeemerfilepath" \ + --mint "5 $mintpolicyid.4D696C6C6172436F696E" \ + --mint-tx-in-reference "$mintingscriptrefinput" \ + --mint-plutus-script-v2 \ + --mint-reference-tx-in-redeemer-file "$redeemerfilepath" \ + --policy-id "$mintpolicyid" \ + --tx-out "$dummyaddress2+10000000 + 5 $mintpolicyid.4D696C6C6172436F696E" \ --protocol-params-file "$WORK/pparams.json" cardano-cli transaction sign \ diff --git a/scripts/plutus/example-babbage-script-usage.sh b/scripts/plutus/example-babbage-script-usage.sh index e60515349cd..f7d26e8e2b9 100755 --- a/scripts/plutus/example-babbage-script-usage.sh +++ b/scripts/plutus/example-babbage-script-usage.sh @@ -19,12 +19,14 @@ echo "Socket path: $(pwd)" ls -al "$CARDANO_NODE_SOCKET_PATH" -plutusscriptinuse="$BASE/scripts/plutus/scripts/v2/required-redeemer.plutus" +plutusspendingscript="$BASE/scripts/plutus/scripts/v2/required-redeemer.plutus" +plutusmintingscript="$BASE/scripts/plutus/scripts/v2/minting-script.plutus" +mintpolicyid=$(cardano-cli transaction policyid --script-file $plutusmintingscript) ## This datum hash is the hash of the untyped 42 scriptdatumhash="9e1199a988ba72ffd6e9c269cadb3b53b5f360ff99f112d9b2ee30c4d74ad88b" datumfilepath="$BASE/scripts/plutus/data/42.datum" redeemerfilepath="$BASE/scripts/plutus/data/42.redeemer" -echo "Script at: $plutusscriptinuse" +echo "Script at: $plutusspendingscript" # # # @@ -33,9 +35,9 @@ echo "Script at: $plutusscriptinuse" ## in order to accommodate this. # # -plutusscriptaddr=$($CARDANO_CLI address build --payment-script-file "$plutusscriptinuse" --testnet-magic "$TESTNET_MAGIC") +plutusspendingscriptaddr=$($CARDANO_CLI address build --payment-script-file "$plutusspendingscript" --testnet-magic "$TESTNET_MAGIC") echo "Plutus Script Address" -echo "$plutusscriptaddr" +echo "$plutusspendingscriptaddr" mkdir -p "$WORK" utxoaddr=$($CARDANO_CLI address build --testnet-magic "$TESTNET_MAGIC" --payment-verification-key-file "$UTXO_VKEY" --stake-verification-key-file example/stake-delegator-keys/staking1.vkey) @@ -45,11 +47,12 @@ cat $WORK/utxo-1.json txin=$(jq -r 'keys[0]' $WORK/utxo-1.json) lovelaceattxin=$(jq -r ".[\"$txin\"].value.lovelace" $WORK/utxo-1.json) -lovelaceattxindiv5=$(expr $lovelaceattxin / 5) +lovelaceattxindiv6=$(expr $lovelaceattxin / 6) $CARDANO_CLI query protocol-parameters --testnet-magic "$TESTNET_MAGIC" --out-file $WORK/pparams.json dummyaddress=addr_test1vpqgspvmh6m2m5pwangvdg499srfzre2dd96qq57nlnw6yctpasy4 dummyaddress2=addr_test1vzq57nyrwdwne9vzjxr908qqkdxwuavlgzl20qveua303vq024qkk +addressformintingrefscript=addr_test1vq73yuplt9c5zmgw4ve7qhu49yxllw7q97h4smwvfgst32qrkwupd readonlyaddress=addr_test1vz3t3f2kgy2re66tnhgxc4t8jgylw2cqfnxdwlrq9agfmtstxxkm5 # We first: @@ -61,14 +64,16 @@ $CARDANO_CLI transaction build \ --testnet-magic "$TESTNET_MAGIC" \ --change-address "$utxoaddr" \ --tx-in "$txin" \ - --tx-out "$readonlyaddress+$lovelaceattxindiv5" \ + --tx-out "$readonlyaddress+$lovelaceattxindiv6" \ --tx-out-inline-datum-file "$datumfilepath" \ - --tx-out "$utxoaddr+$lovelaceattxindiv5" \ - --tx-out "$plutusscriptaddr+$lovelaceattxindiv5" \ + --tx-out "$utxoaddr+$lovelaceattxindiv6" \ + --tx-out "$plutusspendingscriptaddr+$lovelaceattxindiv6" \ --tx-out-inline-datum-file "$datumfilepath" \ - --tx-out "$dummyaddress+$lovelaceattxindiv5" \ + --tx-out "$dummyaddress+$lovelaceattxindiv6" \ --tx-out-inline-datum-file "$datumfilepath" \ - --tx-out-reference-script-file "$plutusscriptinuse" \ + --tx-out-reference-script-file "$plutusspendingscript" \ + --tx-out "$addressformintingrefscript+$lovelaceattxindiv6" \ + --tx-out-reference-script-file "$plutusmintingscript" \ --protocol-params-file "$WORK/pparams.json" \ --out-file "$WORK/create-datum-output.body" @@ -101,15 +106,20 @@ lovelaceattxindiv31=$(expr $lovelaceattxin1 / 3) # Get input at plutus script that we will attempt to spend -$CARDANO_CLI query utxo --address $plutusscriptaddr --testnet-magic "$TESTNET_MAGIC" --out-file $WORK/plutusutxo.json +$CARDANO_CLI query utxo --address $plutusspendingscriptaddr --testnet-magic "$TESTNET_MAGIC" --out-file $WORK/plutusutxo.json plutuslockedutxotxin=$(jq -r 'keys[0]' $WORK/plutusutxo.json) -lovelaceatplutusscriptaddr=$(jq -r ".[\"$plutuslockedutxotxin\"].value.lovelace" $WORK/plutusutxo.json) +lovelaceatplutusspendingscriptaddr=$(jq -r ".[\"$plutuslockedutxotxin\"].value.lovelace" $WORK/plutusutxo.json) #Get read only reference input $CARDANO_CLI query utxo --address "$readonlyaddress" --cardano-mode \ --testnet-magic "$TESTNET_MAGIC" --out-file $WORK/read-only-ref-input-utxo.json readonlyrefinput=$(jq -r 'keys[0]' $WORK/read-only-ref-input-utxo.json) +#Get minting reference script input +$CARDANO_CLI query utxo --address "$addressformintingrefscript" --cardano-mode \ + --testnet-magic "$TESTNET_MAGIC" --out-file $WORK/minting-script-ref-input-utxo.json +mintingscriptrefinput=$(jq -r 'keys[0]' $WORK/minting-script-ref-input-utxo.json) + echo "Plutus txin" echo "$plutuslockedutxotxin" @@ -125,6 +135,9 @@ echo "$plutusreferencescripttxin" echo "Plutus input we are trying to spend" echo "$plutuslockedutxotxin" +echo "Policy id" +echo "$mintpolicyid" + # Alternative build-raw method #$CARDANO_CLI transaction build-raw \ # --babbage-era \ @@ -153,11 +166,16 @@ $CARDANO_CLI transaction build \ --tx-in-collateral "$txinCollateral" \ --out-file "$WORK/test-alonzo-ref-script.body" \ --tx-in "$plutuslockedutxotxin" \ - --tx-in-reference "$plutusreferencescripttxin" \ - --plutus-script-v2 \ - --reference-tx-in-inline-datum-present \ - --reference-tx-in-redeemer-file "$redeemerfilepath" \ - --tx-out "$dummyaddress2+10000000" \ + --spending-tx-in-reference "$plutusreferencescripttxin" \ + --spending-plutus-script-v2 \ + --spending-reference-tx-in-inline-datum-present \ + --spending-reference-tx-in-redeemer-file "$redeemerfilepath" \ + --mint "5 $mintpolicyid.4D696C6C6172436F696E" \ + --mint-tx-in-reference "$mintingscriptrefinput" \ + --mint-plutus-script-v2 \ + --mint-reference-tx-in-redeemer-file "$redeemerfilepath" \ + --policy-id "$mintpolicyid" \ + --tx-out "$dummyaddress2+10000000 + 5 $mintpolicyid.4D696C6C6172436F696E" \ --protocol-params-file "$WORK/pparams.json" $CARDANO_CLI transaction sign \ diff --git a/scripts/plutus/scripts/v2/minting-script.plutus b/scripts/plutus/scripts/v2/minting-script.plutus new file mode 100644 index 00000000000..80b516e064c --- /dev/null +++ b/scripts/plutus/scripts/v2/minting-script.plutus @@ -0,0 +1,5 @@ +{ + "type": "PlutusScriptV2", + "description": "", + "cborHex": "5907655907620100003232323232323232323232323232332232323232322232325335320193333573466e1cd55cea80124000466442466002006004646464646464646464646464646666ae68cdc39aab9d500c480008cccccccccccc88888888888848cccccccccccc00403403002c02802402001c01801401000c008cd4050054d5d0a80619a80a00a9aba1500b33501401635742a014666aa030eb9405cd5d0a804999aa80c3ae501735742a01066a02803e6ae85401cccd54060081d69aba150063232323333573466e1cd55cea801240004664424660020060046464646666ae68cdc39aab9d5002480008cc8848cc00400c008cd40a9d69aba15002302b357426ae8940088c98c80b4cd5ce01701681589aab9e5001137540026ae854008c8c8c8cccd5cd19b8735573aa004900011991091980080180119a8153ad35742a00460566ae84d5d1280111931901699ab9c02e02d02b135573ca00226ea8004d5d09aba2500223263202933573805405204e26aae7940044dd50009aba1500533501475c6ae854010ccd540600708004d5d0a801999aa80c3ae200135742a004603c6ae84d5d1280111931901299ab9c026025023135744a00226ae8940044d5d1280089aba25001135744a00226ae8940044d5d1280089aba25001135744a00226ae8940044d55cf280089baa00135742a004601c6ae84d5d1280111931900b99ab9c018017015101613263201633573892010350543500016135573ca00226ea800448c88c008dd6000990009aa80a911999aab9f0012500a233500930043574200460066ae880080508c8c8cccd5cd19b8735573aa004900011991091980080180118061aba150023005357426ae8940088c98c8050cd5ce00a80a00909aab9e5001137540024646464646666ae68cdc39aab9d5004480008cccc888848cccc00401401000c008c8c8c8cccd5cd19b8735573aa0049000119910919800801801180a9aba1500233500f014357426ae8940088c98c8064cd5ce00d00c80b89aab9e5001137540026ae854010ccd54021d728039aba150033232323333573466e1d4005200423212223002004357426aae79400c8cccd5cd19b875002480088c84888c004010dd71aba135573ca00846666ae68cdc3a801a400042444006464c6403666ae7007006c06406005c4d55cea80089baa00135742a00466a016eb8d5d09aba2500223263201533573802c02a02626ae8940044d5d1280089aab9e500113754002266aa002eb9d6889119118011bab00132001355012223233335573e0044a010466a00e66442466002006004600c6aae754008c014d55cf280118021aba200301213574200222440042442446600200800624464646666ae68cdc3a800a40004642446004006600a6ae84d55cf280191999ab9a3370ea0049001109100091931900819ab9c01101000e00d135573aa00226ea80048c8c8cccd5cd19b875001480188c848888c010014c01cd5d09aab9e500323333573466e1d400920042321222230020053009357426aae7940108cccd5cd19b875003480088c848888c004014c01cd5d09aab9e500523333573466e1d40112000232122223003005375c6ae84d55cf280311931900819ab9c01101000e00d00c00b135573aa00226ea80048c8c8cccd5cd19b8735573aa004900011991091980080180118029aba15002375a6ae84d5d1280111931900619ab9c00d00c00a135573ca00226ea80048c8cccd5cd19b8735573aa002900011bae357426aae7940088c98c8028cd5ce00580500409baa001232323232323333573466e1d4005200c21222222200323333573466e1d4009200a21222222200423333573466e1d400d2008233221222222233001009008375c6ae854014dd69aba135744a00a46666ae68cdc3a8022400c4664424444444660040120106eb8d5d0a8039bae357426ae89401c8cccd5cd19b875005480108cc8848888888cc018024020c030d5d0a8049bae357426ae8940248cccd5cd19b875006480088c848888888c01c020c034d5d09aab9e500b23333573466e1d401d2000232122222223005008300e357426aae7940308c98c804ccd5ce00a00980880800780700680600589aab9d5004135573ca00626aae7940084d55cf280089baa0012323232323333573466e1d400520022333222122333001005004003375a6ae854010dd69aba15003375a6ae84d5d1280191999ab9a3370ea0049000119091180100198041aba135573ca00c464c6401866ae700340300280244d55cea80189aba25001135573ca00226ea80048c8c8cccd5cd19b875001480088c8488c00400cdd71aba135573ca00646666ae68cdc3a8012400046424460040066eb8d5d09aab9e500423263200933573801401200e00c26aae7540044dd500089119191999ab9a3370ea00290021091100091999ab9a3370ea00490011190911180180218031aba135573ca00846666ae68cdc3a801a400042444004464c6401466ae7002c02802001c0184d55cea80089baa0012323333573466e1d40052002200723333573466e1d40092000212200123263200633573800e00c00800626aae74dd5000a4c2400292010350543100122002112323001001223300330020020011" +} From 8d277fad804b26d89078e3f777aa1cad69088abb Mon Sep 17 00:00:00 2001 From: Jordan Millar Date: Fri, 17 Jun 2022 11:55:22 -0500 Subject: [PATCH 06/15] Refactor how we obtain reference inputs in runTxBuild and runTxBuildRaw --- .../Cardano/CLI/Shelley/Run/Transaction.hs | 107 +++++++----------- 1 file changed, 41 insertions(+), 66 deletions(-) diff --git a/cardano-cli/src/Cardano/CLI/Shelley/Run/Transaction.hs b/cardano-cli/src/Cardano/CLI/Shelley/Run/Transaction.hs index 8225e7b9b4c..377d18d21c1 100644 --- a/cardano-cli/src/Cardano/CLI/Shelley/Run/Transaction.hs +++ b/cardano-cli/src/Cardano/CLI/Shelley/Run/Transaction.hs @@ -394,22 +394,16 @@ runTxBuildRaw (AnyCardanoEra era) metadataFiles mpparams mUpdatePropFile outputFormat (TxBodyFile fpath) = do - let referenceInputsWithWits = [ (input, wit) - | (_, wit@(Just (PlutusReferenceScriptWitnessFiles input _ _ _ _ _))) - <- inputsAndScripts - ] ++ - [(input, wit) - | (_, wit@(Just (SimpleReferenceScriptWitnessFiles input _ _))) - <- inputsAndScripts - ] + + allReferenceInputs + <- getAllReferenceInputs era inputsAndScripts mValue certFiles withdrawals readOnlyRefIns txBodyContent <- TxBodyContent <$> validateTxIns era inputsAndScripts <*> validateTxInsCollateral era inputsCollateral - <*> validateTxInsReference - era referenceInputsWithWits withdrawals certFiles mValue readOnlyRefIns + <*> validateTxInsReference era allReferenceInputs <*> validateTxOuts era txouts <*> validateTxTotalCollateral era mTotCollateral <*> validateTxReturnCollateral era mReturnCollateral @@ -488,27 +482,8 @@ runTxBuild (AnyCardanoEra era) (AnyConsensusModeParams cModeParams) networkId mS consensusMode = consensusModeOnly cModeParams dummyFee = Just $ Lovelace 0 inputsThatRequireWitnessing = [input | (input,_) <- txins] - referenceInputs = map fst referenceInputsWithWits ++ readOnlyRefIns ++ mintingRefInputs - mintingRefInputs = case mValue of - Nothing -> [] - Just (_, wits) -> - [ input - | (PlutusReferenceScriptWitnessFiles input _ _ _ _ _) - <- wits - ] ++ - [input - | SimpleReferenceScriptWitnessFiles input _ _ - <- wits - ] - - referenceInputsWithWits = [ (input, wit) - | (_, wit@(Just (PlutusReferenceScriptWitnessFiles input _ _ _ _ _))) - <- txins - ] ++ - [(input, wit) - | (_, wit@(Just (SimpleReferenceScriptWitnessFiles input _ _))) - <- txins - ] + + allReferenceInputs <- getAllReferenceInputs era txins mValue certFiles withdrawals readOnlyRefIns case (consensusMode, cardanoEraStyle era) of (CardanoMode, ShelleyBasedEra sbe) -> do @@ -516,8 +491,7 @@ runTxBuild (AnyCardanoEra era) (AnyConsensusModeParams cModeParams) networkId mS TxBodyContent <$> validateTxIns era txins <*> validateTxInsCollateral era txinsc - <*> validateTxInsReference - era referenceInputsWithWits withdrawals certFiles mValue readOnlyRefIns + <*> validateTxInsReference era allReferenceInputs <*> validateTxOuts era txouts <*> validateTxTotalCollateral era mtotcoll <*> validateTxReturnCollateral era mReturnCollateral @@ -553,7 +527,7 @@ runTxBuild (AnyCardanoEra era) (AnyConsensusModeParams cModeParams) networkId mS utxo <- firstExceptT ShelleyTxCmdTxSubmitErrorEraMismatch . newExceptT . queryExpr $ QueryInEra eInMode $ QueryInShelleyBasedEra sbe - $ QueryUTxO (QueryUTxOByTxIn (Set.fromList $ inputsThatRequireWitnessing ++ referenceInputs)) + $ QueryUTxO (QueryUTxOByTxIn (Set.fromList $ inputsThatRequireWitnessing ++ allReferenceInputs)) txinsExist inputsThatRequireWitnessing utxo @@ -702,41 +676,42 @@ validateTxInsCollateral era txins = validateTxInsReference :: forall era. CardanoEra era - -> [(TxIn, Maybe (ScriptWitnessFiles WitCtxTxIn))] - -- ^ We are only interested in inputs witnessed by reference inputs. - -> [(StakeAddress, Lovelace, Maybe (ScriptWitnessFiles WitCtxStake))] - -- ^ We are only interested in withdrawals witnessed by reference inputs. - -> [(CertificateFile, Maybe (ScriptWitnessFiles WitCtxStake))] - -- ^ We are only interested in certificates witnessed by reference inputs. - -> Maybe (Value, [ScriptWitnessFiles WitCtxMint]) - -- ^ We are only interested in the minting values witnessed by reference inputs. - -> [TxIn] -- ^ Read only reference inputs + -> [TxIn] -> ExceptT ShelleyTxCmdError IO (TxInsReference BuildTx era) -validateTxInsReference _ [] [] [] Nothing [] = return TxInsReferenceNone -validateTxInsReference era txins withdrawals certFiles mMintWitnesses readOnlyRefIns = +validateTxInsReference _ [] = return TxInsReferenceNone +validateTxInsReference era allRefIns = case refInsScriptsAndInlineDatsSupportedInEra era of Nothing -> txFeatureMismatch era TxFeatureReferenceInputs - Just supp -> do - txinsWitByRefInputs <- mapM (getWitnessingReferenceInput . snd) txins - - withdrawalsWitByRefInputs - <- mapM (\(_, _, mSwit) -> getWitnessingReferenceInput mSwit) withdrawals - - certsWitByRefInputs <- mapM (getWitnessingReferenceInput . snd) certFiles - - valuesWitByRefInputs - <- case mMintWitnesses of - Nothing -> return [] - Just (_, mintWitnesses) -> - mapM (getWitnessingReferenceInput . Just) mintWitnesses - - return . TxInsReference supp - . catMaybes $ concat [ txinsWitByRefInputs - , withdrawalsWitByRefInputs - , certsWitByRefInputs - , valuesWitByRefInputs - , map Just readOnlyRefIns - ] + Just supp -> return $ TxInsReference supp allRefIns + + +getAllReferenceInputs + :: CardanoEra era + -> [(TxIn, Maybe (ScriptWitnessFiles WitCtxTxIn))] + -> Maybe (Value, [ScriptWitnessFiles WitCtxMint ]) + -> [(CertificateFile , Maybe (ScriptWitnessFiles WitCtxStake ))] + -> [(StakeAddress, Lovelace, Maybe (ScriptWitnessFiles WitCtxStake ))] + -> [TxIn] + -> ExceptT ShelleyTxCmdError IO [TxIn] +getAllReferenceInputs era txins mValue certFiles withdrawals readOnlyRefIns = do + txinsWitByRefInputs <- mapM (getWitnessingReferenceInput . snd) txins + mintingRefInputs <- + case mValue of + Nothing -> return [] + Just (_, mintWitnesses) -> + mapM (getWitnessingReferenceInput . Just) mintWitnesses + + certsWitByRefInputs <- mapM (getWitnessingReferenceInput . snd) certFiles + + withdrawalsWitByRefInputs + <- mapM (\(_, _, mSwit) -> getWitnessingReferenceInput mSwit) withdrawals + + return . catMaybes $ concat [ txinsWitByRefInputs + , mintingRefInputs + , certsWitByRefInputs + , withdrawalsWitByRefInputs + , map Just readOnlyRefIns + ] where getWitnessingReferenceInput :: Maybe (ScriptWitnessFiles witctx) From e474be610c7a17247a414509533009f43c7ab7d4 Mon Sep 17 00:00:00 2001 From: Jordan Millar Date: Fri, 17 Jun 2022 11:56:12 -0500 Subject: [PATCH 07/15] Add two additional scripts to showcase withdrawing and certifying plutus scripts (not using reference scripts yet) --- .../claim-script-staking-rewards.sh | 101 +++++++++ .../register-script-staking-address.sh | 204 ++++++++++++++++++ 2 files changed, 305 insertions(+) create mode 100755 scripts/babbage/staking-example/claim-script-staking-rewards.sh create mode 100755 scripts/babbage/staking-example/register-script-staking-address.sh diff --git a/scripts/babbage/staking-example/claim-script-staking-rewards.sh b/scripts/babbage/staking-example/claim-script-staking-rewards.sh new file mode 100755 index 00000000000..6ed2faa3625 --- /dev/null +++ b/scripts/babbage/staking-example/claim-script-staking-rewards.sh @@ -0,0 +1,101 @@ +#!/usr/bin/env bash + +set -e +# Unofficial bash strict mode. +# See: http://redsymbol.net/articles/unofficial-bash-strict-mode/ +set -u +set -o pipefail + + +export WORK="${WORK:-example/work}" +export CARDANO_NODE_SOCKET_PATH="${CARDANO_NODE_SOCKET_PATH:-example/main.sock}" +export TESTNET_MAGIC="${TESTNET_MAGIC:-42}" +export UTXO_VKEY1="${UTXO_VKEY1:-example/utxo-keys/utxo1.vkey}" +export UTXO_SKEY1="${UTXO_SKEY1:-example/utxo-keys/utxo1.skey}" +export PV=v1 # Plutus Script Version + +utxoaddr=$(cardano-cli address build --testnet-magic "$TESTNET_MAGIC" --payment-verification-key-file "$UTXO_VKEY1") + + +cardano-cli query utxo \ + --address "$utxoaddr" \ + --cardano-mode \ + --testnet-magic "$TESTNET_MAGIC" \ + --out-file "$WORK/utxo-1.json" + +echo "UTxO" +cat "$WORK/utxo-1.json" +echo "" + +txin=$(jq -r 'keys[0]' $WORK/utxo-1.json) +txin1=$(jq -r 'keys[1]' $WORK/utxo-1.json) +txinlovelace=$(jq -r ".[\"$txin\"].value.lovelace" $WORK/utxo-1.json) +txincollateral=$(jq -r 'keys[1]' $WORK/utxo-1.json) +scriptpaymentaddrwithstakecred=$(cardano-cli address build --payment-verification-key-file $UTXO_VKEY1 --stake-script-file "scripts/plutus/scripts/$PV/guess-42-stake.plutus" --testnet-magic 42) +stakingscriptaddr=$(cardano-cli stake-address build --stake-script-file scripts/plutus/scripts/$PV/guess-42-stake.plutus --testnet-magic 42) + +# STEP 1 - Get reward account balance + +cardano-cli query stake-address-info \ + --address "$stakingscriptaddr" \ + --testnet-magic 42 \ + --out-file "$WORK/scriptdelegationstatusrewards.json" + +rewardamt=$(jq -r '.[0].rewardAccountBalance' $WORK/scriptdelegationstatusrewards.json) + +totalspendable=$(expr $rewardamt + $txinlovelace - 289563) +echo "Lovelace at utxo: $txinlovelace" +echo "Rewards: $rewardamt" +echo "Combined: $totalspendable" + +cardano-cli transaction build \ + --babbage-era \ + --testnet-magic "$TESTNET_MAGIC" \ + --change-address "$utxoaddr" \ + --tx-in "$txin" \ + --tx-in "$txin1" \ + --tx-in-collateral "$txincollateral" \ + --tx-out "$scriptpaymentaddrwithstakecred+$totalspendable" \ + --withdrawal "$stakingscriptaddr+$rewardamt" \ + --withdrawal-script-file "scripts/plutus/scripts/$PV/guess-42-stake.plutus" \ + --withdrawal-redeemer-file "scripts/plutus/data/42.redeemer" \ + --protocol-params-file "$WORK/pparams.json" \ + --out-file "$WORK/script-withdrawal.txbody" + +cardano-cli transaction sign \ + --tx-body-file "$WORK/script-withdrawal.txbody" \ + --testnet-magic "$TESTNET_MAGIC" \ + --signing-key-file "$UTXO_SKEY1" \ + --out-file "$WORK/script-withdrawal.tx" + +echo "Submitting withdrawal..." + + + +echo "" +echo "Reward balance before withdrawal" + +cardano-cli query stake-address-info \ + --address "$stakingscriptaddr" \ + --testnet-magic 42 \ + --out-file "$WORK/scriptrewardscheck-before.json" +scriptrewardscheckbefore=$(jq -r '.[0]' $WORK/scriptrewardscheck-before.json) + +echo "$scriptrewardscheckbefore" + +cardano-cli transaction submit \ + --tx-file "$WORK/script-withdrawal.tx" \ + --testnet-magic "$TESTNET_MAGIC" + +echo "" +echo "Waiting 5 seconds...." +sleep 5 +echo "" +cardano-cli query stake-address-info \ + --address "$stakingscriptaddr" \ + --testnet-magic 42 \ + --out-file "$WORK/scriptrewardscheck.json" + +scriptrewardscheck=$(jq -r '.[0]' $WORK/scriptrewardscheck.json) +echo "Checking if script rewards withdrawal was successful...balance should be 0" +echo "$scriptrewardscheck" diff --git a/scripts/babbage/staking-example/register-script-staking-address.sh b/scripts/babbage/staking-example/register-script-staking-address.sh new file mode 100755 index 00000000000..bb622636d40 --- /dev/null +++ b/scripts/babbage/staking-example/register-script-staking-address.sh @@ -0,0 +1,204 @@ +#!/usr/bin/env bash + +set -e +# Unofficial bash strict mode. +# See: http://redsymbol.net/articles/unofficial-bash-strict-mode/ +set -u +set -o pipefail + + +export WORK="${WORK:-example/work}" +export CARDANO_NODE_SOCKET_PATH="${CARDANO_NODE_SOCKET_PATH:-example/main.sock}" +export TESTNET_MAGIC="${TESTNET_MAGIC:-42}" +export UTXO_VKEY1="${UTXO_VKEY1:-example/utxo-keys/utxo1.vkey}" +export UTXO_SKEY1="${UTXO_SKEY1:-example/utxo-keys/utxo1.skey}" +export UTXO_STAKING_VKEY2="${UTXO_STAKING_VKEY2:=example/utxo-keys/utxo2-stake.vkey}" +export PV=v1 # Plutus Script Version + +mkdir -p "$WORK" +nodepool1dir=example/node-spo1 + +# Pool 1 related +poolownerstakekey="example/pools/staking-reward1.vkey" + + +# Generate stake keys +cardano-cli stake-address key-gen \ + --verification-key-file example/utxo-keys/utxo-stake.vkey \ + --signing-key-file example/utxo-keys/utxo-stake.skey + +cardano-cli stake-address key-gen \ + --verification-key-file example/utxo-keys/utxo2-stake.vkey \ + --signing-key-file example/utxo-keys/utxo2-stake.skey + + +# We want to delegagate the stake from UTXO_STAKING_VKEY2 to node pool 1 +utxoaddrwithstaking=$(cardano-cli address build --payment-verification-key-file "$UTXO_VKEY2" --stake-verification-key-file "$UTXO_STAKING_VKEY2" --testnet-magic 42) +keystakeaddress=$(cardano-cli stake-address build --stake-verification-key-file "$UTXO_STAKING_VKEY2" --testnet-magic 42) + +utxoaddr=$(cardano-cli address build --testnet-magic "$TESTNET_MAGIC" --payment-verification-key-file "$UTXO_VKEY1") + + +cardano-cli query utxo \ + --address "$utxoaddr" \ + --cardano-mode \ + --testnet-magic "$TESTNET_MAGIC" \ + --out-file "$WORK/utxo-1.json" + +echo "UTxO" +cat "$WORK/utxo-1.json" +echo "" + +txin=$(jq -r 'keys[]' "$WORK/utxo-1.json") +lovelaceattxin=$(jq -r ".[\"$txin\"].value.lovelace" "$WORK/utxo-1.json") +lovelaceattxindiv3=$((lovelaceattxin / 3)) +scriptpaymentaddrwithstakecred=$(cardano-cli address build --payment-verification-key-file "$UTXO_VKEY1" --stake-script-file "scripts/plutus/scripts/$PV/guess-42-stake.plutus" --testnet-magic 42) + +# Node Pool 1 +poolcoldkey="example/pools/cold1.vkey" + +# Delegate Plutus staking script address to stake pool + +# Update UTxO again + +cardano-cli query utxo \ + --address "$utxoaddr" \ + --cardano-mode \ + --testnet-magic "$TESTNET_MAGIC" \ + --out-file "$WORK/utxo-2.json" + +cat "$WORK/utxo-2.json" + +txinupdated2=$(jq -r 'keys[0]' "$WORK/utxo-2.json") +echo "" +echo "Selected txin: $txinupdated2" +# Step 1: Create registration certificate for the staking script + +# We also create collateral. + +txin=$(jq -r 'keys[]' "$WORK/utxo-2.json") +lovelaceattxin=$(jq -r ".[\"$txin\"].value.lovelace" "$WORK/utxo-2.json") +lovelaceattxindiv3=$((lovelaceattxin / 3)) + +cardano-cli stake-address registration-certificate \ + --stake-script-file "scripts/plutus/scripts/$PV/guess-42-stake.plutus" \ + --out-file "$WORK/script.regcert" + +cardano-cli transaction build \ + --babbage-era \ + --testnet-magic "$TESTNET_MAGIC" \ + --change-address "$utxoaddr" \ + --tx-in "$txin" \ + --tx-out "$scriptpaymentaddrwithstakecred+999978" \ + --tx-out "$utxoaddr+$lovelaceattxindiv3" \ + --witness-override 3 \ + --certificate-file "$WORK/script.regcert" \ + --out-file "$WORK/script-registration-cert.txbody" + +cardano-cli transaction sign \ + --tx-body-file "$WORK/script-registration-cert.txbody" \ + --testnet-magic "$TESTNET_MAGIC" \ + --signing-key-file "$UTXO_SKEY1" \ + --out-file "$WORK/script-registration-cert.tx" + +cardano-cli transaction submit \ + --tx-file "$WORK/script-registration-cert.tx" \ + --testnet-magic "$TESTNET_MAGIC" + +stakingscriptaddr=$(cardano-cli stake-address build --stake-script-file scripts/plutus/scripts/$PV/guess-42-stake.plutus --testnet-magic 42) + +echo "" +echo "Staking script address" +echo "$stakingscriptaddr" +echo "Waiting 10 seconds..." +sleep 10 +echo "Check to see if the SCRIPT staking address was successfully REGISTERED" + +cardano-cli query stake-address-info \ + --address "$stakingscriptaddr" \ + --testnet-magic 42 \ + --out-file "$WORK/scriptregistration.json" + +registeredscr=$(jq -r '.[0]' "$WORK/scriptregistration.json") +echo "$registeredscr" + +# We have successfully registered our script staking address. + +# We need to delegate the script staking address + +cardano-cli stake-address delegation-certificate \ + --stake-script-file "scripts/plutus/scripts/$PV/guess-42-stake.plutus" \ + --cold-verification-key-file "$poolcoldkey" \ + --out-file "$WORK/script.delegcert" + +cardano-cli query protocol-parameters --testnet-magic "$TESTNET_MAGIC" --out-file "$WORK/pparams.json" + +# We also need collateral + +cardano-cli query utxo \ + --address "$utxoaddr" \ + --cardano-mode \ + --testnet-magic "$TESTNET_MAGIC" \ + --out-file "$WORK/utxo-2.json" + +cat "$WORK/utxo-2.json" + +txinupdated3=$(jq -r 'keys[0]' "$WORK/utxo-2.json") +txincollateral=$(jq -r 'keys[1]' "$WORK/utxo-2.json") +echo "" +echo "Selected txin: $txinupdated2" + +cardano-cli transaction build \ + --babbage-era \ + --testnet-magic "$TESTNET_MAGIC" \ + --change-address "$utxoaddr" \ + --tx-in "$txinupdated3" \ + --tx-in-collateral "$txincollateral" \ + --tx-out "$scriptpaymentaddrwithstakecred+999978" \ + --witness-override 3 \ + --certificate-file "$WORK/script.delegcert" \ + --certificate-script-file "scripts/plutus/scripts/$PV/guess-42-stake.plutus" \ + --certificate-redeemer-file "scripts/plutus/data/42.redeemer" \ + --protocol-params-file "$WORK/pparams.json" \ + --out-file "$WORK/script-delegation-cert.txbody" + +cardano-cli transaction sign \ + --tx-body-file "$WORK/script-delegation-cert.txbody" \ + --testnet-magic "$TESTNET_MAGIC" \ + --signing-key-file "$UTXO_SKEY1" \ + --out-file "$WORK/script-delegation-cert.tx" + +echo "Submitting staking script delegation certificate..." + +cardano-cli transaction submit \ + --tx-file "$WORK/script-delegation-cert.tx" \ + --testnet-magic "$TESTNET_MAGIC" + +echo "" +echo "!!!!!!!!!!!!" +echo "You need to wait 2 epochs after the current epoch for rewards" +cardano-cli query tip --testnet-magic 42 +echo "!!!!!!!!!!!!" +echo "" +echo "Waiting 10 seconds..." +sleep 10 +echo "Check to see if staking script was successfully delegated..." + + +cardano-cli query stake-address-info \ + --address "$stakingscriptaddr" \ + --testnet-magic 42 \ + --out-file "$WORK/scriptdelegation.json" + +delegatedscript=$(jq -r '.[0]' "$WORK/scriptdelegation.json") +echo "$delegatedscript" +echo "" +echo "Staking script payment address" +echo "$scriptpaymentaddrwithstakecred" +echoi "" +echo "If a staking script address is displayed after this message, the registration of the Plutus staking script was successful" +echo "$stakingscriptaddr" +echo "" +echo "Use the following command to check when rewards have been paid to the staking script address" +echo "" +echo "cardano-cli query stake-address-info --testnet-magic 42 --address $stakingscriptaddr" From 4fbffa61a37be21e4a896fa5e4896392156caeb3 Mon Sep 17 00:00:00 2001 From: Jordan Millar Date: Fri, 17 Jun 2022 11:57:01 -0500 Subject: [PATCH 08/15] Update old register-stake-pool command --- scripts/plutus/staking-example/register-stake-pool.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/scripts/plutus/staking-example/register-stake-pool.sh b/scripts/plutus/staking-example/register-stake-pool.sh index f2b87d5585e..3d4dd3549d3 100755 --- a/scripts/plutus/staking-example/register-stake-pool.sh +++ b/scripts/plutus/staking-example/register-stake-pool.sh @@ -415,6 +415,9 @@ cardano-cli transaction submit \ --tx-file "$WORK/script-delegation-cert.tx" \ --testnet-magic "$TESTNET_MAGIC" +echo "Need to wait 2 epochs after current epoch for rewards" +cardano-cli query tip --testnet-magic 42 + echo "Waiting 10 seconds..." sleep 10 echo "Check to see if staking script was successfully delegated..." From 5a2b2d09a2bece5c1d05ebd1a129162a0a9e7449 Mon Sep 17 00:00:00 2001 From: Jordan Millar Date: Fri, 17 Jun 2022 13:00:37 -0500 Subject: [PATCH 09/15] Adjust register-and-deglegate-script-staking-address.sh to use a plutus certifying script --- ...er-and-delegate-script-staking-address.sh} | 78 +++++++++++++------ scripts/plutus/scripts/v2/stake-script.plutus | 5 ++ 2 files changed, 60 insertions(+), 23 deletions(-) rename scripts/babbage/staking-example/{register-script-staking-address.sh => register-and-delegate-script-staking-address.sh} (73%) create mode 100644 scripts/plutus/scripts/v2/stake-script.plutus diff --git a/scripts/babbage/staking-example/register-script-staking-address.sh b/scripts/babbage/staking-example/register-and-delegate-script-staking-address.sh similarity index 73% rename from scripts/babbage/staking-example/register-script-staking-address.sh rename to scripts/babbage/staking-example/register-and-delegate-script-staking-address.sh index bb622636d40..9609342be6f 100755 --- a/scripts/babbage/staking-example/register-script-staking-address.sh +++ b/scripts/babbage/staking-example/register-and-delegate-script-staking-address.sh @@ -13,7 +13,7 @@ export TESTNET_MAGIC="${TESTNET_MAGIC:-42}" export UTXO_VKEY1="${UTXO_VKEY1:-example/utxo-keys/utxo1.vkey}" export UTXO_SKEY1="${UTXO_SKEY1:-example/utxo-keys/utxo1.skey}" export UTXO_STAKING_VKEY2="${UTXO_STAKING_VKEY2:=example/utxo-keys/utxo2-stake.vkey}" -export PV=v1 # Plutus Script Version +export PV=v2 # Plutus Script Version mkdir -p "$WORK" nodepool1dir=example/node-spo1 @@ -52,15 +52,46 @@ echo "" txin=$(jq -r 'keys[]' "$WORK/utxo-1.json") lovelaceattxin=$(jq -r ".[\"$txin\"].value.lovelace" "$WORK/utxo-1.json") lovelaceattxindiv3=$((lovelaceattxin / 3)) -scriptpaymentaddrwithstakecred=$(cardano-cli address build --payment-verification-key-file "$UTXO_VKEY1" --stake-script-file "scripts/plutus/scripts/$PV/guess-42-stake.plutus" --testnet-magic 42) +certifyingscript="scripts/plutus/scripts/v2/stake-script.plutus" +scriptpaymentaddrwithstakecred=$(cardano-cli address build --payment-verification-key-file "$UTXO_VKEY1" --stake-script-file $certifyingscript --testnet-magic 42) +dummyaddress=addr_test1vpqgspvmh6m2m5pwangvdg499srfzre2dd96qq57nlnw6yctpasy4 # Node Pool 1 poolcoldkey="example/pools/cold1.vkey" -# Delegate Plutus staking script address to stake pool +# Delegate Plutus staking script address to stake pool. -# Update UTxO again +cardano-cli query protocol-parameters --testnet-magic "$TESTNET_MAGIC" --out-file "$WORK/pparams.json" + +# Step 1: Create certifying reference script at tx out +cardano-cli transaction build \ + --babbage-era \ + --cardano-mode \ + --testnet-magic "$TESTNET_MAGIC" \ + --change-address "$utxoaddr" \ + --tx-in "$txin" \ + --tx-out "$dummyaddress+$lovelaceattxindiv3" \ + --tx-out-reference-script-file "$certifyingscript" \ + --protocol-params-file "$WORK/pparams.json" \ + --out-file "$WORK/create-stake-reference-script.body" + +cardano-cli transaction sign \ + --tx-body-file "$WORK/create-stake-reference-script.body" \ + --testnet-magic "$TESTNET_MAGIC" \ + --signing-key-file "$UTXO_SKEY1" \ + --out-file "$WORK/create-stake-reference-script.tx" + +cardano-cli transaction submit \ + --tx-file "$WORK/create-stake-reference-script.tx" \ + --testnet-magic "$TESTNET_MAGIC" + +echo "" +echo "Wait 5 seconds..." +echo "" +sleep 5 + +# Step 2: Create and submit registration certificate for the staking script cardano-cli query utxo \ --address "$utxoaddr" \ --cardano-mode \ @@ -68,29 +99,23 @@ cardano-cli query utxo \ --out-file "$WORK/utxo-2.json" cat "$WORK/utxo-2.json" - -txinupdated2=$(jq -r 'keys[0]' "$WORK/utxo-2.json") -echo "" -echo "Selected txin: $txinupdated2" -# Step 1: Create registration certificate for the staking script - # We also create collateral. -txin=$(jq -r 'keys[]' "$WORK/utxo-2.json") -lovelaceattxin=$(jq -r ".[\"$txin\"].value.lovelace" "$WORK/utxo-2.json") -lovelaceattxindiv3=$((lovelaceattxin / 3)) +txin2=$(jq -r 'keys[0]' "$WORK/utxo-2.json") +lovelaceattxin2=$(jq -r ".[\"$txin2\"].value.lovelace" "$WORK/utxo-2.json") +lovelaceattxin2div3=$(($lovelaceattxin2 / 3)) cardano-cli stake-address registration-certificate \ - --stake-script-file "scripts/plutus/scripts/$PV/guess-42-stake.plutus" \ + --stake-script-file "$certifyingscript" \ --out-file "$WORK/script.regcert" cardano-cli transaction build \ --babbage-era \ --testnet-magic "$TESTNET_MAGIC" \ --change-address "$utxoaddr" \ - --tx-in "$txin" \ + --tx-in "$txin2" \ --tx-out "$scriptpaymentaddrwithstakecred+999978" \ - --tx-out "$utxoaddr+$lovelaceattxindiv3" \ + --tx-out "$utxoaddr+$lovelaceattxin2div3" \ --witness-override 3 \ --certificate-file "$WORK/script.regcert" \ --out-file "$WORK/script-registration-cert.txbody" @@ -105,7 +130,7 @@ cardano-cli transaction submit \ --tx-file "$WORK/script-registration-cert.tx" \ --testnet-magic "$TESTNET_MAGIC" -stakingscriptaddr=$(cardano-cli stake-address build --stake-script-file scripts/plutus/scripts/$PV/guess-42-stake.plutus --testnet-magic 42) +stakingscriptaddr=$(cardano-cli stake-address build --stake-script-file $certifyingscript --testnet-magic 42) echo "" echo "Staking script address" @@ -126,12 +151,18 @@ echo "$registeredscr" # We need to delegate the script staking address +# Retrieve plutus reference script tx in +cardano-cli query utxo --address "$dummyaddress" --cardano-mode --testnet-magic "$TESTNET_MAGIC" --out-file $WORK/dummy-address-ref-script.json +cat $WORK/dummy-address-ref-script.json +# Get reference script txin +plutusreferencescripttxin=$(jq -r 'keys[0]' $WORK/dummy-address-ref-script.json) + + cardano-cli stake-address delegation-certificate \ - --stake-script-file "scripts/plutus/scripts/$PV/guess-42-stake.plutus" \ + --stake-script-file "$certifyingscript" \ --cold-verification-key-file "$poolcoldkey" \ --out-file "$WORK/script.delegcert" -cardano-cli query protocol-parameters --testnet-magic "$TESTNET_MAGIC" --out-file "$WORK/pparams.json" # We also need collateral @@ -146,7 +177,7 @@ cat "$WORK/utxo-2.json" txinupdated3=$(jq -r 'keys[0]' "$WORK/utxo-2.json") txincollateral=$(jq -r 'keys[1]' "$WORK/utxo-2.json") echo "" -echo "Selected txin: $txinupdated2" +echo "Selected txin: $txinupdated3" cardano-cli transaction build \ --babbage-era \ @@ -157,8 +188,9 @@ cardano-cli transaction build \ --tx-out "$scriptpaymentaddrwithstakecred+999978" \ --witness-override 3 \ --certificate-file "$WORK/script.delegcert" \ - --certificate-script-file "scripts/plutus/scripts/$PV/guess-42-stake.plutus" \ - --certificate-redeemer-file "scripts/plutus/data/42.redeemer" \ + --certificate-tx-in-reference "$plutusreferencescripttxin" \ + --certificate-plutus-script-v2 \ + --certificate-reference-tx-in-redeemer-file "scripts/plutus/data/42.redeemer" \ --protocol-params-file "$WORK/pparams.json" \ --out-file "$WORK/script-delegation-cert.txbody" @@ -195,7 +227,7 @@ echo "$delegatedscript" echo "" echo "Staking script payment address" echo "$scriptpaymentaddrwithstakecred" -echoi "" +echo "" echo "If a staking script address is displayed after this message, the registration of the Plutus staking script was successful" echo "$stakingscriptaddr" echo "" diff --git a/scripts/plutus/scripts/v2/stake-script.plutus b/scripts/plutus/scripts/v2/stake-script.plutus new file mode 100644 index 00000000000..80b516e064c --- /dev/null +++ b/scripts/plutus/scripts/v2/stake-script.plutus @@ -0,0 +1,5 @@ +{ + "type": "PlutusScriptV2", + "description": "", + "cborHex": "5907655907620100003232323232323232323232323232332232323232322232325335320193333573466e1cd55cea80124000466442466002006004646464646464646464646464646666ae68cdc39aab9d500c480008cccccccccccc88888888888848cccccccccccc00403403002c02802402001c01801401000c008cd4050054d5d0a80619a80a00a9aba1500b33501401635742a014666aa030eb9405cd5d0a804999aa80c3ae501735742a01066a02803e6ae85401cccd54060081d69aba150063232323333573466e1cd55cea801240004664424660020060046464646666ae68cdc39aab9d5002480008cc8848cc00400c008cd40a9d69aba15002302b357426ae8940088c98c80b4cd5ce01701681589aab9e5001137540026ae854008c8c8c8cccd5cd19b8735573aa004900011991091980080180119a8153ad35742a00460566ae84d5d1280111931901699ab9c02e02d02b135573ca00226ea8004d5d09aba2500223263202933573805405204e26aae7940044dd50009aba1500533501475c6ae854010ccd540600708004d5d0a801999aa80c3ae200135742a004603c6ae84d5d1280111931901299ab9c026025023135744a00226ae8940044d5d1280089aba25001135744a00226ae8940044d5d1280089aba25001135744a00226ae8940044d55cf280089baa00135742a004601c6ae84d5d1280111931900b99ab9c018017015101613263201633573892010350543500016135573ca00226ea800448c88c008dd6000990009aa80a911999aab9f0012500a233500930043574200460066ae880080508c8c8cccd5cd19b8735573aa004900011991091980080180118061aba150023005357426ae8940088c98c8050cd5ce00a80a00909aab9e5001137540024646464646666ae68cdc39aab9d5004480008cccc888848cccc00401401000c008c8c8c8cccd5cd19b8735573aa0049000119910919800801801180a9aba1500233500f014357426ae8940088c98c8064cd5ce00d00c80b89aab9e5001137540026ae854010ccd54021d728039aba150033232323333573466e1d4005200423212223002004357426aae79400c8cccd5cd19b875002480088c84888c004010dd71aba135573ca00846666ae68cdc3a801a400042444006464c6403666ae7007006c06406005c4d55cea80089baa00135742a00466a016eb8d5d09aba2500223263201533573802c02a02626ae8940044d5d1280089aab9e500113754002266aa002eb9d6889119118011bab00132001355012223233335573e0044a010466a00e66442466002006004600c6aae754008c014d55cf280118021aba200301213574200222440042442446600200800624464646666ae68cdc3a800a40004642446004006600a6ae84d55cf280191999ab9a3370ea0049001109100091931900819ab9c01101000e00d135573aa00226ea80048c8c8cccd5cd19b875001480188c848888c010014c01cd5d09aab9e500323333573466e1d400920042321222230020053009357426aae7940108cccd5cd19b875003480088c848888c004014c01cd5d09aab9e500523333573466e1d40112000232122223003005375c6ae84d55cf280311931900819ab9c01101000e00d00c00b135573aa00226ea80048c8c8cccd5cd19b8735573aa004900011991091980080180118029aba15002375a6ae84d5d1280111931900619ab9c00d00c00a135573ca00226ea80048c8cccd5cd19b8735573aa002900011bae357426aae7940088c98c8028cd5ce00580500409baa001232323232323333573466e1d4005200c21222222200323333573466e1d4009200a21222222200423333573466e1d400d2008233221222222233001009008375c6ae854014dd69aba135744a00a46666ae68cdc3a8022400c4664424444444660040120106eb8d5d0a8039bae357426ae89401c8cccd5cd19b875005480108cc8848888888cc018024020c030d5d0a8049bae357426ae8940248cccd5cd19b875006480088c848888888c01c020c034d5d09aab9e500b23333573466e1d401d2000232122222223005008300e357426aae7940308c98c804ccd5ce00a00980880800780700680600589aab9d5004135573ca00626aae7940084d55cf280089baa0012323232323333573466e1d400520022333222122333001005004003375a6ae854010dd69aba15003375a6ae84d5d1280191999ab9a3370ea0049000119091180100198041aba135573ca00c464c6401866ae700340300280244d55cea80189aba25001135573ca00226ea80048c8c8cccd5cd19b875001480088c8488c00400cdd71aba135573ca00646666ae68cdc3a8012400046424460040066eb8d5d09aab9e500423263200933573801401200e00c26aae7540044dd500089119191999ab9a3370ea00290021091100091999ab9a3370ea00490011190911180180218031aba135573ca00846666ae68cdc3a801a400042444004464c6401466ae7002c02802001c0184d55cea80089baa0012323333573466e1d40052002200723333573466e1d40092000212200123263200633573800e00c00800626aae74dd5000a4c2400292010350543100122002112323001001223300330020020011" +} From 54a543716e5383654a074ae2b9b87406a818b1a5 Mon Sep 17 00:00:00 2001 From: Jordan Millar Date: Fri, 17 Jun 2022 14:13:00 -0500 Subject: [PATCH 10/15] Update scripts/babbage/staking-example/claim-script-staking-rewards.sh to use a withdrawal reference script --- .../claim-script-staking-rewards.sh | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/scripts/babbage/staking-example/claim-script-staking-rewards.sh b/scripts/babbage/staking-example/claim-script-staking-rewards.sh index 6ed2faa3625..cb1ca50f208 100755 --- a/scripts/babbage/staking-example/claim-script-staking-rewards.sh +++ b/scripts/babbage/staking-example/claim-script-staking-rewards.sh @@ -31,8 +31,9 @@ txin=$(jq -r 'keys[0]' $WORK/utxo-1.json) txin1=$(jq -r 'keys[1]' $WORK/utxo-1.json) txinlovelace=$(jq -r ".[\"$txin\"].value.lovelace" $WORK/utxo-1.json) txincollateral=$(jq -r 'keys[1]' $WORK/utxo-1.json) -scriptpaymentaddrwithstakecred=$(cardano-cli address build --payment-verification-key-file $UTXO_VKEY1 --stake-script-file "scripts/plutus/scripts/$PV/guess-42-stake.plutus" --testnet-magic 42) -stakingscriptaddr=$(cardano-cli stake-address build --stake-script-file scripts/plutus/scripts/$PV/guess-42-stake.plutus --testnet-magic 42) +withdrawingscript="scripts/plutus/scripts/v2/stake-script.plutus" +scriptpaymentaddrwithstakecred=$(cardano-cli address build --payment-verification-key-file $UTXO_VKEY1 --stake-script-file "$withdrawingscript" --testnet-magic 42) +stakingscriptaddr=$(cardano-cli stake-address build --stake-script-file $withdrawingscript --testnet-magic 42) # STEP 1 - Get reward account balance @@ -48,6 +49,11 @@ echo "Lovelace at utxo: $txinlovelace" echo "Rewards: $rewardamt" echo "Combined: $totalspendable" +# Get plutus script reference input + +plutusreferencescripttxin=$(jq -r 'keys[0]' $WORK/dummy-address-ref-script.json) + + cardano-cli transaction build \ --babbage-era \ --testnet-magic "$TESTNET_MAGIC" \ @@ -57,8 +63,9 @@ cardano-cli transaction build \ --tx-in-collateral "$txincollateral" \ --tx-out "$scriptpaymentaddrwithstakecred+$totalspendable" \ --withdrawal "$stakingscriptaddr+$rewardamt" \ - --withdrawal-script-file "scripts/plutus/scripts/$PV/guess-42-stake.plutus" \ - --withdrawal-redeemer-file "scripts/plutus/data/42.redeemer" \ + --withdrawal-tx-in-reference "$plutusreferencescripttxin" \ + --withdrawal-plutus-script-v2 \ + --withdrawal-reference-tx-in-redeemer-file "scripts/plutus/data/42.redeemer" \ --protocol-params-file "$WORK/pparams.json" \ --out-file "$WORK/script-withdrawal.txbody" From 7b7c714aefaa5ad9c2974f77f340f7d198d5375d Mon Sep 17 00:00:00 2001 From: Jordan Millar Date: Sat, 18 Jun 2022 17:23:17 -0500 Subject: [PATCH 11/15] Add documentation explaining how to use a reference certifying script --- .../babbage-certifying-script-example.md | 59 +++++++++++++++++++ ...ter-and-delegate-script-staking-address.sh | 2 +- 2 files changed, 60 insertions(+), 1 deletion(-) create mode 100644 doc/reference/plutus/babbage-certifying-script-example.md diff --git a/doc/reference/plutus/babbage-certifying-script-example.md b/doc/reference/plutus/babbage-certifying-script-example.md new file mode 100644 index 00000000000..73c506fcec6 --- /dev/null +++ b/doc/reference/plutus/babbage-certifying-script-example.md @@ -0,0 +1,59 @@ +# Babbage reference certifying script example + +## Babbage reference certifying plutus script example + +For an overview of reference script usuage in the Babbage era, please see [here](babbage-script-example.md). + +In this example we will delegate stake at a plutus script address to an SPO using a plutus reference script. This is achieved when we run the [register-and-deglegate-script-staking-address.sh](../../../scripts/babbage/staking-example/register-and-deglegate-script-staking-address.sh) script. Below we will outline the key parts + +First we create the reference script at a tx output as usual with the following transaction: + +```bash +cardano-cli transaction build \ + --babbage-era \ + --cardano-mode \ + --testnet-magic "$TESTNET_MAGIC" \ + --change-address "$utxoaddr" \ + --tx-in "$txin" \ + --tx-out "$scriptpaymentaddrwithstakecred+999978" \ + --tx-out "$dummyaddress+$lovelaceattxindiv3" \ + --tx-out-reference-script-file "$certifyingscript" \ + --protocol-params-file "$WORK/pparams.json" \ + --out-file "$WORK/create-stake-reference-script.body" +``` + +Now that we have out certifying reference script at a tx output and we have funded the script address in question. We then register our script stake address as usual. We can now use our reference input to validate the delegation of our stake that exists at our script address with the following tx: + +```bash +cardano-cli transaction build \ + --babbage-era \ + --testnet-magic "$TESTNET_MAGIC" \ + --change-address "$utxoaddr" \ + --tx-in "$txinupdated3" \ + --tx-in-collateral "$txincollateral" \ + --tx-out "$scriptpaymentaddrwithstakecred+999978" \ + --witness-override 3 \ + --certificate-file "$WORK/script.delegcert" \ + --certificate-tx-in-reference "$plutusreferencescripttxin" \ + --certificate-plutus-script-v2 \ + --certificate-reference-tx-in-redeemer-file "scripts/plutus/data/42.redeemer" \ + --protocol-params-file "$WORK/pparams.json" \ + --out-file "$WORK/script-delegation-cert.txbody" +``` + +Once this transaction is successfully submitted, we must wait 2 epochs until rewards begin to accumulate at the script staking address. The shell script helpfully output the cli command needed to check rewards at the staking address. The output will eventually look something like the following: + +```bash +cardano-cli query stake-address-info --testnet-magic 42 --address stake_test17zwga8d8lq0re2gysheja0hunqfhezkzvzs89gqvf2h3gtgtc7vzc + +[ + { + "address": "stake_test17zwga8d8lq0re2gysheja0hunqfhezkzvzs89gqvf2h3gtgtc7vzc", + "delegation": "pool1dg6f0r6gwqfath8zspxfhcnpjxnqr5q0wjupe62f7st4j2am4x3", + "rewardAccountBalance": 25142 + } +] +``` + + + diff --git a/scripts/babbage/staking-example/register-and-delegate-script-staking-address.sh b/scripts/babbage/staking-example/register-and-delegate-script-staking-address.sh index 9609342be6f..2edd6a4b82b 100755 --- a/scripts/babbage/staking-example/register-and-delegate-script-staking-address.sh +++ b/scripts/babbage/staking-example/register-and-delegate-script-staking-address.sh @@ -71,6 +71,7 @@ cardano-cli transaction build \ --testnet-magic "$TESTNET_MAGIC" \ --change-address "$utxoaddr" \ --tx-in "$txin" \ + --tx-out "$scriptpaymentaddrwithstakecred+999978" \ --tx-out "$dummyaddress+$lovelaceattxindiv3" \ --tx-out-reference-script-file "$certifyingscript" \ --protocol-params-file "$WORK/pparams.json" \ @@ -114,7 +115,6 @@ cardano-cli transaction build \ --testnet-magic "$TESTNET_MAGIC" \ --change-address "$utxoaddr" \ --tx-in "$txin2" \ - --tx-out "$scriptpaymentaddrwithstakecred+999978" \ --tx-out "$utxoaddr+$lovelaceattxin2div3" \ --witness-override 3 \ --certificate-file "$WORK/script.regcert" \ From a2b6b9432a306683d0a63a3b6ba6cdc343a295bf Mon Sep 17 00:00:00 2001 From: Jordan Millar Date: Sat, 18 Jun 2022 17:52:00 -0500 Subject: [PATCH 12/15] Add documentation explaining how to use a withdrawal reference script --- .../babbage-withdrawing-script-example.md | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 doc/reference/plutus/babbage-withdrawing-script-example.md diff --git a/doc/reference/plutus/babbage-withdrawing-script-example.md b/doc/reference/plutus/babbage-withdrawing-script-example.md new file mode 100644 index 00000000000..1f431f141b1 --- /dev/null +++ b/doc/reference/plutus/babbage-withdrawing-script-example.md @@ -0,0 +1,43 @@ +# Babbage reference withdrawing script example + +## Babbage reference withdrawing plutus script example + +For an overview of reference script usuage in the Babbage era, please see [here](babbage-script-example.md). + +In this example we will withdraw our rewards from a plutus script address using a plutus reference script. We must first run the [register-and-deglegate-script-staking-address.sh](../../../scripts/babbage/staking-example/register-and-deglegate-script-staking-address.sh) script in order to register and delegate the stake at our plutus script address. We will briefly walk through the [claim-script-staking-rewards.sh](../../../scripts/babbage/staking-example/claim-script-staking-rewards.sh) script that automatically does this all for us. + +Now that we already have our certifying reference script at a tx output so we can use our reference input again to validate the withdrawal of our rewards at our plutus script address with the following tx: + +```bash +cardano-cli transaction build \ + --babbage-era \ + --testnet-magic "$TESTNET_MAGIC" \ + --change-address "$utxoaddr" \ + --tx-in "$txin" \ + --tx-in "$txin1" \ + --tx-in-collateral "$txincollateral" \ + --tx-out "$scriptpaymentaddrwithstakecred+$totalspendable" \ + --withdrawal "$stakingscriptaddr+$rewardamt" \ + --withdrawal-tx-in-reference "$plutusreferencescripttxin" \ + --withdrawal-plutus-script-v2 \ + --withdrawal-reference-tx-in-redeemer-file "scripts/plutus/data/42.redeemer" \ + --protocol-params-file "$WORK/pparams.json" \ + --out-file "$WORK/script-withdrawal.txbody" +``` + +After this transaction is submitted, if successful, we should have 0 rewards at our plutus staking script address: + +```bash +cardano-cli query stake-address-info --testnet-magic 42 --address stake_test17zwga8d8lq0re2gysheja0hunqfhezkzvzs89gqvf2h3gtgtc7vzc + +[ + { + "address": "stake_test17zwga8d8lq0re2gysheja0hunqfhezkzvzs89gqvf2h3gtgtc7vzc", + "delegation": "pool1dg6f0r6gwqfath8zspxfhcnpjxnqr5q0wjupe62f7st4j2am4x3", + "rewardAccountBalance": 0 + } +] +``` + + + From 1d1ec89e37f1fdffa20c07ff6230109fe3a3d5f4 Mon Sep 17 00:00:00 2001 From: Jordan Millar Date: Sat, 18 Jun 2022 18:26:28 -0500 Subject: [PATCH 13/15] Update babbage-script-example.md to include a reference script at our target read only reference input --- doc/reference/plutus/babbage-script-example.md | 1 + scripts/plutus/example-babbage-script-usage.sh | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/doc/reference/plutus/babbage-script-example.md b/doc/reference/plutus/babbage-script-example.md index 036d7ed9d74..1041f58773d 100644 --- a/doc/reference/plutus/babbage-script-example.md +++ b/doc/reference/plutus/babbage-script-example.md @@ -77,6 +77,7 @@ cardano-cli transaction build \ --change-address "$utxoaddr" \ --tx-in "$txin" \ --tx-out "$readonlyaddress+$lovelaceattxindiv6" \ + --tx-out-reference-script-file "$plutusstakescript" \ --tx-out-inline-datum-file "$datumfilepath" \ --tx-out "$utxoaddr+$lovelace" \ --tx-out "$plutusspendingscriptaddr+$lovelace" \ diff --git a/scripts/plutus/example-babbage-script-usage.sh b/scripts/plutus/example-babbage-script-usage.sh index f7d26e8e2b9..e2e286a28b2 100755 --- a/scripts/plutus/example-babbage-script-usage.sh +++ b/scripts/plutus/example-babbage-script-usage.sh @@ -21,6 +21,7 @@ ls -al "$CARDANO_NODE_SOCKET_PATH" plutusspendingscript="$BASE/scripts/plutus/scripts/v2/required-redeemer.plutus" plutusmintingscript="$BASE/scripts/plutus/scripts/v2/minting-script.plutus" +plutusstakescript="scripts/plutus/scripts/v2/stake-script.plutus" mintpolicyid=$(cardano-cli transaction policyid --script-file $plutusmintingscript) ## This datum hash is the hash of the untyped 42 scriptdatumhash="9e1199a988ba72ffd6e9c269cadb3b53b5f360ff99f112d9b2ee30c4d74ad88b" @@ -65,6 +66,7 @@ $CARDANO_CLI transaction build \ --change-address "$utxoaddr" \ --tx-in "$txin" \ --tx-out "$readonlyaddress+$lovelaceattxindiv6" \ + --tx-out-reference-script-file "$plutusstakescript" \ --tx-out-inline-datum-file "$datumfilepath" \ --tx-out "$utxoaddr+$lovelaceattxindiv6" \ --tx-out "$plutusspendingscriptaddr+$lovelaceattxindiv6" \ @@ -161,7 +163,7 @@ $CARDANO_CLI transaction build \ --cardano-mode \ --testnet-magic "$TESTNET_MAGIC" \ --change-address "$utxoaddr" \ - --read-only-tx-in-reference "$readonlyrefinput" \ + --read-only-tx-in-reference "$readonlyrefinput" \ --tx-in "$txin1" \ --tx-in-collateral "$txinCollateral" \ --out-file "$WORK/test-alonzo-ref-script.body" \ From d079fb75c6b4175d0f2117934804cea2a9fdb337 Mon Sep 17 00:00:00 2001 From: Jordan Millar Date: Tue, 21 Jun 2022 08:42:10 -0500 Subject: [PATCH 14/15] Move example-babbage-script-usage.sh to scripts/babbage/ dir --- scripts/{plutus => babbage}/example-babbage-script-usage.sh | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename scripts/{plutus => babbage}/example-babbage-script-usage.sh (100%) diff --git a/scripts/plutus/example-babbage-script-usage.sh b/scripts/babbage/example-babbage-script-usage.sh similarity index 100% rename from scripts/plutus/example-babbage-script-usage.sh rename to scripts/babbage/example-babbage-script-usage.sh From 024e4bc59c5ba13d4e8f8763e333f1bc609ec595 Mon Sep 17 00:00:00 2001 From: Jordan Millar Date: Tue, 21 Jun 2022 09:21:55 -0500 Subject: [PATCH 15/15] Adjust babbage script documentation --- doc/reference/plutus/babbage-certifying-script-example.md | 2 +- doc/reference/plutus/babbage-script-example.md | 8 ++++---- .../plutus/babbage-withdrawing-script-example.md | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/doc/reference/plutus/babbage-certifying-script-example.md b/doc/reference/plutus/babbage-certifying-script-example.md index 73c506fcec6..47f6b773a09 100644 --- a/doc/reference/plutus/babbage-certifying-script-example.md +++ b/doc/reference/plutus/babbage-certifying-script-example.md @@ -4,7 +4,7 @@ For an overview of reference script usuage in the Babbage era, please see [here](babbage-script-example.md). -In this example we will delegate stake at a plutus script address to an SPO using a plutus reference script. This is achieved when we run the [register-and-deglegate-script-staking-address.sh](../../../scripts/babbage/staking-example/register-and-deglegate-script-staking-address.sh) script. Below we will outline the key parts +In this example we will delegate stake at a plutus script address to an SPO using a plutus reference script. This is achieved when we run the [register-and-delegate-script-staking-address.sh](../../../scripts/babbage/staking-example/register-and-delegate-script-staking-address.sh) script. Below we will outline the key parts First we create the reference script at a tx output as usual with the following transaction: diff --git a/doc/reference/plutus/babbage-script-example.md b/doc/reference/plutus/babbage-script-example.md index 1041f58773d..45d501a2219 100644 --- a/doc/reference/plutus/babbage-script-example.md +++ b/doc/reference/plutus/babbage-script-example.md @@ -14,7 +14,7 @@ In the case where we are not using a reference input to reference another transa ### An example of using a Plutus V2 reference script -Below is an example that shows how to use a reference Plutus spending script with an inline datum and a reference minting script. Here we discuss a [shell script example of how to use a reference script to spend a tx input and a reference minting script to mint tokens](scripts/plutus/example-babbage-script-usage.sh). This is a step-by-step process involving: +Below is an example that shows how to use a reference Plutus spending script with an inline datum and a reference minting script. Here we discuss a [shell script example of how to use a reference script to spend a tx input and a reference minting script to mint tokens](../../../scripts/babbage/example-babbage-script-usage.sh). This is a step-by-step process involving: + the creation of the `Required Redeemer` Plutus txin script + the creation of the `Required Redeemer` Plutus script at a transaction output (creation of the reference script) @@ -24,7 +24,7 @@ Below is an example that shows how to use a reference Plutus spending script wit + creating a read only reference tx output + the creation of the reference [minting script](scripts/plutus/scripts/v2) at a transaction output. -In this example we will use the [Required Redeemer](scripts/plutus/scripts/v2/required-redeemer.plutus) Plutus spending script and a [minting script](scripts/plutus/scripts/v2). In order to execute a reference Plutus spending script, we require the following: +In this example we will use the [Required Redeemer](../../../scripts/plutus/scripts/v2/required-redeemer.plutus) Plutus spending script and a [minting script](../../../scripts/plutus/scripts/v2/minting-script.plutus). In order to execute a reference Plutus spending script, we require the following: - Collateral tx input(s) - these are provided and are forfeited in the event the Plutus script fails to execute. - A Plutus tx output. This is the tx output that sits at the Plutus script address. @@ -61,7 +61,7 @@ cabal install cardano-node ``` To start your babbage cluster, you need to run the `example/run/all.sh` shell script. -The remainder of this guide provides a brief walkthrough of the [shell script example](scripts/plutus/example-babbage-script-usage.sh) that automatically creates a reference script and spends the utxo at +The remainder of this guide provides a brief walkthrough of the [shell script example](../../../scripts/babbage/example-babbage-script-usage.sh) that automatically creates a reference script and spends the utxo at the reference script's corresponding script address. #### Creating a reference script at a transaction output, inline datum and @@ -101,7 +101,7 @@ Firstly, we are sending ada and an inline datum to the plutus script address. Th ... ``` -We have seen this before in the [plutus-spending-script-example.md](doc/reference/plutus/plutus-spending-script-example.md). +We have seen this before in the [plutus-spending-script-example.md](plutus-spending-script-example.md). Secondly, we are creating a reference script at a tx output: diff --git a/doc/reference/plutus/babbage-withdrawing-script-example.md b/doc/reference/plutus/babbage-withdrawing-script-example.md index 1f431f141b1..42ed53f91a6 100644 --- a/doc/reference/plutus/babbage-withdrawing-script-example.md +++ b/doc/reference/plutus/babbage-withdrawing-script-example.md @@ -4,7 +4,7 @@ For an overview of reference script usuage in the Babbage era, please see [here](babbage-script-example.md). -In this example we will withdraw our rewards from a plutus script address using a plutus reference script. We must first run the [register-and-deglegate-script-staking-address.sh](../../../scripts/babbage/staking-example/register-and-deglegate-script-staking-address.sh) script in order to register and delegate the stake at our plutus script address. We will briefly walk through the [claim-script-staking-rewards.sh](../../../scripts/babbage/staking-example/claim-script-staking-rewards.sh) script that automatically does this all for us. +In this example we will withdraw our rewards from a plutus script address using a plutus reference script. We must first run the [register-and-delegate-script-staking-address.sh](../../../scripts/babbage/staking-example/register-and-delegate-script-staking-address.sh) script in order to register and delegate the stake at our plutus script address. We will briefly walk through the [claim-script-staking-rewards.sh](../../../scripts/babbage/staking-example/claim-script-staking-rewards.sh) script that automatically does this all for us. Now that we already have our certifying reference script at a tx output so we can use our reference input again to validate the withdrawal of our rewards at our plutus script address with the following tx: