How to create a metadata transaction using cardano-wallet
note
This guide assumes that you have a basic understanding of cardano-wallet
and cardano-cli
, how to use it and that you have installed it into your system. Otherwise, we recommend reading Installing cardano-node, Running cardano-node, and Exploring Cardano Wallets guides first.
This guide also assumes that you have cardano-node
and cardano-wallet
running in the background and connected to the testnet
network.
Overview
This article will explore how we can utilize the Transaction Metadata feature of the Cardano blockchain. More specifically, how we can insert and retrieve metadata that we have stored in the blockchain for a decentralized application using Transaction Metadata.
Use case
Let's imagine a decentralized To-Do List Application that stores and retrieve its metadata not from centralized servers or storage but instead from the Cardano blockchain. First, let's check the diagram below to see how something like this could theoretically work:
important
The diagram is heavily simplified and is not recommended to deploy in production.
We see here that there is a front-end application the user interacts with and is responsible for inserting and retrieving the metadata to/from the back-end server. The back-end server is responsible for communicating to the cardano-node
by creating transactions and querying the blockchain for the metadata information required by the front-end.
The front-end application is not necessarily tied to the specific back-end API and could switch to another API as long as it ultimately communicates to the Cardano network.
How do you actually create transaction metadata in the Cardano blockchain, you ask? We'll let's get our hands dirty!
Setup
To create a transaction metadata using the cardano-wallet
, you must first create a wallet if you haven't already.
Generate mnemonic seed
cardano-wallet recovery-phrase generate
Create Wallet with the generated mnemonic seed
curl --request POST \
--url http://localhost:1337/v2/wallets \
--header 'Content-Type: application/json' \
--data '{
"name": "test_cf_1",
"mnemonic_sentence": ["shift", "badge", "heavy", "action", "tube", "divide", "course", "quality", "capable", "velvet", "cart", "marriage", "vague", "aware", "maximum", "exist", "crime", "file", "analyst", "great", "cabbage", "course", "sad", "apology"],
"passphrase": "test123456"
}' | jq
Now that you have a wallet, we can now retrieve a wallet address:
curl --request GET \
--url 'http://localhost:1337/v2/wallets/5076b34c6949dbd150eb9c39039037543946bdce/addresses?state=unused' | jq '.[0]["id"]'
Now that you have a wallet address, you can now request for some tAda
funds from the Cardano Testnet Faucet.
Once you have some funds, we can now create the sample metadata that we want to store into the blockchain.
Now let's say that the JSON
shape we decided on for our To-Do List application is the following:
{
"1337": {
"name": "hello world",
"completed": 0
}
}
note
Based on our theoretical To-Do List application, this JSON
shape could be a way to insert / update entries into our list. We choose an arbitrary number (1337
) as the key, and we are basically saying that all metadata that will be inserted with that key is related to the To-Do List application data. Although we don't have control over what will be inserted with that metadata key since Cardano is an open platform.
Now that we have our JSON
data, we can create a transaction and embed the metadata into the transaction. Ultimately storing it into the Cardano blockchain forever.
JSON Format
cardano-wallet
has special requirements in terms of the JSON
format of the payload that it accepts. Here are some examples:
{
"0": {
"string": "cardano"
},
"1": {
"int": 14
},
"2": {
"bytes": "2512a00e9653fe49a44a5886202e24d77eeb998f"
},
"3": {
"list": [
{
"int": 14
}
]
},
"4": {
"map": [
{
"k": {
"string": "key"
},
"v": {
"string": "value"
}
}
]
}
}
So we will have to convert our JSON
metadata payload to the format the cardano-wallet
accepts:
{
"1337": {
"map": [
{
"k": {
"string": "name"
},
"v": {
"string": "hello world"
}
},
{
"k": {
"string": "completed"
},
"v": {
"int": 0
}
}
]
}
}
Submit to blockchain
Once we have the accepted format, we can now finally submit the metadata to the blockchain.
First, let's retrieve another unused wallet address from our wallet:
curl --request GET \
--url 'http://localhost:1337/v2/wallets/5076b34c6949dbd150eb9c39039037543946bdce/addresses?state=unused' | jq '.[0]["id"]'
Now we will send 1,000,000 lovelace
to our own wallet while attaching the metadata in the transaction, ultimately storing it into the blockchain forever.
curl --request POST \
--url http://localhost:1337/v2/wallets/5076b34c6949dbd150eb9c39039037543946bdce/transactions \
--header 'Content-Type: application/json' \
--data '{
"passphrase": "test123456",
"payments": [
{
"address": "addr_test1qpg2eglv9gf2rksvdj53t6ajfgzkycaadlt2fatjyn4etpze0592agqpwraqajx2dsu2sxj64uese5s4qum293wuc00q6hnhqq",
"amount": {
"quantity": 1000000,
"unit": "lovelace"
}
}
],
"metadata": {
"1337": {
"map": [
{
"k": {
"string": "name"
},
"v": {
"string": "hello world"
}
},
{
"k": {
"string": "completed"
},
"v": {
"int": 0
}
}
]
}
}
}'
Congratulations, you are now able to submit Cardano transactions with metadata embedded into them. 🎉🎉🎉
Up next, we discuss how to retrieve metadata that we have stored in the Cardano blockchain. @TODO