I'm trying to build a decentralized note-taking app with smart contract and IPFS, but I'm a little confused as to the specifics on which to use and how to use them.

As far as I'm aware, each note a user creates is a separate NFT (ERC721), which points to an IPFS link.

But I have a few questions:

  1. Do I use ERC721 or ERC1155?
  2. What's the difference between IPFS and IPNS?
  3. Is this the best way to build such an application?
  4. If I build it this way, will the user have to pay gas fees every time they save, or is there a way to trigger a save without paying anything?
  5. Can this app be built on L1 as well as L2 chains like Polygon and Avalanche?

Sorry if these are stupid questions, I've been researching this for weeks now and still can't come to a final conclusion...


2 Answers 2


Using 721 or 1155 depends on the type of assets you want to add to your system and the growth you expect for your project. This is: if you're totally sure that you won't need anything else than:

  • Store notes, with links to IPFS.
  • Pay for them using the native token of your blockchain.

Then you will be OK with 721. Now, let's think another scenario: You deployed your 721 contract and everything goes well, but then you feel the need to create another contract to be part of your ecosystem. That contract, on deployment, would take the address of one or more contracts of your already-deployed ecosystem and... another token would be useful, say, for a new feature you are implementing. If you feel that need would come to you, then better go for an 1155 contract (specially if you feel the need to create new fungible tokens).

But if you are fine, and you think you will always be fine, with the current structure of your project where nothing but the NFTs you are creating will exist (save for the native token of your chain)... then stick to 721.

Now, IPFS and IPNS are part of the same. Typically, IPNS is a way to get aliases to some documents you store in IPFS. One particular implementation is to use DNSLink (in which you have your.fancy.domain registered and you add some specific records, and then /ipns/your.fancy.domain/... paths are available through IPFS). Typically, you would want the metadata for your NFTs to be in some sort of mapping(uint256 => string), with the value being the CID (e.g. "QmejFS6no1bJLffPtWdHrsh19skHyG6run8FmNUsutSCGj" for id = 1) of an IPFS resource, and then the method to return the URI should return, for id 1, the URI "ipfs://QmejFS6no1bJLffPtWdHrsh19skHyG6run8FmNUsutSCGj". Usually, you will not overcomplicate yourself with ipns and will just use ipfs.

For whether this is a good approach to build an application, this depends on more details I don't know, but you need to know something:

  • Users can mint an NFT with a certain link to an existing note in IPFS.
  • Users might need to change the note. This means that users, as NFT owners, must be enabled to change the link to the current note (since IPFS files cannot be edited) to point to the new note file.
  • For this to work, the IPFS notes must be pinned into another server which allows you to (e.g. pinata, infura).

Then you can do what you are asking for, if you take that into account.

STATE-MODIFYING FUNCTIONS MUST ALWAYS RUN INSIDE TRANSACTIONS. This implies: it will ALWAYS cost gas. One of the things I was been thinking about is that you would create some sort of sponsoring server in which:

  • Your server would receive a signature from a client wallet and, with it, the server (using a custom private key, signing for a custom wallet, which you will know and will already have afforded some native coins into it) would invoke the NFT minting / updating operation on your target smart contract, on the client's behalf (that's what the signature would serve for), but this needs additional methods you have to invent (and I am not sure how to do this, but I read it in a link I will search later for you).
  • For this to work, you have to fund that server's wallet address manually. Perhaps you can establish a business model in which your server will sell some advertising space to earn some money. This is up to you.

And finally, yes: As long as you use any EVM-compatible network, you can use OpenZeppelin's contracts (ERC721, ERC1155, whatever), and add more methods on top of it (e.g. to do that "sponsoring" stuff).

Edit: For the thing about signed messages, which you may need if you use some sort of "sponsoring" technique, this link could give you an insight. In this case, the purpose is different (it allows to have two different networks to verify the same requester of the operation to be verified in the two chains - but in this case you would make use of the user verification).

Edit 2: The idea behind sponsoring servers is that such server is optional for the user. While the signature process would make the user more trustworty, you should publish the sponsoring server sourcecode so they understand that no cheat can be done there.

Also, the contract will still have (actually: must still have) the direct methods to be invoked by the users who prefer to pay the gas themselves and hit the blockchain themselves, instead of hitting your sponsoring server. If they use an external client being ERC721 or ERC1155 compatible (there are many ones out there which are abstractions over specific standards) and everything works ok, it will suffice for the sake of usage as long as they can see the results appropriately later (querying the contract externally does not consume gas).

Still, for the users to trust you, always publish the source code of the contract (there are tools to reverse-engineer the EVM code of a contract, but being proactive and open about the contract's/contracts' source code(s) will give you a better image).

  • Thanks a lot for this detailed response! This clarifies everything! Jan 24, 2022 at 21:13
  • You're welcome. It helps me to fix concepts better (I'm also a newbie here in these topics). Anyway, you will suffer a lot implementing that. Still, despite my answer, remember something: deployed contracts can't be modified (and it evokes a loss of trust by potential users if you cheat by implementing contract proxying), so test everything a lot using mocha before deploying anything to a mainnet. Jan 24, 2022 at 22:17
  • Alternatively to the thing about sponsoring server, the LAZY MINTING technique would do the trick: blog.openzeppelin.com/…. Perhaps the structure of the methods would be different here, as you would not need to create additional methods, but now the client side must know how to forge a transaction and give it to the server for execution. It is a trade-off in your duties but ultimately the same result. Jan 24, 2022 at 22:43
  • Thanks, will look into it when I get to that stage. I'm thinking of having this available of L2 blockchains, which will just cost users a few cents. Jan 24, 2022 at 23:28

Here's a main part of ERC-721 that is relevant to your app.

ERC-721 lets you make a thing and then later come back to quickly find out who owns that thing. ERC-1155 does not support that use case.

You are still very early in your design so you probably want to spell out an idea of what you want to try before asking detailed questions.

I have a Community Service Hour you might be interested in where we go through a few use cases each week and go through case studies brought up by the audience. You are welcome to join, details at https://phor.net/#speaking

Not the answer you're looking for? Browse other questions tagged or ask your own question.