Skip to content

feat(gno.land): add read-only metadata support to packages #3740

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

Closed
wants to merge 29 commits into from

Conversation

jeronimoalbi
Copy link
Member

Changes in this PR aim to explore adding support for metadata to packages.

Multiple user defined fields can be assigned as metadata.

An important part of metadata is also to allow keeping track of any tools within the gno.land ecosystem, including off chain tools, so they can optionally be associated to packages and realms. This can be done though the "tools" metadata field. This field accepts a JSON string with the following format:

{
  "tools": [
    {
      "name": "Tool Name",               // Mandatory
      "weight": 1,                       // Mandatory, 1 == 100%
      "description": "Tool description", // Optional
    },
    // ...
  ],
}

For example:

{
  "tools": [
    {
      "name": "GnoStudio",
      "weight": 0.8,
    },
    {
      "name": "Adena",
      "weight": 0.2,
      "description": "All-in-one wallet",
    },
  ],
}

Metadata can be optionally added to addpkg messages and once metadata fields are setted they can't be modified.

Metadata can also be setted using the gnokey maketx addpkg command using the -meta flag.

@jeronimoalbi jeronimoalbi self-assigned this Feb 12, 2025
@github-actions github-actions bot added 📦 🤖 gnovm Issues or PRs gnovm related 📦 ⛰️ gno.land Issues or PRs gno.land package related labels Feb 12, 2025
@Gno2D2
Copy link
Collaborator

Gno2D2 commented Feb 12, 2025

🛠 PR Checks Summary

🔴 Maintainers must be able to edit this pull request (more info)
🔴 Changes to 'docs' folder must be reviewed/authored by at least one devrel and one tech-staff
🔴 Pending initial approval by a review team member, or review from tech-staff

Manual Checks (for Reviewers):
  • IGNORE the bot requirements for this PR (force green CI check)
Read More

🤖 This bot helps streamline PR reviews by verifying automated checks and providing guidance for contributors and reviewers.

✅ Automated Checks (for Contributors):

🔴 Maintainers must be able to edit this pull request (more info)
🔴 Changes to 'docs' folder must be reviewed/authored by at least one devrel and one tech-staff
🔴 Pending initial approval by a review team member, or review from tech-staff

☑️ Contributor Actions:
  1. Fix any issues flagged by automated checks.
  2. Follow the Contributor Checklist to ensure your PR is ready for review.
    • Add new tests, or document why they are unnecessary.
    • Provide clear examples/screenshots, if necessary.
    • Update documentation, if required.
    • Ensure no breaking changes, or include BREAKING CHANGE notes.
    • Link related issues/PRs, where applicable.
☑️ Reviewer Actions:
  1. Complete manual checks for the PR, including the guidelines and additional checks if applicable.
📚 Resources:
Debug
Automated Checks
Maintainers must be able to edit this pull request (more info)

If

🟢 Condition met
└── 🟢 And
    ├── 🟢 The base branch matches this pattern: ^master$
    └── 🟢 The pull request was created from a fork (head branch repo: gnostudio/gno)

Then

🔴 Requirement not satisfied
└── 🔴 Maintainer can modify this pull request

Changes to 'docs' folder must be reviewed/authored by at least one devrel and one tech-staff

If

🟢 Condition met
└── 🟢 And
    ├── 🟢 The base branch matches this pattern: ^master$
    └── 🟢 A changed file matches this pattern: ^docs/ (filename: docs/users/interact-with-gnokey.md)

Then

🔴 Requirement not satisfied
└── 🔴 And
    ├── 🔴 Or
    │   ├── 🔴 Pull request author is a member of the team: tech-staff
    │   └── 🔴 At least 1 user(s) of the team tech-staff reviewed pull request(with state "APPROVED")
    └── 🔴 Or
        ├── 🔴 Pull request author is a member of the team: devrels
        └── 🔴 At least 1 user(s) of the team devrels reviewed pull request(with state "APPROVED")

Pending initial approval by a review team member, or review from tech-staff

If

🟢 Condition met
└── 🟢 And
    ├── 🟢 The base branch matches this pattern: ^master$
    └── 🟢 Not (🔴 Pull request author is a member of the team: tech-staff)

Then

🔴 Requirement not satisfied
└── 🔴 If
    ├── 🔴 Condition
    │   └── 🔴 Or
    │       ├── 🔴 At least 1 user(s) of the organization reviewed the pull request (with state "APPROVED")
    │       ├── 🔴 At least 1 user(s) of the team tech-staff reviewed pull request
    │       └── 🔴 This pull request is a draft
    └── 🔴 Else
        └── 🔴 And
            ├── 🟢 This label is applied to pull request: review/triage-pending
            └── 🔴 On no pull request

Manual Checks
**IGNORE** the bot requirements for this PR (force green CI check)

If

🟢 Condition met
└── 🟢 On every pull request

Can be checked by

  • Any user with comment edit permission

Copy link

codecov bot commented Feb 12, 2025

Codecov Report

Attention: Patch coverage is 86.66667% with 20 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
gnovm/pkg/gnolang/store.go 0.00% 20 Missing ⚠️

📢 Thoughts on this report? Let us know!

@jeronimoalbi jeronimoalbi moved this from Triage to In Progress in 🧙‍♂️gno.land core team Mar 25, 2025
@jeronimoalbi jeronimoalbi marked this pull request as ready for review March 25, 2025 16:04
@jeronimoalbi jeronimoalbi moved this from In Progress to In Review in 🧙‍♂️gno.land core team Mar 25, 2025
@Gno2D2 Gno2D2 added the review/triage-pending PRs opened by external contributors that are waiting for the 1st review label Mar 25, 2025
@thehowl
Copy link
Member

thehowl commented Mar 25, 2025

Could this not be a Metadata() function on the realm?

I don't see very good reasons to do this; I think we can keep the metadata logic as Gno code and have indexers and others just call that to retrieve it.

Another thing could be simply an un/exported const, like const toolName, that an indexer can retrieve about a package using qeval.

@jeronimoalbi
Copy link
Member Author

Could this not be a Metadata() function on the realm?

I don't see very good reasons to do this; I think we can keep the metadata logic as Gno code and have indexers and others just call that to retrieve it.

Another thing could be simply an un/exported const, like const toolName, that an indexer can retrieve about a package using qeval.

The idea of the PR is to allow tools running off-chain, like Gno Studio, to be able to add tooling info when they are used to interact with the blockchain.

In the case of Gno Studio this would happen when a user deploys a package or realm using it, in which case we would add Studio and Adena as the tools being used to deploy. Keeping this information would also allow considering these tools for example when distributing tokens.

So I believe there is a requirement where the information should be send within the transaction; In this case the one containing the addpkg message.

The current implementation uses the storage instead of using a realm to avoid some overhead but I think it would be fine to store the tooling information in a realm as long as it comes from the addpkg message. Right now I'm not sure that using a second call to a "metadata" realm after deploy is the way to go.

This idea stems from discussions and brainstorm that happened quite a while ago where the idea was to make the functionality generic, implementing it as a package or realm key/value metadata, where one of the fields would store the tooling information.

cc @ilgooz

@thehowl
Copy link
Member

thehowl commented Mar 26, 2025

If you wanted to register something as "published with GnoStudio", I think it'd be better to have something like:

import "gno.land/r/studio/registry"

func init() { registry.RegisterRealm() }

as a file which is optionally included (ie. checkbox) when uploading from studio / playground.

@salmad3 salmad3 requested a review from zivkovicmilos March 26, 2025 15:28
@jeronimoalbi
Copy link
Member Author

Quoting @ilgooz and adding more context, what drove us to the idea towards a generic Keeper based solution was that we were looking for a solution that is not specific to Studio, allowing other off-chain tools to be able to track their usage when users develop realm and packages so there can be a history for reward distribution.

Injecting code in the user's package would be an invasive approach as it "alters" user's code and might not be a possibility for some off-chain tools.

At some point we might want to also keep metadata for some calls, for example from Connect, and it wouldn't be really possible without adding metadata in the TX's call message.

Also, I believe all TXs sent from Gno Studio would have metadata, it won't be optional, so if that's the case it's something to be considered.

The metadata as a core functionality makes more sense and also makes sure there is a specific type of TX associated to the metadata update. I think using a realm looses that relation or constraint, meaning that for example we can't initially validate that the tooling metadata info for adding a new package (addpkg msg) is valid, because package paths as string can't be validated as a existing on-chain packages, if it makes sense, while metadata within an addpkg message implicitly already means that a package exists.

@thehowl
Copy link
Member

thehowl commented Mar 27, 2025

Injecting code in the user's package would be an invasive approach as it "alters" user's code and might not be a possibility for some off-chain tools.

Sounds like a weak argument.

If you want to add metadata, you need to modify the transaction that's being signed. If you need to do that, it's also trivial to add a file with some additional code to the addpkg message.

It's also unclear whether this metadata should be eventually visible within gno.land.

If you want to have something that is less invasive, you can put metadata in the tx memo or as a Gno comment in the first file, and they're querieable out of the box with the tx-indexer. Or you can make it a separate message that does a MsgCall to a studio realm to track this.

Also, I believe all TXs sent from Gno Studio would have metadata, it won't be optional, so if that's the case it's something to be considered.

Tools should really give the user control over the transactions they're signing and submitting. So no, I think this should be optional. If you want to track what contracts are made using studio for your own information, use analytics beacons.


I don't think there is a strong enough usecase to add metadata, because there are plenty other good solutions, and which I think are more in line with enabling programmatic usage in Gno, and not implementing many redundant features. Happy to listen to other POV's

@ilgooz
Copy link
Contributor

ilgooz commented Mar 27, 2025

I'll start with what led us to save this info on-chain, then jump to metadata as a platform to implement our solution on top.

Hopefully, Gnoland will evolve in a way that rewards its contributors. Contributions may come in many forms, and there might be several ways to distribute rewards, some automated, some through DAO proposals.

I'll focus on covering code contributions in the form of realms and packages, how to automate rewarding devs, as well as tools/tool makers.

At some point in the future, hopefully not too long, we should have ways to determine which realms and packages create the most impact on the chain or at least have more impact compared to others by ranking them. This could be measured in many ways: counting how many function calls are made to packages, how many times they're imported or used, and a similar approach for realms could be one way. Knowing this info, we could actually reward devs, potentially attracting more devs to the Gno ecosystem and encouraging them to stay by building more impactful stuff. Developers should no longer need a "buy me a coffee" link on their Readme; they'll be rewarded automatically by the chain.

In addition to rewarding devs for their contributions, we can also measure whether they are using certain development tools to deploy (addpkg) and making interactions (call). This info could then be used to reward the tools themselves, perhaps by allocating a percentage of the rewards those devs receive.

Tokens minted through inflation and gas fees, possibly combined with preexisting treasuries, could be used for allocating these rewards.

Eventually, this logic could run on-chain once every 24 hours, which is a common approach. All of this can be automated, as all necessary info is already on-chain. DAOs, in this case, set the distribution formula, and parameters are calculated using on-chain data to complete the equation.

I’m genuinely hoping and believing Gno can become a contributor first chain and reward them accordingly. We should also reward tools, as this is the only way they can compete effectively and sustain themselves financially in the long run. Take a look at other teams in the Cosmos ecosystem; great tools often face discontinuation due to lack of funding, which we should prevent through a strongly automated contribution and reward model. There is no robust, native model in Cosmos or in many other ecosystems to appreciate tools and create sustainable funding mechanisms. This is a problem we must address.

What I’ve written so far can be discussed separately; it's not the topic for this PR, but hopefully, it provides some insight into the philosophy in mind.

As mentioned, we should automate as much as possible to reduce the workload on DAOs and establish a social contract in code, minimizing the need for frequent DAO proposals. This brings greater trust, as the human factor is minimized. Consider central banks; they aim for predictability in their decisions, typically achieving it, thus inspiring investor trust. In our case, trust is established through code that autonomously rewards contributors, with DAOs stepping in to modify the reward formula, a relatively rare occurrence.

To automate effectively and later execute on chain logic on top, information about which tools were used for specific Msg actions must also be stored onchain. This requirement makes relying on indexers and memo fields incompatible.

Injecting code during addpkg doesn't entirely solve the problem for some reasons:

  • In the future, we want to expand metadata to function calls (code injection isn't available).
  • We need the implementation to be recognized by Gnoland’s core components, meaning it should be supported at the chain level. Metadata provides a generic and effective approach for this. The core implementation should reside at the keeper level. Implementing it as a realm specific feature would prevent it from being recognized by Gnoland's core components by default. Code injection approach through custom realms would complicate reward distribution, as the reward distribution logic should not depend on awareness of any specific studio registry realm.
  • We want to avoid creating a studio specific solution by injecting or adding studio specific logic/state to custom realms.

Separately, at this stage, we aren't introducing strongly opinionated code. We're only introducing a generic metadata system for msgaddpkg, which may later be extended to msgcall, using it as a platform to add a special read-only metadata field called "tools" understood and checked by the chain logic/message handlers. This implementation approach seems fair to me.

Going back to contributions and rewards, this system will, in the future, allow Gnoland to periodically rank packages and realms using a specific algorithm, combine this ranking with on-chain data from collected metadata, and automatically distribute rewards according to a formula set by a DAO.

Lastly, my 2cents on this:

Tools should really give the user control over the transactions they're signing and submitting. So no, I think this should be optional. If you want to track what contracts are made using studio for your own information, use analytics beacons.

In any case, it's up to the user whether or not to sign a transaction and accept or reject metadata added by a tool. If the user is unhappy with it, they can simply avoid using the tool or configure it to better match their expectations regarding metadata creation, if the tool allows it. Tools aren't charities, they require funding to operate. In this specific case, the information provided is intended solely for that purpose, not for anything malicious. Genuine users, in this case, likely wouldn't remove the tool's metadata, as it creates a win-win situation for everyone.

@salmad3
Copy link
Member

salmad3 commented Mar 28, 2025

Essentially, the proposal is to introduce first-class metadata directly into gno.land to establish a dependable record for deployments, tools, and on-chain interactions.

I see this as a competitive advantage for gno, since it provides the foundation for a native, contributor-first mechanism (among other mechanisms) within an already approachable smart contract platform. Other ecosystems demonstrate that relying on external indexing or off-chain solutions eventually results in complex and brittle implementations. Such approaches frustrate developers and tooling maintainers, while creating governance challenges. Rewards, funding, and incentives end up depending heavily on manual proposals or grants, rather than operating through a reliable and automatic mechanism (and thus they do not function as a true system).

The following is under the assumption that we want to achieve a native contributor-driven mechanism in gno.land.

The metadata must remain trustworthy, unchangeable, and consistent throughout the platform. Alternative approaches like transaction memos, code injections, or third-party registries are worth considering. However, there is a risk of fragmentation, increased complexity, and diminished reliability. They also rely on the user opting-in.

In attempt to be a bit critical:

  • Transaction memos lack structure. They also depend heavily on indexing. When indexing fails, misses data, or shifts schemas, it jeopardizes distribution systems and muddies tracking.
  • Injecting external code into user packages presents its own challenges and seems more like a workaround. In an ideal scenario, the developer shouldn't need to really think about the metadata beyond a certain point. It also brings in additional dependencies, and opens the door to security risks.
  • Third-party registries also fall short. They tend to splinter the ecosystem as different tools or realms adopt conflicting metadata schemas.

Some perspective on where this can take us:

Looking ahead, there shouldn't be room for arbitrary choices or manipulation.

Right now, in this MVP version, the weights are at the discretion of the package owner. One "production-ready" approach down-the-line can be a DAO-managed tooling registry with on-chain parameters.

  • The registry would maintain an objective list of eligible tools. This list confirms eligibility for ecosystem-wide reward programs without suggesting endorsement. DAO proposals would oversee entries and definitions with full transparency.
  • Fairness relies on consistent standards. The DAO would define clear on-chain parameters for tool weights and categories instead of leaning on subjective input from developers or maintainers. These parameters would later drive automated distributions.
  • Metadata should mirror actual deployment conditions without user bias creeping in. Tools would stick to structured fields like name, version, and DAO-set categories, which is based on what the ecosystem decides. This setup avoids random additions and keeps incentives and analytics impartial.
  • Down the road, tracking dependency trees could unlock even greater value. Mapping how packages and realms connect would reveal a clearer picture of ecosystem influence. This method ensures rewards reflect not only direct contributions but also broader impacts across the network.
  • In general, this also accounts for cases where a tool is closed-source or potentially questionable. The registry does not serve as an endorsement. The tool must prove its value, and users choose to adopt it based on their own diligence. The incentive for tools is to provide value in order to be eligible for rewards.

The above is one approach, but this approach relies on certain guarantees which leads to favoring first-class metadata.

@zivkovicmilos zivkovicmilos added the breaking change Functionality that contains breaking changes label Mar 28, 2025
@moul
Copy link
Member

moul commented Apr 1, 2025

TLDR; We won't take any action before the beta launch, but working on a file-based metadata format is beneficial right now, and we can unofficially adopt it (which would become official due to usage). We can also imagine providing best-effort retroactive support on the day this feature is implemented.


We won't add transaction-level package metadata for now, but exploring file-based metadata is worthwhile. It could resemble a package.json file, a metadata.gno file, or simply follow conventions such as:

// Foo has this awesome description.
//
// Additional description.
// X-Bar: baz
package foo

When we eventually add support for such features, we can retroactively consider the package by running a script and proposing to rectify previous packages.

So, let's focus on finding something future-proof and simple.


Regarding the "call" metadata, I like the idea of incentivizing tools to perform well so that we reward them with usage. However, I see privacy concerns that could lead to security risks if we expect transactions to disclose the tools used to sign them. Please consider this, perhaps by ensuring that this metadata is embedded deep within the protocol, so it doesn't reveal the wallet or any specific details, but only indicates "a tool that was useful at some moment." We should avoid mentioning "tool version." I'm not sure we can implement this feature for that reason, but I encourage exploration of what could be done, as it would indeed be fantastic to create an ecosystem where off-chain tool developers are rewarded for their excellent work.


Regarding this specific part of the message: "Injecting external code into user packages presents its own challenges and seems more like a workaround. In an ideal scenario, the developer shouldn't need to think about the metadata beyond a certain point. It also brings in additional dependencies and opens the door to security risks."

Actually, it's the opposite. Reward distribution will be managed by a contract that requires access to such information. Therefore, I expect this information to be made available by an on-chain registry, so we don't need to extend the standard library to provide more non-GNO information from GNO. However, it's fine to think about this design.

@thehowl
Copy link
Member

thehowl commented May 15, 2025

Looking at Manfred's comment, I think we don't want this and can consider this conversation as a base for a PR after mainnet.

@jeronimoalbi maybe you can create an issue for it? :)

@thehowl thehowl closed this May 15, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
breaking change Functionality that contains breaking changes 📦 ⛰️ gno.land Issues or PRs gno.land package related 📦 🤖 gnovm Issues or PRs gnovm related review/triage-pending PRs opened by external contributors that are waiting for the 1st review
Projects
Development

Successfully merging this pull request may close these issues.

7 participants