The Graph
Text

Developing NEAR Contracts that Work With The Graph

Lesson 5

On Ethereum, a subgraph indexes events emitted by a smart contract, but on NEAR, we don't have events (at least not yet). The Graph for NEAR indexes blocks and receipts. The receipts may contain logs if a developer codes them in (ideally in a standard JSON format). So the first thing we need to do is ensure our contract is emitting logs in a manner that the subgraph can listen for and index.

For the purpose of this course we created and deployed a contract account that we know is emitting logs in JSON format so we have something to work with. It's a registry contract that enables people to register and associate their NEAR account with a decentralized identifier (DID) created on the Ceramic Network.

The use case we'll explore in the rest of the course is how to make our app query this subgraph to get all the existing registrations (DIDs). Knowing the DID's, we can then bring in corresponding data from Ceramic for each DID to create interesting and useful directories (like a NEAR Guilds directory or a member's directory for a specific app).

Ethereum Events vs NEAR "Events"

For Ethereum contracts, you can go to Etherscan and lookup the contract address to look at its code and figure out what events are being emitted. For example, you can view the popular Crypto Punk ETH-20 contract and if you click on the "Contract" tab you can also have a look at its Solidity code. The contract's address is `0xb47e3cd837dDF8e4c57F05d70Ab865de6e193BBB`.

Ethereum contracts have ABIs (Application Binary Interface). It defines the methods and structures that can be used to interact with that binary contract and what shape of data you'll get back.

NEAR contracts compile to webAssembly (WASM) and don't have ABIs so it's not as easy to find the data NEAR contracts are emitting. Etherscan support is coming some day, but until then you either know what's being emitted in the logs because you are the developer, you need to go through the code in a Github repo, or look through contract transactions in the Explorer to figure it out.  

Recently, NEAR enhancement proposal 171 (NEP-171) defined an event format primarily aimed at NFTs. However, it's also a useful standard for developers to use in other types of contracts and it's what we're going to use to enable our contracts to work with our subgraph.  If looking through AssemblyScript code, a logging entry may look something like so:

logging.log(`{"EVENT_JSON":{
     "standard":"nep171",
     "version":"1.0.0",
     "event":"removeEditor",
     "data":{
          "editor":"${accountId}",
          "time":${Context.blockTimestamp},
          "removedBy":"${Context.predecessor}"
}}}`)

Can you figure it out?

Looking at that code, can you find the event and data it provides? What function is being called? What arguments are included in the data? We will come back to these logged events very soon.

Enabling Your Contracts

If you have or will have a contract that you want to work with The Graph, you'll need to code in logs like the one above.  You're not constrained to use the NEP-171 standard, but outputting them in a JSON format makes mapping the data to the entities much easier to do which is important if you want to take full advantage of GraphQL queries, create relationships between entities and so on.

You'll typically want to include a logging.log entry at the end of any function call in your contract that "does something".  It takes a little thought as to what data to pass back and how that might be useful in the context of your application.

For example, with the above log listening for the "removeEditor" functionCall, knowing who is removing editors can lead to insights about who is the most active editor.  Coupled with other data can also determine if their are patterns in the types of editors being removed.  That type of insight would not be easily queryable without an indexer or The Graph.

Action Steps

If you just want to follow along with the course, we have already created and deployed a contract that is setup with NEP-171 logs that you can interact with (did.near).  If you want to work on your own project, now would be the time to go through your contract and add logs similar to the one shown above to the functionCalls you want to track.  When done, deploy it.

Note:  currently The Graph only works with the NEAR mainnet (near-mainnet).  It does not index the testnet.  That support is apparently in the works, but you'll need a mainnet contract enabled with JSON formatted logs 

Next Steps

Now that you've got a contract that can be indexed and provide some useful data, we'll move on to scaffolding out a NEAR subgraph and installing the graph-cli so you can generate, build, and deploy your code to the Hosted Service.  See you in the next lesson.


Maybe you'd rather have us build your NEAR subgraph for you?

Not a problem and it can be pretty quick and inexpensive depending on the complexity of your contract.  Get in touch using one of the methods below.

Pen
>