diff --git a/doc/docusaurus/docs/working-with-scripts/script-purposes.md b/doc/docusaurus/docs/working-with-scripts/script-purposes.md
new file mode 100644
index 00000000000..a89c4209e95
--- /dev/null
+++ b/doc/docusaurus/docs/working-with-scripts/script-purposes.md
@@ -0,0 +1,80 @@
+---
+sidebar_position: 2
+---
+
+# Script Purposes
+
+One of the arguments every Plutus script receives is the script context, containing information about the transaction the script is validating.
+One of the fields of script context is the script purpose.
+Since a transaction may do multiple things, each of which is validated by a separate script, the script purpose informs a script what exactly it is supposed to validate.
+
+Plutus V1 and V2 share the same [`ScriptPurpose`](https://plutus.cardano.intersectmbo.org/haddock/master/plutus-ledger-api/PlutusLedgerApi-V1-Contexts.html#t:ScriptPurpose) type with four variants: spending, minting, rewarding and certifying.
+Plutus V3's [`ScriptPurpose`](https://plutus.cardano.intersectmbo.org/haddock/master/plutus-ledger-api/PlutusLedgerApi-V3-Contexts.html#t:ScriptPurpose) has two additional variants: voting and proposing.
+Next we go over and explain all these different script purposes.
+
+## Spending
+
+A spending script validates the spending of a UTXO.
+A UTXO can have either a public key address or a script address.
+To spend a UTXO with a script address, the script whose hash matches the script address must be included in the transaction (either directly, or as a reference script), and is executed to validate it.
+
+The script can make the decision based on the datum attached in the UTXO being spent, if any (datum is mandatory for Plutus V1 and V2, i.e., a UTXO with a Plutus V1 or V2 script address but without a datum cannot be spent; datum is optional for Plutus V3), the redeemer included in the transaction, as well as other fields of the transaction.
+
+The `Spending` constructor of `ScriptPurpose` includes a `TxOutRef` field that references the UTXO the script is validating, which is also one of the UTXOs the transaction attempts to spend.
+
+## Minting
+
+Minting scripts, sometimes also referred to as minting policies, are used to approve or reject minting of new assets.
+
+In Cardano, we can uniquely identify an asset by its `CurrencySymbol` and `TokenName`.
+If a transaction attempts to mint some new assets, then for each unique `CurrencySymbol` in the new assets, the script whose hash matches the `CurrencySymbol` must be included in the transaction, and is executed to validate the minting of that `CurrencySymbol`.
+This is the reason why the `Minting` constructor of `ScriptPurpose` contains a `CurrencySymbol` field.
+
+A minting script should pay attention to the fact that the transaction may attempt to mint multiple assets with the same `CurrencySymbol` but different `TokenNames`.
+In general all these assets with the same `CurrencySymbol` should be checked.
+
+## Rewarding
+
+As previously stated, a UTXO's address can be either a public key address or a script address.
+Both kinds of addresses can optionally have a staking credential.
+A UTXO may contain Ada, and the Ada it contains can be delegated to an SPO to earn staking rewards.
+Staking rewards are deposited into a reward account[^1] corresponding to the staking credential.
+
+A staking credential can contain either a public key hash or a script hash.
+To withdraw rewards from a reward account corresponding to a staking credential that contains a script hash, the script with that particular hash must be included in the transaction, and is executed to validate the withdrawal.
+
+The script might set conditions on reward distribution, such as ensuring that any withdrawal are deposited into one of the designated addresses.
+
+## Certifying
+
+A certifying script can validate a number of certificate-related transactions, such as: (1) registering a staking credential, and in doing so, creating a reward account associated with the staking credential; (2) de-registering a staking credential, and in doing so, terminating the reward account; (3) delegating a staking credential to a particular delegatee.
+
+In all these cases, if the staking credential in question contains a script hash (as opposed to a public key hash), the script with that hash must be included in the transaction, and is executed to validate the action.
+
+Such a script may, for instance, check that certain signatures be provided for registration, de-registration and delegation, or that the delegatee must be among the allowed delegatees.
+
+## Voting
+
+A voting script validates votes cast by a Delegated Representative (DRep) or a constitutional committee member (CCM) in a transaction.
+A DRep or a CCM can be associated with a script hash.
+If a transaction contains one or more votes from a DRep or a constitution committee member associated with a script hash, the script with that hash must be included in the transaction, and is executed to approve or reject the vote.
+
+## Proposing
+
+A proposing script, also known as constitution script or guardrail script, validates two kinds of [governance actions](https://plutus.cardano.intersectmbo.org/haddock/master/plutus-ledger-api/PlutusLedgerApi-V3-Contexts.html#t:ScriptContext): `ParameterChange` and `TreasuryWithdrawals`.
+
+There is a key distinction between proposing scripts and other kinds of scripts: proposing scripts are not written by regular users.
+At any given point in time, there is exactly one active proposing script being used by the entire chain.
+This proposing script must be included in transactions that propose `ParameterChange` or `TreasuryWithdrawals`.
+The ledger enforces that no other proposing script is accepted.
+The proposing script is updated only when there is a change to the constitution, via the `NewConstitution` governance action.
+
+Note that what the proposing script decides is whether the _proposal_ of a governance action is allowed to go through, rather than whether the governance action will be enacted.
+After a proposal goes through, it will need to meet the appropriate criteria (such as gathering enough votes from consitution committee members, DReps and/or SPOs) in order to be enacted.
+
+---
+
+[^1]: Reward accounts are distinct from UTXOs, and are more akin to accounts in account-based blockchains.
+They are used for accumulating staking rewards, rather than using UTXOs, in order to avoid creating a large number of UTXOs with tiny values.
+Reward accounts are special on Cardano and cannot be created arbitrarily.
+Each reward account is associated with a staking credential, and is created automatically when the staking credential is registered.
diff --git a/doc/docusaurus/docs/working-with-scripts/writing-basic-minting-policies.md b/doc/docusaurus/docs/working-with-scripts/writing-basic-minting-policies.md
deleted file mode 100644
index fe74ede8090..00000000000
--- a/doc/docusaurus/docs/working-with-scripts/writing-basic-minting-policies.md
+++ /dev/null
@@ -1,55 +0,0 @@
----
-sidebar_position: 10
----
-
-# Writing basic minting policies
-
-[Minting policy scripts](../reference/glossary.md#minting-policy-script) are the programs that can be used to control the minting of new assets on the chain.
-Minting policy scripts are much like [validator scripts](../reference/glossary.md#validator-script), and they are written similarly, so please review [Writing basic validator scripts](writing-basic-validator-scripts.md) before reading this topic.
-
-## Minting policy arguments
-
-Minting policies, like validators, receive some information from the validating node:
-
-- The [redeemer](../reference/glossary.md#redeemer), which is some script-specific data specified by the party performing the minting.
-- The [script context](../reference/glossary.md#script-context), which contains a representation of the spending transaction, as well as the hash of the minting policy which is currently being run.
-
-The minting policy is a function which receives these two inputs as *arguments*. The validating node is responsible for passing them in and running the minting policy.
-As with validator scripts, the arguments are passed encoded as `PlutusCore.Data.Data`.
-
-## Plutus script context versions
-
-Minting policies have access to the [script context](../reference/glossary.md#script-context) as their second argument.
-Each version of Plutus minting policy scripts are differentiated only by their `ScriptContext` argument.
-
-> See this example from the file `MustSpendScriptOutput.hs` (lines 340 to 422) showing code addressing [Versioned Policies for both Plutus V1 and Plutus V2](https://github.com/IntersectMBO/plutus-apps/blob/05e394fb6188abbbe827ff8a51a24541a6386422/plutus-contract/test/Spec/TxConstraints/MustSpendScriptOutput.hs#L340-L422).
-
-Minting policies tend to be particularly interested in the `mint` field, since the point of a minting policy is to control which tokens are minted.
-
-It is also important for a minting policy to look at the tokens in the `mint` field that use its own currency symbol i.e. policy hash.
-Note that checking only a specific token name is usually not correct.
-The minting policy must check for correct minting (or lack there of) of all token names under its currency symbol.
-This requires the policy to refer to its own hash—fortunately this is provided for us in the script context of a minting policy.
-
-## Writing minting policies
-
-Here is an example that puts this together to make a simple policy that allows anyone to mint the token so long as they do it one token at a time.
-To begin with, we'll write a version that works with structured types.
-
-
-
-However, scripts are actually given their arguments as type `Data`, and must signal failure with `error`, so we need to wrap up our typed version to use it on-chain.
-
-
-
-## Other policy examples
-
-Probably the simplest useful policy is one that requires a specific key to have signed the transaction in order to do any minting.
-This gives the key holder total control over the supply, but this is often sufficient for asset types where there is a centralized authority.
-
-
-
-> :pushpin: **NOTE**
->
-> We don't need to check that this transaction actually mints any of our asset type: the ledger rules ensure that the minting policy will only be run if some of that asset is being minted.
-
diff --git a/doc/docusaurus/docs/working-with-scripts/writing-basic-validator-scripts.md b/doc/docusaurus/docs/working-with-scripts/writing-basic-validator-scripts.md
deleted file mode 100644
index 46e2b0f1b0d..00000000000
--- a/doc/docusaurus/docs/working-with-scripts/writing-basic-validator-scripts.md
+++ /dev/null
@@ -1,88 +0,0 @@
----
-sidebar_position: 5
----
-
-# Writing basic validator scripts
-
-[Validator scripts](../reference/glossary.md#validator-script) are the programs that can be used to lock transaction outputs on the chain.
-Validator scripts are [Plutus Core](../reference/glossary.md#plutus-core) programs, but we can use [Plutus Tx](../reference/glossary.md#plutus-tx) to write them easily in Haskell.
-Please review [Writing Plutus Tx programs](../using-plutus-tx/writing-plutus-tx-programs.md) before going through this topic.
-
-## Validator arguments
-
-Validators receive some information from the validating node:
-
-- The [redeemer](../reference/glossary.md#redeemer), which is some script-specific data specified by the party spending the output.
-- The [datum](../reference/glossary.md#datum), which is some script-specific data specified by the party who created the output.
-- The [script context](../reference/glossary.md#script-context), which contains a representation of the spending transaction, as well as the index of the input whose validator is currently being run.
-
-The validator is a function which receives these three inputs as *arguments*. The validating node is responsible for passing them in and running the validator.
-
-## The `Data` type
-
-But how are the validator's arguments passed?
-Different scripts are going to expect different sorts of values in their datums and redeemers.
-
-The answer is that we pass the arguments as a *generic* structured data type `PlutusCore.Data.Data`.
-`Data` is designed to make it easy to encode structured data into it, and is essentially a subset of CBOR.
-
-Validator scripts take three arguments of type `Data`.
-Since `Data` is represented as a builtin type in Plutus Core, we use a special Haskell type `BuiltinData` rather than the underlying `Data` type.
-
-However, you will typically not want to use `BuiltinData` directly in your program, rather you will want to use your own datatypes.
-We can easily convert to and from `BuiltinData` with the `PlutusTx.IsData.Class.ToData`, `PlutusTx.IsData.Class.FromData`, and `PlutusTx.IsData.Class.UnsafeFromData` typeclasses.
-You usually don't need to write your own instances of these classes.
-Instead, you can use the `unstableMakeIsData` or `makeIsDataIndexed` Template Haskell functions to generate one.
-
-> :pushpin: **NOTE**
->
-> The `PlutusTx.IsData.Class.UnsafeFromData` class provides `unsafeFromBuiltinData`, which is the same as `fromBuiltinData`, but is faster and fails with `error` rather than returning a `Maybe`.
-> We'll use `unsafeFromBuiltinData` in this tutorial, but sometimes the other version is useful.
-
-
-
-## Signaling failure
-
-The most important thing that a validator can do is *fail*.
-This indicates that the attempt to spend the output is invalid and that transaction validation should fail.
-A validator succeeds if it does not explicitly fail.
-The actual value returned by the validator is irrelevant.
-
-How does a validator fail?
-It does so by using the `PlutusTx.Builtins.error` builtin.
-Some other builtins may also trigger failure if they are used incorrectly (for example, `1/0`).
-
-## Validator functions
-
-We write validator scripts as Haskell functions, which we compile with Plutus Tx into Plutus Core.
-The type of a validator function is `BuiltinData -> BuiltinData -> BuiltinData -> ()`, that is, a function which takes three arguments of type `BuiltinData`, and returns a value of type `()` ("unit" or "the empty tuple" -- since the return type doesn't matter we just pick something trivial).
-
-Here are two examples of simple validators that always succeed and always fail, respectively:
-
-
-
-If we want to write a validator that uses types other than `BuiltinData`, we'll need to use the functions from `PlutusTx.IsData.Class.FromData` to decode them.
-Importantly, `unsafeFromBuiltinData` can fail: in our example, if the `BuiltinData` in the second argument is *not* a correctly encoded `Date`, then it will fail the whole validation with `error`, which is usually what we want if we have bad arguments.
-
-> :red_circle: **Important**
->
-> Unfortunately, there's no way to provide failure diagnostics when a validator fails on chain—it just fails.
-> However, since transaction validation is entirely deterministic, you'll always be informed of this before you submit the transaction to the chain, so you can debug it locally using `traceError`.
-
-Here's an example that uses our date types to check whether the date which was provided is less than the stored limit in the datum.
-
-
-
-## Plutus script context versions
-
-Validators have access to the [script context](../reference/glossary.md#script-context) as their third argument.
-Each version of Plutus validators are differentiated only by their `ScriptContext` argument.
-
-> See this example from the file `MustSpendScriptOutput.hs` (lines 340 to 422) showing code addressing [Versioned Policies for both Plutus V1 and Plutus V2](https://github.com/IntersectMBO/plutus-apps/blob/05e394fb6188abbbe827ff8a51a24541a6386422/plutus-contract/test/Spec/TxConstraints/MustSpendScriptOutput.hs#L340-L422).
-
-The script context gives validators a great deal of power, because it allows them to inspect other inputs and outputs of the current transaction.
-For example, here is a validator that will only accept the transaction if a particular payment is made as part of it.
-
-
-
-This makes use of some useful functions for working with script contexts.