{"id":19319680,"url":"https://github.com/blockcoders/ink-substrate-explorer-api","last_synced_at":"2025-04-22T17:31:58.224Z","repository":{"id":63357332,"uuid":"520518007","full_name":"blockcoders/ink-substrate-explorer-api","owner":"blockcoders","description":"Ink Explorer is an application that provides Ink contracts related information on Substrate based blockchains.","archived":false,"fork":false,"pushed_at":"2022-12-10T09:54:17.000Z","size":801,"stargazers_count":7,"open_issues_count":0,"forks_count":2,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-04-02T02:22:28.418Z","etag":null,"topics":["blockchain","dot","erc1155","erc20","erc721","graphql","ink","ink-contract","ink-event","kusama","nft","polkadot","polkadot-js","smart-contracts","substrate","token","trait","trait-erc1155","trait-erc20","trait-erc721"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/blockcoders.png","metadata":{"files":{"readme":"README-es.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":"CODEOWNERS","security":null,"support":null}},"created_at":"2022-08-02T13:51:45.000Z","updated_at":"2023-08-17T23:24:41.000Z","dependencies_parsed_at":"2023-01-26T03:01:29.420Z","dependency_job_id":null,"html_url":"https://github.com/blockcoders/ink-substrate-explorer-api","commit_stats":null,"previous_names":[],"tags_count":8,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/blockcoders%2Fink-substrate-explorer-api","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/blockcoders%2Fink-substrate-explorer-api/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/blockcoders%2Fink-substrate-explorer-api/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/blockcoders%2Fink-substrate-explorer-api/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/blockcoders","download_url":"https://codeload.github.com/blockcoders/ink-substrate-explorer-api/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250287651,"owners_count":21405656,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["blockchain","dot","erc1155","erc20","erc721","graphql","ink","ink-contract","ink-event","kusama","nft","polkadot","polkadot-js","smart-contracts","substrate","token","trait","trait-erc1155","trait-erc20","trait-erc721"],"created_at":"2024-11-10T01:24:48.509Z","updated_at":"2025-04-22T17:31:57.628Z","avatar_url":"https://github.com/blockcoders.png","language":"TypeScript","readme":"Ink! Explorer API\n=================\n\n[![App Build](https://img.shields.io/github/workflow/status/blockcoders/ink-substrate-explorer-api/Pulll%20Request%20App%20Build/main?logo=github)](https://github.com/blockcoders/ink-substrate-explorer-api/actions/workflows/pr.yaml)\n[![Coverage Status](https://coveralls.io/repos/github/blockcoders/ink-substrate-explorer-api/badge.svg?branch=main)](https://coveralls.io/github/blockcoders/ink-substrate-explorer-api?branch=main)\n[![Codacy Badge](https://app.codacy.com/project/badge/Grade/fe5ba084394c4730b35948e2a39ad1c7)](https://www.codacy.com/gh/blockcoders/ink-substrate-explorer-api/dashboard?utm_source=github.com\u0026amp;utm_medium=referral\u0026amp;utm_content=blockcoders/ink-substrate-explorer-api\u0026amp;utm_campaign=Badge_Grade)\n[![BCH compliance](https://bettercodehub.com/edge/badge/blockcoders/ink-substrate-explorer-api?branch=main)](https://bettercodehub.com/)\n[![Docker Image Version](https://img.shields.io/docker/v/blockcoders/ink-substrate-explorer-api?logo=docker\u0026logoColor=white)](https://hub.docker.com/repository/docker/blockcoders/ink-substrate-explorer-api/general)\n[![Docker Image Size](https://img.shields.io/docker/image-size/blockcoders/ink-substrate-explorer-api?logo=docker\u0026logoColor=white)](https://hub.docker.com/repository/docker/blockcoders/ink-substrate-explorer-api/general)\n[![License](https://img.shields.io/badge/license-MIT%20License-brightgreen.svg)](https://opensource.org/licenses/MIT)\n\n## Demo\n\n[ink-explorer-api.blockcoders.io](https://ink-explorer-api.blockcoders.io/graphql)\n\n## **Acerca del explorador**\n\nInk Explorer es una aplicacion que provee informacion relativa a los contratos que utilizan Ink! en blockchains basadas en Substrate. Se suscribe a la blockchain y a los eventos emitidos por los modulos de Ink! y guarda la informacion en su propia base de datos. El back-end expone una API que puede interactuar con la base de datos y ejecutar consultas rapidas para obtener informacion especifica en poco tiempo.\n\nLa idea de este proyecto es brindar una herramienta que permita a los desarrolladores de Ink! explorar y analizar los contratos que se encuentran en blockchain. Esta herramienta se puede utilizar para analizar los contratos que se encuentran en blockchains basadas en Substrate que utilizan módulos Ink!. También se puede usar para analizar contratos que están en una blockchain local.\n\nEste proyecto ofrece información útil que no está disponible en ningún otro lugar. Ya que el back end se encarga de obtener información relacionada con los saldos, transacciones y más, de los contratos que utilizan módulos Ink!. El explorador utiliza polkadot.js para comunicarse con las redes Substrate/Polkadot. Es seguro decir que este proyecto es imprescindible.\n\n## **Introduccion**\n\n## Levantando el servicio localmente\n\n### Configuracion del entorno\n\n- Instalar [Node.js](https://nodejs.org/)\n  - El metodo recomentado es utilizando [NVM](https://github.com/creationix/nvm)\n  - La verision de Node.js recomendada es v16.13\n- Instalar [Docker](https://docs.docker.com/get-docker/)\n\n### Instalar todas las dependencias\n\n```sh\npnpm i --frozen-lockfile\n```\n\n### Configurar las variables de entorno\n\n**Nota**: El archivo .env tiene la configuracion para GraphQL, la base de datos Mongo, Node y la url del RPC de la blockchain basada en Substrate.\n\n```sh\ncp .env.sample .env\n```\n\n#### Configuraciones del servicio\n\n```sh\nNODE_ENV=development\nPORT=8080\nLOG_NAME=ink-substrate-explorer-api\nLOG_LEVEL=debug\n```\n\n#### Configuraciones de GraphQL\n\n```sh\nGRAPHQL_DEBUG=true\nGRAPHQL_PLAYGROUND=true\nGRAPHQL_SORT_SCHEMA=true\nGRAPHQL_INTROSPECTION=true\n```\n\n#### Configuraciones de la base de datos\n\n```sh\nDATABASE_HOST=mongo\nDATABASE_NAME=ink\nDATABASE_USERNAME=mongodb\nDATABASE_PASSWORD=mongodb\nDATABASE_RETRY_ATTEMPTS=5\nDATABASE_RETRY_DELAY=3000\n```\n\n#### Configuraciones de la blockchain y la sincronizacion de datos\n\n```sh\nWS_PROVIDER=wss://rococo-contracts-rpc.polkadot.io\n# Asignar el valor _true_ para procesar cada bloque desde FIRST_BLOCK_TO_LOAD hasta el ultimo bloque de la cadena. Asignar el valor _false_ para solo comenzar a procesar los bloques desde el ultimo bloque existente en la base de datos.\nLOAD_ALL_BLOCKS=false\n# Número de bloque a partir del cual el servicio comenzará a procesar bloques. (Puede ser génesis o algún otro bloque. Por ejemplo, el primer bloque admite contratos)\nFIRST_BLOCK_TO_LOAD=0\n# Número de bloques a procesar simultáneamente. Esto puede acelerar o retrasar el proceso de sincronización.\nBLOCK_CONCURRENCY=1000\n```\n\n## **Levantando el servicio (DEV)**\n\n### Instanciar una BD Mongo utilizando docker (opcional)\n\nPara levantar el servicio es necesario contar con una **BD Mongo**. Para esto, el archivo **dev-docker-compose.yaml** ya tiene una imagen configurada lista para usar.\nEjecutando el siguiente comando tambien instanciara un contenedor para Mongo Express:\n\n```sh\ndocker-compose -f dev-docker-compose.yaml up -d\n```\n\nUna vez que el servicio se está ejecutando, se puede acceder a Mongo Express siguiendo el enlace que se muestra en la terminal (en este caso localhost:8081).\n\n### Instanciar un nodo local de Substrate (opcional)\n\nEl servicio necesita conectarse a una blockchain basada en Substrate. Para esto, el archivo **dev-docker-compose.yaml** ya tiene una imagen configurada lista para usar.\nEjecute este comando:\n\n```sh\ndocker-compose -f dev-docker-compose.yaml up -d\n```\n\nOtra forma de ejecutar un nodo local es con [esta guía de paritytech](https://github.com/paritytech/substrate-contracts-node).\n\n**Nota**: Cambie la variable WS_PROVIDER en el archivo **.env** para que sea `ws://127.0.0.1:9944`\n\n### Levantando el servicio\n\n```sh\npnpm start:dev\n```\n\nEjecuta el servicio en el modo de desarrollo.\nEl servicio se recargará si realiza ediciones.\n\n**Nota**: Se requiere una base de datos Mongo en funcionamiento y una conexión válida a un nodo de Substrate.\n\n## **Levantando el servicio (PROD)**\n\nPara iniciar los contenedores del servicio de backend, la BD y Mongo Express ejecutar el siguiente comando:\n\n```sh\ndocker-compose up -d\n```\n\n**Nota**: Se requiere una base de datos Mongo en funcionamiento y una conexión válida a un nodo de Substrate.\nOpcionalmente, comente el servicio de back-end en el archivo docker-compose si desea ejecutar la imagen localmente.\n\n## Ejecutar la imagen de Docker del servicio back-end\n\n### Descarga la imagen de DockerHub\n\n```sh\ndocker pull blockcoders/ink-substrate-explorer-api:latest\n```\n\n### Run\n\n```sh\n# Crear la red de docker\ndocker network create ink-explorer-network\n\n# Correr servicio\ndocker run -it -p 5000:5000 --network ink-explorer-network --env-file {pathToEnvFile} blockcoders/ink-substrate-explorer-api:latest\n```\n\n#### Verifique que la imagen comenzó a ejecutarse\n\n```sh\ndocker ps\n```\n\nEl resultado debería verse así:\n\n```sh\nCONTAINER ID   IMAGE                                    COMMAND                  CREATED          STATUS          PORTS                                       NAMES\nf31a7d0fd6c8   blockcoders/ink-substrate-explorer-api   \"docker-entrypoint.s…\"   15 seconds ago   Up 14 seconds   0.0.0.0:5000-\u003e5000/tcp, :::5000-\u003e5000/tcp   funny_lumiere\n```\n\nEl servicio se conectará al contenedor DB y comenzará a procesar bloques.\n\n## **Testing**\n\nEjecución de las pruebas unitarias.\n\n```sh\npnpm test\n```\n\nEjecución de la cobertura de pruebas.\n\n```sh\npnpm test:cov\n```\n\nProbando las consultas de GraphQL.\n\n```sh\n{\"level\":30,\"time\":1664298430389,\"pid\":1388770,\"hostname\":\"username\",\"name\":\"ink-substrate-explorer-api\",\"msg\":\"App listening on http://0.0.0.0:5000\"}\n```\n\nUna vez que el servicio back-end se está ejecutando, se puede acceder a GraphQL Playground en http://localhost:5000/graphql\n\n![backend](/.images/graphql_example.png)\n\n## **Definicion de la API**\n\nUna vez que el servicio esta levantado y corriendo correctamente se provee una API que puede utilizarse enviado consultas de GraphQL.\n\n### **Consultas**\n\n\u003cspan style=\"color:#2a98db\"\u003e **Status**: Recupera el estado de la aplicación\u003c/span\u003e\n\n```graphql\nquery {\n  status\n}\n```\n\n\u003cspan style=\"color:#5EBA7D\"\u003e Respuesta: \u003c/span\u003e\n\n```graphql\n{\n  \"data\": {\n    \"status\": \"running\"\n  }\n}\n```\n\n\u003cspan style=\"color:#2a98db\"\u003e **Version**: Recupera la version de la aplicación\u003c/span\u003e\n\n```graphql\nquery {\n  status\n}\n```\n\n\u003cspan style=\"color:#5EBA7D\"\u003e Respuesta: \u003c/span\u003e\n\n```graphql\n{\n  \"data\": {\n    \"version\": \"v1.1.1\"\n  }\n}\n```\n\n\u003cspan style=\"color:#2a98db\"\u003e **getBlock**: Recupera el bloque por hash \u003c/span\u003e\n\n```graphql\nquery {\n  getBlock(hash: \"0x0f615cf7edf8a1e8591893a594fe0ef67d5d56c4d9b1a89d8d120c5f821127fe\") {\n    hash\n    number\n    parentHash\n    timestamp\n    encodedLength\n    transactions {\n      hash\n    }\n  }\n}\n```\n\n\u003cspan style=\"color:#5EBA7D\"\u003e Respuesta: \u003c/span\u003e\n\n```graphql\n{\n  \"data\": {\n    \"getBlock\": {\n      \"hash\": \"0x0f615cf7edf8a1e8591893a594fe0ef67d5d56c4d9b1a89d8d120c5f821127fe\",\n      \"number\": 7,\n      \"parentHash\": \"0xd8ecc752f280a3786c5cdd4d441d71488414fd6132ace481dd6ddb23fd8000b0\",\n      \"timestamp\": 1666888006111,\n      \"encodedLength\": 312,\n      \"transactions\": [\n        {\n          \"hash\": \"0xdb561ee4432e07a959292acf9895ce379e2474a52160b93fd62496806fdf26cd\"\n        },\n        {\n          \"hash\": \"0x33831da6b804e82cd7613e0d780823c7455c773546ea5e76c945ed10a6f6554b\"\n        }\n      ]\n    }\n  }\n}\n```\n\n\u003cspan style=\"color:#2a98db\"\u003e **getBlocks**: Recupera bloques. Use 'skip' y 'take' para paginar. Use 'orderByNumber: false' para ordenar por tiempo y 'orderAsc: true' para ver primero los bloques más antiguos.\u003c/span\u003e\n\n```graphql\nquery {\n  getBlocks(skip: 0, take: 1, orderByNumber: false, orderAsc: false) {\n    hash\n    number\n    parentHash\n    timestamp\n    encodedLength\n    transactions {\n      hash\n    }\n  }\n}\n```\n\n\u003cspan style=\"color:#5EBA7D\"\u003e Respuesta: \u003c/span\u003e\n\n```graphql\n{\n  \"data\": {\n    \"getBlocks\": [\n      {\n        \"hash\": \"0x0f615cf7edf8a1e8591893a594fe0ef67d5d56c4d9b1a89d8d120c5f821127fe\",\n        \"number\": 7,\n        \"parentHash\": \"0xd8ecc752f280a3786c5cdd4d441d71488414fd6132ace481dd6ddb23fd8000b0\",\n        \"timestamp\": 1666888006111,\n        \"encodedLength\": 312,\n        \"transactions\": [\n          {\n            \"hash\": \"0xdb561ee4432e07a959292acf9895ce379e2474a52160b93fd62496806fdf26cd\"\n          },\n          {\n            \"hash\": \"0x33831da6b804e82cd7613e0d780823c7455c773546ea5e76c945ed10a6f6554b\"\n          }\n        ]\n      }\n    ]\n  }\n}\n```\n\n\u003cspan style=\"color:#2a98db\"\u003e **getTransaction**: Recupera una sola transacción por hash\u003c/span\u003e\n\n```graphql\nquery {\n  getTransaction(hash: \"0x33831da6b804e82cd7613e0d780823c7455c773546ea5e76c945ed10a6f6554b\") {\n    args\n    blockHash\n    callIndex\n    decimals\n    encodedLength\n    era\n    events {\n      method\n    }\n    hash\n    method\n    nonce\n    section\n    signature\n    signer\n    ss58\n    timestamp\n    tip\n    tokens\n    type\n    version\n  }\n}\n```\n\n\u003cspan style=\"color:#5EBA7D\"\u003e Respuesta: \u003c/span\u003e\n\n```graphql\n{\n  \"data\": {\n    \"getTransaction\": {\n      \"args\": \"{\\\"dest\\\":{\\\"id\\\":\\\"5DfG5TyaffuJ78rHP71cvkYEtktRkpeMiJNJyxd8Q5924GR8\\\"},\\\"value\\\":0,\\\"gas_limit\\\":75000000000,\\\"storage_deposit_limit\\\":null,\\\"data\\\":\\\"0x84a15da18eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48005039278c0400000000000000000000\\\"}\",\n      \"blockHash\": \"0x0f615cf7edf8a1e8591893a594fe0ef67d5d56c4d9b1a89d8d120c5f821127fe\",\n      \"callIndex\": \"7,0\",\n      \"decimals\": \"12\",\n      \"encodedLength\": 201,\n      \"era\": \"{\\\"mortalEra\\\":\\\"0x0b00\\\"}\",\n      \"events\": [\n        {\n          \"method\": \"ContractEmitted\"\n        }\n      ],\n      \"hash\": \"0x33831da6b804e82cd7613e0d780823c7455c773546ea5e76c945ed10a6f6554b\",\n      \"method\": \"call\",\n      \"nonce\": 3,\n      \"section\": \"contracts\",\n      \"signature\": \"0x78582786706e947a6d77ac5b49ba140b4c88ebc644421136bbfa8b66577e1e3efdbc1d981948546fff41600be9a716e4c38a8531a867853f26ba11ee21128f82\",\n      \"signer\": \"5GVmSPghWsjACADGYi78dmhuZEgfgDwfixR7BM3aMEoNuTBc\",\n      \"ss58\": \"42\",\n      \"timestamp\": 1666888006111,\n      \"tip\": \"0\",\n      \"tokens\": \"Unit\",\n      \"type\": 4,\n      \"version\": 132\n    }\n  }\n}\n```\n\n\u003cspan style=\"color:#2a98db\"\u003e **getTransactionsByContract**: Recupera una lista de transacciones de un contrato.\u003c/span\u003e\n\n```graphql\nquery {\n  getTransactionsByContract(\n    address: \"5DfG5TyaffuJ78rHP71cvkYEtktRkpeMiJNJyxd8Q5924GR8\"\n    skip: 0\n    take: 1\n    orderAsc: false\n  ) {\n    args\n    blockHash\n    callIndex\n    decimals\n    encodedLength\n    era\n    events {\n      method\n    }\n    hash\n    method\n    nonce\n    section\n    signature\n    signer\n    ss58\n    timestamp\n    tip\n    tokens\n    type\n    version\n  }\n}\n```\n\n\u003cspan style=\"color:#5EBA7D\"\u003e Respuesta: \u003c/span\u003e\n\n```graphql\n{\n  \"data\": {\n    \"getTransactionsByContract\": [\n      {\n        \"args\": \"{\\\"dest\\\":{\\\"id\\\":\\\"5DfG5TyaffuJ78rHP71cvkYEtktRkpeMiJNJyxd8Q5924GR8\\\"},\\\"value\\\":0,\\\"gas_limit\\\":75000000000,\\\"storage_deposit_limit\\\":null,\\\"data\\\":\\\"0x84a15da18eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48005039278c0400000000000000000000\\\"}\",\n        \"blockHash\": \"0x0f615cf7edf8a1e8591893a594fe0ef67d5d56c4d9b1a89d8d120c5f821127fe\",\n        \"callIndex\": \"7,0\",\n        \"decimals\": \"12\",\n        \"encodedLength\": 201,\n        \"era\": \"{\\\"mortalEra\\\":\\\"0x0b00\\\"}\",\n        \"events\": [\n          {\n            \"method\": \"ContractEmitted\"\n          }\n        ],\n        \"hash\": \"0x33831da6b804e82cd7613e0d780823c7455c773546ea5e76c945ed10a6f6554b\",\n        \"method\": \"call\",\n        \"nonce\": 3,\n        \"section\": \"contracts\",\n        \"signature\": \"0x78582786706e947a6d77ac5b49ba140b4c88ebc644421136bbfa8b66577e1e3efdbc1d981948546fff41600be9a716e4c38a8531a867853f26ba11ee21128f82\",\n        \"signer\": \"5GVmSPghWsjACADGYi78dmhuZEgfgDwfixR7BM3aMEoNuTBc\",\n        \"ss58\": \"42\",\n        \"timestamp\": 1666888006111,\n        \"tip\": \"0\",\n        \"tokens\": \"Unit\",\n        \"type\": 4,\n        \"version\": 132\n      }\n    ]\n  }\n}\n```\n\n\u003cspan style=\"color:#2a98db\"\u003e **getTransactions**: Recupera transacciones por hash de bloque (use 'skip' y 'take' para paginar. use 'orderAsc' para ver primero las más antiguas o las más nuevas)\u003c/span\u003e\n\n```graphql\nquery {\n  getTransactions(skip: 0, take: 1, orderAsc: false) {\n    args\n    blockHash\n    callIndex\n    decimals\n    encodedLength\n    era\n    events {\n      method\n    }\n    hash\n    method\n    nonce\n    section\n    signature\n    signer\n    ss58\n    timestamp\n    tip\n    tokens\n    type\n    version\n  }\n}\n```\n\n\u003cspan style=\"color:#5EBA7D\"\u003e Respuesta: \u003c/span\u003e\n\n```graphql\n{\n  \"data\": {\n    \"getTransactions\": [\n      {\n        \"args\": \"{\\\"now\\\":1666888006111}\",\n        \"blockHash\": \"0x0f615cf7edf8a1e8591893a594fe0ef67d5d56c4d9b1a89d8d120c5f821127fe\",\n        \"callIndex\": \"2,0\",\n        \"decimals\": \"12\",\n        \"encodedLength\": 11,\n        \"era\": \"{\\\"immortalEra\\\":\\\"0x00\\\"}\",\n        \"events\": [],\n        \"hash\": \"0xdb561ee4432e07a959292acf9895ce379e2474a52160b93fd62496806fdf26cd\",\n        \"method\": \"set\",\n        \"nonce\": 0,\n        \"section\": \"timestamp\",\n        \"signature\": \"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\",\n        \"signer\": \"5C4hrfjw9DjXZTzV3MwzrrAr9P1MJhSrvWGWqi1eSuyUpnhM\",\n        \"ss58\": \"42\",\n        \"timestamp\": 1666888006111,\n        \"tip\": \"0\",\n        \"tokens\": \"Unit\",\n        \"type\": 4,\n        \"version\": 4\n      }\n    ]\n  }\n}\n```\n\n\u003cspan style=\"color:#2a98db\"\u003e **getEvent**: Recupera un evento por su id\u003c/span\u003e\n\n```graphql\nquery {\n  getEvent(id: \"81735cc9-76d3-5984-83af-5872bc9eaeb7\") {\n    id\n    index\n    method\n    section\n    timestamp\n    topics\n    transactionHash\n    data\n    decodedData\n    formattedData\n  }\n}\n```\n\n\u003cspan style=\"color:#5EBA7D\"\u003e Respuesta: \u003c/span\u003e\n\n```graphql\n{\n  \"data\": {\n    \"getEvent\": {\n      \"id\": \"81735cc9-76d3-5984-83af-5872bc9eaeb7\",\n      \"index\": \"0x0703\",\n      \"method\": \"ContractEmitted\",\n      \"section\": \"contracts\",\n      \"timestamp\": 1666888006111,\n      \"topics\": \"[0x0045726332303a3a5472616e7366657200000000000000000000000000000000, 0x08be862c40d599dc6f4f28076712bb324c0cd2197c30f07459887b41fadff2c8, 0x2b00c7d40fe6d84d660f3e6bed90f218e022a0909f7e1a7ea35ada8b6e003564]\",\n      \"transactionHash\": \"0x33831da6b804e82cd7613e0d780823c7455c773546ea5e76c945ed10a6f6554b\",\n      \"data\": \"[\\\"5DfG5TyaffuJ78rHP71cvkYEtktRkpeMiJNJyxd8Q5924GR8\\\",\\\"0x0001c40e2006bbebf9022c317f9337ad376e56d392917e5ac1397fe09b07c765c050018eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48005039278c0400000000000000000000\\\"]\",\n      \"decodedData\": \"{\\\"args\\\":[\\\"5GVmSPghWsjACADGYi78dmhuZEgfgDwfixR7BM3aMEoNuTBc\\\",\\\"5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty\\\",\\\"0x00000000000000000000048c27395000\\\"],\\\"event\\\":{\\\"args\\\":[{\\\"name\\\":\\\"from\\\",\\\"type\\\":{\\\"sub\\\":{\\\"docs\\\":[],\\\"info\\\":10,\\\"type\\\":\\\"AccountId\\\",\\\"namespace\\\":\\\"ink_env::types::AccountId\\\",\\\"lookupIndex\\\":2,\\\"lookupNameRoot\\\":\\\"InkEnvAccountId\\\"},\\\"docs\\\":[],\\\"info\\\":9,\\\"type\\\":\\\"Option\u003cAccountId\u003e\\\",\\\"namespace\\\":\\\"Option\\\",\\\"lookupIndex\\\":11}},{\\\"name\\\":\\\"to\\\",\\\"type\\\":{\\\"sub\\\":{\\\"docs\\\":[],\\\"info\\\":10,\\\"type\\\":\\\"AccountId\\\",\\\"namespace\\\":\\\"ink_env::types::AccountId\\\",\\\"lookupIndex\\\":2,\\\"lookupNameRoot\\\":\\\"InkEnvAccountId\\\"},\\\"docs\\\":[],\\\"info\\\":9,\\\"type\\\":\\\"Option\u003cAccountId\u003e\\\",\\\"namespace\\\":\\\"Option\\\",\\\"lookupIndex\\\":11}},{\\\"name\\\":\\\"value\\\",\\\"type\\\":{\\\"info\\\":10,\\\"type\\\":\\\"Balance\\\"}}],\\\"docs\\\":[\\\" Event emitted when a token transfer occurs.\\\"],\\\"index\\\":0,\\\"identifier\\\":\\\"Transfer\\\"}}\",\n      \"formattedData\": \"{\\\"from\\\":\\\"5GVmSPghWsjACADGYi78dmhuZEgfgDwfixR7BM3aMEoNuTBc\\\",\\\"to\\\":\\\"5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty\\\",\\\"value\\\":5}\"\n    }\n  }\n}\n```\n\n\u003cspan style=\"color:#2a98db\"\u003e **getEvents**: Recupera eventos por dirección de contrato o hash de transacción (use 'skip' y 'take' para paginar, 'orderAsc' para ver primero los más antiguos o los más nuevos)\u003c/span\u003e\n\n```graphql\nquery {\n  getEvents(contract: \"5DfG5TyaffuJ78rHP71cvkYEtktRkpeMiJNJyxd8Q5924GR8\", skip: 0, take: 1, orderAsc: false) {\n    id\n    index\n    method\n    section\n    timestamp\n    topics\n    transactionHash\n    data\n    decodedData\n    formattedData\n  }\n}\n```\n\n\u003cspan style=\"color:#5EBA7D\"\u003e Respuesta: \u003c/span\u003e\n\n```graphql\n{\n  \"data\": {\n    \"getEvents\": [\n      {\n        \"id\": \"81735cc9-76d3-5984-83af-5872bc9eaeb7\",\n        \"index\": \"0x0703\",\n        \"method\": \"ContractEmitted\",\n        \"section\": \"contracts\",\n        \"timestamp\": 1666888006111,\n        \"topics\": \"[0x0045726332303a3a5472616e7366657200000000000000000000000000000000, 0x08be862c40d599dc6f4f28076712bb324c0cd2197c30f07459887b41fadff2c8, 0x2b00c7d40fe6d84d660f3e6bed90f218e022a0909f7e1a7ea35ada8b6e003564]\",\n        \"transactionHash\": \"0x33831da6b804e82cd7613e0d780823c7455c773546ea5e76c945ed10a6f6554b\",\n        \"data\": \"[\\\"5DfG5TyaffuJ78rHP71cvkYEtktRkpeMiJNJyxd8Q5924GR8\\\",\\\"0x0001c40e2006bbebf9022c317f9337ad376e56d392917e5ac1397fe09b07c765c050018eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48005039278c0400000000000000000000\\\"]\",\n        \"decodedData\": \"{\\\"args\\\":[\\\"5GVmSPghWsjACADGYi78dmhuZEgfgDwfixR7BM3aMEoNuTBc\\\",\\\"5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty\\\",\\\"0x00000000000000000000048c27395000\\\"],\\\"event\\\":{\\\"args\\\":[{\\\"name\\\":\\\"from\\\",\\\"type\\\":{\\\"sub\\\":{\\\"docs\\\":[],\\\"info\\\":10,\\\"type\\\":\\\"AccountId\\\",\\\"namespace\\\":\\\"ink_env::types::AccountId\\\",\\\"lookupIndex\\\":2,\\\"lookupNameRoot\\\":\\\"InkEnvAccountId\\\"},\\\"docs\\\":[],\\\"info\\\":9,\\\"type\\\":\\\"Option\u003cAccountId\u003e\\\",\\\"namespace\\\":\\\"Option\\\",\\\"lookupIndex\\\":11}},{\\\"name\\\":\\\"to\\\",\\\"type\\\":{\\\"sub\\\":{\\\"docs\\\":[],\\\"info\\\":10,\\\"type\\\":\\\"AccountId\\\",\\\"namespace\\\":\\\"ink_env::types::AccountId\\\",\\\"lookupIndex\\\":2,\\\"lookupNameRoot\\\":\\\"InkEnvAccountId\\\"},\\\"docs\\\":[],\\\"info\\\":9,\\\"type\\\":\\\"Option\u003cAccountId\u003e\\\",\\\"namespace\\\":\\\"Option\\\",\\\"lookupIndex\\\":11}},{\\\"name\\\":\\\"value\\\",\\\"type\\\":{\\\"info\\\":10,\\\"type\\\":\\\"Balance\\\"}}],\\\"docs\\\":[\\\" Event emitted when a token transfer occurs.\\\"],\\\"index\\\":0,\\\"identifier\\\":\\\"Transfer\\\"}}\",\n        \"formattedData\": \"{\\\"from\\\":\\\"5GVmSPghWsjACADGYi78dmhuZEgfgDwfixR7BM3aMEoNuTBc\\\",\\\"to\\\":\\\"5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty\\\",\\\"value\\\":5}\"\n      }\n    ]\n  }\n}\n```\n\n\u003cspan style=\"color:#2a98db\"\u003e **getContract**: Recupera un contrato por address\u003c/span\u003e\n\n```graphql\nquery {\n  getContract(address: \"5G24svh2w4QXNhsHU5XBxf8N3Sw2MPu7sAemofv1bCuyxAzc\") {\n    address\n    metadata\n    hasMetadata\n  }\n}\n```\n\n\u003cspan style=\"color:#5EBA7D\"\u003e Respuesta: \u003c/span\u003e\n\n```graphql\n{\n  \"data\": {\n    \"getContract\": {\n      \"address\": \"5G24svh2w4QXNhsHU5XBxf8N3Sw2MPu7sAemofv1bCuyxAzc\",\n      \"metadata\": \"{\\n  \\\"source\\\": {\\n    \\\"hash\\\": ...   }\\n}\\n\",\n      \"hasMetadata\": true\n    }\n  }\n}\n```\n\n\u003cspan style=\"color:#2a98db\"\u003e **getContracts**: Recupera una lista de contratos\u003c/span\u003e\n\n```graphql\nquery {\n  getContracts(skip: 0, take: 10) {\n    address\n    metadata\n    hasMetadata\n    events {\n      method\n    }\n  }\n}\n```\n\n\u003cspan style=\"color:#5EBA7D\"\u003e Respuesta: \u003c/span\u003e\n\n```graphql\n{\n  \"data\": {\n    \"getContracts\": [\n      {\n        \"address\": \"5DfG5TyaffuJ78rHP71cvkYEtktRkpeMiJNJyxd8Q5924GR8\",\n        \"hasMetadata\": true,\n        \"metadata\": \"{ ... }\",\n        \"events\": [\n          {\n            \"method\": \"ContractEmitted\"\n          },\n        ]\n      }\n    ]\n  }\n}\n```\n\n\u003cspan style=\"color:#2a98db\"\u003e **getContractQueries**: Recupera un contrato. Si este contrato ha cargado metadatos, también recuperará las consultas y los métodos de transacción que se pueden ejecutar.\u003c/span\u003e\n\n```graphql\nquery {\n  getContractQueries(address: \"5DfG5TyaffuJ78rHP71cvkYEtktRkpeMiJNJyxd8Q5924GR8\") {\n    address\n    hasMetadata\n    queries {\n      args\n      docs\n      method\n      name\n    }\n  }\n}\n```\n\n\u003cspan style=\"color:#5EBA7D\"\u003e Respuesta: \u003c/span\u003e\n\n```graphql\n{\n  \"data\": {\n    \"getContractQueries\": {\n      \"address\": \"5DfG5TyaffuJ78rHP71cvkYEtktRkpeMiJNJyxd8Q5924GR8\",\n      \"hasMetadata\": true,\n      \"queries\": [\n        {\n          \"args\": [],\n          \"docs\": [\n            \" Returns the total token supply.\"\n          ],\n          \"method\": \"totalSupply\",\n          \"name\": \"Total supply\"\n        },\n        {\n          \"args\": [\n            \"{\\\"name\\\":\\\"to\\\",\\\"type\\\":{\\\"info\\\":10,\\\"type\\\":\\\"AccountId\\\"}}\",\n            \"{\\\"name\\\":\\\"value\\\",\\\"type\\\":{\\\"info\\\":10,\\\"type\\\":\\\"Balance\\\"}}\"\n          ],\n          \"docs\": [\n            \" Transfers `value` amount of tokens from the caller's account to account `to`.\",\n            \"\",\n            \" On success a `Transfer` event is emitted.\",\n            \"\",\n            \" # Errors\",\n            \"\",\n            \" Returns `InsufficientBalance` error if there are not enough tokens on\",\n            \" the caller's account balance.\"\n          ],\n          \"method\": \"transfer\",\n          \"name\": \"Transfer\"\n        }\n      ]\n    }\n  }\n}\n```\n\n### **Mutaciones**\n\n\u003cspan style=\"color:#2a98db\"\u003e **decodeEvent**: Decodifica los datos del evento para un evento específico. Requiere que los metadatos del contrato ya se hayan subido usando la mutación **uploadMetadata**\u003c/span\u003e\n\n```graphql\nmutation {\n  decodeEvent(\n    contractAddress: \"5ELpkDtq7werhT5ybZZMbVBcQTPNomvJP7j5kJQifv7GzVik\"\n    id: \"972e782c-2517-5648-9bf1-4c693d2fed90\"\n  )\n}\n```\n\n\u003cspan style=\"color:#5EBA7D\"\u003e Respuesta: \u003c/span\u003e\n\n```graphql\n{\n  \"data\": {\n    \"decodeEvent\": \"{\\\"identifier\\\":\\\"Transfer\\\",\\\"decodedData\\\":{\\\"args\\\":[\\\"5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty\\\",\\\"5FLSigC9HGRKVhB9FiEo4Y3koPsNmBmLJbpXg2mp1hXcS59Y\\\",\\\"0x000000000000000000002d79883d2000\\\"],\\\"event\\\":{\\\"args\\\":[{\\\"name\\\":\\\"from\\\",\\\"type\\\":{\\\"info\\\":9,\\\"lookupIndex\\\":11,\\\"type\\\":\\\"Option\u003cAccountId\u003e\\\",\\\"docs\\\":[],\\\"namespace\\\":\\\"Option\\\",\\\"sub\\\":{\\\"info\\\":10,\\\"lookupIndex\\\":2,\\\"type\\\":\\\"AccountId\\\",\\\"docs\\\":[],\\\"namespace\\\":\\\"ink_env::types::AccountId\\\",\\\"lookupNameRoot\\\":\\\"InkEnvAccountId\\\"}}},{\\\"name\\\":\\\"to\\\",\\\"type\\\":{\\\"info\\\":9,\\\"lookupIndex\\\":11,\\\"type\\\":\\\"Option\u003cAccountId\u003e\\\",\\\"docs\\\":[],\\\"namespace\\\":\\\"Option\\\",\\\"sub\\\":{\\\"info\\\":10,\\\"lookupIndex\\\":2,\\\"type\\\":\\\"AccountId\\\",\\\"docs\\\":[],\\\"namespace\\\":\\\"ink_env::types::AccountId\\\",\\\"lookupNameRoot\\\":\\\"InkEnvAccountId\\\"}}},{\\\"name\\\":\\\"value\\\",\\\"type\\\":{\\\"info\\\":10,\\\"type\\\":\\\"Balance\\\"}}],\\\"docs\\\":[\\\" Event emitted when a token transfer occurs.\\\"],\\\"identifier\\\":\\\"Transfer\\\",\\\"index\\\":0}},\\\"formattedData\\\":{\\\"from\\\":\\\"5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty\\\",\\\"to\\\":\\\"5FLSigC9HGRKVhB9FiEo4Y3koPsNmBmLJbpXg2mp1hXcS59Y\\\",\\\"value\\\":50}}\"\n  }\n}\n```\n\n\u003cspan style=\"color:#2a98db\"\u003e **decodeEvents**: Decodifica los datos de eventos para un contrato específico (use 'skip' y 'take' para seleccionar los eventos y 'orderAsc' para ordenar por tiempo). Requiere que los metadatos del contrato ya se hayan subido usando la mutación **uploadMetadata**\u003c/span\u003e\n\n```graphql\nmutation {\n  decodeEvents(contract: \"5DfG5TyaffuJ78rHP71cvkYEtktRkpeMiJNJyxd8Q5924GR8\", skip: 0, take: 1, orderAsc: false)\n}\n```\n\n\u003cspan style=\"color:#5EBA7D\"\u003e Respuesta: \u003c/span\u003e\n\n```graphql\n{\n  \"data\": {\n    \"decodeEvents\": \"[{\\\"decodedData\\\":{\\\"args\\\":[\\\"5GVmSPghWsjACADGYi78dmhuZEgfgDwfixR7BM3aMEoNuTBc\\\",\\\"5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty\\\",\\\"0x00000000000000000000048c27395000\\\"],\\\"event\\\":{\\\"args\\\":[{\\\"name\\\":\\\"from\\\",\\\"type\\\":{\\\"info\\\":9,\\\"lookupIndex\\\":11,\\\"type\\\":\\\"Option\u003cAccountId\u003e\\\",\\\"docs\\\":[],\\\"namespace\\\":\\\"Option\\\",\\\"sub\\\":{\\\"info\\\":10,\\\"lookupIndex\\\":2,\\\"type\\\":\\\"AccountId\\\",\\\"docs\\\":[],\\\"namespace\\\":\\\"ink_env::types::AccountId\\\",\\\"lookupNameRoot\\\":\\\"InkEnvAccountId\\\"}}},{\\\"name\\\":\\\"to\\\",\\\"type\\\":{\\\"info\\\":9,\\\"lookupIndex\\\":11,\\\"type\\\":\\\"Option\u003cAccountId\u003e\\\",\\\"docs\\\":[],\\\"namespace\\\":\\\"Option\\\",\\\"sub\\\":{\\\"info\\\":10,\\\"lookupIndex\\\":2,\\\"type\\\":\\\"AccountId\\\",\\\"docs\\\":[],\\\"namespace\\\":\\\"ink_env::types::AccountId\\\",\\\"lookupNameRoot\\\":\\\"InkEnvAccountId\\\"}}},{\\\"name\\\":\\\"value\\\",\\\"type\\\":{\\\"info\\\":10,\\\"type\\\":\\\"Balance\\\"}}],\\\"docs\\\":[\\\" Event emitted when a token transfer occurs.\\\"],\\\"identifier\\\":\\\"Transfer\\\",\\\"index\\\":0}},\\\"formattedData\\\":{\\\"from\\\":\\\"5GVmSPghWsjACADGYi78dmhuZEgfgDwfixR7BM3aMEoNuTBc\\\",\\\"to\\\":\\\"5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty\\\",\\\"value\\\":5}}]\"\n  }\n}\n```\n\n\u003cspan style=\"color:#2a98db\"\u003e **uploadMetadata**: Para decodificar eventos es necesario cargar el ABI del contrato. Pasar un ABI en base64 a esta mutación lo guardará en la base de datos. Después de eso, ejecute una consulta **decodeEvents** para ver los datos decodificados en los eventos.\u003c/span\u003e\n\n```graphql\nmutation Upload {\n  uploadMetadata(\n    contractAddress: \"5G24svh2w4QXNhsHU5XBxf8N3Sw2MPu7sAemofv1bCuyxAzc\"\n    metadata: \"ewogICJzb3VyY2UiOiB7CiAgICAiaGFzaCI6I...(base64)\"\n  )\n}\n```\n\n\u003cspan style=\"color:#5EBA7D\"\u003e Respuesta: \u003c/span\u003e\n\n```graphql\n{\n  \"data\": {\n    \"uploadMetadata\": true\n  }\n}\n```\n\n### **Acerca de la decodificación de eventos**\n\nPara ver los datos decodificados de los eventos, hay un requisito: los metadatos del contrato deben cargarse al menos una vez.\n\nEjemplo de metadatos de un contrato ERC20:\n\n```json\n{\n  \"source\": {\n    \"hash\": \"0x3aa1c8ba5f59034a42a93c00ee039a9464d6fa63d70b6889a2596f4528b28a19\",\n    \"language\": \"ink! 3.3.0\",\n    \"compiler\": \"rustc 1.64.0-nightly\"\n  },\n  \"contract\": {\n    \"name\": \"erc20\",\n    \"version\": \"0.1.0\",\n    \"authors\": [\n      \"[your_name] \u003c[your_email]\u003e\"\n    ]\n  },\n  \"V3\": {\n    \"spec\": {\n      \"constructors\": [\n        {\n          \"args\": [\n            {\n              \"label\": \"initial_supply\",\n              \"type\": {\n                \"displayName\": [\n                  \"Balance\"\n                ],\n                \"type\": 0\n              }\n            }\n          ],\n          \"docs\": [\n            \"Creates a new ERC-20 contract with the specified initial supply.\"\n          ],\n          \"label\": \"new\",\n          \"payable\": false,\n          \"selector\": \"0x9bae9d5e\"\n        }\n      ],\n      \"docs\": [],\n      \"events\": [\n        {\n          \"args\": [\n            {\n              \"docs\": [],\n              \"indexed\": true,\n              \"label\": \"from\",\n              \"type\": {\n                \"displayName\": [\n                  \"Option\"\n                ],\n                \"type\": 11\n              }\n            },\n            {\n              \"docs\": [],\n              \"indexed\": true,\n              \"label\": \"to\",\n              \"type\": {\n                \"displayName\": [\n                  \"Option\"\n                ],\n                \"type\": 11\n              }\n            },\n            {\n              \"docs\": [],\n              \"indexed\": false,\n              \"label\": \"value\",\n              \"type\": {\n                \"displayName\": [\n                  \"Balance\"\n                ],\n                \"type\": 0\n              }\n            }\n          ],\n          \"docs\": [\n            \" Event emitted when a token transfer occurs.\"\n          ],\n          \"label\": \"Transfer\"\n        },\n        {\n          \"args\": [\n            {\n              \"docs\": [],\n              \"indexed\": true,\n              \"label\": \"owner\",\n              \"type\": {\n                \"displayName\": [\n                  \"AccountId\"\n                ],\n                \"type\": 2\n              }\n            },\n            {\n              \"docs\": [],\n              \"indexed\": true,\n              \"label\": \"spender\",\n              \"type\": {\n                \"displayName\": [\n                  \"AccountId\"\n                ],\n                \"type\": 2\n              }\n            },\n            {\n              \"docs\": [],\n              \"indexed\": false,\n              \"label\": \"value\",\n              \"type\": {\n                \"displayName\": [\n                  \"Balance\"\n                ],\n                \"type\": 0\n              }\n            }\n          ],\n          \"docs\": [\n            \" Event emitted when an approval occurs that `spender` is allowed to withdraw\",\n            \" up to the amount of `value` tokens from `owner`.\"\n          ],\n          \"label\": \"Approval\"\n        }\n      ],\n      ...\n```\n\nUna vez cargado, los eventos se pueden decodificar mediante las mutaciones _decodeEvent_ o _decodeEvents_ que se encuentran en la sección **Mutaciones**.\n\n**Nota**: Los metadatos deben cargarse como un texto (string) en **base64**.\n\nPara obtener más información sobre la carga de metadatos, vaya a la sección **Mutaciones** y busque _uploadMetadata_.\n\n## **Suscripciones**\n\nLa primera vez que se inicia el nodo, es posible que deba comenzar desde el bloque 0 y cargar todos los bloques (LOAD_ALL_BLOCKS env var debe establecerse en verdadero). Si desea comenzar desde un bloque específico, puede usar FIRST_BLOCK_TO_LOAD env var para comenzar desde otro bloque.\n\nEn caso de un tiempo de inactividad del nodo, las suscripciones se reconectarán automáticamente recuperando todos los bloques nuevos desde el último bloque que se procesó.\n\n**Nota**: Cargar todos los bloques puede llevar mucho tiempo dependiendo de la cantidad de bloques que deban cargarse. Se recomienda utilizar un nodo con una conexión rápida a Internet. El nodo podrá procesar todos los bloques en unas pocas horas.\n\n### Algunos puntos de referencia\n\n#### Utilizando BLOCK_CONCURRENCY = 100\n\n- 100 bloques en ~ 6 segundos\n- 1000 bloques en ~ 30.5 segundos\n- 10000 bloques en ~ 4:24 minutos\n- 100000 bloques en ~ 39.57 minutos\n\n#### Utilizando BLOCK_CONCURRENCY = 1000\n\n- 100 bloques en ~ 0.5 segundos\n- 1000 bloques en ~ 5 segundos\n- 10000 bloques en ~ 3 minutos\n- 100000 bloques en ~ 24 minutos\n\n## Registro de cambios\n\nConsulte [Changelog](CHANGELOG.md) para más información.\n\n## Contribuye\n\n¡Las contribuciones son bienvenidas! Consulte [Contributing](CONTRIBUTING.md).\n\n## Colaboradores\n\n- [**Jose Ramirez**](https://github.com/0xslipk)\n- [**Fernando Sirni**](https://github.com/fersirni)\n- [**Ruben Gutierrez**](https://github.com/RubenGutierrezC)\n\n## Licencia\n\nCon licencia de Apache 2.0 - consulte el archivo [LICENSE](LICENSE) para obtener más información.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fblockcoders%2Fink-substrate-explorer-api","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fblockcoders%2Fink-substrate-explorer-api","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fblockcoders%2Fink-substrate-explorer-api/lists"}