# Solving the Canonical Chain Problem
It is clear that grants-stack core focus is to abstract away the pain of ensuring the same metadata is reflected across chains for a project. This is an app level problem but it's evident that other users of Allo will end up with a similar problem.
We will explore a solution which can be implemented at the protocol level but currently the solution described here would be app-level
If a dapp chooses to use this feature, they would be first expected to pick a canonical chain as their source of truth. This means the actual IPFS hash for a project created via the dapp would have be stored on the canonical chain. If the project were to duplicated on another chain, the metadata would simply store a reference to the canonical chain, registry and project Id (This would provide the means for the dapp to fetch the real metadata). In case of grants-stack, this would be handled by the indexer
## How do we identify if a project's metadata
Currently onchain, the project's metadata is stored using the `Metadata` struct
```
struct Metadata {
uint256 protocol;
string pointer
}
```
#### Current Metadata Documentation
| Protocol | Pointer | Notes |
| -------- | ----------------| -------- |
| 0 | null | No metadata |
| 1 | <ipfs-hash> | This siginifes data is an IPFS hash |
The proposal is if
- project is on the canonical chain, on parsing the IPFS hash, it shows the actual metadata
- project is not on the canonical chain, on parsing the IPFS hash, it shows the JSON which points to the actual canonical chain, registry address and project id
```
{
canonicalChain: {
chainId: number,
registryAddress: string,
projectId: string
}
}
```
### Limitations
- If the profile wanted to change the name or add/remove team members, they would have to do this across all the chains
### Problems
Assume a user were to create a profile on the canonical chain (assume PGN) and then migrate to another chain (let's assume polygon) via grants-stack
Now if the user wanted to use their profile on another dapp which polygon -> if the dapp could choose to ignore the canonical chain and force the user to create the metadata once more (this overwriting the metadata to)
```
{
protocol: 1,
pointer: "IPFSHASH"
}
```
Or overwrite the metadata with another chanonical-chain
This would result in the user having profiles on either chain with 2 distinct metadata and builder app would have to help us the user, sync it across chains
### Summary
This solution is not fool-proof but is the recommended way of handling the canonical chain until the protocol team comes up with a better way to enforce it at the protocol level
## Migrating Allo V1 Profiles to V2
Once grants-stack picks it's canonical chain, allo team would be tasked with auto-migrating the profiles.
The flow of events would be:
- Have the script to fetch profiles from the grants-stack indexer
- Have a script which migrates the data onto the canonical chain. Additionally a means to update the indexer DB to establish a link btwn old and new profile
**Ask from Grants-Stack:**
- Pick the canonical chain
- Endpoint from the indexer which we would use get the list of profiles from Allo v1
- Endpoint which our script can invoke to link the new allo v2 profile to the allo v1 profile
**Discussion to be had with Grants-stack :**
- Since grants-stack has projects which may have been duplicated, we should discuss how to handle this. If the indexer already takes care of this, then this wouldn't be a problem
- If a project is present on a chain other than the canonical chain, should we also migrate those projects to those chain using the canonical chain solution discussed above
- Additonally to be discussed with the team is we'd want to also auto migrate programs into allo-v2 profiles (WITHOUT the team members) This would be beneficial but grants-stack would have to decide if this makes sense OR if they would rather have the migration as an opt in service on the UI