Skip to content

Commit

Permalink
Make the auction example end-to-end (#6477)
Browse files Browse the repository at this point in the history
  • Loading branch information
zliu41 authored Sep 25, 2024
1 parent 91800ce commit 2694830
Show file tree
Hide file tree
Showing 28 changed files with 980 additions and 468 deletions.
8 changes: 8 additions & 0 deletions doc/docusaurus/docs/auction-smart-contract/_category_.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"label": "Example: An Auction Smart Contract",
"position": 15,
"link": {
"type": "generated-index",
"description": "In this example we first present the Plutus Tx code for writing the on-chain validator script of a smart contract that controls the auction of an asset, which can be executed on the Cardano blockchain. We will then walk you through the steps to run it end-to-end on Cardano's Preview testnet."
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"label": "End to end",
"position": 10,
"link": {
"type": "generated-index",
"description": "We will now demonstrate the process of running the auction example end-to-end on Cardano's Preview testnet."
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
---
sidebar_position: 25
---

# Closing the Auction

Once the auction's end time has elapsed, a transaction can be submitted to finalize the auction, distributing the token and the highest bid accordingly.
This transaction needs to do the following:

- Spend the UTxO that contains the token being auctioned.
- If no bids were placed (which can be determined by examining the datum attached to the UTxO), the token should be returned to the seller's address.
- If at least one bid was placed, the token should be transferred to the highest bidder's address, and the highest bid amount should be sent to the seller's address.
- Set a validity interval that starts no earlier than the auction's end time.

The off-chain code for building and submitting this transaction will be very similar to the code for the bidding transactions, so the details are left as an exercise.
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
---
sidebar_position: 5
---

# Generating Keys and Addresses

To start, clone the plutus-tx-template repository into the `on-chain` directory.
Make sure to have [NodeJS](https://nodejs.org/en) and [yarn](https://yarnpkg.com/) (or [npm](https://github.com/npm/cli), which comes bundled with NodeJS) installed. Then, create a separate `off-chain` directory, set up `package.json`, and add the required dependencies:

```
git clone [email protected]:IntersectMBO/plutus-tx-template.git on-chain
mkdir off-chain && cd $_
yarn init -y
yarn add @meshsdk/core
yarn add cbor
```

We recommend using the Nix shell that comes with `plutus-tx-template` to run this example.
The Nix shell provides the correct versions of all dependencies, including GHC, Cabal, Node.js, and various C libraries.
To enter the nix shell, run

```
nix develop on-chain/
```

The first run of `nix develop` may take some time so please be patient.

We'll use [mesh](https://meshjs.dev/), a JavaScript framework, for writing off-chain code.
We'll use [Blockfrost](https://blockfrost.io/) as the blockchain provider, to avoid the need of running a local node.
If you don't have a Blockfrost account, you can sign up for one, and create a project for the Preview network.

The first step is to generate keys and addresses for the seller and the bidders.
Add a new file named `off-chain/generate-keys.mjs`, with the following content:

<LiteralInclude file="generate-keys.mjs" language="javascript" title="generate-keys.mjs" />

Then, generate keys and addresses for one seller and two bidders by running:

```
node generate-keys.mjs seller
node generate-keys.mjs bidder1
node generate-keys.mjs bidder2
```

This will create three files for each participant (seller, bidder1, and bidder2): a `.skey` file that contains a secret key, a `.addr` file that contains the corresponding wallet address, and a `.pkh` file that contains the corresponding public key hash.
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
---
sidebar_position: 10
---

# Getting Funds from the Faucet

Next, we'll need to fund the wallet of each participant (seller, bidder1 and bidder2), in order to cover transaction fees and place bids.
We can get funds from Cardano's [testnet faucet](https://docs.cardano.org/cardano-testnets/tools/faucet/).

To request funds, enter the seller's address into the address field and click "request funds."
This will deposit 10,000 (test) ADA into the seller's wallet.
Make sure you select the correct network (Preview).

Since the faucet limits how frequently you can request funds, and 10,000 ADA is more than sufficient for this example, we'll share the 10,000 ADA among the seller, bidder1, and bidder2.
To do so, create a file named `off-chain/send-lovelace.mjs` with the following content:

<LiteralInclude file="send-lovelace.mjs" language="javascript" title="send-lovelace.mjs" />

Substitute your Blockfrost project ID for `Replace with Blockfrost Project ID`.

This Javascript module builds and submits a transaction that sends 1 billion Lovelace (equivalent to 1000 Ada) from the seller's wallet to the specified recipient.
Run the following commands:

```
node send-lovelace.mjs bidder1
node send-lovelace.mjs bidder2
```

After the transactions are confirmed and included in a block (usually within a minute), bidder1's and bidder2's wallets should each have 1000 Ada, and the seller's wallet should have approximately 8000 Ada (minus transaction fees), which you can verify on [Cardanoscan](https://preview.cardanoscan.io/).
91 changes: 91 additions & 0 deletions doc/docusaurus/docs/auction-smart-contract/end-to-end/mint.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
---
sidebar_position: 15
---

# Minting the Token to be Auctioned

Before we can start the auction, we need to mint a token to be auctioned.
To do so, we first must determine the token's currency symbol and name.
To mint or burn tokens with a specific currency symbol (`currencySymbol`), a Plutus script whose hash matches `currencySymbol` must be provided, and is used to validate the minting or burning action.
Therefore, we'll first write the on-chain script, then compute its hash and use it as the currency symbol.

## On-chain Minting Policy Script

The full minting policy code can be found at [AuctionMintingPolicy.hs](https://github.com/IntersectMBO/plutus-tx-template/blob/main/src/AuctionMintingPolicy.hs).
The main logic is in the following function:

<LiteralInclude file="AuctionMintingPolicy.hs" language="haskell" title="AuctionMintingPolicy.hs" start="-- BLOCK1" end="-- BLOCK2" />

This script will pass if the following two conditions are met:

1. The transaction is signed by a specific public key.
2. The transaction mints exactly one token, whose currency symbol matches the script's hash (i.e., `ownCurrencySymbol ctx`).
The token name can be anything.

> :pushpin: **NOTE**
>
> A token minted in this way is _not_ considered a non-fungible token (NFT) because, while only one token can be minted in a single transaction, multiple transactions can mint additional tokens with the same currency symbol and token name.
> To create a truly unique token, you would need a more complex minting policy, but for simplicity, that is not covered here.
## Compile and Generate Blueprint for the Minting Policy

Next, we need to compile the minting policy script and create its blueprint.
To do so, we first need to supply a public key hash, which the minting policy will use for checking condition 1 above.
Assuming the seller is the one minting the token, this should be the seller's public key hash.
Open `GenMintingPolicyBlueprint.hs` in the `on-chain` directory, and replace `error "Replace with seller pkh"` with the content of `off-chain/seller.pkh`.

The minting policy code comes with `plutus-tx-template`, so you can find it in the `on-chain` repository.
To compile it and generate the blueprint, navigate to the `on-chain` directory and run

```
cabal run gen-minting-policy-blueprint -- ../off-chain/plutus-auction-minting-policy.json
```

You may need to run `cabal update` before executing this command for the first time.

This should produce a blueprint file named `off-chain/plutus-auction-minting-policy.json`.

## Compile and Generate Blueprint for the Auction Validator

One final step before minting the token: since we want to lock the minted token at the script address corresponding to the auction validator,
we must supply the parameters (i.e., `AuctionParams`) to the auction validator, compile the auction validator, and calculate its script address.

Open `GenAuctionValidatorBlueprint.hs` in the `on-chain` directory, and replace all placeholders:
- Replace `error "Replace with sellerh pkh"` with the content of `off-chain/seller.pkh`.
- Replace `error "Replace with currency symbol"` with the minting policy hash, which you can find in the `hash` field in `off-chain/plutus-auction-minting-policy.json`.
- Replace `error "Replace with the auction's end time"` with a POSIX timestamp for a time in the near future (say 24 hours from now).
Note that the POSIX timestamp in Plutus is the number of _milliseconds_, rather than seconds, elapsed since January 1, 1970.
In other words, add three zeros to the usual POSIX timestamp.
For instance, the POSIX timestamp of September 1, 2024, 21:44:51 UTC, is 1725227091000.

Then, navigate to the `on-chain` directory and run

```
cabal run gen-auction-validator-blueprint -- ../off-chain/plutus-auction-validator.json
```

This will generate a blueprint file named `off-chain/plutus-auction-validator.json`, which the off-chain code can read and calculate the auction validator's script address.


## Off-chain Code for Minting

We are now ready to write and execute the off-chain code for minting.
Create a file named `off-chain/mint-token-for-auction.mjs` with the following content:

<LiteralInclude file="mint-token-for-auction.mjs" language="javascript" title="mint-token-for-auction.mjs" />

Substitute your Blockfrost project ID for `Replace with Blockfrost Project ID`.

This Javascript module uses the mesh library to build a transaction that mints a token (`tx.mintAsset`).
The token will have the currency symbol of the minting policy's hash, and a token name of `TokenToBeAuctioned`.
It will be sent to `auctionValidatorAddress`, with a datum corresponding to `Nothing`.
The transaction is signed by the seller (`seller.skey`), and then submitted to the Preview testnet.

Run the coding using:

```
node mint-token-for-auction.mjs
```

and you should see a message "Minted a token at address ..." printed in the console.
Within a minute, you should be able to find the transaction using the transaction hash on [Cardanoscan](https://preview.cardanoscan.io/) and review its details.
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
---
sidebar_position: 20
---

# Placing Bids

Now we can start bidding.
Let's place a bid of 100 Ada from bidder1, followed by a bid of 200 Ada from bidder2.
Each transaction that places a bid must do the following:

- Spend the UTxO that contains the token being auctioned.
For bidder1, the transaction that produced the UTxO is the one that minted the token.
For bidder2, the transaction that produced the UTxO is bidder1's transaction.
The address of this UTxO is always the auction validator's script address, so each bidding transaction must include the auction validator and a redeemer[^1].
- Place a bid (via the redeemer) with an amount at least as high as the auction's minimum bid, and higher than the previous highest bid (if any).
The existence and the details of a previous highest bid can be determined by inspecting the datum attached to the aforementioned UTxO.
This is enforced by the auction validator's `sufficientBid` condition.
- Lock the token being auctioned, together with the bid amount, in a new UTxO at the auction validator's script address.
The new UTxO should also include a datum containing the details of this bid.
This is enforced by the auction validator's `correctOutput` condition.
- Refund the previous highest bid (if any) to its bidder's wallet address.
This is enforced by the auction validator's `refundsPreviousHighestBid` condition.
- Set a validity interval that ends no later than the auction's end time.
This is enforced by the auction validator's `validBidTime` condition.

To submit these bidding transactions, create a file named `off-chain/bid.mjs` for the off-chain code, with the following content:

<LiteralInclude file="bid.mjs" language="javascript" title="bid.mjs" />

This Javascript module builds and submits a transaction that does exactly the above.

The following substitutions are needed:

- Substitute your Blockfrost project ID for `Replace with Blockfrost Project ID`.
- Substitute a slot number no later than the auction's end time for `Replace with transaction expiration time`.
For instance, if you set the auction's end time to be approximately 24 hours from now, you can use a slot number corresponding to approximately 12 hours from now.
To determine the slot nmber, go to [Cardanoscan](https://preview.cardanoscan.io/), click on a recent transaction, take its Absolute Slot, and add 12 hours (43200) to it.

Place the first bid by running

```
node bid.mjs <minting-transaction-hash> bidder1 100000000
```

Replace `<minting-transaction-hash>` with the hash of the transaction we previously submitted for minting the token.
This hash is used by the off-chain code to locate the UTxO that contains the token.

After the first bidding transaction is confirmed, we can submit the second bid from bidder2, with a similar command:

```
node bid.mjs <bidder1-transaction-hash> bidder2 200000000
```

Replace `<bidder1-transaction-hash>` with the hash of the previous transaction.

---

[^1]: Instead of including the script in the transaction, we can use a reference script, but to keep things simple, we won't discuss that here.
Original file line number Diff line number Diff line change
@@ -1,30 +1,30 @@
---
sidebar_position: 25
sidebar_position: 15
---

# Life cycle of the auction smart contract

With the Plutus script written, Alice is now ready to start the auction smart contract.
At the outset, Alice creates a script UTXO whose address is the hash of the Plutus script, whose value is the token to be auctioned, and whose datum is `Nothing`.
Recall that the datum represents the highest bid, and there's no bid yet.
With the Plutus script written, Alice is now ready to start the auction smart contract.
At the outset, Alice creates a script UTXO whose address is the hash of the Plutus script, whose value is the token to be auctioned, and whose datum is `Nothing`.
Recall that the datum represents the highest bid, and there's no bid yet.
This script UTXO also contains the script itself, so that nodes validating transactions that try to spend this script UTXO have access to the script.

## Initial UTXO

Alice needs to create the initial UTXO transaction with the desired UTXO as an output.
The token being auctioned can either be minted by this transaction, or if it already exists in another UTXO on the ledger, the transaction should consume that UTXO as an input.
Alice needs to create the initial UTXO transaction with the desired UTXO as an output.
The token being auctioned can either be minted by this transaction, or if it already exists in another UTXO on the ledger, the transaction should consume that UTXO as an input.
We will not go into the details here of how minting tokens works.

## The first bid

Suppose Bob, the first bidder, wants to bid 100 Ada for Alice's NFT.
Suppose Bob, the first bidder, wants to bid 100 Ada for Alice's NFT.
In order to do this, Bob creates a transaction that has at least two inputs and at least one output.

The required inputs are (1) the script UTXO Alice created; (2) Bob's bid of 100 Ada.
The 100 Ada can come in one or multiple UTXOs.
The required inputs are (1) the script UTXO Alice created; (2) Bob's bid of 100 Ada.
The 100 Ada can come in one or multiple UTXOs.
Note that the input UTXOs must have a total value of more than 100 Ada, because in addition to the bid amount, they also need to cover the transaction fee.

The required output is a script UTXO with the same address as the initial UTXO (since the Plutus script itself remains the same), which is known as a *continuing output*.
The required output is a script UTXO with the same address as the initial UTXO (since the Plutus script itself remains the same), which is known as a *continuing output*.
This continuing output UTXO should contain:

- a datum that contains Bob's wallet address and Bob's bid amount (100 Ada).
Expand All @@ -34,41 +34,40 @@ This continuing output UTXO should contain:
If the input UTXOs contain more Ada than 100 plus the transaction fee, then there should be additional output UTXOs that return the extra Ada.
Again, verifying that the input value of a transaction minus the transaction fee equals the output value (unless the transaction is burning tokens) is the responsibility of the ledger, not the Plutus script.

In order for Bob's transaction to be able to spend the initial script UTXO Alice created, Bob's transaction must also contain a redeemer.
As shown in the code above, there are two kinds of redeemers in our example: `NewBid Bid` and `Payout`.
In order for Bob's transaction to be able to spend the initial script UTXO Alice created, Bob's transaction must also contain a redeemer.
As shown in the code above, there are two kinds of redeemers in our example: `NewBid Bid` and `Payout`.
The redeemer in Bob's transaction is a `NewBid Bid` where the `Bid` contains Bob's wallet address and bid amount.

![First bid diagram](../../static/img/first-bid-simple-auction-v3.png)

Once Bob's transaction is submitted, the node validating this transaction will run the Plutus script, which checks a number of conditions like whether the bid happens before the deadline, and whether the bid is high enough.
If the checks pass and everything else about the transaction is valid, the transaction will go through and be included in a block.
Once Bob's transaction is submitted, the node validating this transaction will run the Plutus script, which checks a number of conditions like whether the bid happens before the deadline, and whether the bid is high enough.
If the checks pass and everything else about the transaction is valid, the transaction will go through and be included in a block.
At this point, the initial UTXO created by Alice no longer exists on the ledger, since it has been spent by Bob's transaction.

## The second bid

Next, suppose a second bidder, Charlie, wants to outbid Bob.
Next, suppose a second bidder, Charlie, wants to outbid Bob.
Charlie wants to bid 200 Ada.

Charlie will create another transaction.
This transaction should have an additional output compared to Bob's transaction: a UTXO that returns Bob's bid of 100 Ada.
Charlie will create another transaction.
This transaction should have an additional output compared to Bob's transaction: a UTXO that returns Bob's bid of 100 Ada.
Recall that this is one of the conditions checked by the Plutus script; the transaction is rejected if the refund output is missing.

![Second bid diagram](../../static/img/second-bid-simple-auction-v3.png)

Charlie's transaction needs to spend the script UTXO produced by Bob's transaction, so it also needs a redeemer.
Charlie's transaction needs to spend the script UTXO produced by Bob's transaction, so it also needs a redeemer.
The redeemer is a `NewBid Bid` where `Bid` contains Charlie's wallet address and bid amount.
Charlie's transaction cannot spend the initial UTXO produced by Alice, since it has already been spent by Bob's transaction.

## Closing the auction

Let's assume that there won't be another bid.
Let's assume that there won't be another bid.
Once the deadline has passed, the auction can be closed.

In order to do that, somebody has to create another transaction.
That could be Alice, who wants to collect the bid, or it could be Charlie, who wants to collect the NFT.
In order to do that, somebody has to create another transaction.
That could be Alice, who wants to collect the bid, or it could be Charlie, who wants to collect the NFT.
It can be anybody, but Alice and Charlie have an incentive to create it.

This transaction has one required input: the script UTXO produced by Charlie's transaction, and two required outputs: (1) the payment of the auctioned token to Charlie; (2) the payment of 200 Ada to Alice.

![Closing transaction diagram](../../static/img/closing-tx-simple-auction-v3.png)

Loading

1 comment on commit 2694830

@github-actions
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Performance Alert ⚠️

Possible performance regression was detected for benchmark 'Plutus Benchmarks'.
Benchmark result of this commit is worse than the previous benchmark result exceeding threshold 1.05.

Benchmark suite Current: 2694830 Previous: 91800ce Ratio
validation-auction_1-1 189.6 μs 177.9 μs 1.07
validation-auction_1-2 913.1 μs 634.7 μs 1.44
validation-auction_1-3 898.5 μs 623.9 μs 1.44
validation-auction_1-4 343.1 μs 230.5 μs 1.49
validation-auction_2-1 231.8 μs 179 μs 1.29
validation-future-pay-out-1 263.8 μs 248.8 μs 1.06
validation-game-sm-success_2-1 549 μs 521.1 μs 1.05
validation-multisig-sm-7 547 μs 383.9 μs 1.42
validation-multisig-sm-8 558.8 μs 392.3 μs 1.42
validation-multisig-sm-9 560 μs 393.8 μs 1.42
validation-multisig-sm-10 787.1 μs 556.1 μs 1.42
validation-ping-pong-1 472 μs 331.5 μs 1.42
validation-ping-pong-2 472.3 μs 336.9 μs 1.40
validation-ping-pong_2-1 285.8 μs 201.2 μs 1.42
validation-prism-1 185 μs 168.8 μs 1.10
validation-prism-2 589.1 μs 415.9 μs 1.42
validation-pubkey-1 199.7 μs 150.2 μs 1.33
validation-decode-escrow-refund-1 445 μs 310.7 μs 1.43
validation-decode-future-increase-margin-1 326.2 μs 226.6 μs 1.44
validation-decode-future-increase-margin-2 445.5 μs 310.4 μs 1.44
validation-decode-future-increase-margin-4 951.9 μs 696.7 μs 1.37
validation-decode-future-settle-early-2 441.5 μs 309.5 μs 1.43
validation-decode-future-settle-early-3 379 μs 310.2 μs 1.22
validation-decode-multisig-sm-8 806.3 μs 588.1 μs 1.37
validation-decode-multisig-sm-9 805.9 μs 562.4 μs 1.43
validation-decode-multisig-sm-10 806.3 μs 612.9 μs 1.32
validation-decode-ping-pong_2-1 678.6 μs 560.8 μs 1.21
validation-decode-prism-1 214.6 μs 156.7 μs 1.37
validation-decode-stablecoin_2-1 933.8 μs 835.4 μs 1.12
validation-decode-stablecoin_2-2 229.5 μs 160.2 μs 1.43
validation-decode-stablecoin_2-3 1188 μs 853.3 μs 1.39
validation-decode-stablecoin_2-4 217.2 μs 161.5 μs 1.34
validation-decode-uniswap-3 1014.9999999999999 μs 818.7 μs 1.24
validation-decode-uniswap-4 250.3 μs 177.7 μs 1.41
nofib-clausify/formula3 11940 μs 11150 μs 1.07
nofib-clausify/formula4 36250 μs 25540 μs 1.42
nofib-clausify/formula5 76950 μs 54210 μs 1.42
nofib-knights/4x4 24840 μs 17440 μs 1.42
nofib-knights/6x6 65140 μs 45810 μs 1.42
nofib-knights/8x8 114300 μs 80560 μs 1.42
nofib-primetest/05digits 14500 μs 10250 μs 1.41
nofib-primetest/10digits 28390 μs 20110 μs 1.41
nofib-primetest/30digits 87160 μs 77440 μs 1.13
nofib-queens4x4/bm 9490 μs 7520 μs 1.26
nofib-queens4x4/bjbt1 9162 μs 6533 μs 1.40
marlowe-semantics/0000020002010200020101020201000100010001020101020201010000020102 460.3 μs 368.5 μs 1.25
marlowe-semantics/0001000101000000010101000001000001010101010100000001000001010000 518.9 μs 441 μs 1.18
marlowe-semantics/004025fd712d6c325ffa12c16d157064192992faf62e0b991d7310a2f91666b8 1159 μs 815.5 μs 1.42
marlowe-semantics/0101010001010101010101000100010100000001010000010001000001000101 1127 μs 913.7 μs 1.23
marlowe-semantics/5d0a88250f13c49c20e146819357a808911c878a0e0a7d6f7fe1d4a619e06112 1494 μs 1052 μs 1.42
marlowe-semantics/5e274e0f593511543d41570a4b03646c1d7539062b5728182e073e5760561a66 1450 μs 1020.9999999999999 μs 1.42
marlowe-semantics/5e2c68ac9f62580d626636679679b97109109df7ac1a8ce86d3e43dfb5e4f6bc 746.5 μs 525.4 μs 1.42
marlowe-semantics/5f130d19918807b60eab4c03119d67878fb6c6712c28c54f5a25792049294acc 432.7 μs 304.7 μs 1.42
marlowe-semantics/5f306b4b24ff2b39dab6cdc9ac6ca9bb442c1dc6f4e7e412eeb5a3ced42fb642 1084 μs 763.3 μs 1.42
marlowe-semantics/5f3d46c57a56cef6764f96c9de9677ac6e494dd7a4e368d1c8dd9c1f7a4309a5 703.5 μs 495.4 μs 1.42
marlowe-semantics/64c3d5b43f005855ffc4d0950a02fd159aa1575294ea39061b81a194ebb9eaae 951.1 μs 669.8 μs 1.42
marlowe-semantics/65bc4b69b46d18fdff0fadbf00dd5ec2b3e03805fac9d5fb4ff2d3066e53fc7e 3310 μs 2345 μs 1.41
marlowe-semantics/66af9e473d75e3f464971f6879cc0f2ef84bafcb38fbfa1dbc31ac2053628a38 1770 μs 1321 μs 1.34
marlowe-semantics/cf542b7df466b228ca2197c2aaa89238a8122f3330fe5b77b3222f570395d9f5 704.3 μs 654.6 μs 1.08
marlowe-semantics/d1ab832dfab25688f8845bec9387e46ee3f00ba5822197ade7dd540489ec5e95 47810 μs 36280 μs 1.32
marlowe-semantics/d1c03759810747b7cab38c4296593b38567e11195d161b5bb0a2b58f89b2c65a 1466 μs 1030 μs 1.42
marlowe-semantics/d64607eb8a1448595081547ea8780886fcbd9e06036460eea3705c88ea867e33 429.4 μs 303.3 μs 1.42
marlowe-semantics/dc241ac6ad1e04fb056d555d6a4f2d08a45d054c6f7f34355fcfeefebef479f3 667.9 μs 470.5 μs 1.42
marlowe-semantics/dd11ae574eaeab0e9925319768989313a93913fdc347c704ddaa27042757d990 1085 μs 762.4 μs 1.42
marlowe-semantics/e26c1cddba16e05fd10c34cbdb16ea6acdbac7c8323256c31c90c520ee6a1080 531.4 μs 373.4 μs 1.42
marlowe-semantics/e34b48f80d49360e88c612f4016f7d68cb5678dd8cd5ddb981375a028b3a40a5 559.1 μs 393.5 μs 1.42
marlowe-semantics/e3afd22d01ff12f381cf915fd32358634e6c413f979f2492cf3339319d8cc079 431.5 μs 305 μs 1.41
marlowe-semantics/e9234d2671760874f3f660aae5d3416d18ce6dfd7af4231bdd41b9ec268bc7e1 1356 μs 947.9 μs 1.43
marlowe-semantics/eb4a605ed3a64961e9e66ad9631c2813dadf7131740212762ae4483ec749fe1d 430.3 μs 303.3 μs 1.42
marlowe-semantics/ecb5e8308b57724e0f8533921693f111eba942123cf8660aac2b5bac21ec28f0 947.2 μs 667.7 μs 1.42
marlowe-semantics/f2a8fd2014922f0d8e01541205d47e9bb2d4e54333bdd408cbe7c47c55e73ae4 1063 μs 749.1 μs 1.42
marlowe-semantics/f339f59bdf92495ed2b14e2e4d3705972b4dda59aa929cffe0f1ff5355db8d79 6384 μs 4482 μs 1.42
marlowe-semantics/ffdd68a33afd86f8844c9f5e45b2bda5b035aa02274161b23d57709c0f8b8de6 1334 μs 943.2 μs 1.41
marlowe-role-payout/0004000402010401030101030100040000010104020201030001000204020401 264 μs 185.3 μs 1.42
marlowe-role-payout/0100000100010000000001000100010101000101000001000000010000010000 372.1 μs 261 μs 1.43
marlowe-role-payout/0101000100000101010000010101000100010101000001000001000000010101 280.9 μs 196.9 μs 1.43
marlowe-role-payout/01dcc372ea619cb9f23c45b17b9a0a8a16b7ca0e04093ef8ecce291667a99a4c 232.7 μs 163.6 μs 1.42
marlowe-role-payout/0201020201020000020000010201020001020200000002010200000101010100 264.7 μs 186 μs 1.42
marlowe-role-payout/0202010002010100020102020102020001010101020102010001010101000100 246.1 μs 198.3 μs 1.24
marlowe-role-payout/0303020000020001010201060303040208070100050401080304020801030001 243.7 μs 171 μs 1.43
marlowe-role-payout/031d56d71454e2c4216ffaa275c4a8b3eb631109559d0e56f44ea8489f57ba97 298.9 μs 210.4 μs 1.42
marlowe-role-payout/03d730a62332c51c7b70c16c64da72dd1c3ea36c26b41cd1a1e00d39fda3d6cc 278.1 μs 195 μs 1.43
marlowe-role-payout/0403020000030204010000030001000202010101000304030001040404030100 257.1 μs 181.1 μs 1.42
marlowe-role-payout/0405010105020401010304080005050800040301010800080207080704020206 282.7 μs 261.3 μs 1.08

This comment was automatically generated by workflow using github-action-benchmark.

CC: @IntersectMBO/plutus-core

Please sign in to comment.