2

I have a design question about a SmartContract. I would like to create a endpoint that deals with SFT and NFT and must access to there attributes to compute the result. Basically, the user send two NFTs and, depends on there attributes, it will receive a new NFT or not. In both case, we return user's NFT.

In this case, is it possible to only send token identifiers to the endpoint instead of NFTs (via payable) and retreive NFT informations directly from the smart contract? It seems boilerplate and gaz consuming to send back NFT from a smart contract each time

  • 1
    You should definitely send the NFTs in the transaction, since a contract can't read the data if the nft current owner is on a different shard. – Raress96 Jan 14 '22 at 15:40

1 Answers1

3

In order to retrieve data encoded in the attributes field you have to decode that data back to a struct.

Let's say you have the struct YourStruct defined as shown below:

#[derive(NestedEncode, NestedDecode, TopEncode, TopDecode, TypeAbi)]
pub struct YourStruct<M: ManagedTypeApi> {
    pub name: ManagedBuffer<M>,
    pub timestamp: u64,
    pub amount: BigUint<M>,
}

Then to retrieve it, in your endpoint you would do something like this:

let nft_info = self.blockchain().get_esdt_token_data(
    &self.blockchain().get_sc_address(),
    &token_identifier,
    token_nonce,
);

let attributes = nft_info.decode_attributes::<YourStruct<Self::Api>>()?;

For your second question, I think it depends on your particular use case. But it would be considered best practice to send those NFT tokens to your contract.

matei
  • 436
  • 5
  • 4
  • Thanks for your reply to this. Helped a lot. I'm having "user errors" ("input too short") however when I go to test it. What would be a valid attribute for your YourStruct example? I'm using `name:elrond;timestamp:0;amount:0x1`. – mingles Jan 08 '22 at 06:19
  • Thanks for your response. It indeed work with Elrond SDK Codec. If you want to use a "clear" semi-colon"/"colon" format you have to decode it by yourself. Attributes are a ManagedBuffer which can be converted to BoxedByte and then to an array of u8 ( attributes.to_boxed_bytes().as_slice() ) – Stéphane Leroy Jan 15 '22 at 16:16