Ethereum — Auto Generate GraphQL Schema, Resolver, and Server

Angello Pozo
Jul 23, 2018 · 4 min read

Over the last year, there have been more and more projects that allow developers to use GraphQL to query Ethereum smart contracts. Although this is great, their one big flaw is that it requires the developer to write a GraphQL schema and resolver. That means anytime an update in Solidity is made, the entire stack has to be updated. To make this processes easier, we’re open sourcing ethereum-to-graphql, a library that auto generates the schema and resolver for any Ethereum smart contract.


Problem: ETH → GraphQL Development Process

To use GraphQL with your Ethereum smart contract, you must do the following:

  1. Compile Solidity Contracts

A GraphQL schema defines the types that are allowed for your query. A GraphQL resolver is a function that is triggered upon query to fetch data. You can make it do whatever you want as long is it returns the data requested.

What is cumbersome about the entire process is that you are forced to rewrite the schema and resolver anytime you change anything in your Smart Contract. This adds development time and complexity. To exemplify the process, take a look at the example below:

// (1) Solidity
function getBalanceInEth(address addr) public returns(uint) {
return ConvertLib.convert(getBalance(addr), 2);
}
// (2) GraphQL Schema
type getBalanceInEth {
balance: Int
}
// (3) GraphQL Resolver
Query: {
async getBalanceInEth() {
let balance = 0;
await contractInstance.getBalanceInEth.call()
.then(bal => (balance = bal / wie)) // convert to ETH
.catch(err => console.log(err));
return {
balance
};
}
}
// (4) Start server --> npm run start// (5a) GraphQL Query
{
query {
getBalanceInEth(addr: "0x7b2c6c6e9026bcef8d...a") {
balance
}
}
}
// (5b) Result
{
'getBalanceInEth': {
'balance': 5
}
}

Solution: Auto Generate Schema And Resolver

Our package Ethereum-to-GraphQL consumes the ABI(Application Binary Interface) created from compiling Solidity and generates the necessary schema and resolver for ANY smart contract. This means the steps above are reduced to:

  1. Compile Solidity Contracts

This process has been vastly improved and streamlined. This means a developer can go directly from Solidity to GraphQL.

Imagine adding this to Etherscan, and being able to explore data within any smart contract. As long as you have access to the correct ABI, everything will be queryable. Just look at how simple the process blow is compared to the example above:

// (1) Solidity
function getBalanceInEth(address addr) public returns(uint) {
return ConvertLib.convert(getBalance(addr), 2);
}
// (2) Start server --> npm run start// (3a) GraphQL Query
{
query {
getBalanceInEth(addr: "0x7b2c6c6e9026bcef8d...a") {
uint256_0 {
string
int
}
}
}
}

// (3b) Result
{
'getBalanceInEth': {
'uint256_0': {
'string': '5',
'int': 5
}
}
}

Details: How The Internals Work (Short)

When Solidity is compiled, an ABI is created. It describes all the inputs and outputs of the smart contract. For example, the ABI for getBalanceInEth is shown below:

[{
"constant": false,
"inputs": [{
"name": "addr",
"type": "address"
}],
"name": "getBalanceInEth",
"outputs": [{
"name": "",
"type": "uint256"
}],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
}]

Given this ABI, we have enough information to generate the correct GraphQL schema.

type Value {
string: String
int: Number
}
type getBalanceInEth {
uint256_0: Value
}

Because we are auto generating everything we decided to define a few helpful types like the Value type. You can choose to see the string or int version of the result. We also have a type for bytes where you can select raw or decoded.

With the schema generated, all that is left to create is the resolver. This requires 2 functions: a function that gets data from Ethereum (sourceFn) and a function to handle the result (outputMapper). As we iterate through we create the wrapper function that binds the two together.

Notice how the SourceFn accepts an outputMapper. This output mapper receives the data and transforms the data in the necessary GraphQL format that allows queries.

Those two methods are combined and attached returned as a resolver for GraphQL to utilize. All you have to do is pass your contract ABI to our package and then pass that into your GraphQL server of choice. Below is an example for Truffle’s Metacoin:

Conclusion: Call To Action

We’re very excited to be open sourcing an internal project to the world. We see this package helping a lot of people as it lowers the barrier for GraphQL and Ethereum. We are very open to accepting pull requests and have a few suggestions on how to contribute.


To keep up with the latest HelloSugoi news as it’s happening, we invite you join our mailing list, message us on Discord, follow us on Twitter @HelloSugoi, and visit our website hellosugoi.

HelloSugoi

Blockchain powered live entertainment ecosystem

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store