Skip to content

Commit

Permalink
ETCM-9287 update native tokens docs (#437)
Browse files Browse the repository at this point in the history
kpinter-iohk authored Jan 30, 2025
1 parent c97d2ba commit 53d257e
Showing 1 changed file with 96 additions and 143 deletions.
239 changes: 96 additions & 143 deletions docs/developer-guides/native-token-reserve-management.md
Original file line number Diff line number Diff line change
@@ -2,16 +2,16 @@

## Overview

This guide covers the following tasks:
This guide covers the following tasks:

1. **On Cardano:**
1. **On Cardano:**

- Creating your new token and setting up rules for how tokens are released over time.
- This involves setting up and managing a token management contract on the Cardano blockchain, enabling proper observability on your partner chain.
- Creating your new token and setting up rules for how tokens are released over time.
- This involves setting up and managing a token management contract on the Cardano blockchain, enabling proper observability on your partner chain.

2. **On your partner chain:**
2. **On your partner chain:**

- Connecting your partner chain to track the token and enable token operations across both chains.
- Connecting your partner chain to track the token and enable token operations across both chains.
- This involves following a step-by-step process for interacting with both the Cardano blockchain and your partner chain.

After you complete the steps in this guide, you will have a fully functioning token system that works across Cardano and your partner chain.
@@ -20,23 +20,21 @@ After you complete the steps in this guide, you will have a fully functioning to

## Prerequisites

- **Cardano Node Setup:** A running Cardano node, including Ogmios and Kupo, to interact with the Cardano blockchain.
- **Cardano Node Setup:** A running Cardano node, including Ogmios, to interact with the Cardano blockchain.

- **Partner Chain Node Setup:** A running partner chain node.

- **Development Environment:** Haskell and related tools installed for running scripts.

- **Native Token Creation Knowledge:** Familiarity with creating Cardano native tokens.

- **Command-Line Tools:** `pc-contracts-cli` ([partner-chains-smart-contracts release binary](https://github.com/input-output-hk/partner-chains-smart-contracts/releases))

## Rewards schemes

Please note that rewards schemes for token release is the responsibility of the Chain Builder.
Please note that rewards schemes for token release is the responsibility of the Chain Builder.

# Part One: Initialization

Initialization includes creating the native token on Cardano, writing the `VFunction`, running the commands `init-reserve-management` and `reserve-create` at the `pc-contracts-cli` side.
Initialization includes creating the native token on Cardano, writing the `VFunction`, running the commands `smart-contracts reserve init` and `smart-contracts reserve create` at the `partner-chains-node` side.

## 1. Setting up your token on Cardano

@@ -46,8 +44,8 @@ Objective: Create a Cardano native token within your partner chain ecosystem.

#### Steps

This step is outside the scope of partner chains and requires following the standard procedure for creating Cardano native tokens.
Please see: [Minting Native Assets](https://developers.cardano.org/docs/native-tokens/minting/) on the Cardano Developer Portal for details.
This step is outside the scope of partner chains and requires following the standard procedure for creating Cardano native tokens.
Please see: [Minting Native Assets](https://developers.cardano.org/docs/native-tokens/minting/) on the Cardano Developer Portal for details.
Generally speaking, however, the process includes these steps:

1. Defining the token policy: establishing the monetary policy script for your token.
@@ -77,17 +75,17 @@ Generally speaking, however, the process includes these steps:

- The Validity interval is to be present and equal to `[T, infinity]`, where `T` is time in the recent past, close to the current time.

- The Transaction input with ReserveAuthPolicy token is to be present.
- The Transaction input with ReserveAuthPolicy token is to be present.

- The `VFunction` should be able to mint X tokens and be invoked repeatedly, each time minting X new tokens. The value of X should grow in time and represent the total number of tokens to be released from the Reserve to IlliquidCirculationSupply up to the current moment in time.

- Smart contracts do not pass anything to each other directly. However, each smart contract in a given single transaction has access to the context of the whole transaction, including input UTXOs, datums, etc.

- Implementers of the `VFunction` should expect the validity interval to be correctly set up by the offchain release command.

**User responsibility:**
**User responsibility:**

- You need to provide the logic for `VFunction`, which determines how tokens are released.
- You need to provide the logic for `VFunction`, which determines how tokens are released.

- This logic can be written using native or Plutus scripts as well as Aiken scripts. The code should be compiled and attached as a reference script to UTXO.

@@ -107,253 +105,214 @@ Submit the transaction with the compiled `V(t)` release function:

```bash
cardano-cli conway transaction build \
--tx-in TX#TX_ID \
--tx-out OUT_ADDRESS+FEE \
--tx-out-reference-script-file reference.json \
--change-address CHANGE_ADDRESS --testnet-magic 2 --out-file tx
--tx-in TX#TX_ID \
--tx-out OUT_ADDRESS+FEE \
--tx-out-reference-script-file reference.json \
--change-address CHANGE_ADDRESS --testnet-magic 2 --out-file tx

cardano-cli conway transaction sign \
--tx-body-file tx \
--signing-key-file <PaymentSigningKeyFile> \
--testnet-magic 2 \
--out-file tx.signed
--tx-body-file tx \
--signing-key-file <PAYMENT_KEY_FILE> \
--testnet-magic 2 \
--out-file tx.signed

cardano-cli conway transaction submit --tx-file tx.signed --testnet-magic 2
```

#### Steps

1. Implement `VFunction` (see [example VFunction](https://github.com/input-output-hk/partner-chains-smart-contracts/blob/master/onchain/src/TrustlessSidechain/ExampleVFunction.hs) in the partner-chains-smart-contracts repository).
1. Implement `VFunction` (see [example VFunction](https://github.com/input-output-hk/partner-chains-smart-contracts/blob/master/onchain/src/TrustlessSidechain/ExampleVFunction.hs) in the partner-chains-smart-contracts repository).

2. Compile the `VFunction` script.

3. Include the script as a CBOR in the reference.json.

4. Add reference.json to the transaction and submit it to Cardano.
4. Add reference.json to the transaction and submit it to Cardano.

5. Find and note the hash#id for the transaction that has the `VFunction` script attached.

### 1.3 Initializing token reserve controls

Objective: Initialize the reserve management system for your token.

#### 1.3.1 Run the `init-reserve-management` command
#### 1.3.1 Run the `reserve init` command

Command template:

```bash
./pc-contracts-cli init-reserve-management \
--genesis-utxo <GenesisCommitteeHashUTxO> \
--ogmios-host <Ogmios_Host> \
--ogmios-port <Ogmios_Port> \
--kupo-host <Kupo_Host> \
--kupo-port <Kupo_Port> \
--payment-signing-key-file <PaymentSigningKeyFile> \
--network testnet
./partner-chains-node smart-contracts reserve init \
--genesis-utxo <GENESIS_UTXO> \
--ogmios-url <OGMIOS_URL> \
--payment-key-file <PAYMENT_KEY_FILE>
```

#### Steps

1. Execute the `init-reserve-management` command.
1. Execute the `reserve init` command.

2. Confirm initialization: Ensure that the `InitReserveManagement` scripts are correctly initialized by checking the command output.

### 1.4 Creating your token reserve

Objective: Create a reserve for your token and define the release function `V`.

#### 1.4.1 Run the `reserve-create` command
#### 1.4.1 Run the `reserve create` command

Command template:

```bash
/pc-contracts-cli reserve-create \
--genesis-utxo <GenesisCommitteeHashUTxO> \
--total-accrued-function-script-hash <VFunctionScriptHash> \
--reserve-posixtime-t0 <POSIXTimeT0> \
--reserve-asset-script-hash <ReserveAssetScriptHash> \
--reserve-asset-name <ReserveAssetName> \
--reserve-initial-deposit-amount <InitialDepositAmount> \
--ogmios-host <Ogmios_Host> \
--ogmios-port <Ogmios_Port> \
--kupo-host <Kupo_Host> \
--kupo-port <Kupo_Port> \
--payment-signing-key-file <PaymentSigningKeyFile> \
--network <Network>
/partner-chains-node smart-contracts reserve create \
--genesis-utxo <GENESIS_UTXO> \
--ogmios-url <OGMIOS_URL> \
--payment-key-file <PAYMENT_KEY_FILE> \
--total-accrued-function-script-hash <TOTAL_ACCRUED_FUNCTION_SCRIPT_HASH> \
--token <TOKEN> \
--initial-deposit-amount <INITIAL_DEPOSIT_AMOUNT>
```

#### Example command

```bash
/pc-contracts-cli reserve-create \
/partner-chains-node smart-contracts reserve create \
--genesis-utxo b88dd63b770357e58c30d17f364a7b681a8fd52f721614db35977594 \
--ogmios-url ws://localhost:1337 \
--payment-key-file payment.skey \
--total-accrued-function-script-hash e833119231cabfc4de0733b05e0889a736373079c414a1b8c9ae6ac0 \
--reserve-posixtime-t0 1729851426 \
--reserve-asset-script-hash 55e8a5e0df12e794f2e78f55848c7cbd8f6de9a23be16be98d769116 \
--reserve-asset-name 416c657854657374546f6b656e \
--reserve-initial-deposit-amount 1000000 \
--payment-signing-key-file payment.skey \
--ogmios-host localhost \
--ogmios-port 1337 \
--kupo-host localhost \
--kupo-port 1442 \
--network testnet
--token 55e8a5e0df12e794f2e78f55848c7cbd8f6de9a23be16be98d769116.416c657854657374546f6b656e \
--initial-deposit-amount 1000000
```

#### Explanation of parameters

* `--genesis-utxo`: The genesis UTXO of the running partnerchain.

* `--network`: The network you operate on (for example, `testnet` or `mainnet`).

* `--total-accrued-function-script-hash`: The script hash of your `V` function.

* `--reserve-posixtime-t0`: an integer that could possibly be used by user-defined `V` function. It will be written into PlutusData of UTXO at Reserve Validator. Deprecated. This field will be set to 0 in the future versions of the CLI.

* `--reserve-asset-script-hash`: The script hash of the reserve asset (policy ID).

* `--reserve-asset-name`: The asset name in hexadecimal.
* `--token`: Reserve token asset id encoded in form `<policy_id_hex>.<asset_name_hex>`.

* `--reserve-initial-deposit-amount`: The initial amount of tokens to deposit into the reserve.
* `--initial-deposit-amount`: The initial amount of tokens to deposit into the reserve.

* `--payment-signing-key-file`: Your payment signing key file for transaction signing. This key has to have `reserve-initial-deposit-amount` in its wallet.
* `--payment-key-file`: Your payment key file for transaction signing. This key has to have `initial-deposit-amount` in its wallet.

#### Steps

1. Prepare the parameters: Replace the placeholders with your actual values.

2. Execute the command: Run the `reserve-create` command with your parameters.
2. Execute the command: Run the `reserve create` command with your parameters.

3. Confirm initialization: Ensure that the reserve initialization transaction has been confirmed by checking the command output.


# Part Two: Usage

Usage includes the `reserve-release-funds` and `reserve-handover` commands.
Usage includes the `reserve release` and `reserve handover` commands.

- `reserve-handover` &ndash; a command for finishing the flow (either there is nothing to release or the Governance Authority user wants to finish the flow).
- `reserve-release-funds` &ndash; a command to "move" the flow until the end.
- `reserve handover` &ndash; a command for finishing the flow (either there is nothing to release or the Governance Authority user wants to finish the flow).
- `reserve release` &ndash; a command to "move" the flow until the end.

## 2. Releasing tokens from reserve to circulation

Objective: Release available reserve tokens (defined by the `VFunction`).

### 2.1 Run the `reserve-release-funds` command
### 2.1 Run the `reserve release` command

#### Command template

```bash
./pc-contracts-cli reserve-release-funds \
--genesis-utxo <GenesisCommitteeHashUTxO> \
--ogmios-host localhost \
--ogmios-port 1337 \
--kupo-host localhost \
--kupo-port 1442 \
--payment-signing-key-file <PaymentSigningKeyFile> \
--network <Network> \
--reserve-transaction-input 156803a18a4dbde48dc83a21b8b1007b693cdf096b73596252745fdef1de6414#0 \
--total-accrued-till-now 5
./partner-chains-node smart-contracts reserve release \
--genesis-utxo <GENESIS_UTXO> \
--ogmios-url ws://localhost:1337 \
--payment-key-file <PAYMENT_KEY_FILE> \
--reference-utxo 156803a18a4dbde48dc83a21b8b1007b693cdf096b73596252745fdef1de6414#0 \
--token <TOKEN> \
--amount <AMOUNT>
```

#### Explanation of parameters

* `--genesis-utxo`: The genesis UTXO of the running partnerchain
* `--genesis-utxo`: The genesis UTXO of the running partnerchain.

* `--network`: The network you operate on (for example, `testnet` or `mainnet`)
* `--payment-key-file`: Your payment key file for transaction signing.

* `--payment-signing-key-file`: Your payment signing key file for transaction signing
* `--reference-utxo`: UTXO where the `VFunction` script is attached as a reference.

* `--reserve-transaction-input`: UTXO where the `VFunction` script is attached as a reference
* `--token`: Reserve token asset id encoded in form `<policy_id_hex>.<asset_name_hex>`.

* `--total-accrued-till-now`: amount of tokens to release
* `--amount`: amount of tokens to release

- The number should be calculated as `number of tokens release up to this time + amount of tokens to release`

- If 10 tokens have already been released and you want to release 10 more, then the total accrued until now should be defined as 20.
- If 10 tokens have already been released and you want to release 10 more, then the total accrued until now should be defined as 20.

- If `--total-accrued-till-now` passed by the user is lower than the factual number, then nothing will be released.
- If `--amount` passed by the user is lower than the factual number, then nothing will be released.

- Ensure you have enough tokens to release in this time frame (the `VFunction` defines release logic).
- Ensure you have enough tokens to release in this time frame (the `VFunction` defines release logic).

#### Steps

1. Execute the `reserve-release-funds` command.
1. Execute the `reserve release` command.

2. Confirm completion: make sure that the release process has been completed by checking the command output.

## 2.2 Transferring token control to smart contracts

Objective: Complete the reserve setup by handing over control to the appropriate scripts.

### 2.2.1 Run the `reserve-handover` command
### 2.2.1 Run the `reserve handover` command

#### Command template

```bash
./pc-contracts-cli reserve-handover \
--genesis-utxo <GenesisCommitteeHashUTxO> \
--ogmios-host <Ogmios_Host> \
--ogmios-port <Ogmios_Port> \
--kupo-host <Kupo_Host> \
--kupo-port <Kupo_Port> \
--payment-signing-key-file <PaymentSigningKeyFile> \
--network <Network>
--hand-over
./partner-chains-node smart-contracts reserve handover \
--genesis-utxo <GENESIS_UTXO> \
--ogmios-url <OGMIOS_URL> \
--payment-key-file <PAYMENT_KEY_FILE>
```

#### Steps

1. Execute the `reserve-handover` command.
1. Execute the `reserve handover` command.

2. Confirm completion: Make sure that the handover process has been completed and the illiquid circulation supply transaction has been confirmed by checking the command output.

## 3 Initializing token reserve with initial deposit

Objective: Configure the initial token reserve by depositing a specified amount of tokens into the reserve contract.

### 3.1 Run the `reserve-deposit` command (optional)
### 3.1 Run the `reserve deposit` command (optional)

#### Command template

```bash
./pc-contracts-cli reserve-deposit \
--genesis-utxo <GenesisCommitteeHashUTxO> \
--deposit-reserve-asset c1ad57f3e3e6e69562cd2236fe05b4494bb4826269c3d0c7e1123220 \
--reserve-asset-name 54657374546f6b656e30313039 \
--reserve-initial-deposit-amount 100 \
--ogmios-host localhost \
--ogmios-port 1337 \
--kupo-host localhost \
--kupo-port 1442 \
--payment-signing-key-file <PaymentSigningKeyFile> \
--network <Network>
./partner-chains-node smart-contracts reserve deposit \
--genesis-utxo <GENESIS_UTXO> \
--ogmios-url ws://localhost:1337 \
--payment-key-file <PAYMENT_KEY_FILE> \
--token <TOKEN> \
--amount <AMOUNT>
```

#### Explanation of parameters

* `--genesis-utxo`: The genesis UTXO of the running partner chain

* `--network`: The network you operate on (for example, `testnet` or `mainnet`)

* `--payment-signing-key-file`: Your payment signing key file for transaction signing
* `--genesis-utxo`: The genesis UTXO of the running partner chain.

* `--deposit-reserve-asset`: The script hash of the reserve asset (policy ID)
* `--payment-key-file`: Your payment key file for transaction signing.

* `--reserve-asset-name`: The asset name in hexadecimal
* `--token`: Reserve token asset id encoded in form `<policy_id_hex>.<asset_name_hex>`.

* `--reserve-initial-deposit-amount`: The amount of tokens to deposit into the reserve
* `--amount`: Amount of tokens to deposit. They must be present in the payment wallet.

#### Steps

1. Replace the placeholder values with your specific configuration parameters.

2. Execute the `reserve-deposit` command.
2. Execute the `reserve deposit` command.

3. Verify that the deposit completed successfully by checking the command output status.

# Part Three: Configuration

Configuration includes `reserve-update-settings` commands used to either change token in reserve or `VFunction`.
Configuration includes `reserve update-settings` commands used to either change token in reserve or `VFunction`.

<!-- Only "initialize", "create" and "update settings" are related to configuration. -->

@@ -369,28 +328,22 @@ Objective: Collect the essential parameters needed to configure the native token

- NATIVE_TOKEN_ASSET_NAME - the asset name from Step 1.1.

- ILLIQUID_SUPPLY_VALIDATOR_ADDRESS - can be obtained from the output of the `addresses` command (see below).
- ILLIQUID_SUPPLY_VALIDATOR_ADDRESS - can be obtained from the output of the `get-scripts` command (see below).

#### 4.1.1 Retrieving the validator address

Execute the `addresses` command:
Execute the `get-scripts` command:

```bash
./pc-contracts-cli addresses \
--genesis-utxo <GenesisCommitteeHashUTxO> \
--ogmios-host <Ogmios_Host> \
--ogmios-port <Ogmios_Port> \
--kupo-host <Kupo_Host> \
--kupo-port <Kupo_Port> \
--payment-signing-key-file <PaymentSigningKeyFile> \
--network <Network>
./partner-chains-node smart-contracts get-scripts \
--genesis-utxo <GENESIS_UTXO> \
--ogmios-url <OGMIOS_URL> \
```

Locate the validator address in the command output:
Locate the validator address in the command output:

```bash
{
"endpoint": "GetAddrs",
"addresses": {
...
"IlliquidCirculationSupplyValidator": "<ADDRESS>"
@@ -419,7 +372,7 @@ Objective: Update native token configuration if migration has already happened.

**Warning:** The following steps need to be executed by the Governance Authority from the sudo account in the Polkadot UI.

1. Run `set_main_chain_scripts` extrinsic on the nativeTokenManagement pallet via the Polkadot UI portal to set the native token `policy ID`, `asset name`, and `illiquid supply validator address`.
1. Run `set_main_chain_scripts` extrinsic on the nativeTokenManagement pallet via the Polkadot UI portal to set the native token `policy ID`, `asset name`, and `illiquid supply validator address`.

![Polkadot UI portal](Polkadot-UI-portal-native-token-mgt.png)

@@ -441,12 +394,12 @@ Example native token configuration:

* The partner chains node follows any token movements on the illiquid supply validator address once the block becomes stable on Cardano (it is based on the `securityParam` of Cardano).

- The `securityParam` of Cardano specifies that the blockchain is considered to be final after 2160 blocks for mainnet. See [CIPs/CIP-0009/README.md](https://github.com/cardano-foundation/CIPs/blob/master/CIP-0009/README.md#non-updatable-parameters) for details about the protocol parameter specifications.
- The `securityParam` of Cardano specifies that the blockchain is considered to be final after 2160 blocks for mainnet. See [CIPs/CIP-0009/README.md](https://github.com/cardano-foundation/CIPs/blob/master/CIP-0009/README.md#non-updatable-parameters) for details about the protocol parameter specifications.

- 2.5h for preview

- ~12h for mainnet

* The `reserve-deposit` command can be executed only by the governance authority &ndash; the one who created the reserve.
* The `reserve deposit` command can be executed only by the governance authority &ndash; the one who created the reserve.

* One native token is expected to be in the reserve at a time. The governance authority can create another reserve with another token for a single genesis UTXO. However, it is recommended to move all tokens from the `ReserveValidator` address to the `IlliquidSupplyValidator` address (using `release-handover`) before starting to manage a second token.
* One native token is expected to be in the reserve at a time. The governance authority can create another reserve with another token for a single genesis UTXO. However, it is recommended to move all tokens from the `ReserveValidator` address to the `IlliquidSupplyValidator` address (using `release-handover`) before starting to manage a second token.

0 comments on commit 53d257e

Please sign in to comment.