Cardano Token und NFTs automatisch von einer Webseite erzeugen

Mit Alonzo werden die explorer-api und die submit-api sterben. Zeit sich nach etwas Neuen umzusehen, wenn man eine API braucht.

Das Ziel ist es, mit onchain Daten per JSON über HTTP zu interagieren.

Die neuen Cardano APIs Pakete sind

In diesem Zusammenhang ist ebenfalls die

Cardano-Wallet einrichten

Zunächst laden wir uns den neuesten build der Cardano-Wallet-Api herunter. Wir bekommen den build von der github Seite des Projekts:

https://github.com/input-output-hk/cardano-wallet/releases/tag/

Hier den neuesten Release suchen und herunterladen.

Wir erstellen uns ein Verzeichnis cardano-my-wallet in HOME.

Wir wechseln dorthin:

cd ~/cardano-my-wallet

Jetzt erstellen wir ein Verzeichnis db in cardano-my-wallet.

Jetzt erstellen wir ein weiteres Verzeichnis bin in cardano-my-wallet.

Wir verschieben den soeben heruntergeladenen Release der Cardano-Wallet-API dorthin und entpacken es nach ~/cardano-my-wallet/bin.

Als nächstes erstellen wir in ~/cardano-my-wallet folgende Datei startCardanoWallet.sh:

DIRECTORY=/home/sniemeyer/cardano-my-wallet
#PORT=6000
HOSTADDR=0.0.0.0
DB_PATH=${DIRECTORY}/db
CA_CERT=${DIRECTORY}/cert/ca-crt.pem
SV_CERT=${DIRECTORY}/cert/server-crt.pem
SV_KEY=${DIRECTORY}/cert/server-key.pem
bin/cardano-wallet serve --listen-address $HOSTADDR --node-socket /home/sniemeyer/cardano-my-node/db/socket --mainnet --database $DB_PATH --tls-ca-cert $CA_CERT --tls-sv-cert $SV_CERT --tls-sv-key $SV_KEY

Wir machen die Datei mit chmod +x startCardanoWallet.sh ausführbar.

Nun erstellen wir im Verzeichnis ~/cardano-my-wallet folgende Datei cardano-wallet.service:

# The Cardano wallet service (part of systemd)
# file: /etc/systemd/system/cardano-wallet.service

[Unit]
Description = Cardano wallet service
Wants = network-online.target
After = network-online.target cardano-node.service

[Service]
User = sniemeyer
Type = simple
WorkingDirectory= /home/sniemeyer/cardano-my-wallet
ExecStart = /bin/bash -c '/home/sniemeyer/cardano-my-wallet/startCardanoWallet.sh'
KillSignal=SIGINT
RestartKillSignal=SIGINT
TimeoutStopSec=2
LimitNOFILE=32768
Restart=always
RestartSec=5
SyslogIdentifier=cardano-wallet

[Install]
WantedBy= multi-user.target

Die Datei cardano-wallet.service verschieben wir nach systemd und aktivieren den Service:

sudo mv cardano-wallet.service /etc/systemd/system/
sudo chmod 644 /etc/systemd/system/cardano-wallet.service
sudo systemctl daemon-reload
sudo systemctl enable cardano-wallet

Jetzt sollte der systemd service für die Cardano-Wallet-Api aktiv sein. Die API läuft allerdings noch nicht. Aktivieren können wir sie mit:

sudo systemctl start cardano-wallet.service

Die Ausgabe können wir mit journalctl verfolgen:

journalctl --unit=cardano-wallet --follow

Um die Cardano-Wallet-API von außen erreichen zu können, müssen wir unter Umständen die Firewall freischalten:

sudo ufw allow 8090

Wir sehen, die Cardano-Wallet-API läuft auf dem Port 8090.

Gratulation, jetzt sollte alles funktionieren.

Absichern der Wallet

Die Cardano-Wallet unterstützt tls-Authentifizierung, diese werden wir nutzen.

Dafür wird eine Mutual authentification mittels openssl Zertifikaten verwendet. Die Einrichtung ist hier im Blog in diesem Beitrag beschrieben.

Es ist wichtig, dass x509.V3 verwendet wird, da sonst zum hier beschriebenen Fehler kommt.

Einfache Aktionen mit der Cardano-Wallet-API

Die API Beschreibung der Wallet API kann unter:

gefunden werden.

Ein wenig Dokumentation findet sich hier:

Payment Adresse

Wir brauchen eine Payment Adresse, um möglichst nahe an einer Automatisierung zu sein, leiten wir eine neue Payment Adresse von einer Wallet her und prüfen die Balance.

Hierzu können wir uns an dem Vorgehen von der developers Seite halten.

Zunächst holen wir uns eine Adresse von der bestehenden Wallet, die noch ungenutzt ist:

curl --cert certs/client1-crt.pem --cacert certs/ca-crt.pem --key /certs/client1-key.pem https://relaynode1.fire-pool.com:8001/v2/wallets/<walletid>/addresses?state=unused

Wir wählen uns eine Adresse aus, zum Beispiel diese hier:

addr1qyc8van85drxkd4dxyk3eslx03ly22kpw300aywetkkeyvtcgdtgs8q2xexajy8hr2lrh57gfjlzjrdm0s70jcv7qnvqncvt3x

Wir warten, bis die Adresse in der Liste der Used adresses auftraucht:

curl --cert certs/client1-crt.pem --cacert certs/ca-crt.pem --key /certs/client1-key.pem https://relaynode1.fire-pool.com:8001/v2/wallets/<walletid>/addresses?state=used

Wechselt die Adresse zu used, dann schauen wir, ob die korrekte Balance autaucht:

curl --cert certs/client1-crt.pem --cacert /certs/ca-crt.pem --key /certs/client1-key.pem https://relaynode1.fire-pool.com:8090/v2/wallets/<walletid>/transactions

Hier müssen wir leider alle Transaktionen der Wallet holen und unsere Adresse heraussuchen.

Cardano-Submit-Api einrichten

Zum Zeitpunkt, wo dieses Tutorial entsteht, kann die Wallet-API noch keine Assets minten. Das bedeutet, dass wir die Cardano-Submit-Api brauchen werden, um die Transaktionen abzuschließen. Vergleiche hierzu die Diskussion im folgenden Issue im Cardano Node Github.

Ich gehe davon aus, dass auf dem Server bereits einer nach diesem Tutorial eingerichtete Cardano Node läuft. Das heißt, Cabal und alle Environment Variablen sind gesetzt.

Im 1. Schritt bauen wir nun die Cardano-Submit-Api. Folgende Kommanodos führen zum Ziel:

cd $HOME/git/cardano-node
rm -Rf dist-newstyle/build/x86_64-linux/ghc-8.10.7/cardano-submit-api-3.1.2/
cabal build cardano-submit-api
sudo cp dist-newstyle/build/x86_64-linux/ghc-8.10.7/cardano-submit-api-3.1.2/x/cardano-submit-api/build/cardano-submit-api/cardano-submit-api /usr/local/bin/
cd $HOME

Wir testen die submit-api:

cardano-submit-api --shelley-mode --mainnet --socket-path $CARDANO_NODE_SOCKET_PATH --listen-address 0.0.0.0 --port 8101 --config git/cardano-node/cardano-submit-api/config/tx-submit-mainnet-config.yaml

Der Submit-Api Server sollte ohne Beanstandung starten. Wir können jetzt das Environment einrichten, so dass der Server automatisch startet und von außen erreichbar ist. Zunächst wird der Server jetzt wieder beendet. Strg+C.

Wir erstellen ein Konfigurationsverzeichnis für die submit-API:

mkdir cardano-my-submit
cd cardano-my-submit

Wir kopieren nun die vorgefertigte tx-submit-mainnet-config.yaml das Verzeichnis cardano-my-submit:

cp ../git/cardano-node/cardano-submit-api/config/tx-submit-mainnet-config.yaml .

Um später einen systemd-Service erstellen zu können, erstellen wir nun die starter-Datei:

touch startCardanoSubmitApi.sh
nano startCardanoSubmitApi.sh

Die Datei bekommt folgenden Inhalt:

#!/bin/bash
DIRECTORY=/home/sniemeyer/cardano-my-submit
PORT=8101
HOSTADDR=0.0.0.0
CONFIG_PATH=${DIRECTORY}/tx-submit-mainnet-config.yaml

cardano-submit-api --shelley-mode --mainnet --socket-path /home/sniemeyer/cardano-my-node/db/socket --listen-address $HOSTADDR --port $PORT --config $CONFIG_PATH

Wir machen die Datei mit chmod +x startCardanoSubmitApi.sh ausführbar

Jetzt erstellen wir einen systemd-Service für unsere zukünftige Node. Wir erstellen die Datei cardano-submit.service:

touch cardano-submit.service

Die Datei bekommt folgenden Inhalt:

# The Cardano wallet service (part of systemd) 
# file: /etc/systemd/system/cardano-submit.service 

[Unit] 
Description = Cardano submit service 
Wants = network-online.target 
After = network-online.target cardano-node.service 

[Service] 
User = sniemeyer 
Type = simple 
WorkingDirectory= /home/sniemeyer/cardano-my-submit 
ExecStart = /bin/bash -c '/home/sniemeyer/cardano-my-submit/startCardanoSubmitApi.sh' 
KillSignal=SIGINT 
RestartKillSignal=SIGINT 
TimeoutStopSec=2 
LimitNOFILE=32768 
Restart=always 
RestartSec=5 
SyslogIdentifier=cardano-submit 

[Install] 
WantedBy= multi-user.target

Die Datei cardano-submit.service verschieben wir nach /etc/systemd/system und aktivieren den Service:

sudo mv cardano-submit.service /etc/systemd/system/
sudo chmod 644 /etc/systemd/system/cardano-submit.service
sudo systemctl daemon-reload
sudo systemctl enable cardano-submit

Jetzt sollte der systemd service für die Cardano-Submit-Api aktiv sein. Die API läuft allerdings noch nicht. Aktivieren können wir sie mit:

sudo systemctl start cardano-submit.service

Die Ausgabe können wir mit journalctl verfolgen:

journalctl --unit=cardano-submit --follow

Um die Cardano-Submit-API von außen erreichen zu können, müssen wir unter Umständen die Firewall freischalten:

sudo ufw allow 8101

Wir sehen, die Cardano-Submit-API läuft auf dem Port 8101.

Gratulation, jetzt sollte alles funktionieren.

Umgang mit der Submit API

Die Dokumentation der API kann hier gefunden werden:

Informationen zum Testen der API können hier gefunden werden:

Token manuell Minten

Bevor wir zur Automatisierung des Vorgangs kommen, führen wir den Mint Vorgang zunächst manuell durch.

Unsere Verzeichnisstruktur wird so aussehen:

├── burning.raw # Raw transaction to burn token
├── burning.signed # Signed transaction to burn token
├── matx.raw # Raw transaction to mint token
├── matx.signed # Signed transaction to mint token
├── metadata.json # Metadata to specify NFT attributes
├── payment.addr # Address to send / receive 
├── payment.skey # Payment signing key
├── payment.vkey # Payment verification key
├── policy # Folder which holds everything policy-wise
│ ├── policy.script # Script to genereate the policyID
│ ├── policy.skey # Policy signing key
│ ├── policy.vkey # Policy verification key
│ └── policyID # File which holds the policy ID
└── protocol.json # Protocol parameters

Vorbedingungen

Zunächst die Vorbereitung. Wir benötigen eine Wallet, auf die wir mit der Wallet-API Zugriff haben.

Wallet erstellen:

Diesen Schritt können wir am besten handhaben, wie in Cardano Wallets und Adressen verwalten, beschrieben.

Der Wallet ein Paar Funds geben, um die Transaktionsgebühren bezahlen zu können. Max 10 Ada sollten locker ausreichen.

Environment steht:

Das Environment muss stehen. Das bedeutet, dass die Variable CARDANO_NODE_SOCKET_PATH getsetzt sein muss und die Node laufen muss.

Wir testen das mit folgenden Kommando:

cardano-cli query tip --mainnet

Epoche und slot müsen mit einen beliebigen block-explorer übereinstimmen.

Einrichten

Wir richten nun unsere Umgebung ein.

Beginnen wir mit dem Workspace:

mkdir cardano-my-token
cd cardano-my-murphToken
mkdir Lunatic
cd Lunatic

Eine Datei environment mit folgenden Inhalt erstellen:

mainnet="mainnet"
tokenname1="Lunatic"
tokenamount="2000000"
output="0"

Nun erstellen wir uns eine Payment Adresse, welche wir mit Funds versorgen können, um den Token zu minten:

cardano-cli address build --payment-verification-key-file payment.vkey --out-file LunaticsPayment.addr --$mainnet
address=$(cat LunaticsPayment.addr)

Für die Transaktionen werden wir die Protokoll Parameter brauchen:

cardano-cli query protocol-parameters --$mainnet --out-file protocol.json

Der Minting Prozess

Der Prozess besteht aus 3 Schritt

  • Policy
  • Minten
  • Transaktion

Policy

Wir erstellen die Policy:

mkdir policy

Wir werden nicht in dieses Verzeichnis wechseln und stattdessen alles von unseren Arbeitsverzeichnis aus erledigen.

Wir erstellen jetzt den policy key, für den neuen Token:

cardano-cli address key-gen --verification-key-file policy/policy.vkey --signing-key-file policy/policy.skey

Nun benötigen wir ein policy.script, zunächst füllen wir es mit einen leeren string:

touch policy/policy.script && echo "" > policy/policy.script

Diese Datei befüllen wir nun mithilfe des echo Kommandos:

echo "{" >> policy/policy.script 
echo " \"keyHash\": \"$(cardano-cli address key-hash --payment-verification-key-file policy/policy.vkey)\"," >> policy/policy.script 
echo " \"type\": \"sig\"" >> policy/policy.script 
echo "}" >> policy/policy.script

Dies ist ein extrem einfaches Skript, kein Timelock keine weiteren Signaturen. Wer auch immer den policy key besitzt, kann beliebig viele Tokens für immer erstellen.

Asset Minten

Wir beginnen damit eine policy ID vom soeben erstellten Skript zu erstellen.

cardano-cli transaction policyid --script-file ./policy/policy.script >> policy/policyID

Bis hierhin sind wir komplett ohne Blockchain, Node oder irgendwelcher Verbindungen zur Blockchain ausgekommen. Die oben bereits geholten Netzwerkparameter und das Funding der erstellten Wallet Adresse, wäre bisher noch nicht notwendig geworden.

Erst jetzt wird eine funktionierende Node wichtig, denn der eigentliche Minting Vorgang ist nichts anderes, als eine Transaktion, welche die bisher erstellten Skripte mit auf dem Weg bekommt.

Wir prüfen die utxo der erstellten Adresse LunaticsPayment.addr:

cardano-cli query utxo --address $(cat LunaticsPayment.addr) --$mainnet

Merke: Die letzte Transaktion liegt oben auf! Das bedeutet, die obersten Einträge sind für uns wichtig.

Wir benötigen alle Werte der Ausgabe, daher speichern wir diese in Shell Variablen:

txhash=<hash>
txix="TxIx"
funds="Amount"
policyid=$(cat policy/policyID)

Da eine Transaktion auch eine fee kostet, speichern wir zunächst eine fiktionale fee, wir werden den Wert noch ersetzen:

fee=”300000″

Wir bauen nun eine Transaktion, um die fee berechnen zu können:

cardano-cli transaction build-raw --fee $fee --tx-in $txhash#$txix --tx-out $address+$output+"$tokenamount $policyid.$tokenname1" --mint=$tokenamount $policyid.$tokenname1" --minting-script-file policy/policy.script --out-file matx.raw

Damit haben wir alles, um die fee berechnen zu können:

fee=$(cardano-cli transaction calculate-min-fee --tx-body-file matx.raw --tx-in-count 1 --tx-out-count 1 --witness-count 2 --$mainnet --protocol-params-file protocol.json | cut -d " " -f1)

Jetzt können wir den output berechnen:

output=$(expr $funds - $fee)

Jetzt setzen wir das exakt gleiche Transaction command noch einmal ab, aber eben mit korrekter fee und output:

cardano-cli transaction build-raw --fee $fee --tx-in $txhash#$txix --tx-out $address+$output+"$tokenamount $policyid.$tokenname1" --mint=$tokenamount $policyid.$tokenname1" --minting-script-file policy/policy.script --out-file matx.raw

Nun signieren wir die raw-transaction

cardano-cli transaction sign --signing-key-file payment.skey --signing-key-file policy/policy.skey --$mainnet --out-file matx.signed

Schlussendlich submitten wir das signed transaction file

cardano-cli transaction submit --tx-file matx.signed --$mainnet

Gratulation, der token ist geminted, nach einigen Sekunden, wird er in der Wallet erscheinen.

Prüfbar, auch per folgenden Kommando:

cardano-cli query utxo --address $address --$mainnet

NFT manuell Minten

NFTs sind nativen assets sehr ähnlich. Trotzdem existieren einige Unterschiede, daher hier die Unterschiede im Detail.

Distinktion gegenüber nativen token

  • NFT sind “non-fungible”. Das bedeutet, dass jeder einzelne NFT Token zum Nächsten unterscheidbar sein muss.
  • Ein NFT bleibt ewig auf der Blockchain, es ist unmöglich ihn zu löschen. Damit er auch immer eindeutig bleibt, brauchen wir Mechanismen um sicherzustellen, das niemand einen NFT mit gleichen Eigenschaften erzeugt.

Die policyID

Ein Token hat folgende Identifikationen:

  • Menge/Anzahl
  • Name
  • Eine einzigartige PolicyID

Da ein Name gedoppelt werden kann, werden NFTs komplett über die policyID identifiziert.

Diese ID wird dem Asset (NFT) permanent zugewiesen. Die PolicyID stammt aus dem policy script, beziehungsweise identifiziert dieses.

Viele NFT Projekte machen die policyID mit der ein NFT geminted wurde öffentlich, so das gedoppelte oder gefälschte NFTs schnell identifiziert werden können. 

Einige Dienste erlauben es auch die policyID eines Tokens zu registrieren.

Metadaten Attribute

Zusätzlich zum notwendigen policy script und der policyID können Metadaten zum NFT-Asset hinzugefügt werden.

Ein Beispiel von nft-maker.io

{
    "721": {
        "{policy_id}": {
            "{policy_name}": {
                "name": "<required>",
                "description": "<optional>",
                "sha256": "<required>",
                "type": "<required>",
                "image": "<required>",
                "location": {
                    "ipfs": "<required>",
                    "https": "<optional>",
                    "arweave": "<optional>"
                }
            }
        }
    }
}

Die Metadaten sind für einen NFT sogar grundsätzlich notwendig, denn durch diese können wir die Daten zum Asset angeben. Zum Beispiel eine Bild-URL.

So können drittanbier Dienste, wie pool.pm Daten zum Asset extrahieren:

  • Asset Name und policyID
  • Die letzte minting Transaktion
  • Metadaten
  • Asset Name mit policy name abgleichen
  • Query auf das IPFS (Hash Query).

Time locking

Da NFT in der Regel als Einzelstücke gehandelt werden. Das heißt gekauft und verkauft. Sollten sie noch einige zusätzliche Sicherheiten beinhalten.

Das ist enorm wichtig, denn Assets erhalten ihren Wert durch die Knappheit. Daher muss ein unkontrolliertes Vervielfältigen der Assets absolut ausgeschlossen werden.

Diese Dinge können durch multi-signature-scripts geregelt werden.

Im einfachen weg (Wir wählen diesen hier) reicht folgendes.

Nur eine einzige Signatur darf den NFT minten.

Nach 10000 Slots wird das Minten des NFTs endgültig verboten.

Vorbedingungen

  • Eine laufende Cardano node.
  • Gutes Verständnis von Linux Systemen und ihrer Shell.
  • Wir müssen wissen, welchen NFT wir minten möchten und wie viele.
  • Eine bereits veröffentlichte metadata.json
  • Die Minting policy, dass heißt, wie diese aussehen soll
  • Hash des hochzuladenen Bildes.

Setup

Wir fangen wieder mit unseren Arbeitsverzeichnis an, welches wir nach erstellen auch nicht mehr verlassen werden:

mkdir murphNft1
cd murphNft1

Im nächsten Schritt setzen wir wieder einige Umgebungsvariablen:

tokenname="murphChainInverted"
hexTokenname=$(echo -n $realtokenname | xxd -b -ps -c 80 | tr -d '\n')
tokenamount="1"
fee="0"
output="0"
ipfs_hash="<The IPFS CID File Hash>"

Keys und Adressen

Die Keys und die Adresse für das Payment, bzw. die Transaktionen, können nach dieser Anleitung erzeugt werden.

Den Address-Hash speichern wir dann folgendermaßen:

address=$(cat payment.addr)

Wir werden die Adresse nun mit 10 Ada befüllen, dass reicht für unsere Zwecke aus.

Nach dem funding können wir mit folgenden Kommando:

cardano-cli query utxo --address $address --mainnet

Eine Ausgabe wie diesen hervorbringen:

 TxHash                                                             TxIx     Amount
--------------------------------------------------------------------------------------
0e3a50b81b824ae5a76a033069d1d42da2d32d0969a04f77992f8daffee26c92    0        8647174 lovelace + TxOutDatumNone

alle Werte hier speichern wir nun in Bash-Variablen

txhash
txix
amount

Als nächstes holen wir uns die Protokollparameter:

cardano-cli query protocol-parameters --mainnet --out-file protocol.json

Die Policy

Wir fangen mit der Erstellung des entsprechenden Verzeichnisses an:

mkdir policy

Jetzt erzeugen wir in diesem Verzeichnis den Schlüsselsatz:

cardano-cli address key-gen \
--verification-key-file policy/policy.vkey \
--signing-key-file policy/policy.skey

Jetzt erstellen wir das policy Skript. Dieses Skript hat eine Besonderheit gegenüber dem Asset Skript, wir erstellen es mit einem Time Lock. Das bedeutet, dass wir das minten des Tokens nach einem bestimmten Slot verbieten. So wird es zu einen wirklichen NFT. Niemand kann weitere NFTs dieser Art erzeugen. Er wird einzigartig.

Ein policy.script könnte so aussehen:

{
    "type": "all",
    "scripts":
    [
        {
            "type": "before",
            "slot": <insert slot here>
        },
        {
            "type": "sig",
            "keyHash": "insert keyHash here"
        }
    ]
}

Am einfachsten ist es folgendermaßen zu erstellen:

echo "{" >> policy/policy.script
echo " \"type\": \"all\"," >> policy/policy.script 
echo " \"scripts\":" >> policy/policy.script 
echo " [" >> policy/policy.script 
echo " {" >> policy/policy.script 
echo " \"type\": \"before\"," >> policy/policy.script 
echo " \"slot\": $(expr $(cardano-cli query tip --mainnet | jq .slot?) + 10000)" >> policy/policy.script
echo " }," >> policy/policy.script 
echo " {" >> policy/policy.script
echo " \"type\": \"sig\"," >> policy/policy.script 
echo " \"keyHash\": \"$(cardano-cli address key-hash --payment-verification-key-file policy/policy.vkey)\"" >> policy/policy.script 
echo " }" >> policy/policy.script
echo " ]" >> policy/policy.script 
echo "}" >> policy/policy.script

Jetzt erstellen wir die policyId:

cardano-cli transaction policyid --script-file ./policy/policy.script >> policy/policyID

Die Metadaten

Jetzt wo wir die policyID des zukünftigen NFTs haben, können wir die Metadaten erstellen und mit der policy – Das heißt dem NFT – verknüpfen.

{
    "721": {
    "please_insert_policyID_here": {
        "NFT1": {
            "description": "This is my first NFT thanks to the Cardano foundation",
            "name": "Cardano foundation NFT guide token",
            "id": 1,
            "image": ""
            }
        }
    }
}

Hier muss NFT1 (Das dritte Element) mit unseren NFT Namen verknüpft sein. Das heißt, derselbe sein. Die policyID natürlich ebenso und der korrekte Pfad zum IPFS Image ist absolut wünschenswert.

Die 721, sind ein standard Wert, dieser Wert gehört zur grundstruktur einen jeden Cardano-NFT.

Automatisch können die Metadaten folgendermaßen erstellt werden:

echo "{" >> metadata.json
echo " \"721\": {" >> metadata.json 
echo " \"$(cat policy/policyID)\": {" >> metadata.json 
echo " \"$(echo $tokenname)\": {" >> metadata.json
echo " \"description\": \"This is my first NFT thanks to the Cardano foundation\"," >> metadata.json
echo " \"name\": \"Cardano foundation NFT guide token\"," >> metadata.json
echo " \"id\": \"1\"," >> metadata.json
echo " \"image\": \"ipfs://$(echo $ipfs_hash)\"" >> metadata.json
echo " }" >> metadata.json
echo " }" >> metadata.json 
echo " }" >> metadata.json 
echo "}" >> metadata.json

Die Transaktion

Wir haben nun alle Informationen, die wir brauchen. Die Transaktion kann beginnen.

1. Schritt: Wir holen uns die Transaktionsdaten der vorherigen Transaktion, um den utxo Status der Adresse zu kennen:

cardano-cli query utxo --address $address --mainnet

Es ergibt folgend formatierte Ausagabe:

                     TxHash                                         TxIx     Amount
--------------------------------------------------------------------------------------
0e3a50b81b824ae5a76a033069d1d42da2d32d0969a04f77992f8daffee26c92    0        8647174 lovelace + TxOutDatumNone

2. Schritt: wir notieren alle relevanten Daten in Bash-Variablen:

txhash="insert your txhash here"
txix="insert your TxIx here"
funds="insert Amount in lovelace here"
policyid=$(cat policy/policyID)
script="policy/policy.script
slotnumber=<insert the slotnumber from the policy script here!>

3. Schritt: Zur Sicherheit noch einmal alle Werte durchgehen:

echo $fee
echo $address
echo $output
echo $tokenamount
echo $policyid
echo $hexTokenname
echo $slotnumber
echo $script

4. Schritt: Alles ist gut, wir legen mit der Raw-Transaction los:

cardano-cli transaction build-raw \
--fee $fee \
--tx-in $txhash#$txix \
--tx-out $address+$output+"$tokenamount $policyid.$hexTokenname" \
--mint="$tokenamount $policyid.$hexTokenname" \
--minting-script-file $script \
--metadata-json-file metadata.json \
--invalid-hereafter $slotnumber \
--out-file matx.raw

5. Schritt: Damit berechnen wir die Fee:

fee=$(cardano-cli transaction calculate-min-fee --tx-body-file matx.raw --tx-in-count 1 --tx-out-count 1 --witness-count 2 --mainnet --protocol-params-file protocol.json | cut -d " " -f1)

6. Schritt: Damit berechnen wir den neuen output:

output=$(expr $funds - $fee)

7. Schritt: Jetzt können wir die endgültige Transaktion bauen:

cardano-cli transaction build-raw \
--fee $fee \
--tx-in $txhash#$txix \
--tx-out $address+$output+"$tokenamount $policyid.$hexTokenname" \
--mint="$tokenamount $policyid.$hexTokenname" \
--minting-script-file $script \
--metadata-json-file metadata.json \
--invalid-hereafter $slotnumber \
--out-file matx.raw

8. Schritt: Wir signieren die Transaktion:

cardano-cli transaction sign \
--signing-key-file addr.skey \
--signing-key-file policy/policy.skey \
--mainnet --tx-body-file matx.raw \
--out-file matx.signed

9. Schritt: Wir feuern die Transaktion auf die Blockchain ab:

cardano-cli transaction submit --tx-file matx.signed --mainnet

10. Schritt: Wir prüfen das Resultat:

cardano-cli query utxo --address $address --mainnet

Die Token Registry

Nachdem ein Asset erstellt wurde, macht es Sinn, dieses in die Token Registry einzutragen.

5 Vorbedingungen müssen für einen Eintrag vorliegen:

  • Das asset muss geminted sein
  • Das monetary policy script unseres nativen assets.
  • Der asset name unseres assets.
  • Die policyID des policy scripts.
  • Die privaten keys, welche für die asset policy verwendet wurden. (Zum signieren derer)
  • Wir brauchen die off-chain-metadaten tools
  • Wir brauchen einen github account und müssen die cardano-token-registry forken

Haben wir all das parat, dann können wir loslegen.

Schritt 1: Das “subject” erstellen:

Beispiel: Wir haben folgendes asset

90dcf637d6c683aa82a27177cda8dc4856cde44e678f5700ac845534.Murph

Dies führt zu folgenden Kommando:

echo -n "Murph" | xxd -ps
4d75727068

Die Ausgabe ist der base16 kodierte AssetName. Das Subject ist nun die Konkatenation der base16 kodierten policyID und des base16 kodierten Asset Namens:

90dcf637d6c683aa82a27177cda8dc4856cde44e678f5700ac8455344d75727068

Damit erstellen wir nun den draft entry

./token-metadata-creator entry --init 90dcf637d6c683aa82a27177cda8dc4856cde44e678f5700ac8455344d75727068

Schritt 2: Die required-fields hinzufügen:

./token-metadata-creator entry 90dcf637d6c683aa82a27177cda8dc4856cde44e678f5700ac8455344d75727068 \
--name "The Mighty Murph Token" \
--description "A currency for the FIRE project" \
--policy Murph/policy/policy.script

Schritt 3: Optionale Felder hinzufügen:

./token-metadata-creator entry 90dcf637d6c683aa82a27177cda8dc4856cde44e678f5700ac8455344d75727068 \
--ticker "MURPH" \
--url "https://fire-pool.com/the-murph-token" \
--logo "murphTokenLogo.png" \
--decimals 2

Schritt 4: Signieren der  Metadaten:

./token-metadata-creator entry 90dcf637d6c683aa82a27177cda8dc4856cde44e678f5700ac8455344d75727068 -a policy.skey

Schritt 5: Finalisieren der Metadaten

./token-metadata-creator entry 90dcf637d6c683aa82a27177cda8dc4856cde44e678f5700ac8455344d75727068 --finalize

Beim finalisieren werden einige Tests durchgeführt. Sind diese erfolgreich, wird der Eintrag finalisiert.

Schritt 6: Den Pull Request ins Repository hinzufügen:

Wir gehen davon aus, dass das Cardano Token Registry repository bereits in github geforkt wurde.

Wir clonen es nun.

Der soeben erstellte json-File wird dem mappings verzeichnis hinzugefügt.

cp 90dcf637d6c683aa82a27177cda8dc4856cde44e678f5700ac8455344d75727068.json cardano-token-registry/mappings

Wir fügen einen commit hinzu:

git add mappings/90dcf637d6c683aa82a27177cda8dc4856cde44e678f5700ac8455344d75727068.json
git commit -m "tokenname"
git push origin HEAD

Schritt 7: Einen pull-request erstellen:

Wir erstellen einen pull-request für unseren fork.

Wenn der Pull-Request alle Prüfungen besteht, wird unser Token in die Registry eingetragen. Dies kann ein paar Stunden dauern.

Quellen

Scroll to Top