forked from celo-org/docs
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* add graph post * add clarity around mappings * Rename 2021-11-18-using-the-graph.md to index.md * show blog page est reading time * show more text in summary * update post * add blog to navbar * add post * update title * update link * add intro + tips
- Loading branch information
1 parent
683fac5
commit aa20aa8
Showing
10 changed files
with
316 additions
and
9 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,14 +8,11 @@ authors: | |
url: https://github.com/critesjosh | ||
image_url: https://github.com/critesjosh.png | ||
tags: [code playground] | ||
image: https://i.imgur.com/mErPwqL.png | ||
hide_table_of_contents: false | ||
--- | ||
|
||
This post provides an introduction to the live code editor that is included as a feature in this blog. It allows you to see working examples of things like connecting to the Celo network with Metamask and initiating user transactions with the SDK. | ||
|
||
<!--truncate--> | ||
|
||
If you have any suggestions for examples that you'd like to see, or if you'd like to create one yourself and have it included in the blog, please reach out to me at [[email protected]](mailto:[email protected]) or on Discord at joshc#0001. | ||
|
||
## Live coding | ||
|
@@ -28,6 +25,7 @@ The code is rendered using [React Live](https://github.com/FormidableLabs/react- | |
|
||
::: | ||
|
||
<!--truncate--> | ||
### Hello World | ||
|
||
Try it out: | ||
|
@@ -57,4 +55,4 @@ function logger(){ | |
|
||
Cool! | ||
|
||
This is just a small preview into what code sharing and learning experiences we can build with this tool. Check out this post about [Connecting to Metamask](2021-11-15-connect-to-metamask.md) to learn more. | ||
This is just a small preview into what code sharing and learning experiences we can build with this tool. Check out this post about [Connecting to Metamask](2021-11-16-connect-to-metamask.md) to learn more. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
--- | ||
title: Demos with ObservableHQ | ||
description: Learn more about Observable notebooks and how they can be used in a blog | ||
slug: observable-intro | ||
authors: [josh] | ||
tags: [observable] | ||
image: https://logowik.com/content/uploads/images/the-graph-grt1266.jpg | ||
hide_table_of_contents: false | ||
--- | ||
|
||
## What is Observable? | ||
|
||
[Observable HQ](https://observablehq.com/) is a Javascript notebook tool that makes it easy to share executable Javascript code right in the browser. This greatly reduces the friction around introducing and educating people about tools or features. Observable is designed primarily as a data visualization tool, but I have found it to be helpful for explaining and demonstrating concepts and behaviors for web3 as well. | ||
|
||
For the official introduction to Observable, [check out the 5 minute introduction.](https://observablehq.com/@observablehq/five-minute-introduction?collection=@observablehq/introduction) | ||
|
||
## Why I like it | ||
|
||
### Easy to setup | ||
|
||
First of all, there is nothing to download! This is a huge benefit when introducing developers to new technology. I can show off features and techniques for using new tech without requiring developers to have to download anything or set up an environment. This makes it easier to spark curiosity and inspire people to continue on their learning journey. | ||
|
||
<!--truncate--> | ||
|
||
### Code + Visualizations + Text | ||
|
||
Observable supports Javascript, Markdown and HTML in cells. This means I can write executable Javascript surrounded by markdown that helps explain the context in which this code can be used and may be useful. The notebooks are also easy to embed into other contexts (like this blog). | ||
|
||
Here is an example from a post on Merkle Trees. You can [view the full notebook here.](https://observablehq.com/@critesjosh/merkle-trees) | ||
|
||
<iframe width="100%" height="643" frameborder="0" className="observable-notebook" | ||
src="https://observablehq.com/embed/@critesjosh/merkle-trees?cells=chart%2Cp1%2Cvisualize_heading"></iframe> | ||
|
||
### Executable Javascript | ||
|
||
Observable allows anyone inspect the Javascript in the notebook and displays the results of the code execution. This is particularly useful to demo interactions with a connected web3 wallet or reviewing the structure of responses from API calls. Also, when code in one cell is updated, all other cells that use the code are referenced as well, kind of like hot reloading. | ||
|
||
For example, in the [graph post](../2021-11-18-using-the-graph/index.md), I make a query to the Graph and the notebook shows a live response. Viewers can click through the notebook response to insepct the results. | ||
|
||
[![the graph query](query.gif)](https://observablehq.com/@critesjosh/query-the-graph) | ||
|
||
### Remix + Share | ||
|
||
Viewers can edit the Javascript in the notebook and execute their own code to see the results. They can fork their changes and save them in their own notebook to be worked on later or to share with others. | ||
|
||
I can import common node packages into a notebook and run them as I would in an application. This allows me to quickly test things and share them. | ||
|
||
## What I don't like | ||
|
||
Using Observable isn't great for everything--it has its limitations. | ||
|
||
### Limited packages | ||
|
||
While many npm packages work with observable, not all of them do. You may need to build packages to work specifically for Observable or import minified versions from a CDN. [This tool](https://observablehq.com/@observablehq/module-require-debugger) can help you figure out how to import packages that you want to use. | ||
|
||
### Simple, specific actions | ||
|
||
Observable is great for showing simple interactions with packages or creating visualizations, but is not well suited for demonstrating how to design or build an application. It is a unique environment where Javascript syntax may be different than what developers are used to, so it is useful for specific things. | ||
|
||
### Iframe limitations | ||
|
||
Observable notebooks are easiest to embed in other pages using an [iframe](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe). This means the context of the notebook is limited by the same things as an iframe, which may or may not be a problem, depending on what you are trying to do. There are ways around this as well, you can link readers directly to your notebook or embed the notebook using a React component or vanilla Javascript. You can read more about embedding on the [Observable site here](https://observablehq.com/@observablehq/introduction-to-embedding). |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,228 @@ | ||
--- | ||
title: Using the Graph w/ Celo | ||
description: Learn about what the Graph is and how to use it in your Celo DApp | ||
slug: using-the-graph | ||
authors: [josh] | ||
tags: [The Graph, DApps] | ||
image: https://logowik.com/content/uploads/images/the-graph-grt1266.jpg | ||
hide_table_of_contents: false | ||
--- | ||
|
||
import styles from '../styles.css' | ||
|
||
[The Graph protocol](https://thegraph.com/) makes it easy to get historical blockchain data. This can be useful when you want to check a users history of using a specific token or interacting with a specific contract. It may also be useful when collecting data about the activity around a specific contract, or set of contracts. The Graph also makes this data easy to transform, organize and share across applications. | ||
|
||
In this post I explore | ||
|
||
- [What the Graph is](index.md#what-is-the-graph) | ||
- [How to get started using the Graph with Celo](index.md#using-the-graph) | ||
- [What a subgraph is and how to create one](index.md#initialize-your-subgraph) | ||
- [How to deploy a subgraph to the Graph's hosted service](index.md#deploy-subgraph) | ||
- [How to query a subgraph](index.md#query-the-subgraph) | ||
|
||
## What is the Graph? | ||
|
||
From the Graph website: | ||
|
||
*The Graph is a decentralized protocol for indexing and querying data from blockchains, starting with Ethereum. It makes it possible to query data that is difficult to query directly.* | ||
|
||
The problem that the Graph solves is that indexing blockchain data is actually very difficult. Additionally, the Graph makes it easy to get historical blockchain data without having to run your own archive node or paying to access an archive node through a node service provider, like [Quicknode](https://www.quicknode.com/chains/celo). | ||
|
||
<!--truncate--> | ||
|
||
## Using the Graph | ||
|
||
I will be using [this GitHub repository](https://github.com/critesjosh/the-graph-hello-world) as a reference throughout this post. This repo contains a simple [HelloWorld contract](https://github.com/critesjosh/the-graph-hello-world/blob/master/HelloWorld.sol) that stores a string that can be updated. | ||
|
||
`HelloWorld.sol` | ||
```js | ||
// HelloWorld.sol | ||
|
||
// Learn more about Solidity here: https://solidity.readthedocs.io | ||
pragma solidity >=0.5.0; | ||
|
||
contract HelloWorld { | ||
|
||
event NameUpdated(string newName, address updater); | ||
|
||
// Define a string called name | ||
string name; | ||
|
||
// Declares a function called getName | ||
// The 'public' label means the function can be called internally, by transactions or other contracts | ||
// The 'view' label indicates that the function does not change the state of the contract | ||
// The function returns a string, from the memory data location | ||
function getName() | ||
public | ||
view | ||
returns (string memory) | ||
{ | ||
// Return the storage variable 'name' | ||
return name; | ||
} | ||
|
||
// Declare a function called setName | ||
// The function takes 1 parameter, a string, called newName, with the calldata data location in the Ethereum Virtual Machine | ||
// The 'external' label means the function can only be called from an external source | ||
function setName(string calldata newName) | ||
external | ||
{ | ||
emit NameUpdated(newName, msg.sender); | ||
// Set the storage variable, name, to the value passed in as newName | ||
name = newName; | ||
} | ||
} | ||
``` | ||
|
||
The contract emits an event every time the storage sting is updated. Event handlers in the subgraph are triggered by contract events, so setting up a contract with events is required. | ||
|
||
It is easiest to get started using the Graph hosted service, which supports queries on the Celo network. | ||
|
||
:::tip | ||
|
||
You can [learn more about the Graph's hosted service here](https://thegraph.com/docs/hostedservice/what-is-hosted-service). | ||
|
||
::: | ||
|
||
### Install the Graph CLI | ||
|
||
The first step is to install the graph command line tool. | ||
|
||
```bash | ||
npm install -g @graphprotocol/graph-cli | ||
``` | ||
|
||
or | ||
|
||
```bash | ||
yarn global add @graphprotocol/graph-cli | ||
``` | ||
|
||
:::tip | ||
|
||
Learn more about the `graph-cli` package [here](https://www.npmjs.com/package/@graphprotocol/graph-cli). | ||
|
||
::: | ||
|
||
### Initialize your Subgraph | ||
|
||
*A subgraph defines which data The Graph will index from Ethereum, and how it will store it. Once deployed, it will form a part of a global graph of blockchain data.* | ||
|
||
:::tip | ||
|
||
[Read more about subgraphs on the Graph website.](https://thegraph.com/docs/developer/define-subgraph-hosted) | ||
|
||
::: | ||
|
||
In a new, empty project directory, run the following command in the terminal: | ||
|
||
```bash | ||
graph init --product hosted-service --from-contract 0xd2dC7E59971E934bF479B8eA86B9Ec1627B0F3D6 --network celo-alfajores --abi <FILE> critesjosh/Hello-World | ||
``` | ||
|
||
The CLI tool will prompt you for some additional information. Use the "Hosted Service" for creating subgraphs that query contracts on the Celo network. | ||
|
||
For the subgraph name, enter your GitHub username followed by the name of your project. In my case this is `critesjosh/Hello-World`. | ||
|
||
The tool will ask you to specify a directory, network and contract address that you would like to query. I chose the default directory (Hello-World), the `celo-alfajores` network, the address of my deployed Solidity contract and the path to my [contract ABI](https://docs.soliditylang.org/en/latest/abi-spec.html). | ||
|
||
The tool sets up my subgraph in the specified directory. Open `subgraph.yml` in the new subgraph project folder to see how it is configured. You can find more information about the [Subgraph Manifest file here](https://thegraph.com/docs/developer/create-subgraph-hosted#the-subgraph-manifest). | ||
|
||
### Define the schema | ||
|
||
The next step is to define your graphql schema in `schema.graphql` in the new project directory. | ||
|
||
A graphql schema is like a dictionary that defines the types of entities to map from the data and how the entities are related. This is an important step to spend some time thinking about because this will define how your data is structured and linked. Here is [sushiswap's subgraph repo](https://github.com/sushiswap/sushiswap-subgraph) as a complex project reference. | ||
|
||
For the simple HelloWorld contract that we are querying with this subgraph, I defined the schema like this: | ||
|
||
```graphql | ||
type Name @entity { | ||
id: ID! | ||
newName: String | ||
updater: Bytes! | ||
} | ||
``` | ||
|
||
This will tell us the new name that is being stored in the contract, `newName`, and the account address that updated the name, `udpater`. | ||
|
||
:::tip | ||
|
||
[Read more about the Graph schemas here.](https://thegraph.com/docs/developer/create-subgraph-hosted#the-graphql-schema) | ||
|
||
::: | ||
|
||
### Define Mappings | ||
|
||
Mappings are defined in `./src/mappings.ts` and transform the contract data (events) into the entities that are defined in `schema.graphql`. These mappings are written in a subset of Typescript. | ||
|
||
In this example, there is only one event being indexed, so there is only one mapping. | ||
|
||
```ts | ||
import { NameUpdated } from '../generated/HelloWorld/HelloWorld' | ||
import { Name } from '../generated/schema' | ||
|
||
export function handleNameUpdated(event: NameUpdated): void { | ||
let id = event.transaction.hash.toHex() | ||
let name = Name.load(id) | ||
if (name == null) { | ||
name = new Name(id) | ||
} | ||
name.newName = event.params.newName | ||
name.updater = event.params.updater | ||
name.save() | ||
} | ||
``` | ||
|
||
This mapping sets the entity `id` as the transaction hash, the entity `newName` as the newName from the event parameter and the entity `updater` as the updater from the event parameter. The mapping will update an entity if one with a known `id` already exists, but since transaction hashes are unique, each event emitted from the contract will create a new entity. | ||
|
||
:::tip | ||
|
||
You can find more information about mappings on [the Graph website here](https://thegraph.com/docs/developer/create-subgraph-hosted#writing-mappings). | ||
|
||
::: | ||
|
||
Once the mapping is defined, you can generate the Graph AssemblyScript by running | ||
|
||
```bash | ||
graph codegen | ||
``` | ||
|
||
"This will generate an AssemblyScript class for every smart contract in the ABI files mentioned in subgraph.yaml, allowing you to bind these contracts to specific addresses in the mappings and call read-only contract methods against the block being processed. It will also generate a class for every contract event to provide easy access to event parameters as well as the block and transaction the event originated from." | ||
|
||
*--[The Graph codegen docs](https://thegraph.com/docs/developer/create-subgraph-hosted#code-generation)* | ||
|
||
### Deploy Subgraph | ||
|
||
To deploy the subgraph to the hosted service, you will need to create an account on [the Graph's hosted service site](https://thegraph.com/hosted-service). | ||
|
||
From the [dashboard](https://thegraph.com/hosted-service/dashboard), you can find your Access Token for deploying the subgraph. Once you have that, you can authenticate with: | ||
|
||
```bash | ||
graph auth --product hosted-service <ACCESS_TOKEN> | ||
``` | ||
|
||
Next, click the "Add Subgraph" button. Fill out the subgraph info with the appropriate information and deploy it with: | ||
|
||
```bash | ||
graph deploy --product hosted-service <GITHUB_USER>/<SUBGRAPH NAME> | ||
``` | ||
|
||
Once your subgraph is deployed, you should be able to view it on the hosted service dashboard. You can view my [Hello World subgraph page here](https://thegraph.com/hosted-service/subgraph/critesjosh/hello-world). | ||
|
||
![](dashboard.png) | ||
|
||
Once the subgraph is deployed, the service will take some time to sync the events from the contract. Once it has been fully synced, you can run queries in the playground to test it out. | ||
|
||
### Query the subgraph | ||
|
||
You can learn more about [querying your subgraph from the hosted service here](https://thegraph.com/docs/hostedservice/query-hosted-service). | ||
|
||
The following embedded code notebook from [Observable HQ](https://observablehq.com/) shows how to query the subgraph I deployed with basic Javascript. You can [view the notebook on Observable here](https://observablehq.com/@critesjosh/query-the-graph). I wrote a post that goes into more detail about Observable, you can [read it here](../2021-11-18-observable-intro/index.md). | ||
|
||
You can inspect the JavaScript objects in the notebook by clicking on them. Try clicking on the `result` object. Click on the `names` array in the `data` object. | ||
|
||
<iframe width="100%" height="500" frameborder="0" class="observable-notebook" | ||
src="https://observablehq.com/embed/@critesjosh/query-the-graph?cell=*"></iframe> | ||
|
||
You can see the entities that were defined in the `schema.graphql`, populated with event information like the `newName` and `updater` from each transaction! |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
josh: | ||
name: Josh Crites | ||
title: Developer Relations, cLabs | ||
url: https://github.com/critesjosh | ||
image_url: https://github.com/critesjosh.png |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
.observable-notebook { | ||
background: white; | ||
} |
Oops, something went wrong.