Gimbalabs series: Create, Deploy, and Manage your own Plutus contracts effectively - Part 3

日本語版はスクロールダウンしてください。

Fig 1. Gimbalabs Plutus PBL

In the final part of this comprehensive three-part series, created and taught by the Gimbalabs instructor M. Ali Modiri, a.k.a Professor Mix, as part of the Gimbalabs Plutus Project-Based Learning, we will reach the end of our journey with the realization of a key concept in blockchain and smart contracts: Time.

You will gain an understanding of how time functions in Plutus, including the crucial concepts of POSIXTime and Ledger Slot Numbers.

Time plays a pivotal role in the world of blockchain and smart contract development.

It influences the execution of various operations, contract validation, and the orchestration of decentralized applications (DApps).

In this part of our series, you will learn how to work with POSIXTime to create time-sensitive smart contracts and applications as well discover how these slot numbers are used to measure time intervals, schedule contract executions, and manage blockchain events.


Student Learning Targets (SLT)

  • I can plan and implement my own Plutus contracts
  • I can create, update and maintain a Plutus project
  • I understand how time works on Plutus (POSIXTime) and Ledger (Slot Number)

In the first part of the series, we covered the first SLT: I can plan and implement my own Plutus contracts. In the second part, we covered the second SLT: I can create, update and maintain a Plutus project. Today, in this third and final part of the series, we will focus on the next SLT:

I understand how time works on Plutus (POSIXTime) and Ledger (Slot Number).


Fig 2. Find the lesson of this document + video lesson in Gimbalabs Plutus PBL - SLT 302.3.

So, let’s earn that “I understand”.


How Lockbox Contract Works


In this smart contract called “Lockbox”, we’ve created an experiment to help you understand how time operates in Plutus and the Cardano Ledger. Imagine it as a lockbox with three phases, each containing some ADA or tokens. Each of these phases has a deadline by which you, need to claim the funds inside.

Now, let’s break down the logic step by step. First, we send three UTxOs into this lockbox contract. Each UTxO holds a certain amount of ADA or tokens, and we attach a unique number to it, which would be the “datum” of those UTxOs. This number is crucial because it helps the contract differentiate between these UTxOs.

At the compilation stage, we specify three deadlines using a concept called POSIXTime. These deadlines are timestamps that determine when each phase of the lockbox will expire. It’s like setting a timer for each phase.

Here’s where it gets interesting. When you want to unlock, or “spend,” these UTxOs before their respective deadlines, you’ll use the concept of Slot numbers in your transaction building. Slot numbers are like the slots in a calendar that correspond to specific moments in time on the Cardano blockchain.

Now, let’s talk about two essential components: the Redeemer and the Datum. Both of these have parameters, and these parameters are the unique numbers we assigned at the compilation stage alongside the deadlines.

Why do we do this? It’s not just for fun; it’s to demonstrate the power of parameterized data in action. By attaching these numbers to the Redeemer and Datum, we’re showing you how the contract can recognize and distinguish between the different UTxOs, each with its own number and deadline.

So, in essence, this smart contract is your playground to explore the interaction between time, data, and logic in Plutus and Cardano. You’ll get hands-on experience in using timestamps, slot numbers, and parameterized data to make this contract come to life. Let’s dive in and unravel the mysteries of time and smart contracts together!


Preparation

Step 1: Clone or Update the Repository

  • If you don’t have ppbl-2023-plutus-template, clone it.
  • If you already have it, make sure it’s up to date by doing a git pull.

Step 2: Prepare Your Development Environment

  • Run cabal update to update your Cabal package manager.
  • Run cabal repl to open the REPL (Read-Eval-Print Loop) for interactive development.

Step 3: Load the Compiler Module

  • Inside the REPL, load the Lockbox.Compiler module by typing the following command:
AlwaysSucceeds.Compiler> :l Lockbox.Compiler

Step 4: Create the Output Folder

  • Call the createOutputFolder function to create an output folder where all contract files, datums, and redeemers will be stored:
Lockbox.Compiler> createOutputFolder

Step 5: Configure Deadlines and Numbers

  • Navigate to the Compiler.hs file located at ./src/Lockbox/Compiler.
  • Locate the lockboxParams section and modify the values for firstDeadline, secondDeadline, thirdDeadline, num1, num2, and num3 according to your requirements.
  • Make sure to specify deadlines in POSIXTime milliseconds.
num1 :: Integer
num1 = 1

num2 :: Integer
num2 = 2

num3 :: Integer
num3 = 3

lockboxParams :: LockboxParams
lockboxParams = LockboxParams
    {   firstDeadline  = 999999999
    ,   secondDeadline = 999999999
    ,   thirdDeadline  = 999999999
    ,   number1        = num1
    ,   number2        = num2
    ,   number3        = num3
    }

Step 6: Compile the Contract and Generate Datums and Redeemers

  • Compile the contract and generate datums and redeemers using the following commands one by one
Lockbox.Compiler> writeLockboxScript
Lockbox.Compiler> writeDatum1
Lockbox.Compiler> writeDatum2
Lockbox.Compiler> writeDatum3
Lockbox.Compiler> writeFirstClaimRedeemer
Lockbox.Compiler> writeSecondClaimRedeemer
Lockbox.Compiler> writeThirdClaimRedeemer

Locking Funds

To lock your funds into the contract, follow these instructions. Ensure you have all the necessary requirements in place before proceeding.

Step 1: Generate the Contract Address

Before creating and sending your UTxOs to the contract, you need to generate a contract address from your contract file. Open your terminal and navigate to the “output” directory:

$   cd output

Now, run the following command to build the contract address, ensuring you specify the correct path to your contract file lockbox.plutus:

$   cardano-cli address build --payment-script-file ./lockbox.plutus --testnet-magic 1 > lockbox.addr

Step 2: Locking Tokens

Now that you have the contract address, it’s time to create and send three UTxOs to the lockbox contract. Make sure you have cardano-node and cardano-cli version 8.1.2 or above installed.

For each UTxO, follow these steps, repeating them two more times with appropriate datum files:

UTxO 1:

cardano-cli transaction build \
--testnet-magic 1 \
--tx-in "INPUT_UTxO_TxID_FROM_YOUR_WALLET" \
--tx-in-collateral "COLLATERAL_UTxO_TxID_FROM_YOUR_WALLET_IN_CASE_TX_FAIL" \
--tx-out "$(cat lockbox.addr)+2000000" \
--tx-out-inline-datum-file lockboxDatum1.json \
--change-address "YOUR_WALLET_ADDRESS" \
--out-file tx.body

cardano-cli transaction sign \
    --testnet-magic 1 \
    --out-file tx.signed \
    --tx-body-file tx.body \
    --signing-key-file "YOUR_WALLET_SINGING_KEY"

cardano-cli transaction submit \
    --testnet-magic 1 \
    --tx-file tx.signed

UTxO 2:

  • Repeat the above steps, but change the datum file name to lockboxDatum2.json. Adjust the --tx-out-inline-datum-file flag accordingly.

UTxO 3:

  • Repeat the above steps, but change the datum file name to lockboxDatum3.json.Adjust the --tx-out-inline-datum-file flag accordingly.

Unlocking Funds

Now that we have funds securely locked within our contract, it’s time to explore the exciting process of unlocking them. Let’s begin by examining the first claim condition of the lockbox contract:

(FirstClaim redeemerNumber, LockboxDatum datumNumber) ->
        traceIfFalse "First Deadline Has NOT Been Reached"
            (from firstDeadline `contains` txInfoValidRange info )
    &&  traceIfFalse "Numbers Mismatched"
            (       number1 == redeemerNumber
                &&  number1 == datumNumber
            )

In this section, we’re addressing the scenario where the redeemer is set to FirstClaim, and the datum is set to LockboxDatum. Under these conditions, the contract must validate the transaction based on the following criteria:

Step 1:

First Deadline Check: The transaction’s time must be “after” the firstDeadline. This ensures that the transaction is attempted only “after” the specified deadline has passed.

Step 2:

Number Matching: We compare the number1 value, a contract parameter, with both the redeemer parameter (redeemerNumber) and the datum parameter (datumNumber). This check ensures that the numbers align correctly, adding an extra layer of security to the contract.

Now that we’ve confirmed that the first deadline has been reached and conditions are met, we can proceed to unlock UTxO 1. To do this, we need to construct a transaction, which requires knowledge of the current slot number.

You can query the node to obtain the current slot number:

$   cardano-cli query tip --testnet-magic 1
{
    "block": 1390609,
    "epoch": 94,
    "era": "Babbage",
    "hash": "844cb91b7a8c9f26ada3db6249d094cfff91f4c2343d9eafd7bd3852cee6bf00",
    "slot": 39309638,
    "slotInEpoch": 343238,
    "slotsToEpochEnd": 88762,
    "syncProgress": "100.00"
}

In this example, the current slot number is "slot": 39309638. Armed with this information, we can proceed to build the transaction needed to unlock “UTxO 1”.

cardano-cli transaction build \
--testnet-magic 1 \
--tx-in "INPUT_UTxO_TxID_FROM_YOUR_WALLET_TO_PAY_THE_TX_FEE" \
--tx-in-collateral "COLLATERAL_UTxO_TxID_FROM_YOUR_WALLET_IN_CASE_TX_FAIL" \
--tx-in "INPUT_UTxO_TxID_FROM_LOCKBOX_CONTRACT" \
--tx-in-inline-datum-present \
--tx-in-script-file ./output/lockbox.plutus \
--tx-in-redeemer-file ./output/firstClaimRedeemer.json \
--tx-out "YOUR_WALLET_ADDRESS+2000000" \
--invalid-before "NOW_SLOT_NUMBER" \
--change-address "YOUR_WALLET_ADDRESS" \
--out-file tx.body

cardano-cli transaction sign \
    --testnet-magic 1 \
    --out-file tx.signed \
    --tx-body-file tx.body \
    --signing-key-file "YOUR_WALLET_SINGING_KEY"

cardano-cli transaction submit \
    --testnet-magic 1 \
    --tx-file tx.signed

This sequence of commands constructs, signs, and submits the transaction, unlocking the desired funds. Make sure to replace the placeholders with your actual transaction details. The YOUR_WALLET_ADDRESS and NOW_SLOT_NUMBER should be replaced with your wallet address and the current slot number you obtained earlier.

Now, let’s delve into the intricacies of the second claim condition within the lockbox contract:

(SecondClaim redeemerNumber, LockboxDatum datumNumber) ->
        traceIfFalse "Second Deadline Has NOT Been Reached"
            (from secondDeadline `contains` txInfoValidRange info)
    &&  traceIfFalse "Third Deadline Has Been Reached"
            (to thirdDeadline `contains` txInfoValidRange info)
    &&  traceIfFalse "Numbers Mismatched"
            (       number2 == redeemerNumber
                &&  number2 == datumNumber
            )

In this section, we’re focusing on the scenario where the redeemer is set to SecondClaim, and the datum is set to LockboxDatum. Under these conditions, the contract must validate the transaction based on the following criteria:

Step 3:

Second Deadline Check: The transaction’s time must be “after” the secondDeadline. . This condition ensures that the transaction is only processed “after” the specified deadline has passed.

Step 4:

Third Deadline Check: Conversely, the transaction’s time must be “before” the thirdDeadline. This condition ensures that the transaction is attempted only “before” the specified deadline.

Step 5:

Number Matching: As with the first claim, we compare the number2 value (a contract parameter) with both the redeemer parameter (redeemerNumber) and the datum parameter (datumNumber). This check ensures that the numbers align correctly, adding an extra layer of security to the contract.

Now that we’ve confirmed that the second deadline has been reached while still being before the third deadline, we can proceed to unlock “UTxO 2”. Just as before, constructing the transaction requires knowledge of the current slot number. You can obtain this information by querying the node, similar to what we did for UTxO 1.

cardano-cli transaction build \
--testnet-magic 1 \
--tx-in "INPUT_UTxO_TxID_FROM_YOUR_WALLET_TO_PAY_THE_TX_FEE" \
--tx-in-collateral "COLLATERAL_UTxO_TxID_FROM_YOUR_WALLET_IN_CASE_TX_FAIL" \
--tx-in "INPUT_UTxO_TxID_FROM_LOCKBOX_CONTRACT" \
--tx-in-inline-datum-present \
--tx-in-script-file ./output/lockbox.plutus \
--tx-in-redeemer-file ./output/secondClaimRedeemer.json \
--tx-out "YOUR_WALLET_ADDRESS+2000000" \
--invalid-before "NOW_SLOT_NUMBER" \
--invalid-hereafter "$((NOW_SLOT_NUMBER + 60))" \
--change-address "YOUR_WALLET_ADDRESS" \
--out-file tx.body

Upon successfully executing these commands, the funds within UTxO 2 will be unlocked. Great! but what just occurred, what was --invalid-before and why now we needed --invalid-hereafter too?


Invalid Before Or Invalid Here After, That Is The Question

The --invalid-before and --invalid-hereafter parameters are used in Cardano transactions to specify time constraints. In lockbox smart contract, we are dealing with time-sensitive conditions. We have different phases or deadlines for claiming funds within the contract. To enforce these deadlines, we use slot numbers as a measure of time on the Cardano blockchain. Let’s explore their meanings and why both are needed in the context of the lockbox smart contract you’re working with:

  • --invalid-before: This parameter is used to set an “earliest” valid slot number. In the context of lockbox contract, it ensures that the transaction is only valid if it is included in a block with a slot number greater than or equal to the value specified here. This is important because it enforces the condition that a transaction can only occur after a certain slot (deadline) has been reached. For example, when claiming funds in the second phase of the contract, you want to make sure that it’s not done before the second deadline.
  • --invalid-hereafter: This parameter is used to set a “latest” valid slot number. It ensures that the transaction is only valid if it is included in a block with a slot number less than the value specified here. In lockbox contract, this is essential to enforce the condition that a transaction must occur before a certain slot (deadline) is reached. For example, when claiming funds in the second phase, you want to ensure that the transaction is submitted before the third deadline.

By using both –invalid-before and –invalid-hereafter, you create a time window during which the transaction is valid. This time window aligns with the specific phase or deadline you are targeting within the contract. It allows you to precisely control when the transaction can occur, ensuring that it adheres to the contract’s temporal rules.


Find here the original lesson (including the video lesson)

Follow Gimbalabs for further announcements.

Come to Gimbalabs Discord and start interacting with the Gimbalabs community.

And one more thing :boom::

If you want to navigate the depths of building on the Cardano blockchain hand in hand with those who are putting it at the service of solving significant problems, the Andamio platform is holding a series of Live Coding sessions, open access to all. Live Coding is the building of blockchain projects in public, live, without secrets or reservations, and with the right to ask anything you want. In Andamio’s calendar you will find the following sessions:


Best + see you soon!

Sebastian Pabon
Gimbalabs team



自分自身のPlutusコントラクトを効果的に作成し、デプロイし、管理する方法 - パート3


Fig 1. Gimbalabs Plutus PBL - Japanese version

この包括的な3部作シリーズの最終部では、ブロックチェーンとスマートコントラクトの重要な概念である「時間」の理解により、旅の終わりに到達します。

Plutusにおける時間の動作、POSIXTimeおよびLedger Slot Numbersという重要な概念を含む理解を得るでしょう。

時間は、ブロックチェーンやスマートコントラクト開発の世界で重要な役割を果たします。

それは、さまざまな操作の実行、契約の検証、および分散型アプリケーション(DApps)のオーケストレーションに影響を与えます。

このレッスンでは、時間に敏感なスマートコントラクトやアプリケーションを作成するためにPOSIXTimeを使用する方法、およびこれらのslot numbersが時間間隔を測定し、契約の実行をスケジュールし、ブロックチェーンイベントを管理する方法について学びます。


Student Learning Targets (SLT)

  • 私は自分自身のPlutus契約を計画し、実装することができます。
  • 私はPlutusプロジェクトを作成し、更新し、メンテナンスすることができます。
  • 以下のシナリオで時間がどのように機能するかを理解しています:Plutus(‘POSIXTime’)、‘Ledger’(‘Slot Number’)。

シリーズの最初の部分では、最初のSLTをカバーしました:私は自分自身のPlutus契約を計画し、実装することができます。第2部では、第2のSLTをカバーしました:私はPlutusプロジェクトを作成し、更新し、メンテナンスすることができます。本日、このシリーズの第3部である最終部では、次のSLTに焦点を当てます:

以下のシナリオで時間がどのように機能するかを理解しています:Plutus(‘POSIXTime’)、‘Ledger’(‘Slot Number’)。


Fig 2. このドキュメントとビデオレッスンのレッスンをGimbalabs Plutus PBL - SLT 302.3で見つけてください。

それでは、「理解しました」という成果を得ましょう。


Lockbox契約の仕組み


このスマートコントラクトでは、PlutusおよびCardano Ledgerで時間がどのように機能するかを理解するのに役立つ実験を作成しました。これを、3つの段階を含むロックボックスと考えてください。各段階には一定のADAやトークンが含まれています。これらの各段階には、内部の資金を請求するための締め切りがあります。

さて、ロジックを段階的に解説しましょう。まず、3つのUTxOsをこのロックボックス契約に送信します。各UTxOには一定量のADAまたはトークンが含まれており、それぞれに固有の番号を添付します。その番号がそれらのUTxOsの「datum」となります。この番号は重要です。なぜなら、これによって契約がこれらのUTxOsを区別できるからです。

コンパイル段階で、POSIXTimeという概念を使用して、3つの期限を指定します。これらの期限は、ロックボックスの各段階が期限切れになるタイムスタンプです。各段階にタイマーを設定するのと同じです。

興味深いことがここから始まります。各UTxOを、それぞれの期限前にロック解除、または「支出」したい場合、トランザクションを構築する際に Slot numbers の概念を使用します。Slot numbers は、カレンダーのスロットのようなもので、Cardanoブロックチェーン上の特定の時間を表します。

さて、2つの重要なコンポーネントについて話しましょう:RedeemerDatumです。どちらもパラメータを持ち、これらのパラメータは、コンパイル段階で期限と一緒に割り当てた固有の番号です。

なぜこれを行うのか?それはただ楽しいだけではありません。パラメータ化されたデータの力を実践で示すためです。これらの数字を RedeemerDatum に添付することで、契約が異なる UTxOs を認識し区別する方法を示しています。それぞれが固有の番号と期限を持っています。

要するに、このスマートコントラクトは、PlutusとCardanoで時間、データ、およびロジックの相互作用を探索するための遊び場です。タイムスタンプ、スロット番号、およびパラメータ化されたデータを使用して、この契約を実現するための実践的な経験を積むことができます。さあ、一緒に時間とスマートコントラクトの謎を解き明かしましょう!

準備


ステップ1: リポジトリをクローンまたは更新します。

  • もしあなたがppbl-2023-plutus-templateを持っていない場合、それをクローンしてください。
  • すでに持っている場合は、git pullを行って最新の状態にしてください。

ステップ2: 開発環境を準備します。

  • cabal updateを実行して、Cabal Package managerを更新してください。
  • cabal replを実行して、インタラクティブな開発のためのREPL(Read-Eval-Print Loop)を開いてください

ステップ3: Compilerモジュールをロードします。

  • REPL内で、次のコマンドを入力してLockbox.Compilerモジュールをロードしてください。
AlwaysSucceeds.Compiler> :l Lockbox.Compiler

ステップ4: Outputフォルダを作成します。

  • createOutputFolder 関数を呼び出して、すべての契約ファイル、datums、および redeemers が保存される output フォルダを作成してください。
Lockbox.Compiler> createOutputFolder

ステップ5: DeadlinesとNumbersを設定します。

  • ./src/Lockbox/CompilerにあるCompiler.hsファイルに移動してください。
  • lockboxParamsセクションを探し、firstDeadlinesecondDeadlinethirdDeadlinenum1num2、およびnum3の値を、要件に応じて変更してください。
  • deadlinesをPOSIXTimeミリ秒で指定してください。
num1 :: Integer
num1 = 1

num2 :: Integer
num2 = 2

num3 :: Integer
num3 = 3

lockboxParams :: LockboxParams
lockboxParams = LockboxParams
    {   firstDeadline  = 999999999
    ,   secondDeadline = 999999999
    ,   thirdDeadline  = 999999999
    ,   number1        = num1
    ,   number2        = num2
    ,   number3        = num3
    }

ステップ6: 契約をコンパイルし、DatumsとRedeemersを生成します。

  • 契約をコンパイルし、次のコマンドを1つずつ使用してdatumsとredeemersを生成してください。
Lockbox.Compiler> writeLockboxScript
Lockbox.Compiler> writeDatum1
Lockbox.Compiler> writeDatum2
Lockbox.Compiler> writeDatum3
Lockbox.Compiler> writeFirstClaimRedeemer
Lockbox.Compiler> writeSecondClaimRedeemer
Lockbox.Compiler> writeThirdClaimRedeemer

資金のロック


資金を契約にロックするには、次の手順に従ってください。手順を進める前に、すべての必要な要件を満たしていることを確認してください。

ステップ1: 契約アドレスを生成します。

UTxOsを契約に作成して送信する前に、契約ファイルから契約アドレスを生成する必要があります。ターミナルを開き、「output」ディレクトリに移動してください。

$   cd output

次に、以下のコマンドを実行して契約アドレスを構築します。契約ファイル lockbox.plutus の正しいパスを指定することを確認してください。

$   cardano-cli address build --payment-script-file ./lockbox.plutus --testnet-magic 1 > lockbox.addr

ステップ2:トークンをロックします

今、コントラクトアドレスを取得したら、lockboxコントラクトに3つのUTxOsを作成して送信する時です。 cardano-nodecardano-cliのバージョン8.1.2以上がインストールされていることを確認してください。

各UTxOについて、適切なdatumファイルでこれらの手順を繰り返します。

UTxO 1:

cardano-cli transaction build \
--testnet-magic 1 \
--tx-in "INPUT_UTxO_TxID_FROM_YOUR_WALLET" \
--tx-in-collateral "COLLATERAL_UTxO_TxID_FROM_YOUR_WALLET_IN_CASE_TX_FAIL" \
--tx-out "$(cat lockbox.addr)+2000000" \
--tx-out-inline-datum-file lockboxDatum1.json \
--change-address "YOUR_WALLET_ADDRESS" \
--out-file tx.body

cardano-cli transaction sign \
    --testnet-magic 1 \
    --out-file tx.signed \
    --tx-body-file tx.body \
    --signing-key-file "YOUR_WALLET_SINGING_KEY"

cardano-cli transaction submit \
    --testnet-magic 1 \
    --tx-file tx.signed

UTxO 2:

  • 前述の手順を繰り返しますが、datumファイルの名前をlockboxDatum2.jsonに変更します。--tx-out-inline-datum-fileフラグを適切に調整してください。

UTxO 3:

  • 前述の手順を繰り返しますが、datumファイルの名前をlockboxDatum3.jsonに変更します。--tx-out-inline-datum-fileフラグを適切に調整してください。

資金の解除


現在、契約内に安全にロックされた資金を解除する、という面白いプロセスを探索していきましょう。lockbox コントラクトの first claim 条件を調査しましょう。

(FirstClaim redeemerNumber, LockboxDatum datumNumber) ->
        traceIfFalse "First Deadline Has NOT Been Reached"
            (from firstDeadline `contains` txInfoValidRange info )
    &&  traceIfFalse "Numbers Mismatched"
            (       number1 == redeemerNumber
                &&  number1 == datumNumber
            )

このセクションでは、redeemer が FirstClaim に設定され、datum が LockboxDatum に設定されている場合のシナリオに対処しています。この条件下では、契約は次の基準に基づいてトランザクションを検証する必要があります:

ステップ1:

First Deadline Check: トランザクションの時刻は firstDeadline よりも「」でなければなりません。これにより、指定された締め切り時刻が過ぎた後にのみトランザクションが試行されることを保証します。

ステップ2:

Number Matching: 我々は、contract parameter である number1 の値を、redeemer parameter (redeemerNumber) と datum parameter (datumNumber) の両方と比較します。このチェックにより、数字が正しく整合していることを保証し、契約に追加のセキュリティレイヤーを提供します。

最初の締め切りが達成され、条件が満たされたことを確認したので、UTxO 1 をアンロックすることができます。これを行うには、現在の slot number を知る必要があります。そして、トランザクションを構築する必要があります。

node をクエリして現在の slot number を取得できます:

$   cardano-cli query tip --testnet-magic 1
{
    "block": 1390609,
    "epoch": 94,
    "era": "Babbage",
    "hash": "844cb91b7a8c9f26ada3db6249d094cfff91f4c2343d9eafd7bd3852cee6bf00",
    "slot": 39309638,
    "slotInEpoch": 343238,
    "slotsToEpochEnd": 88762,
    "syncProgress": "100.00"
}

この例では、現在のslot numberは 「slot」: 39309638 です。この情報を元に、「UTxO 1」 をアンロックするために必要なトランザクションを構築することができます。

cardano-cli transaction build \
--testnet-magic 1 \
--tx-in "INPUT_UTxO_TxID_FROM_YOUR_WALLET_TO_PAY_THE_TX_FEE" \
--tx-in-collateral "COLLATERAL_UTxO_TxID_FROM_YOUR_WALLET_IN_CASE_TX_FAIL" \
--tx-in "INPUT_UTxO_TxID_FROM_LOCKBOX_CONTRACT" \
--tx-in-inline-datum-present \
--tx-in-script-file ./output/lockbox.plutus \
--tx-in-redeemer-file ./output/firstClaimRedeemer.json \
--tx-out "YOUR_WALLET_ADDRESS+2000000" \
--invalid-before "NOW_SLOT_NUMBER" \
--change-address "YOUR_WALLET_ADDRESS" \
--out-file tx.body

cardano-cli transaction sign \
    --testnet-magic 1 \
    --out-file tx.signed \
    --tx-body-file tx.body \
    --signing-key-file "YOUR_WALLET_SINGING_KEY"

cardano-cli transaction submit \
    --testnet-magic 1 \
    --tx-file tx.signed

前のコマンドのシーケンスは、所望の資金をアンロックするトランザクションを構築し、署名して送信します。プレースホルダーを実際のトランザクションの詳細で置き換えてください。YOUR_WALLET_ADDRESSNOW_SLOT_NUMBER は、以前に取得した “あなたの” ウォレットアドレスと現在のslot numberで置き換える必要があります。

さて、lockbox コントラクト内の second claim 条件の詳細について掘り下げましょう。

(SecondClaim redeemerNumber, LockboxDatum datumNumber) ->
        traceIfFalse "Second Deadline Has NOT Been Reached"
            (from secondDeadline `contains` txInfoValidRange info)
    &&  traceIfFalse "Third Deadline Has Been Reached"
            (to thirdDeadline `contains` txInfoValidRange info)
    &&  traceIfFalse "Numbers Mismatched"
            (       number2 == redeemerNumber
                &&  number2 == datumNumber
            )

このセクションでは、redeemer が SecondClaim に設定され、datum が LockboxDatum に設定されている場合のシナリオに対処しています。この条件下では、契約は次の基準に基づいてトランザクションを検証する必要があります:

ステップ3:

Second Deadline Check: トランザクションの時刻は secondDeadline よりも「」でなければなりません。これにより、指定された締め切り時刻が過ぎた後にのみトランザクションが試行されることを保証します。

ステップ4:

Third Deadline Check: 逆に、トランザクションの時刻は thirdDeadline よりも「」でなければなりません。この条件により、トランザクションが指定された締め切り前のみに試行されることが保証されます。

ステップ5:

Number Matching: first claim と同様に、number2 の値(contract parameter)を redeemer parameter (redeemerNumber) および datum parameter (datumNumber) と比較します。このチェックにより、数字が正しく整合していることが確認され、契約に追加のセキュリティレイヤーが追加されます。

第二の締め切りが到達したことを確認しましたが、まだ第三の締め切り前にあるため、「UTxO 2」 をアンロックする準備ができました。前回と同様に、トランザクションを構築するには現在の slot number を知る必要があります。これに関する情報は、UTxO 1の場合と同様に、node をクエリすることで取得できます。

cardano-cli transaction build \
--testnet-magic 1 \
--tx-in "INPUT_UTxO_TxID_FROM_YOUR_WALLET_TO_PAY_THE_TX_FEE" \
--tx-in-collateral "COLLATERAL_UTxO_TxID_FROM_YOUR_WALLET_IN_CASE_TX_FAIL" \
--tx-in "INPUT_UTxO_TxID_FROM_LOCKBOX_CONTRACT" \
--tx-in-inline-datum-present \
--tx-in-script-file ./output/lockbox.plutus \
--tx-in-redeemer-file ./output/secondClaimRedeemer.json \
--tx-out "YOUR_WALLET_ADDRESS+2000000" \
--invalid-before "NOW_SLOT_NUMBER" \
--invalid-hereafter "$((NOW_SLOT_NUMBER + 60))" \
--change-address "YOUR_WALLET_ADDRESS" \
--out-file tx.body

これらのコマンドを正常に実行すると、UTxO 2 内の資金がアンロックされます。素晴らしいですね!しかし、何が起こったのか、--invalid-before とは何で、なぜ今 --invalid-hereafter も必要になったのでしょうか?

「Invalid Before」か「Invalid Here After」、それが問題だ。


--invalid-before および --invalid-hereafter パラメータは、Cardanoトランザクション内で時間制約を指定するために使用されます。lockboxスマートコントラクトでは、時間に敏感な条件を扱っています。契約内での資金の請求には異なる段階や締め切りがあります。これらの締め切りを強制するために、Cardanoブロックチェーン上の時間を測定するために slot numbers を使用します。これらの意味と、lockbox スマートコントラクトのコンテキストで両方が必要な理由を探ってみましょう:

  • --invalid-before: このパラメータは、「最も早い」有効な slot number を設定するために使用されます。lockbox コントラクトの文脈では、ここで指定された値以上のslot numberを持つブロックにトランザクションが含まれる場合にのみ、トランザクションが有効であることを保証します。これは重要です。なぜなら、特定の slot(締め切り)が達成された後にのみトランザクションが発生する条件を強制するからです。たとえば、契約の第2フェーズで資金を請求する場合、第2の締め切り前に行われないようにしたいと思います。
  • –invalid-hereafter: このパラメータは、「最新の」有効なスロット番号を設定するために使用されます。指定された値よりも小さいslot numberを持つブロックにトランザクションが含まれる場合にのみ、トランザクションが有効であることを保証します。lockbox契約では、この条件を強制するために不可欠です。つまり、トランザクションが特定の slot(締め切り)に達する前に発生する必要があります。たとえば、第2段階で資金を請求する場合、トランザクションが第3の締め切り前に送信されることを確認したいと思うでしょう。

–invalid-before–invalid-hereafter の両方を使用することで、トランザクションが有効な時間ウィンドウが作成されます。この時間ウィンドウは、契約内で対象としている特定のフェーズや締め切りに合わせています。これにより、トランザクションが発生できるタイミングを正確に制御し、契約の時間ルールに準拠することが保証されます。



オリジナルのレッスン(ビデオレッスンを含む)はこちらからご覧いただけます。

今後のお知らせについては、Gimbalabsをフォローしてください。

GimbalabsのDiscordに参加して、Gimbalabsコミュニティとのやり取りを始めましょう。

もう一つだけ :boom::

カルダノブロックチェーンを活用した開発の奥深くに携わりたい方、そしてその技術を使って重大な問題解決に取り組んでいる方々と共に歩みたい方を対象に、Andamio platformでは、どなたでも参加可能な「ライブコーディング」セッションを開催しています。Live Coding は、ブロックチェーンプロジェクトを公開で、生放送で、秘密や保留なしに構築することを指します。そして、何でも質問する権利があります。Andamio’s calendarには、以下のセッションがあります:

Cardano Go Live Coding:Goプログラミング言語を使用した構築。毎週月曜日、13:00 UTC。

Mesh Live Coding:Cardanoのよく知られたMeshライブラリを使用した構築。毎週月曜日、13:00 UTC


よろしくお願いします、 :bowing_man:

Sebastian Pabon
Gimbalabs チーム

1 Like