Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Generate JSON API description #35

Closed
Robbepop opened this issue Mar 18, 2019 · 2 comments
Closed

Generate JSON API description #35

Robbepop opened this issue Mar 18, 2019 · 2 comments
Labels
A-ink_lang [ink_lang] Work item B-enhancement New feature or request

Comments

@Robbepop
Copy link
Collaborator

Robbepop commented Mar 18, 2019

For a smart contract compiled written using pdsl_lang we want it to generate an API description file, probably encoded as JSON. The API file lists all the available messages, their hash selectors as well as their arguments in the required order so that an external system could eventually use this information to create and manage calls to the smart contract.

Uses

The pDSL itself as well as external tools can make use of the API description files.
For the pDSL it could help smart contract developers in calling messages of external smart contracts by introspecting their API description files.

Open Questions

For an MVP a smart contracts API should be restricted to just some primitives types such as (), bool, u{8,16,32,64,128}, i{8,16,32,64,128}, Balance, Address. Later we want to open this to allow for more and even custom types. However, for custom types, or even for Rust standard library types such as Option<T> we need a clear and concise way to communicate our intention in a language agnostic way.

This means that instead of describing that our message takes an Option<u32> we need to specify that our message takes an object of type Option<u32> that is encoded through {u8, u32}. This way we can keep our encoding interfaces clean and language agnostic.

The JSON shard for this could look like the following:
{ "name": "my_optional_int", "type_name": "Option<u32>", "encoded_as": ["u8", "u32"] }

Example

Looking again at the simple Incrementer smart contract:

/// A simple contract that has a value that can be
/// incremented, returned and compared.
struct Incrementer {
    /// The internal value.
    value: storage::Value<u32>,
}

impl Deploy for Incrementer {
    /// Automatically called when the contract is deployed.
    fn deploy(&mut self, init_value: u32) {
        self.value.set(init_value)
    }
}

impl Incrementer {
    /// Increments the internal counter.
    pub(external) fn inc(&mut self, by: u32) {
        self.value += by
    }

    /// Returns the internal counter.
    pub(external) fn get(&self) -> u32 {
        *self.value
    }

    /// Returns `true` if `x` is greater than the internal value.
    pub(external) fn compare(&self, x: u32) -> bool {
        x > *self.value
    }
}

The pdsl_lang should generate a JSON file that roughly looks like this:

{
    "name": "Incrementer",
    "deploy": {
        "params": [],
        "return_type": null
    },
    "messages": [
        {
            "name": "inc",
            "selector": 0,
            "mutates": true,
            "params": [
                {"name": "by", "type": "u32"}
            ],
            "return_type": null
        },
        {
            "name": "get",
            "selector": 1,
            "mutates": false,
            "params": [],
            "return_type": "u32"
        },
        {
            "name": "compare",
            "selector": 2,
            "mutates": false,
            "params": [
                {"name": "with", "type": "u32"}
            ],
            "return_type": "bool"
        }
    ]
}
@Robbepop Robbepop added B-enhancement New feature or request D-medium A-ink_lang [ink_lang] Work item labels Mar 18, 2019
@Robbepop
Copy link
Collaborator Author

Robbepop commented Mar 19, 2019

Commit 45c3f21 implements JSON API output in its initial state.

An example output for the simple incrementer smart contract currently looks like the following:
Note that there is currently a bug that ret_ty is nested. Fixed by 1e16239.

{
    "name": "Incrementer",
    "deploy": {
        "params": [
            {
                "name": "init_value",
                "ty": "U32"
            }
        ]
    },
    "messages": [
        {
            "name": "inc",
            "selector": 0,
            "mutates": true,
            "params": [
                {
                    "name": "by",
                    "ty": "U32"
                }
            ],
            "ret_ty": null
        },
        {
            "name": "get",
            "selector": 0,
            "mutates": false,
            "params": [],
            "ret_ty": "U32"
        },
        {
            "name": "compare",
            "selector": 0,
            "mutates": false,
            "params": [
                {
                    "name": "x",
                    "ty": "U32"
                }
            ],
            "ret_ty": "Bool"
        }
    ]
}

@Robbepop
Copy link
Collaborator Author

Closing this in favor of the other opened issues that enhance JSON api description generation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-ink_lang [ink_lang] Work item B-enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

1 participant