website logo
Join the CommunityContact Us
Navigate through spaces
⌘K
Portal del Desarrollador de la Red Palm
La Red Palm
Envía un Artículo
Detalles de la red
Validadores
Primeros Pasos
Obtén Tokens PALM
Cuotas de Gas
Conéctate a la red Palm
Ejecuta un Nodo de Transacciones
Tutoriales prácticos
Configuración de la cartera MetaMask
Desplegar contratos NFT
Verificando Contratos NFT
Acuña NFTs con Hardhat
Puente
Utilizar el Puente
Integración con el Puente
Direcciones Componentes del Puente
Descontinuados
Utiliza las Herramientas Compatibles
Explorador de Bloques
Moralis
Palm Safe
The Graph
API Covalent
Docs powered by archbee 

The Graph

28min

Resumen

DApps como los mercados NFT necesitan constantemente recuperar información de la cadena sobre la transferencia de tokens o la acuñación de activos. Una forma de obtener esa información es extraerla directamente de la blockchain. Esto suele ser un proceso complicado que requiere construir una instancia de servidor ad-hoc. En su lugar, puedes utilizar un protocolo dedicado como The Graph, que se centra en la indexación y el almacenamiento de datos de contratos inteligentes.



1. ¿Cómo funciona The Graph?

The Graph es un protocolo descentralizado para consultar blockchains como la red Palm. Permite a los desarrolladores crear APIs personalizadas denominadas Subgraphs.

¿Qué son los Subgraphs?

Los Subgraphs escuchan eventos específicos de contratos inteligentes y actúan como almacenes de datos para que la información pueda ser recuperada fácilmente por una DApp. Dado que los Subgraphs se construyen en torno a los requisitos de datos específicos de los desarrolladores (por ejemplo, IEP-721 subgraph schema) solo es necesario llamarlos una vez, a diferencia de las API de propósito general que a veces requieren cientos de llamadas para recopilar información relevante.

Más información sobre la red Graph y su protocolo



2. Consulta de los Subgraphs en la red Palm

The Graph proporciona una GraphQL API. Si está familiarizado con GraphQL, debería sentirse cómodo consultando The Graph. Asegúrese de conocer los detalles de la The Graph’s API.

Recursos GraphQL para principiantes

  • GraphQL
  • Tutoriales prácticos GraphQL

Resources to Experiment with Subgraphs and GraphQL

(optional)

  • A training toolkit to deploy a contract and immediately mint NFTs on the Palm Network
  • GraphiQL tests queries against deployed Subgraphs and the NFTs you’ve minted


3. Subgraphs disponibles en la red Palm

La red Palm proporciona un nodo Graph y una serie de Subgraphs desplegados adaptados a contextos NFT. Los desarrolladores pueden acceder a esos subgrafos mediante llamadas a API RESTful o WebSocket:

Nombre & repo

Uso

Endpoint red Principal/GraphiQL

Endpoint red de Pruebas/GraphiQL

wighawag/eip721-subgraph

Consulta de tokens ERC-721

https://graph.palm.io/subgraphs/name/wighawag/eip721-subgraph

https://graph.palm-uat.xyz/subgraphs/name/wighawag/eip721-subgraph

amxx/eip1155-subgraph

Consulta de tokens ERC-721

https://graph.palm.io/subgraphs/name/amxx/eip1155-subgraph

https://graph.palm-uat.xyz/subgraphs/name/amxx/eip1155-subgraph

sushi/exchange-palm

Consulta del intercambio de Sushi en Palm

https://graph.palm.io/subgraphs/name/sushi/exchange-palm



nftx-project/nftx-v2-subgraph

Consulta los contratos https://nftx.io/ desplegados en Palm

https://graph.palm.io/subgraphs/name/nftx-project/nftx-v2-palm



ethereum-blocks

Consulta de los bloques de la mainnet Palm

https://graph.palm.io/subgraphs/name/blocklytics/palm-mainnet-blocks





4. Utiliza de The Graph desde una DApp

Existe una gran variedad de herramientas para consumir Subgraphs a partir de aplicaciones basadas en:

  • React
  • Vue
  • iOS
  • Android
  • React Native

Puedes utilizar un paquete completo como Apollo o una implementación más sencilla como GraphQL-Request.





💡 Conoce Más

  • Más información sobre consultas a The Graph desde una DApp


Ejemplo de código para una DApp en React

Index.tsx
App.tsx
|
{% raw %}
  import { gql } from "@apollo/client";
  import React, { useState } from "react";
  import {
      Chains,
      Subgraph,
      Subgraphs,
      TheGraphProvider,
      useCreateSubgraph,
      useSubgraph,
  } from "thegraph-react";

  function PalmNfts({ NFTs }: { readonly NFTs: Subgraph }): JSX.Element {
      const { useQuery } = useSubgraph(NFTs);

      const { error, loading, data } = useQuery(gql`
        {
          tokens(
            where: { contract: "0xaadc2d4261199ce24a4b0a57370c4fcf43bb60aa" }
            first: 10
          ) {
            id
            owner {
              id
              numTokens
            }
            contract {
              name
              symbol
            }

            tokenURI
          }
        }
      `);

      console.log("data from GQL query:", data);

      return (
          <div >
              <div >
                  <div style={{ flex: 1, textAlign: "left" }}>
                      <h1>Tokens Dashboard</h1>
                  </div>
                  <div style={{ textAlign: "left", flex: 2, alignSelf: "center" }}></div>
              </div>
              {error || loading ? (
                  <blockquote>
                      <br />
                      <br />
  Loading...
                  </blockquote>
              ) : (
                  (data as any).tokens.map((n: any, i: number) => {
                      return (
                          <div>
                              <div>Tokens name: {`"${n.contract.name.toString()}"`}</div>
                              <br />
                              <div>
                                  Owner wallet public address: {`"${n.owner.id.toString()}"`}
                              </div>
                              <br />
                              <div>
                                  Number of NFTs owned by this address:{`"${n.owner.numTokens}"`}
                              </div>
                              <br />
                              <div>Token URI: {n.tokenURI.toString()}</div>
                              <br />
                              <div ></div>
                              <br /> <div></div>
                          </div>
                      );
                  })
              )}
          </div>
      );
  }

  export default function App(): JSX.Element {
      const NFTs = useCreateSubgraph({
          [Chains.MAINNET]:
              "https://graph.palm.io/subgraphs/name/wighawag/eip721-subgraph",
      });
      const subgraphs = React.useMemo((): Subgraphs => {
          return [NFTs];
      }, [NFTs]);

      return (
          <TheGraphProvider chain={Chains.MAINNET} subgraphs={subgraphs}>
              <PalmNfts NFTs={NFTs} />
          </TheGraphProvider>
      );
  }
{% endraw %}



5. Crea un nuevo Subgraph

La creación de un Subgraph permite determinar los datos que The Graph indexará en la blockchain. A continuación, decidirá cómo se almacenarán estos datos.

Para ello:

  1. Despliega los contratos inteligentes que serán indexados (y sus direcciones)
  2. Crea subgraph.yaml
    • El manifiesto de Subgraph, es decir, un archivo de configuración, contiene información sobre los contratos inteligentes indexados por Subgraph.
  3. Crea schema.graphql
    • GraphQL schema define la estructura del Subgraph
      • 💡 Conoce Más
  4. Crea un mapeo AssemblyScript
    • Código TypeScript utilizado para traducir los datos de eventos de los contratos en objetos específicos del esquema.
    • The Graph ofrece un generador de código para ello
      • 💡 Conoce Más
  5. Para hacerte una idea de la estructura habitual de un repositorio de subgraph, puedes utilizar el ejemlpo de graphprotocol para empezar.
  6. Más información en los repositorios específicos de NFT dedicados a:


Archivos de ejemplo

No hay un orden concreto a la hora de modificar los archivos necesarios para crear un Subgraph.

Una vez que hayas terminado de editar los 3 archivos siguientes para definir tu subgraph, puedes probar opcionalmente tu mapeo en un entorno sandbox e iniciar el proceso de añadir tu subgraph a la red Palm.



Manifest/config File
|
specVersion: 0.0.2
description: EIP-721
repository: https://github.com/wighawag/eip721-subgraph
schema:
  file: ./schema.graphql
dataSources:
  - kind: ethereum/contract
    name: EIP721
    network: Palm-mainnet
    source:
    address: '0x2E645469f354BB4F5c8a05B3b30A929361cf77eC'
      abi: EIP721
      startBlock: 5806610
    mapping:
      kind: ethereum/events
      apiVersion: 0.0.4
      language: wasm/assemblyscript
      entities:
        - Token
        - TokenContract
        - Owner
        - OwnerPerTokenContract
        - All
      abis:
        - name: EIP721
          file: ./abis/All.json
      eventHandlers:
        - event: Transfer(indexed address,indexed address,indexed uint256)
          handler: handleTransfer
      file: ./src/mapping.ts


Licencia[1]



Diseñado para Contratos Compatibles con EIP-721

Schema.graphql
|
type All @entity {
id: ID!
numTokenContracts: BigInt!
  numTokens: BigInt!
  numOwners: BigInt!
}

type Token @entity {
  id: ID!
  contract: TokenContract!
  tokenID: BigInt!
  owner: Owner!
  mintTime: BigInt!
  tokenURI: String!
}

type TokenContract @entity {
  id: ID!
  name: String,
  symbol: String,
  doAllAddressesOwnTheirIdByDefault: Boolean!
  supportsEIP721Metadata: Boolean!
  tokens: [Token!]! @derivedFrom(field: "contract")
  numTokens: BigInt!
  numOwners: BigInt!
}

type Owner @entity {
  id: ID!
  tokens: [Token!]! @derivedFrom(field: "owner")
  numTokens: BigInt!
}

type OwnerPerTokenContract @entity {
  id: ID!
  owner: Owner!
  contract: TokenContract!
  numTokens: BigInt!
}


Licencia[1:1]



Archivo de asignaciones

JS
|
import { store, Bytes, BigInt } from '@graphprotocol/graph-ts';
import { Transfer, EIP721 } from '../generated/EIP721/EIP721';
import { Token, TokenContract, Owner, All, OwnerPerTokenContract } from '../generated/schema';

// import { log } from '@graphprotocol/graph-ts';

let zeroAddress = '0x0000000000000000000000000000000000000000';

function toBytes(hexString: String): Bytes {
    let result = new Uint8Array(hexString.length / 2);
    for (let i = 0; i < hexString.length; i += 2) {
        result[i / 2] = parseInt(hexString.substr(i, 2), 16) as u32;
    }
    return result as Bytes;
}

function supportsInterface(contract: EIP721, interfaceId: String, expected: boolean = true): boolean {
    let supports = contract.try_supportsInterface(toBytes(interfaceId));
    return !supports.reverted && supports.value == expected;
}

function setCharAt(str: string, index: i32, char: string): string {
    if (index > str.length - 1) return str;
    return str.substr(0, index) + char + str.substr(index + 1);
}

function normalize(strValue: string): string {
    if (strValue.length === 1 && strValue.charCodeAt(0) === 0) {
        return "";
    } else {
        for (let i = 0; i < strValue.length; i++) {
            if (strValue.charCodeAt(i) === 0) {
                strValue = setCharAt(strValue, i, '\ufffd'); // graph-node db does not support string with '\u0000'
            }
        }
        return strValue;
    }
}

export function handleTransfer(event: Transfer): void {
    let tokenId = event.params.id;
    let id = event.address.toHex() + '_' + tokenId.toString();
    let contractId = event.address.toHex();
    let from = event.params.from.toHex();
    let to = event.params.to.toHex();

    let all = All.load('all');
    if (all == null) {
        all = new All('all');
        all.numOwners = BigInt.fromI32(0);
        all.numTokens = BigInt.fromI32(0);
        all.numTokenContracts = BigInt.fromI32(0);
    }

    let contract = EIP721.bind(event.address);
    let tokenContract = TokenContract.load(contractId);
    if (tokenContract == null) {
        // log.error('contract : {}',[event.address.toHexString()]);
        let supportsEIP165Identifier = supportsInterface(contract, '01ffc9a7');
        let supportsEIP721Identifier = supportsInterface(contract, '80ac58cd');
        let supportsNullIdentifierFalse = supportsInterface(contract, '00000000', false);
        let supportsEIP721 = supportsEIP165Identifier && supportsEIP721Identifier && supportsNullIdentifierFalse;


Licencia[1:2]



6. Cómo añadir tu propio subgraph a la red Palm

  1. Despliega tus contratos inteligentes y obtén sus direcciones para el manifiesto del subgraph
  2. Crea un archivo de configuración para la red de prueba y la red principal de Palm con la información necesaria network: palm-mainnet o palm-testnet
  3. Solicita al equipo de la Red Palm que configure y despliegue el subgraph rellenando el formulario de registro de subgraph
  4. Otorga acceso al equipo de la red Palm al repositorio de código del subgraph correspondiente.
  5. El equipo de la red Palm revisará el subgraph y lo desplegará en entornos de red de pruebas.
  6. A continuación, podrás validar que el subgraph de prueba funciona correctamente
  7. El equipo de la red Palm desplegará el subgraph en la red principal
  8. Ahora vas a validar que el subgraph en la red principal Palm funciona correctamente
  9. El equipo de la red Palm documentará el punto final de tu subgraph en la página docs.palm.io


Copyright (C) <2019-2020> Ronan Sandford - GNU - https://github.com/wighawag/eip721-subgraph ↩︎ ↩︎ ↩



👉 Tutorial para Acuñar NFTs

🔥 Ejemplos de Consultas



Actualizado 03 Mar 2023
¿Esta página le fue útil?
Sí
No
ANTERIOR
Palm Safe
SIGUIENTE
Tutorial para Acuñar NFTs
Docs powered by archbee 
CONTENIDO
Resumen
1. ¿Cómo funciona The Graph?
¿Qué son los Subgraphs?
2. Consulta de los Subgraphs en la red Palm
Recursos GraphQL para principiantes
Resources to Experiment with Subgraphs and GraphQL
3. Subgraphs disponibles en la red Palm
4. Utiliza de The Graph desde una DApp
💡 Conoce Más
Ejemplo de código para una DApp en React
5. Crea un nuevo Subgraph
Archivos de ejemplo
Diseñado para Contratos Compatibles con EIP-721
Archivo de asignaciones
6. Cómo añadir tu propio subgraph a la red Palm
👉 Tutorial para Acuñar NFTs
🔥 Ejemplos de Consultas