Skip to content
This repository has been archived by the owner on Feb 8, 2023. It is now read-only.

RFC Custom "CID" to define blockchain smart contract interaction and value retrieval #453

Open
markg85 opened this issue Feb 14, 2022 · 1 comment
Labels
need/triage Needs initial labeling and prioritization

Comments

@markg85
Copy link

markg85 commented Feb 14, 2022

Hi,

I'm not entirely sure what an appropriate title is for this. We'll probably figure something out along discussing it here.
Also, do note that everything in this proposal is a "nice to have". None of it is required for some future feature that I'll describe in the IPNS usecase but it will certainly make it a lot easier!

Rationale

This proposal aims to provide a "standard" way to get a value from an EVM compatible blockchain. It only describes the message format that would allow another user/application to interpret and use to to get a value from said chain. It does not describe how to make a connection to a given blockchain but the subject is touched in the IPNS usecase.

For this to work i'd like to have a new CID (actually a new multicodec) to make it easily detectable that a given CID with that codec is intented to be a file that describes in a defined format how to get a value from a blockchain.

Proposing dag-bcv (bcv = blockchainvalue)

Now the format itself in dag-language isn't clear to me yet so i'll just post it as json for the time being.

{
  "blockchainID": 10,
  "contractAccress": "0x...",
  "getFunction": {
    "functionName": "getValue",
    "args": [{
      "parameter" : "address",
      "value": "0x..."
    }, {
      "parameter" : "uint256",
      "value": 01234565789
    }],
    "returnValue": "uint256"
  }
}

I'll go over each property and it's intended meaning.

blockchainID

This is the blockchain ID as it's known on https://chainlist.org/. It are these id's that you also need in - for example - metamask so it seems to make sense to rely on data from them.

contractAccress

This would be the deployed smart contract from which a value is going to be requested.

getFunction

This is an object that is going to describe the actual function call that needs to be done on the blockchain along with the arguments that would need to be passed in.

functionName

The function to be executed on the given smart contract address (contractAccress).

args

The type of arguments, and in that order. This is an array of objects where each object will have a parameter (the type of argument that is expected) and a value which is the actual value that needs to be passed as function argument.

returnValue

This described the type of return value that the caller can expect.

How the new CID would look like

Disclaimer: i'm not sure about this at all. This just "seems" like the shortest and smartest route but i might be completely wrong here.
This new CID would have dag-bcv as opposed to dag-pb.
This CID would not be done computationally (like hashing) but would be constructed based on another CIDv1.
Say you add the json CID from the example above using just the normal regular ipfs add command.
From this resulting CID we take only the sha-2-256 part.
Then we compose a new CID (with dag-bcv as codec). In terms of protocol logic it is then forced that only a sha-2-256 of a CIDv1 can be used as the sha-2-256 part of this dag-bcv cid.

A downside of this approach is that any cid could potentially be a dag-bcv encoded one while the data of that cid might not match the format we described. So this might not be the most ideal solution? If it's not, I'll need some help in understanding what the ideal solution is :)

An example smart contract

As an example contract you can look at this one: https://polygonscan.com/address/0x41ec72b8b36269b85e584d7b0187067a6cc1a04d#code
I made that specifically to store key -> values pairs where they are unique on a per wallet address basis. So each individual wallet can store the key "settings" which is then mapped to a uint256 value. Note that the key is hashed too, the string version is never stored.

I am using this in one place to only store the sha-256 hash part of a CID which conveniently fits in one uint256 slot. That allows me to get "mutable" content on two systems (IPFS and Blockchain) that are essential immutable. Again note that there isn't a single use of IPNS in this. More on that later.

If i were to use that smart contract as a basis then the above json description file would looks as follows:

{
  "blockchainID": 137,
  "contractAccress": "0x41ec72b8b36269b85e584d7b0187067a6cc1a04d",
  "getFunction": {
    "functionName": "getValue",
    "args": [{
      "parameter" : "string",
      "value": "settings"
    }, {
      "parameter" : "address",
      "value": "0xf03214714ddc99856eb9301d2c945195974064da"
    }],
    "returnValue": "uint256"
  }
}

Now if there were to be a value with the key settings added by the wallet 0xf03214714ddc99856eb9301d2c945195974064da then you'd get the value belonging with that key+address combination . That value would in this very specific case be a sha-2-256 hash from a CID. Depending on the application (on the place where i use this contract, this is enough) one could compose a CID from this information. A very important note here. This is just how "i" use this for my own purposes. The fact that i can translate a sha-2-256 to a CID is only because i make sure the data i expect is in the contract. This doesn't have to be the case.

IPNS usecase

None of the above was specific to IPFS. Having the above would have no effect of the way IPFS works.
This potential usecase would change that very significantly.

Assume this new CID with dag-bcv is in place. This opens up a whole new possibility for IPNS.
If the IPNS logic were to be made aware of the gad-bcv logic then IPFS could internally do the RPC call to the blockchain defined in the above mentioned json blob. IPFS could then fetch the value from that blockchain. If that value is - in terms of protocol logic- forced to be a sha-2-256 hash from a certain CID format then IPFS know - by virtue of the protocol - how to reconstruct a valid CID from the value gathered from the blockchain smart contract.

It could have very significant advantages for IPNS too. To name some of them:

  1. The whole concept of TTL can be ignored. The latest record is the one you fetch from a smart contract.
  2. Updating a IPNS record becomes a hash update on the blockchain. While this is a transaction (and thus cost money), it means we can rely on the blockchain for storing the value. In other terms, there would be no single point of failure in terms of relying on the original IPFS publisher to be online. That being said, we do have a new single point of failure in the blockchain RPC address. Still a win imho.
  3. IPNS resolving should be significantly faster.
    3.1 Note. The first time an entry is looked up it would be 2 requests. One to get the json blob from above and one to get the data from the blockchain. This could mean the first lookup is slow.
    3.2 Then again. Currently IPNS resolving can take minutes so this new approach is quite likely to be faster in the majority of cases.
  4. Combines the best of IPFS with the best of blockchain! Blockchain has a hard responsibility to be online, be immutable and - essentially - be a key -> value store. This is exactly what maps perfectly for IPNS use. And on top of that the above spec is blockchain agnostic as long as it's EVM compatible.
  5. Fully transparent to ipfs:// and ipns:// once implemented. Which means this could be used in dnslink too with 0 changes to that spec!

Closing notes

  1. Why making this spec proposal? I've had this idea for some time and slowly started thinking about how to implement it. So i thought it might be valuable - or at least wise - to take some hours and document it somewhere. Here seems to be a very suitable place for that.
  2. The above has a lot of assumptions! It definitely needs more thought to iron out how it would work exactly.
  3. I quite like the IPNS idea but i hate it's current limitations. It's unusable in my opinion. The above solves it, or so i think :)
  4. I'm not set at all on my dag-bcv idea with a derived CID approach... It might be a garbage idea. Regardless, a new CID would be rather essential so alternatively a native IPLD approach? (how does that look like? IPLD is still like a black box to me, even after reading lots about it).
  5. This proposal (or more like a braindump idea) does add a potential point of costs (money wise) for IPFS with regards to IPNS. Each update to an IPNS record would be on the blockchain and that will cost you. Now there's dirt cheap chains like polygon where adding a value like a sha-2-256 hash + it's key to access it by is like 1 cent or so. So we're not talking about large sums. Also the format how i set it up allows for using any EVM compatible chain. Even the filecoin chain could be used once it supports EVM compatibility with it's upcoming FVM!

I'm very eager to hear your opinion on this!

@markg85 markg85 added the need/triage Needs initial labeling and prioritization label Feb 14, 2022
@lidel lidel transferred this issue from ipfs/specs Mar 24, 2022
@Stebalien
Copy link
Member

You should talk with @petar and take a look at https://github.com/ipld/edelweiss/. It allows one to describe IPLD datastructures, but also functions etc.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
need/triage Needs initial labeling and prioritization
Projects
None yet
Development

No branches or pull requests

2 participants