I'm having trouble receiving these values with a script

65 Views Asked by At

I have simple resource with two Int variable and a string array. I want to write seperate scripts to retrieve each variable in a resource. this is the resource i have.

pub resource State{

        pub var Name: String
        pub var P: Int
        pub var H: Int
        pub var M: [String]


        init(_name: String){

            self.Name = _name
            self.P = 0
            self.H = 0
            self.M =[]

        }
        
        pub fun GetName() : String
        {
            return self.Name
        }



        pub fun addP(_P: Int){
            self.P = self.P + _P
        } 

    }

(i havent added the functions to add values in to the varibales in the code.) I wanna write separate functions and scripts to access each of my variable induvidually.

1

There are 1 best solutions below

0
On

In the first place, you should have a clear understanding of the concept of Resource.
It is a bundle of information wrapped into an asset. And like a NFT, once it exists, it will always belong to someone and only that person.

But you can also "borrow" some "parts" of it if it has References. For example, there is a chair belongs to Alice, but she grants Bob the permission to sit on it and allows everyone to take photos of it.
Which means, in order to get some information inside a Resource. You have three ways:

  1. That Resource must have a public Reference
  2. You must own that Resource
  3. You must have its private Capability or have claimed it

Okay so now let's go to the answers for your question.

With the first way, you must implement its interface:

pub resource interface IState {
    pub fun GetName();
}

pub resource State: IState {
    // your code
}

And in the initialization of that Foo contract, you should save and link that resource into your account by the following code:

self.account.save(<- create State(), to: /storage/state)
self.account.link<&State{IState}>(/public/state, target: /storage/state)

Once you linked it into a public path, you can access to getName() by this script:

import Foo from "Foo"

access(all) fun main(): String {
    return getAccount(yourAddress).getCapability<&State{IState}>(/public/state).borrow()!.getName()
}

The second way works only with transactions or the deployment contract because scripts cannot access to AuthAccount.

For example, with same implementation I gave in the first way, you can get it inside the contract like this:

// `self.account` is the deployment's `AuthAccount`
self.account.borrow<&State>(from: /storage/state)!.getName()

Same for transactions, but with this way, you will not need to implement its interface based on your aim


The third way may be too complex for this question so I will not mention.

If you have any question, just ask me below. Happy coding.