Skip to main content

PSP37 Metadata

This example shows how you can reuse the implementation of PSP37 token with PSP37Metadata extension.

First, you should implement basic version of PSP37.

Step 1: Implement PSP37Metadata

#![cfg_attr(not(feature = "std"), no_std, no_main)]

#[openbrush::implementation(PSP37, PSP37Metadata)]
#[openbrush::contract]
pub mod my_psp37 {
...

Step 2: Define storage

Declare storage struct and declare the field related to the metadata module. Then you need to derive the Storage trait and mark the corresponding field with the #[storage_field] attribute. Deriving this trait allows you to reuse the PSP37Metadata extension in your PSP37 implementation.

#[derive(Default, Storage)]
#[ink(storage)]
pub struct Contract {
...
#[storage_field]
metadata: metadata::Data,
}

Step 3: Define constructor

Define constructor. Your PSP37Metadata contract is ready!

impl Contract {
#[ink(constructor)]
pub fn new() -> Self {
Self::default()
}
}

Final code

#![cfg_attr(not(feature = "std"), no_std, no_main)]

#[openbrush::implementation(PSP37, PSP37Metadata)]
#[openbrush::contract]
pub mod my_psp37 {
use openbrush::traits::{
Storage,
String,
};

#[derive(Default, Storage)]
#[ink(storage)]
pub struct Contract {
#[storage_field]
psp37: psp37::Data,
#[storage_field]
metadata: metadata::Data,
}

impl Contract {
#[ink(constructor)]
pub fn new() -> Self {
Self::default()
}

#[ink(message)]
pub fn set_attribute(&mut self, id: Id, key: String, data: String) -> Result<(), PSP37Error> {
metadata::Internal::_set_attribute(self, &id, &key, &data)
}
}
}

You can check an example of the usage of PSP37 Metadata.