<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title></title>
    <description>A consolidated place for all my writing and links to supporting material and resources.</description>
    <link>https://garethtdavies.com/</link>
    <atom:link href="https://garethtdavies.com/feed.xml" rel="self" type="application/rss+xml"/>
    <pubDate>Tue, 10 Jan 2023 22:38:08 +0000</pubDate>
    <lastBuildDate>Tue, 10 Jan 2023 22:38:08 +0000</lastBuildDate>
    <generator>Jekyll v3.2.1</generator>
    
      <item>
        <title>MINA zkApp staking pool</title>
        <description>&lt;blockquote&gt;
  &lt;p&gt;This article is published on &lt;a href=&quot;https://hackmd.io/@garethtdavies/BJH3xMpFs&quot;&gt;HackMD&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Currently, when delegating to a block producer (aka validator) on MINA, the distribution of rewards is conducted off-chain, so block producers are responsible for calculating and distributing payouts according to their terms and conditions. Typical terms and conditions would include the fee percentage, the payout frequency, and perhaps the &lt;a href=&quot;https://github.com/jrwashburn/mina-pool-payout&quot;&gt;payout algorithm used&lt;/a&gt;. While the delegator’s funds are not at risk (you merely delegate the right to produce a block), a pool operator can steal any rewards in the worst-case scenario. The only recourse for a delegator would be to switch, which due to the latency involved in delegation transactions, would result in at least two epochs of rewards lost.&lt;/p&gt;
</description>
        <pubDate>Tue, 10 Jan 2023 00:00:00 +0000</pubDate>
        <link>https://garethtdavies.com/crypto/mina-zkapp-staking-pool.html</link>
        <guid isPermaLink="true">https://garethtdavies.com/crypto/mina-zkapp-staking-pool.html</guid>
        
        <category>mina</category>
        
        
        <category>crypto</category>
        
      </item>
    
      <item>
        <title>An Introduction to MinaExplorer's BigQuery Public Dataset</title>
        <description>&lt;blockquote&gt;
  &lt;p&gt;This article is published on &lt;a href=&quot;https://garethtdavies.medium.com/an-introduction-to-minaexplorers-bigquery-public-dataset-2c21a4b62aa5&quot;&gt;Medium&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href=&quot;https://minaprotocol.com/&quot;&gt;Mina&lt;/a&gt; is a succinct blockchain, which means while we can verify the chain’s current state using a zero-knowledge proof, the prior history is not retained. So, if we want to analyze the chain’s history (for example, to see individual transactions), we need to obtain it from an &lt;a href=&quot;https://docs.minaprotocol.com/en/advanced/archive-node&quot;&gt;archive node&lt;/a&gt;. The official implementation of an archive node stores its data to a &lt;a href=&quot;https://www.postgresql.org/&quot;&gt;Postgres&lt;/a&gt; database, which typically requires the use of &lt;a href=&quot;https://www.postgresqltutorial.com/postgresql-recursive-query/&quot;&gt;recursive queries&lt;/a&gt; to determine the canonical chain information.&lt;/p&gt;
</description>
        <pubDate>Fri, 15 Oct 2021 00:00:00 +0000</pubDate>
        <link>https://garethtdavies.com/crypto/an-introduction-to-minaexplorers-bigquery-public-dataset.html</link>
        <guid isPermaLink="true">https://garethtdavies.com/crypto/an-introduction-to-minaexplorers-bigquery-public-dataset.html</guid>
        
        <category>mina</category>
        
        
        <category>crypto</category>
        
      </item>
    
      <item>
        <title>Evaluating a Mina staking pool’s performance</title>
        <description>&lt;blockquote&gt;
  &lt;p&gt;This article is published on &lt;a href=&quot;https://garethtdavies.medium.com/evaluating-a-mina-delegators-performance-149c7110469b&quot;&gt;Medium&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Mina uses a proof of stake consensus mechanism with a block producer selection similar to &lt;a href=&quot;https://www.cardano.org/ouroboros/&quot;&gt;Ouroboros&lt;/a&gt;, known as &lt;a href=&quot;https://www.youtube.com/watch?v=EUR3TKcsx2M&quot;&gt;Ouroboros Samisika&lt;/a&gt;. The opportunity to produce a block for a slot is determined by a &lt;a href=&quot;https://en.wikipedia.org/wiki/Verifiable_random_function&quot;&gt;verifiable random function&lt;/a&gt; (VRF). This selection can be thought of like a lottery with each block producer independently running this function for each slot. If they get a VRF output greater than a threshold proportional to the producer’s stake, they get the chance to produce a block at the designated slot.&lt;/p&gt;
</description>
        <pubDate>Wed, 21 Jul 2021 00:00:00 +0000</pubDate>
        <link>https://garethtdavies.com/crypto/evaluating-a-mina-staking-pools-performance.html</link>
        <guid isPermaLink="true">https://garethtdavies.com/crypto/evaluating-a-mina-staking-pools-performance.html</guid>
        
        <category>mina</category>
        
        
        <category>crypto</category>
        
      </item>
    
      <item>
        <title>Running a Mina Archive Node</title>
        <description>&lt;blockquote&gt;
  &lt;p&gt;This article is published on &lt;a href=&quot;https://garethtdavies.medium.com/running-a-mina-archive-node-f6299219aab1&quot;&gt;Medium&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href=&quot;https://minaprotocol.com/&quot;&gt;Mina&lt;/a&gt; is a succinct blockchain, and as a result, consensus nodes only store the recent history of the chain before discarding it (the last &lt;code class=&quot;highlighter-rouge&quot;&gt;k&lt;/code&gt; blocks, currently 290). While prior transaction history is not required to prove the current state is valid (this is handled via a recursive zero-knowledge proof), many applications would like access to this prior transaction history. Examples include &lt;a href=&quot;https://hubble.figment.io/mina/chains/mainnet&quot;&gt;block explorers&lt;/a&gt; and &lt;a href=&quot;https://clor.io/&quot;&gt;wallets&lt;/a&gt;. To solve this problem, users may optionally run an archive node that stores a summary of each block seen in a &lt;a href=&quot;https://www.postgresql.org/&quot;&gt;Postgres&lt;/a&gt; database.&lt;/p&gt;
</description>
        <pubDate>Tue, 27 Apr 2021 00:00:00 +0000</pubDate>
        <link>https://garethtdavies.com/crypto/running-a-mina-archive-node.html</link>
        <guid isPermaLink="true">https://garethtdavies.com/crypto/running-a-mina-archive-node.html</guid>
        
        <category>mina</category>
        
        
        <category>crypto</category>
        
      </item>
    
      <item>
        <title>Introduction to the Coda Javascript SDK</title>
        <description>&lt;blockquote&gt;
  &lt;p&gt;This article is published on &lt;a href=&quot;https://medium.com/@_garethtdavies/introduction-to-the-coda-javascript-sdk-2eb8a57cead4?source=friends_link&amp;amp;sk=90cbe25acb01ff2f64544a79b14bf87a&quot;&gt;Medium&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This post provides an introduction to the current implementation of the &lt;a href=&quot;https://www.npmjs.com/package/@o1labs/client-sdk&quot;&gt;Coda Javascript SDK&lt;/a&gt;. Using the SDK, it is possible with Javascript to generate keys, sign and verify messages, and sign transactions that can be broadcast to the network. From the package’s Readme:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;This is a NodeJS client SDK that allows you to sign transactions and strings using Coda’s keypairs. The project contains Typescript and ReasonML typings but can be used from plain NodeJS as well.&lt;/p&gt;
&lt;/blockquote&gt;
</description>
        <pubDate>Thu, 23 Jul 2020 00:00:00 +0000</pubDate>
        <link>https://garethtdavies.com/crypto/introduction-to-the-coda-javascript-sdk.html</link>
        <guid isPermaLink="true">https://garethtdavies.com/crypto/introduction-to-the-coda-javascript-sdk.html</guid>
        
        <category>coda</category>
        
        
        <category>crypto</category>
        
      </item>
    
      <item>
        <title>Consensus on the Coda Blockchain</title>
        <description>&lt;blockquote&gt;
  &lt;p&gt;This article is published on &lt;a href=&quot;https://medium.com/@_garethtdavies/consensus-on-the-coda-blockchain-7ba9b6749deb?source=friends_link&amp;amp;sk=713750254a2fbc2481b61e4efbeb4611&quot;&gt;Medium&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href=&quot;https://codaprotocol.com/&quot;&gt;Coda&lt;/a&gt; is a succinct blockchain where full nodes only require downloading and verification of a tiny proof to ensure that the state of the blockchain is valid. It achieves this through incrementally computed SNARKs where the latest block contains a proof that validates the new block in addition to the previous SNARK.&lt;/p&gt;

&lt;p&gt;Coda utilizes a proof of stake (POS) consensus mechanism as opposed to the proof of work (POW) consensus mechanism popularized by Bitcoin. POS consensus algorithms have unique challenges, most notably the nothing at stake issue. Whereas in POW, miners are forced to complete work that expends energy and has a cost, in a POS system it is essentially free to participate, and an adversary can try different things to see what is favorable at no cost.&lt;/p&gt;
</description>
        <pubDate>Tue, 14 Jul 2020 00:00:00 +0000</pubDate>
        <link>https://garethtdavies.com/crypto/consensus-on-the-coda-blockchain.html</link>
        <guid isPermaLink="true">https://garethtdavies.com/crypto/consensus-on-the-coda-blockchain.html</guid>
        
        <category>coda</category>
        
        
        <category>crypto</category>
        
      </item>
    
      <item>
        <title>Running Coda with Docker</title>
        <description>&lt;p&gt;Docker provides one of the simplest ways of getting a &lt;a href=&quot;https://codaprotocol.com/&quot;&gt;Coda&lt;/a&gt; node up and running while providing the benefits of container isolation. It also resolves issues around dependencies on unsupported systems and allows specifying restart policies should the daemon crash.&lt;/p&gt;

&lt;p&gt;It is important to use the correct image for each testnet release. The tags for all releases are available on &lt;a href=&quot;https://hub.docker.com/r/codaprotocol/coda-daemon/tags&quot;&gt;DockerHub&lt;/a&gt;. For testnet 3.2b this tag is &lt;code class=&quot;highlighter-rouge&quot;&gt;0.0.12-beta-feature-bump-genesis-timestamp-3e9b174&lt;/code&gt;. This image is updated for each testnet, so the image used in the below commands should be updated accordingly.&lt;/p&gt;

&lt;p&gt;At its simplest, we can start a Coda node with the following command. We’ll build upon this basic command for other Coda specific functions such as block production and SNARK workers.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;$ &lt;/span&gt;docker run -d --name coda &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
-p 8302:8302 &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
-p 8303:8303 &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
--restart always &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
codaprotocol/coda-daemon:0.0.12-beta-feature-bump-genesis-timestamp-3e9b174 daemon &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
-peer &amp;lt;PEER_1&amp;gt; &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
-peer &amp;lt;PEER_2&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;!--more--&gt;

&lt;p&gt;In the above command, you should replace &lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;lt;PEER_1&amp;gt;&lt;/code&gt; and &lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;lt;PEER_2&amp;gt;&lt;/code&gt; with the correct peer addresses that are &lt;a href=&quot;https://discordapp.com/channels/484437221055922177/601171209287368715/724725848178950205&quot;&gt;made available&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The command will create a container named &lt;code class=&quot;highlighter-rouge&quot;&gt;coda&lt;/code&gt; and output a container id, with the container running in the background (due to the &lt;code class=&quot;highlighter-rouge&quot;&gt;-d&lt;/code&gt; or &lt;code class=&quot;highlighter-rouge&quot;&gt;--detached&lt;/code&gt; option). The &lt;code class=&quot;highlighter-rouge&quot;&gt;--restart always&lt;/code&gt; option means that if the container exits, it will automatically restart. There are two published ports (8302, 8303) to allow communication on the peer-to-peer network. To view the running container’s status, run &lt;code class=&quot;highlighter-rouge&quot;&gt;docker ps&lt;/code&gt; that should display output similar to the below. Checking the status column, it will indicate any potential issues, such as the container crash-looping.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;CONTAINER ID        IMAGE                                                                         COMMAND                  CREATED             STATUS              PORTS                              NAMES
ae9f09595a4f        codaprotocol/coda-daemon:0.0.12-beta-feature-bump-genesis-timestamp-3e9b174   &lt;span class=&quot;s2&quot;&gt;&quot;/usr/bin/dumb-init …&quot;&lt;/span&gt;   25 hours ago        Up 25 hours         0.0.0.0:8302-8303-&amp;gt;8302-8303/tcp   coda
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;To view the logs of the container, you can tail the log output using the command:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;$ &lt;/span&gt;docker logs --follow coda
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;To interact with the Coda daemon, you can &lt;code class=&quot;highlighter-rouge&quot;&gt;exec&lt;/code&gt; into the container to run the available &lt;a href=&quot;https://codaprotocol.com/docs/cli-reference#cli-reference&quot;&gt;commands&lt;/a&gt;. For example, running &lt;code class=&quot;highlighter-rouge&quot;&gt;docker exec -it coda bash&lt;/code&gt; will open a terminal inside the container from where you can run any available &lt;code class=&quot;highlighter-rouge&quot;&gt;coda&lt;/code&gt; commands, such as &lt;code class=&quot;highlighter-rouge&quot;&gt;coda client status&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Alternatively, you can run from the command line non-interactively, e.g. &lt;code class=&quot;highlighter-rouge&quot;&gt;docker exec coda coda client status&lt;/code&gt;. The format of this command is &lt;code class=&quot;highlighter-rouge&quot;&gt;docker exec container_name &amp;lt;COMMAND TO RUN&amp;gt;&lt;/code&gt;.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Coda daemon status
-----------------------------------

Global number of accounts:       10089
Block height:                    4969
Max observed block length:       4969
Local uptime:                    6d1h18m32s
...
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;h2 id=&quot;running-a-block-producer&quot;&gt;Running a block producer&lt;/h2&gt;

&lt;p&gt;As a next step, let’s run a block producer. We’ll remove the current instance via &lt;code class=&quot;highlighter-rouge&quot;&gt;docker rm -f coda&lt;/code&gt; to remove the running container and avoid container name and published port conflicts. To run a block producer, you will need the private key and corresponding password for the key that you wish to stake with.&lt;/p&gt;

&lt;p&gt;While this private key may be located anywhere on your host system in the following example, the private key (generated via the &lt;a href=&quot;https://forums.codaprotocol.com/t/testnet-beta-phase-3-staking-signups/225&quot;&gt;Coda keygen tool&lt;/a&gt;) is in a subdirectory &lt;code class=&quot;highlighter-rouge&quot;&gt;keys&lt;/code&gt; and named &lt;code class=&quot;highlighter-rouge&quot;&gt;my-wallet&lt;/code&gt;. This key will be &lt;a href=&quot;https://docs.docker.com/storage/bind-mounts/&quot;&gt;bind mounted&lt;/a&gt; into the container at &lt;code class=&quot;highlighter-rouge&quot;&gt;/root/keys&lt;/code&gt;. We also pass an environment variable of &lt;code class=&quot;highlighter-rouge&quot;&gt;CODA_PRIVKEY_PASS&lt;/code&gt; to set the password for the key non-interactively.&lt;/p&gt;

&lt;p&gt;Ensure you are running the following command from the directory that contains the &lt;code class=&quot;highlighter-rouge&quot;&gt;keys&lt;/code&gt; subdirectory or adjust the bind mount accordingly below, which needs to be an absolute path.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;$ &lt;/span&gt;docker run -d --name coda &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
-e &lt;span class=&quot;s2&quot;&gt;&quot;CODA_PRIVKEY_PASS=&amp;lt;PASSWORD&amp;gt;&quot;&lt;/span&gt; &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
--mount &lt;span class=&quot;nb&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;bind&lt;/span&gt;,source&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;$(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;pwd&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;/keys,target&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;/root/keys &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
-p 8302:8302 &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
-p 8303:8303 &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
--restart always &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
codaprotocol/coda-daemon:0.0.12-beta-feature-bump-genesis-timestamp-3e9b174 daemon &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
-block-producer-key /root/keys/my-wallet &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
-peer &amp;lt;PEER_1&amp;gt; &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
-peer &amp;lt;PEER_2&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Once again, you will be returned a container id, and you can follow the logs to identify any potential issues. The following command should indicate a block producer is running with your public key:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ docker exec coda coda client status | grep &quot;Block producers&quot;
Block producers running:         1 (4vsRCVGPNFDmHvuCctawApbyUg8J6iWzdHvJ2bNP8AL1GtMeaLwC6P8ZNTavKmAD4mMGbDq8H6DYramtiQP5fcf5xhdqAfYibt7Am9syUUU91oSf7HhLKrA26RPutsoyQSmZiMjPZoe1vDXW)
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;h2 id=&quot;running-a-snark-worker&quot;&gt;Running a SNARK worker&lt;/h2&gt;

&lt;p&gt;Another advantage of running the Coda daemon in Docker is limiting the available resources to the container. These resource constraints are of particular use to SNARK workers that will, by default, use all available resources. By default, a container has no resource constraints. However, you can set limits to, for example, the &lt;a href=&quot;https://docs.docker.com/config/containers/resource_constraints/&quot;&gt;memory available and the number of cpus to use&lt;/a&gt; via the &lt;code class=&quot;highlighter-rouge&quot;&gt;--memory&lt;/code&gt; and &lt;code class=&quot;highlighter-rouge&quot;&gt;--cpus&lt;/code&gt; options.&lt;/p&gt;

&lt;p&gt;It is not generally recommended to run a SNARK worker and a block producer on the same machine as it can affect block production. While &lt;a href=&quot;https://github.com/c29r3/coda-snark-stopper&quot;&gt;workarounds exist&lt;/a&gt; to disable the SNARK worker at the time of block production, you could alternatively run multiple containers on a machine (adjusting published ports as necessary) with applicable resource constraints.&lt;/p&gt;

&lt;p&gt;The following example limits the container running a SNARK worker to 4 CPUs and 8GB of RAM.&lt;/p&gt;

&lt;div class=&quot;language-shell highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;$ &lt;/span&gt;docker run -d --name coda &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
-p 8305:8305 &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
--memory 8g &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
--cpus 4 &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
--restart always &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
codaprotocol/coda-daemon:0.0.12-beta-feature-bump-genesis-timestamp-3e9b174 daemon &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
-run-snark-worker &amp;lt;PUBLIC_KEY&amp;gt; &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
-snark-worker-fee 0.25 &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
-work-selection seq &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
-peer &amp;lt;PEER_1&amp;gt; &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
-peer &amp;lt;PEER_2&amp;gt; &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
-external-port 8305
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;h2 id=&quot;accessing-the-graphql-api&quot;&gt;Accessing the GraphQL API&lt;/h2&gt;

&lt;p&gt;The GraphQL API is available to interact with the Coda daemon. You can read more about the API &lt;a href=&quot;https://garethtdavies.com/crypto/first-steps-with-coda-graphql-api.html&quot;&gt;in this article&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;By default, the GraphQL API is bound to &lt;code class=&quot;highlighter-rouge&quot;&gt;localhost&lt;/code&gt;. To access it outside of the container, you will need to pass the &lt;code class=&quot;highlighter-rouge&quot;&gt;-insecure-rest-server&lt;/code&gt; option allowing the API to listen on all interfaces and then publish this port outside of the container. Crucially, if you do this, you must block the port (&lt;code class=&quot;highlighter-rouge&quot;&gt;3085&lt;/code&gt; by default) from external users via a firewall on the host, as the API is unauthenticated, and anyone with access could gain access to your wallet.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;$ &lt;/span&gt;docker run -d --name coda &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
-e &lt;span class=&quot;s2&quot;&gt;&quot;CODA_PRIVKEY_PASS=xxxxxx&quot;&lt;/span&gt; &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
--mount &lt;span class=&quot;nb&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;bind&lt;/span&gt;,source&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;$(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;pwd&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;/keys,target&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;/root/keys &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
-p 8302:8302 &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
-p 8303:8303 &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
-p 3085:3085 &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
--restart always &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
codaprotocol/coda-daemon:0.0.12-beta-feature-bump-genesis-timestamp-3e9b174 daemon &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
-insecure-rest-server &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
-peer &amp;lt;PEER_1&amp;gt; &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
-peer &amp;lt;PEER_2&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Once this is running, on the host where Docker is running, visit &lt;code class=&quot;highlighter-rouge&quot;&gt;localhost:3085/graphql&lt;/code&gt;. If you are using a VM, you can use SSH port forwarding to forward port 3085 on your development machine to the remote machine, e.g., &lt;code class=&quot;highlighter-rouge&quot;&gt;ssh -L3085:127.0.0.1:3085 user@remotehost&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://garethtdavies-uploads.s3.us-east-1.amazonaws.com/graphiql.png&quot; alt=&quot;Coda GraphQL API&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;additional-options&quot;&gt;Additional options&lt;/h2&gt;

&lt;p&gt;There are many other options available to customize the running daemon, and you should &lt;a href=&quot;https://codaprotocol.com/docs/cli-reference#coda-daemon&quot;&gt;consult the documentation&lt;/a&gt;. You can optionally add these options to the docker command, such as &lt;code class=&quot;highlighter-rouge&quot;&gt;-coinbase-receiver&lt;/code&gt; that will direct any coinbase payments to an address other than the block producer key, such as to a &lt;a href=&quot;https://github.com/CodaProtocol/ledger-coda-app&quot;&gt;cold storage wallet&lt;/a&gt;.&lt;/p&gt;
</description>
        <pubDate>Wed, 08 Jul 2020 12:00:00 +0000</pubDate>
        <link>https://garethtdavies.com/crypto/running-coda-with-docker.html</link>
        <guid isPermaLink="true">https://garethtdavies.com/crypto/running-coda-with-docker.html</guid>
        
        <category>coda</category>
        
        
        <category>crypto</category>
        
      </item>
    
      <item>
        <title>Prototyping a Coda Blockchain Explorer</title>
        <description>&lt;blockquote&gt;
  &lt;p&gt;This article is published on &lt;a href=&quot;https://medium.com/@_garethtdavies/prototyping-a-coda-blockchain-explorer-dbe5c12b4ae2&quot;&gt;Medium&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A block explorer is a tool typically used to visualise the current and historical state of a blockchain including all transaction information. Coda, a succinct blockchain, presents some interesting challenges in this regard as this prior state information is not required to be stored by end-users or even block producers, but rather the protocol relies on cryptographic proofs to prove the current chain state (and thus everything preceding it).&lt;/p&gt;

&lt;p&gt;Coda currently provides an option for users to run an archive node that persists block data. This data is then exportable via the GraphQL API and it is this data that has been used to produce a prototype block explorer to help users become better acquainted with the testnet and Coda’s functionality.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://garethtdavies-uploads.s3.us-east-1.amazonaws.com/coda-blog-local.png&quot; alt=&quot;Prototyping a Coda Blockchain Explorer&quot; title=&quot;Prototyping a Coda Blockchain Explorer&quot; /&gt;&lt;/p&gt;
</description>
        <pubDate>Sun, 08 Sep 2019 00:00:00 +0000</pubDate>
        <link>https://garethtdavies.com/crypto/whats-next-for-zcash-in-2019.html</link>
        <guid isPermaLink="true">https://garethtdavies.com/crypto/whats-next-for-zcash-in-2019.html</guid>
        
        <category>coda</category>
        
        
        <category>crypto</category>
        
      </item>
    
      <item>
        <title>First steps with the Coda GraphQL API</title>
        <description>&lt;p&gt;&lt;a href=&quot;https://codaprotocol.com/&quot;&gt;Coda&lt;/a&gt; is a cryptocurrency that uses a &lt;a href=&quot;https://medium.com/codaprotocol/o-1-labs-releases-testnet-beta-for-coda-protocol-the-first-succinct-blockchain-b937eada81a9&quot;&gt;succinct blockchain&lt;/a&gt; that is enabled through the &lt;a href=&quot;https://hackernoon.com/a-blockchain-the-size-of-a-few-tweets-9db820eb6b29&quot;&gt;recursive composition of zk-SNARKs&lt;/a&gt;. For clients, this means they can verify the chain with only a few kB of data which opens up exciting opportunities for scalable blockchain applications.&lt;/p&gt;

&lt;p&gt;Coda recently launched their &lt;a href=&quot;https://medium.com/codaprotocol/o-1-labs-releases-testnet-beta-for-coda-protocol-the-first-succinct-blockchain-b937eada81a9&quot;&gt;public testnet&lt;/a&gt; and encourages users who want to help develop the protocol to join the testnet and complete &lt;a href=&quot;https://codaprotocol.com/blog/testnet-retro-1.html&quot;&gt;various weekly challenges&lt;/a&gt;. While Coda has a traditional &lt;a href=&quot;https://codaprotocol.com/docs/cli-reference/&quot;&gt;command-line interface&lt;/a&gt; (CLI) that will be familiar to anyone running a full node implementation, e.g. Bitcoin Core, it also exposes a &lt;a href=&quot;https://graphql.org/&quot;&gt;GraphQL API&lt;/a&gt; that we will explore in this article.&lt;/p&gt;

&lt;!--more--&gt;

&lt;p&gt;&lt;a href=&quot;https://graphql.org/&quot;&gt;GraphQL&lt;/a&gt;, which is an open-source query language for APIs, is relatively new being publicly &lt;a href=&quot;https://en.wikipedia.org/wiki/GraphQL&quot;&gt;released in 2015&lt;/a&gt; and was developed by Facebook to resolve some common issues with more traditional REST APIs. Now hosted under the umbrella of the GraphQL Foundation (part of the &lt;a href=&quot;https://www.linuxfoundation.org/&quot;&gt;Linux Foundation&lt;/a&gt;) many organisations, notably including &lt;a href=&quot;https://developer.github.com/v4/&quot;&gt;Github&lt;/a&gt;, &lt;a href=&quot;https://docs.gitlab.com/ee/api/graphql/&quot;&gt;Gitlab&lt;/a&gt;, &lt;a href=&quot;https://help.shopify.com/en/api/storefront-api&quot;&gt;Shopify&lt;/a&gt;, &lt;a href=&quot;https://developers.facebook.com/docs/graph-api&quot;&gt;Facebook&lt;/a&gt;, &lt;a href=&quot;https://github.com/APIs-guru/graphql-apis&quot;&gt;and many more&lt;/a&gt; all offer a GraphQL API.&lt;/p&gt;

&lt;p&gt;While REST APIs still dominate, with GraphQL, clients can obtain all of the data they need in one request and reduces the data returned to only what is required. Let’s illustrate these concepts through an example of retrieving block and transaction data from the Bitcoin blockchain. We’ll use the &lt;a href=&quot;https://bitcoinchain.com/api&quot;&gt;BitcoinChain API&lt;/a&gt;, though the exact implementation is largely irrelevant in exploring the concepts.&lt;/p&gt;

&lt;p&gt;We can retrieve the latest block via &lt;code class=&quot;highlighter-rouge&quot;&gt;https://api-r.bitcoinchain.com/v1/blocks/1/withTx&lt;/code&gt; which returns the following response containing the full block data as well as all the transactions contained in the block (only three shown in the example below for brevity).&lt;/p&gt;

&lt;div class=&quot;language-json highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&quot;hash&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;0000000000000000001592abc23acc699f54145b5794f56cf60f63f7e412ba2c&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&quot;height&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;591791&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&quot;prev_block&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;0000000000000000000d8dd10509cbfbd778d4ddb359bee4f4700178aff7f015&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&quot;next_block&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&quot;mrkl_root&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;b1700f7e82d199fb8102e88988dae3e5570c7d3731b3864c3131963104613f8b&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&quot;tx&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;e4ea88cf747e9cd3a848a9b933f8b231cdd6b2fbaf950f2b6a202aaefd7c5ea8&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;09c33e084f7d6fcf2fdc94cb0a80681e82378a0afeeca8563a350c0a5ee2b9f9&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;c7a3c795142bec4b7b3049a1e3af95adcf20c4490fd2ae631ba63ce7831a0d19&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&quot;tx_count&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2748&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&quot;reward&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;12.50000000&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&quot;fee&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;0.22152797&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&quot;vout_sum&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;7230.03209165&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&quot;is_main&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&quot;version&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;1073676288&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&quot;difficulty&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;10183488432890.000000&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&quot;size&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1150937&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&quot;bits&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;387687377&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&quot;nonce&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;1158314858&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&quot;time&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1566791311&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Let’s say for our sample application, we are merely interested in the &lt;code class=&quot;highlighter-rouge&quot;&gt;hash&lt;/code&gt; and &lt;code class=&quot;highlighter-rouge&quot;&gt;height&lt;/code&gt; of the block. In this case, we are discarding ~99% of the data received, which is not applicable to our use-case. This is an example of &lt;em&gt;overfetching&lt;/em&gt;, where we are receiving more data then we require. In GraphQL, we construct the query to only contain the data we want to be returned. An overly simplified example (in reality we would likely pass in arguments such as first to specify how many results we want to return) of the same request would be:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;query {
  blocks {
    hash
    height
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;which would return the following JSON:&lt;/p&gt;

&lt;div class=&quot;language-json highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&quot;data&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&quot;blocks&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&quot;hash&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;0000000000000000001592abc23acc699f54145b5794f56cf60f63f7e412ba2c&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&quot;height&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;591791&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Conversely, let’s say we wanted all the transaction information for the latest block from the REST API. In this case, we’d need to construct &lt;a href=&quot;[https://api-r.bitcoinchain.com/v1/tx/e4ea88cf747e9cd3a848a9b933f8b231cdd6b2fbaf950f2b6a202aaefd7c5ea8]&quot;&gt;multiple further queries for each transaction&lt;/a&gt; using the transaction id to get the required data. As we don’t have all the data we require in our API response, this is known as &lt;em&gt;underfetching&lt;/em&gt;. GraphQL solves this problem with the ability to nest our queries, and when it is executed, it can traverse related objects so we can make one request and get two types of data (in this case blocks and transaction data). Using GraphQL, such a query may look like the below:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;query {
  blocks {
    hash
    height
    transactions {
      transaction_id
      block_time
      inputs {
        value
        sender
      }
      outputs {
        value
        receiver
      }
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Whenever a query is executed against a GraphQL server, it is validated against a type system defined by a schema. Coda’s GraphQL schema is published &lt;a href=&quot;https://github.com/CodaProtocol/coda/blob/develop/graphql_schema.json&quot;&gt;here&lt;/a&gt; which defines the objects and types permitted by the API, a number of which we will explore in the remainder of this article. &lt;em&gt;Note that the Coda GraphQL API is in active development and liable to change.&lt;/em&gt;&lt;/p&gt;

&lt;h2 id=&quot;initial-setup-of-coda-graphql-api&quot;&gt;Initial setup of Coda GraphQL API&lt;/h2&gt;

&lt;p&gt;We’ll first need to &lt;a href=&quot;https://codaprotocol.com/docs/getting-started/&quot;&gt;install Coda&lt;/a&gt; for the current active testnet. Once installed the GraphQL API is enabled via passing the &lt;code class=&quot;highlighter-rouge&quot;&gt;-rest-port&lt;/code&gt; flag to the &lt;code class=&quot;highlighter-rouge&quot;&gt;coda daemon&lt;/code&gt; startup command, specifying the port to expose, e.g. the following exposes the GraphQL API on port 8000.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;coda daemon -rest-port 8000
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Note that the GraphQL API is bound to &lt;code class=&quot;highlighter-rouge&quot;&gt;localhost&lt;/code&gt; for security. The API is unauthenticated, and as we will demonstrate later with the &lt;code class=&quot;highlighter-rouge&quot;&gt;sendPayment&lt;/code&gt; mutation, anyone with access can send payments from a wallet known to the daemon. You can disable this security feature with the &lt;code class=&quot;highlighter-rouge&quot;&gt;-insecure-rest-server&lt;/code&gt; option which will listen on all interfaces and not just &lt;code class=&quot;highlighter-rouge&quot;&gt;localhost&lt;/code&gt;. If you are running Coda on a remote host the best way is to use SSH port forwarding to forward a local port on your machine to the GraphQL port on the remote machine e.g.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;ssh -L 8000:127.0.0.1:8000 user@remotehost
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Finally, if you want to work with an existing wallet, you’ll need to import it with a temporary workaround that copies it and strips it of its password. You can also alternatively, as we will demonstrate, create a new wallet via the GraphQL API.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;coda daemon -propose-key /keys/my-private-key -unsafe-track-propose-key -rest-port 8000
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Now you should be able to point your browser to &lt;code class=&quot;highlighter-rouge&quot;&gt;localhost:8000/graphql&lt;/code&gt; and can explore the GraphQL API via the &lt;a href=&quot;https://github.com/graphql/graphiql&quot;&gt;GraphiQL&lt;/a&gt; tool, an in-browser IDE for explorer GraphQL APIs.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://garethtdavies-uploads.s3.us-east-1.amazonaws.com/coda-graph-ql-hello.png&quot; alt=&quot;Hello GraphiQL&quot; title=&quot;Hello GraphiQL&quot; /&gt;&lt;/p&gt;

&lt;p&gt;On the right-hand side, you will see the Documentation explorer that lists the different types available to use. At the root level, GraphQL supports query, mutation and subscription types. Let’s start with some GraphQL queries.&lt;/p&gt;

&lt;h2 id=&quot;querying-the-coda-graphql-api&quot;&gt;Querying the Coda GraphQL API&lt;/h2&gt;

&lt;p&gt;Clicking on the query type in the interactive documentation displays a list of fields, the first being &lt;code class=&quot;highlighter-rouge&quot;&gt;syncStatus&lt;/code&gt; which returns the “Network sync status”. Enter the following into the left panel and execute the query:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;query {
  syncStatus
}
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;&lt;img src=&quot;https://garethtdavies-uploads.s3.us-east-1.amazonaws.com/coda-graph-ql-query.png&quot; alt=&quot;Get the syncStatus of the node&quot; title=&quot;Get the syncStatus of the node&quot; /&gt;&lt;/p&gt;

&lt;p&gt;The return value &lt;code class=&quot;highlighter-rouge&quot;&gt;SYNCED&lt;/code&gt; is defined as &lt;a href=&quot;[https://github.com/CodaProtocol/coda/blob/master/frontend/wallet/schema.graphql#L327]&quot;&gt;one of the following values&lt;/a&gt;. You can use the GraphiQL IDE to explore and test the various queries available. In this example, there was a single return value, but now we’ll use a more advanced query to retrieve block information that requires specifying the exact data we require via nesting.&lt;/p&gt;

&lt;h3 id=&quot;blocks-data&quot;&gt;Blocks data&lt;/h3&gt;

&lt;p&gt;In Coda, a node by default will only store information about blocks it has seen (unless it is running as an archive node), so before running these queries leave your node running for a while before executing these queries to get some meaningful results.&lt;/p&gt;

&lt;p&gt;According to the documentation, the &lt;code class=&quot;highlighter-rouge&quot;&gt;blocks&lt;/code&gt; object accepts the &lt;code class=&quot;highlighter-rouge&quot;&gt;before&lt;/code&gt;, &lt;code class=&quot;highlighter-rouge&quot;&gt;last&lt;/code&gt;, &lt;code class=&quot;highlighter-rouge&quot;&gt;after&lt;/code&gt;, &lt;code class=&quot;highlighter-rouge&quot;&gt;first&lt;/code&gt; and &lt;code class=&quot;highlighter-rouge&quot;&gt;filter&lt;/code&gt; arguments to specify which blocks to return. All of these are optional (nullable) as indicated by the lack of a trailing &lt;code class=&quot;highlighter-rouge&quot;&gt;!&lt;/code&gt;. It returns a &lt;code class=&quot;highlighter-rouge&quot;&gt;BlockConnection&lt;/code&gt; object (required) which itself is comprised of various fields that we can explore by clicking through on the explorer documentation.&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;blocks(
  before: String
  last: Int
  after: String
  first: Int
  filter: BlockFilterInput): BlockConnection!
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;First, let’s get the &lt;code class=&quot;highlighter-rouge&quot;&gt;totalCount&lt;/code&gt; of blocks known to this node:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;query {
  blocks {
    totalCount
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Which returns:&lt;/p&gt;

&lt;div class=&quot;language-json highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&quot;data&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&quot;blocks&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&quot;totalCount&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;236&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;We can also filter the blocks to only contain blocks that contain a public key whose transaction is in a block or produced this block. Applying this to my staking node and getting the first result:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;query {
  blocks(first: 1, filter: {relatedTo: &quot;tNciEHZuC9SdpdKjG3cLw8dpdKUdXpbrqkhctcE422NyspG8G3ddArHJupGvV591mRKd6hEMBoPNPNRZMSjyN1S8Jp4jD8zMyHSzvsFhzKhqa7Q3F2a3uNmNUHp2rtVsj3HuLt9Zw3whHM&quot;}) {
    totalCount
    nodes {
      creator
      stateHash
      transactions {
        coinbase
        userCommands {
          id
          nonce
          from
          to
          amount
          fee
        }
      }
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;This returns the following response. In this instance, there were no transactions in the block, but the public key produced the block. Note, I have specified the fields I am interested in returning, but there are many more available as demonstrated in the &lt;a href=&quot;https://github.com/CodaProtocol/coda/blob/master/frontend/wallet/schema.graphql&quot;&gt;schema&lt;/a&gt;.&lt;/p&gt;

&lt;div class=&quot;language-json highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&quot;data&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&quot;blocks&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&quot;totalCount&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;17&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&quot;nodes&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&quot;creator&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;tNciEHZuC9SdpdKjG3cLw8dpdKUdXpbrqkhctcE422NyspG8G3ddArHJupGvV591mRKd6hEMBoPNPNRZMSjyN1S8Jp4jD8zMyHSzvsFhzKhqa7Q3F2a3uNmNUHp2rtVsj3HuLt9Zw3whHM&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&quot;stateHash&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;4ApWKSeBhPyZDgYVFCYg6WzN1oGHpQxmdTfPbVs4LEd2JCxvwR3hzcVsjto45Kt58cpbciFxvt7ZoCq6HsM3iqZfpNh5p9DWXR8RHZFnVRczvPij7xeMYvBXcJ3kVzqkf9aufNS344VoR&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&quot;transactions&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
          &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&quot;coinbase&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;0&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
          &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&quot;userCommands&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
          &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;h2 id=&quot;mutations-modifying-data-with-the-coda-graphql-api&quot;&gt;Mutations, modifying data with the Coda GraphQL API&lt;/h2&gt;

&lt;p&gt;So far, we have explored some basic queries using the GraphQL API. GraphQL supports two additional root types of &lt;strong&gt;mutations&lt;/strong&gt; and &lt;strong&gt;subscriptions&lt;/strong&gt;. We won’t touch on subscriptions in this article, but they allow GraphQL clients to subscribe to published events. Coda’s GraphQL API provides two events &lt;code class=&quot;highlighter-rouge&quot;&gt;newSyncUpdate&lt;/code&gt; that triggers when the network sync status changes and &lt;code class=&quot;highlighter-rouge&quot;&gt;newBlock&lt;/code&gt; that triggers when a new block is created.&lt;/p&gt;

&lt;p&gt;Mutations, as the name suggests, modify data in some way. Coda’s GraphQL API includes the following mutations:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;addWallet
deleteWallet
sendPayment
sendDelegation
addPaymentReceipt
setStaking
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Let’s list any existing wallets known to the daemon:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;query {
  ownedWallets{
    publicKey,
    balance {
      total
      unknown
    }
    nonce
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;If you didn’t import an existing wallet, likely this will be empty. Create a new one:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;mutation {
  addWallet{
    publicKey
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;This will return the public key of your new wallet. Use this to request some Coda from the testnet faucet on &lt;a href=&quot;https://discordapp.com/invite/Vexf4ED&quot;&gt;Discord&lt;/a&gt;) or any other helpful Codans. Now retrying the &lt;code class=&quot;highlighter-rouge&quot;&gt;ownedWallets&lt;/code&gt; query should return the wallet and balance associated.&lt;/p&gt;

&lt;div class=&quot;language-json highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&quot;data&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&quot;ownedWallets&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&quot;publicKey&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;tNciDhKWNmKpoQ4jHvP4oqt7gnuQYaUYz8pMSE1wewiXjaozksHVL5YpkC4bSx3hqaZHH6cgxwLicrXAdddGyHx8eh3WJBZN6XzpAZdfYM861t53khP9v74Kj3CBxHCbfVPisD8ikNaBGE&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&quot;balance&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&quot;total&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;470&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&quot;unknown&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;470&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&quot;nonce&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;0&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Next, let’s send a payment specifying the &lt;code class=&quot;highlighter-rouge&quot;&gt;from&lt;/code&gt; address as your wallet with funds in it and a &lt;code class=&quot;highlighter-rouge&quot;&gt;to&lt;/code&gt; address (&lt;a href=&quot;https://codaprotocol.com/docs/my-first-transaction/&quot;&gt;e.g. to the echo service&lt;/a&gt;) and the fee associated with the transaction, and we’ll return the full details of the transaction.&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;mutation {
  sendPayment(input: {fee: 5, amount: 10, to: &quot;tNciEHZuC9SdpdKjG3cLw8dpdKUdXpbrqkhctcE422NyspG8G3ddArHJupGvV591mRKd6hEMBoPNPNRZMSjyN1S8Jp4jD8zMyHSzvsFhzKhqa7Q3F2a3uNmNUHp2rtVsj3HuLt9Zw3whHM&quot;, from: &quot;tNciDhKWNmKpoQ4jHvP4oqt7gnuQYaUYz8pMSE1wewiXjaozksHVL5YpkC4bSx3hqaZHH6cgxwLicrXAdddGyHx8eh3WJBZN6XzpAZdfYM861t53khP9v74Kj3CBxHCbfVPisD8ikNaBGE&quot;}) {
    payment {
      id
      isDelegation
      nonce
      from
      to
      amount
      fee
      memo
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;This produced the following response:&lt;/p&gt;

&lt;div class=&quot;language-json highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&quot;data&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&quot;sendPayment&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&quot;payment&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&quot;id&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;3XCgvAHM3twoJ2T8dcTvxpuyrnBJ12b7Y1HXYjAgVXVLHNPcr95VSaQ9eoGZTmq3LXh2rKvePPes58Zi4EJXjiFo77uo1meAMh3qty88RXmfrPjP1xQ58wm9oop499ZUgT5Fspbok7Yxg4eCFR8zRvd8bob7RdojY38DLDiHD9hrEmEXbZhAThZWS6sdxuHBpsimL4ZZJkvbQcs24MonG2Fd1MvbjNhfSE5sR7PGGjqAX4hbEb6hskjF8czVDnCqD3yLwGRFrL2tchCrZUHc6njci3294SsFMmbgAqwog6nBVQojE42sYgcXdPK7oPEFV2Com53QCSPPSfdiCeRNF5QhG5tEC1viwGtBLbKmF9qFR7PVg8UEJhBwsyu5LpLNwxzVEA4rdEy3syDZFrC4GfYmKdohQvBWv2DgVgUKwe7xRH5fh5UPx2f3GyV87pcxvdoq5BnZYDB6MkktsQxpeTk8zykrvXacHtYkZhMfLVLhgxW9EwEb6dfJTUMHaSp2F1uXFzwa6cJe8RdUt4EWQiVYgDUN8Hwai5AGLaXfn86Yjck3D6E5MiBDwhrcQBiKF6xFSzEFJGcnjTrFd5aMKE9KKqyyUuUjoj8YKz4woUXUBHbyaTBrJP2dVs8vaePyieueq5pFxtD9Lhqwx6f9ejUQnbz53HPzfsNzkDNA9n5NJimrgWDrZvkUmq8F2B3zj35Mzf4M9PFbjeWkUwAjRveRpBEy2oBWswX&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&quot;isDelegation&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&quot;nonce&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&quot;from&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;tNciDhKWNmKpoQ4jHvP4oqt7gnuQYaUYz8pMSE1wewiXjaozksHVL5YpkC4bSx3hqaZHH6cgxwLicrXAdddGyHx8eh3WJBZN6XzpAZdfYM861t53khP9v74Kj3CBxHCbfVPisD8ikNaBGE&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&quot;to&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;tNciEHZuC9SdpdKjG3cLw8dpdKUdXpbrqkhctcE422NyspG8G3ddArHJupGvV591mRKd6hEMBoPNPNRZMSjyN1S8Jp4jD8zMyHSzvsFhzKhqa7Q3F2a3uNmNUHp2rtVsj3HuLt9Zw3whHM&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&quot;amount&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;10&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&quot;fee&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;5&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&quot;memo&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;2pmu64f2x97tNiDXMycnLwBSECDKbX77MTXVWVsG8hcRFsedhXDWWq&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;The nonce value is used to prevent replaying transactions on the network. As this was our first transaction, the nonce was 0. If we repeat this transaction we’ll see the nonce has increased to 1.&lt;/p&gt;

&lt;div class=&quot;language-json highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&quot;data&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&quot;sendPayment&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&quot;payment&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&quot;id&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;3XCgvAHM3txTHrcrWcodUm1nkUVEQjUa8Q4WxkrwVueTvAvCM6NVehmxiVZuzMY3gV5cRanzk2A41vQp59sdGfAothQuoydrcW9s12NSgM9wqqgGtJidUq29b6qDmUh7N6RVkaJtynNuEtYgbeubWaYQfNvN3nruehRHnY6Xuk4uyuvqob4zGerMKS4Qpzq1nirb6GbWYCYouwz5fhZPmRtPuX3FDR5LtgSY1JqV8VrcHY7BRgb6qQJco83n1HcDZS1uQsxRTJEDzM4EvHCeg6qx7Wc6GeuDEDTMmkvZyP3jgvRXS3oLRhnXLDzR9EhoHu2pwLZGmwEBBYrSeoEY7sFeMTByRTbsaHZi69rJsrxBAHmpY8CY7WZypf9mxiz2aRfRffy5AGCEY74EsGpKbAYszBww6k5p6PUvnuk2PTnFdagdMeJ6Udm7qGDcRwA6FL9VixEazyMYtZSMNaFweyTo1zic5viusJfZiTAQZ6JnJ7R88uAbRiwZ7v5oweqLrkHi9gLcqF8ULwWTQwh84zW9ei8GGNneFHn4SY2c2AZK7NLPMtQhLXbtALG7CMN3V1u8NoFzCUCYx3omAP8qHiDCAjxPvjkPViYj9m3YeBEkukMzjW7BMQK52BxBKSbQC7xXbxm4x4dyCKW9BSkrvkz3a27ePbwouSESoHURDmSqGYUjd9uSaboVmkvdqpFdw43sd3dPqbEaXXDxvdgkGrUBXd24DzuriaF&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&quot;isDelegation&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&quot;nonce&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&quot;from&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;tNciDhKWNmKpoQ4jHvP4oqt7gnuQYaUYz8pMSE1wewiXjaozksHVL5YpkC4bSx3hqaZHH6cgxwLicrXAdddGyHx8eh3WJBZN6XzpAZdfYM861t53khP9v74Kj3CBxHCbfVPisD8ikNaBGE&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&quot;to&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;tNciEHZuC9SdpdKjG3cLw8dpdKUdXpbrqkhctcE422NyspG8G3ddArHJupGvV591mRKd6hEMBoPNPNRZMSjyN1S8Jp4jD8zMyHSzvsFhzKhqa7Q3F2a3uNmNUHp2rtVsj3HuLt9Zw3whHM&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&quot;amount&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;10&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&quot;fee&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;5&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&quot;memo&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;2pmu64f2x97tNiDXMycnLwBSECDKbX77MTXVWVsG8hcRFsedhXDWWq&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Now finally, we’ll check the status of our transaction on the Coda network using the returned &lt;code class=&quot;highlighter-rouge&quot;&gt;id&lt;/code&gt; of the payment.&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;query {
  transactionStatus(payment: &quot;3XCgvAHM3txTHrcrWcodUm1nkUVEQjUa8Q4WxkrwVueTvAvCM6NVehmxiVZuzMY3gV5cRanzk2A41vQp59sdGfAothQuoydrcW9s12NSgM9wqqgGtJidUq29b6qDmUh7N6RVkaJtynNuEtYgbeubWaYQfNvN3nruehRHnY6Xuk4uyuvqob4zGerMKS4Qpzq1nirb6GbWYCYouwz5fhZPmRtPuX3FDR5LtgSY1JqV8VrcHY7BRgb6qQJco83n1HcDZS1uQsxRTJEDzM4EvHCeg6qx7Wc6GeuDEDTMmkvZyP3jgvRXS3oLRhnXLDzR9EhoHu2pwLZGmwEBBYrSeoEY7sFeMTByRTbsaHZi69rJsrxBAHmpY8CY7WZypf9mxiz2aRfRffy5AGCEY74EsGpKbAYszBww6k5p6PUvnuk2PTnFdagdMeJ6Udm7qGDcRwA6FL9VixEazyMYtZSMNaFweyTo1zic5viusJfZiTAQZ6JnJ7R88uAbRiwZ7v5oweqLrkHi9gLcqF8ULwWTQwh84zW9ei8GGNneFHn4SY2c2AZK7NLPMtQhLXbtALG7CMN3V1u8NoFzCUCYx3omAP8qHiDCAjxPvjkPViYj9m3YeBEkukMzjW7BMQK52BxBKSbQC7xXbxm4x4dyCKW9BSkrvkz3a27ePbwouSESoHURDmSqGYUjd9uSaboVmkvdqpFdw43sd3dPqbEaXXDxvdgkGrUBXd24DzuriaF&quot;)
}
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;This returns the &lt;code class=&quot;highlighter-rouge&quot;&gt;transactionStatus&lt;/code&gt; which in our case is &lt;code class=&quot;highlighter-rouge&quot;&gt;PENDING&lt;/code&gt; i.e. is waiting to be included in a block.&lt;/p&gt;

&lt;div class=&quot;language-json highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&quot;data&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&quot;transactionStatus&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;PENDING&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;h2 id=&quot;next-steps&quot;&gt;Next steps&lt;/h2&gt;

&lt;p&gt;We’ve only touched on a few queries available via the Coda GraphQL API, and there are many more to explore. While the API is in active development, it’s a great learning experience to interact with the Coda protocol this way. It offers some improvements over the existing CLI interface but more importantly allows the development of future tools such as block explorers, wallets etc…&lt;/p&gt;

&lt;p&gt;You can also interact with the GraphQL API using multiple client libraries such as &lt;a href=&quot;https://www.apollographql.com/docs/react/&quot;&gt;Apollo&lt;/a&gt;, building a status page for your own node, for example. Additionally, the excellent &lt;a href=&quot;https://blog.getpostman.com/2019/06/18/postman-v7-2-supports-graphql/&quot;&gt;Postman client&lt;/a&gt; now supports GraphQL, which can be used to further experiment with and develop for the Coda GraphQL API.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://garethtdavies-uploads.s3.us-east-1.amazonaws.com/coda-graphql-postman.png&quot; alt=&quot;Coda API Postman Collection&quot; title=&quot;Coda API Postman Collection&quot; /&gt;&lt;/p&gt;
</description>
        <pubDate>Mon, 26 Aug 2019 12:00:00 +0000</pubDate>
        <link>https://garethtdavies.com/crypto/first-steps-with-coda-graphql-api.html</link>
        <guid isPermaLink="true">https://garethtdavies.com/crypto/first-steps-with-coda-graphql-api.html</guid>
        
        <category>coda</category>
        
        
        <category>crypto</category>
        
      </item>
    
      <item>
        <title>Zcash Insight Blockchain Explorer</title>
        <description>&lt;p&gt;With the launch of &lt;a href=&quot;https://github.com/zcash/zcash/releases&quot;&gt;2.0.7&lt;/a&gt;, zcashd now includes full support for the &lt;a href=&quot;https://github.com/bitpay/bitcore/tree/master/packages/insight&quot;&gt;Insight blockchain explorer&lt;/a&gt;. The Insight explorer, which will be familiar to those who have used one of the many popular block explorers it powers, was developed by &lt;a href=&quot;https://bitpay.com/&quot;&gt;Bitpay&lt;/a&gt; as part of its &lt;a href=&quot;https://bitcore.io/&quot;&gt;bitcore&lt;/a&gt; suite of tools. The tool, released under a permissive open-source license (&lt;a href=&quot;https://choosealicense.com/licenses/mit/&quot;&gt;MIT&lt;/a&gt;), contains many development tools to “build bitcoin and blockchain applications” but we will concentrate on installing the explorer portion for this article which has been ported to support Zcash.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://garethtdavies-uploads.s3.us-east-1.amazonaws.com/zcash-insight.png&quot; alt=&quot;The Insight block explorer on Zcash testnet&quot; title=&quot;The Insight block explorer on Zcash testnet&quot; /&gt;&lt;/p&gt;

&lt;!--more--&gt;

&lt;p&gt;While there are existing implementations of the Insight explorer on Zcash it relies on running a &lt;a href=&quot;https://github.com/zcash-hackworks/zcash-patched-for-explorer&quot;&gt;patched version of zcashd&lt;/a&gt;. This caused issues with maintaining multiple versions which required regular updating as versions by default reach end of support halt and shut down every 16 weeks. In addition, the &lt;a href=&quot;https://github.com/zcash/zips/blob/master/zip-0206.rst&quot;&gt;Blossom network upgrade&lt;/a&gt; will activate on testnet at height 584000 and so a compatible version of zcashd is required to follow the upgraded chain.&lt;/p&gt;

&lt;p&gt;These &lt;a href=&quot;https://zcash.readthedocs.io/en/latest/rtd_pages/insight_explorer.html&quot;&gt;updates to zcashd&lt;/a&gt; specifically include new fields to the &lt;code class=&quot;highlighter-rouge&quot;&gt;getrawtransaction&lt;/code&gt; RPC call as well as a set of new RPC (CLI) methods that allow, for example, to get the balance of (transparent) addresses. While you can run zcashd in isolation to extract this information, the Insight explorer user interface presents the information in a visual and easily searchable way.&lt;/p&gt;

&lt;p&gt;For the remainder of the article, we’ll walk through installing Insight explorer on an Ubuntu 18.04 machine, such as a local machine or VM (cloud-hosted or otherwise). I’ve tested these instructions successfully on a local machine as well as on a Digital Ocean cloud instance. As this is running zcashd in addition to other components, make sure you meet the &lt;a href=&quot;https://zcash.readthedocs.io/en/latest/rtd_pages/user_guide.html#getting-started&quot;&gt;minimum specs&lt;/a&gt; and allow some headroom in disk space to accommodate future growth of the chain (running zcashd in this manner will also increase the disk space used by the data directory).&lt;/p&gt;

&lt;p&gt;The following installation is heavily based on the &lt;a href=&quot;https://github.com/zcash-hackworks/zcash-insight-explorer&quot;&gt;Dockerfile&lt;/a&gt; in the &lt;a href=&quot;https://github.com/zcash-hackworks&quot;&gt;zcash-hackworks&lt;/a&gt; repository. Rather than assume Docker knowledge and detail additional requirements such as persistent data volumes (you’ll want to mount the zcash data directory and parameters), I’ll outline the process on Ubuntu 18.04 which can be easily adapted to a Dockerfile if necessary or deployed as is to a cloud VM.&lt;/p&gt;

&lt;h2 id=&quot;installation&quot;&gt;Installation&lt;/h2&gt;

&lt;p&gt;For this tutorial, we will be running everything as the &lt;em&gt;zcashd&lt;/em&gt; user. As some of the paths below are absolute, you will need to either create a new user of that name or simply update references to the &lt;em&gt;zcashd&lt;/em&gt; user to your (non-root) username.&lt;/p&gt;

&lt;p&gt;Installation consists of building zcashd (though this isn’t strictly required, as you could substitute the &lt;a href=&quot;https://zcash.readthedocs.io/en/latest/rtd_pages/install_binary_tarball.html&quot;&gt;pre-built binaries&lt;/a&gt;), installing &lt;a href=&quot;https://nodejs.org/en/&quot;&gt;Node.js&lt;/a&gt; and pulling in the relevant Zcash ported bitcore packages and editing some configuration files.&lt;/p&gt;

&lt;p&gt;To begin, we’ll start by pulling in the required dependencies for our zcashd build:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;sudo apt update
sudo apt install -y gnupg2 wget libzmq3-dev git &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
    build-essential pkg-config libc6-dev m4 g++-multilib &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
    autoconf libtool ncurses-dev unzip git python &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
    python-zmq zlib1g-dev curl bsdmainutils automake
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Next, we’ll install Node.js. We’ll use version 8 as this has been confirmed to work and we’ll use the installation tool from &lt;a href=&quot;https://nodesource.com/&quot;&gt;nodesource.com&lt;/a&gt;. This script involves piping to bash with the sudo command so if you don’t want to proceed with this method simply follow the instructions for a &lt;a href=&quot;https://github.com/nodesource/distributions#manual-installation&quot;&gt;manual installation&lt;/a&gt;.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;curl -sL https://deb.nodesource.com/setup_8.x | sudo bash -
sudo apt-get install -y nodejs
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;To get around some &lt;a href=&quot;https://docs.npmjs.com/resolving-eacces-permissions-errors-when-installing-packages-globally&quot;&gt;node permissions issues&lt;/a&gt; on this version of Node.js we’ll use the following configuration:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;mkdir -p /home/zcashd/.npm-global
&lt;span class=&quot;nb&quot;&gt;export &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;NPM_CONFIG_PREFIX&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;/home/zcashd/.npm-global
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Finally, add the installation directory to our path so we can simplify references to the Node.js libraries later in the installation and apply these changes to the current shell (note these values won’t persist so if you don’t complete the installation in a single terminal you’ll need to add these environment values again or persist them e.g. using &lt;code class=&quot;highlighter-rouge&quot;&gt;bashrc&lt;/code&gt;).&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nb&quot;&gt;export &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;PATH&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;/home/zcashd/.npm-global/bin:&lt;span class=&quot;nv&quot;&gt;$PATH&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;source&lt;/span&gt; ~/.profile
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Next, we’ll clone the &lt;a href=&quot;https://github.com/zcash/zcash&quot;&gt;zcash repo&lt;/a&gt; and checkout &lt;a href=&quot;https://github.com/zcash/zcash/releases&quot;&gt;version 2.0.7&lt;/a&gt;. If version 2.0.7 isn’t available at the time of reading then install the release candidate v2.0.7-rc1. Update this &lt;a href=&quot;https://github.com/zcash/zcash/releases&quot;&gt;version tag&lt;/a&gt; if a later version is available or remove this line entirely to build the current master.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;git clone https://github.com/zcash/zcash.git
&lt;span class=&quot;nb&quot;&gt;cd &lt;/span&gt;zcash
git checkout v2.0.7 &lt;span class=&quot;c&quot;&gt;# ignore the detached head message&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Start the build and wait for it to complete:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;./zcutil/build.sh -j&lt;span class=&quot;k&quot;&gt;$(&lt;/span&gt;nproc&lt;span class=&quot;k&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Next, we’ll download the Zcash proving and verifying keys which will be placed in &lt;code class=&quot;highlighter-rouge&quot;&gt;~/.zcash-params&lt;/code&gt;. These keys are just under 1.7GB.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;./zcutil/fetch-params.sh
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Now we’ll &lt;a href=&quot;https://zcash.readthedocs.io/en/latest/rtd_pages/user_guide.html#configuration&quot;&gt;create a zcash conf file&lt;/a&gt; to complete the zcashd setup. Create a file using your favourite editor named &lt;code class=&quot;highlighter-rouge&quot;&gt;zcash.conf&lt;/code&gt; in the &lt;code class=&quot;highlighter-rouge&quot;&gt;~/zcash&lt;/code&gt; directory (the following instructions use the &lt;a href=&quot;https://linux.die.net/man/1/nano&quot;&gt;nano editor&lt;/a&gt;).&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;mkdir -p ~/.zcash
&lt;span class=&quot;nb&quot;&gt;cd&lt;/span&gt; ~/.zcash
nano zcash.conf
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Use the following values to run on testnet (see &lt;a href=&quot;#running-on-mainnet&quot;&gt;this for mainnet configuration&lt;/a&gt;).&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;testnet=1
addnode=testnet.z.cash
server=1
whitelist=127.0.0.1
zmqpubrawtx=tcp://127.0.0.1:28332
zmqpubhashblock=tcp://127.0.0.1:28332
txindex=1
experimentalfeatures=1
insightexplorer=1
addressindex=1
timestampindex=1
spentindex=1
rpcport=18232
rpcallowip=127.0.0.1
rpcuser=&amp;lt;username&amp;gt;
rpcpassword=&amp;lt;secretpassword&amp;gt;
showmetrics=0
uacomment=bitcore
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;You can confirm that everything is working with the command &lt;code class=&quot;highlighter-rouge&quot;&gt;./src/zcashd —version&lt;/code&gt; which should output the version information you installed.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;./src/zcashd --version
Zcash Daemon version v2.0.7
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Now install npm and the &lt;code class=&quot;highlighter-rouge&quot;&gt;bitcore-node-zcash&lt;/code&gt; library.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nb&quot;&gt;cd&lt;/span&gt; ~
sudo npm install -g npm@latest
npm install -g zcash-hackworks/bitcore-node-zcash
bitcore-node create zc
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;You should see the output like the following: &lt;code class=&quot;highlighter-rouge&quot;&gt;Successfully created node in directory:  zc&lt;/code&gt;. This final command creates a configuration file named &lt;code class=&quot;highlighter-rouge&quot;&gt;bitcore-node.json&lt;/code&gt; in the zc directory that we will need to edit to match our installation.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nb&quot;&gt;cd &lt;/span&gt;zc
nano bitcore-node.json
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Update this configuration to match the below, making a note of the port and also update the paths of the &lt;code class=&quot;highlighter-rouge&quot;&gt;datadir&lt;/code&gt; and zcashd executable &lt;code class=&quot;highlighter-rouge&quot;&gt;exec&lt;/code&gt; if you installed as a different user.&lt;/p&gt;

&lt;div class=&quot;language-json highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&quot;network&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;testnet&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&quot;port&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3001&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&quot;services&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;bitcoind&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;web&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&quot;servicesConfig&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&quot;bitcoind&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&quot;spawn&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&quot;datadir&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;/home/zcashd/.zcash&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&quot;exec&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;/home/zcashd/zcash/src/zcashd&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&quot;insight-api-zcash&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&quot;routePrefix&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;api&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&quot;insight-ui-zcash&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&quot;apiPrefix&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;api&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&quot;routePrefix&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Then install the Insight component from this &lt;code class=&quot;highlighter-rouge&quot;&gt;zc&lt;/code&gt; directory.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;bitcore-node install zcash-hackworks/insight-api-zcash &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
	zcash-hackworks/insight-ui-zcash
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;If all works, you should see &lt;code class=&quot;highlighter-rouge&quot;&gt;Successfully added services(s): zcash-hackworks/insight-api-zcash, zcash-hackworks/insight-ui-zcash&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Finally we can start with the following command:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;/home/zcashd/zc/node_modules/bitcore-node-zcash/bin/bitcore-node start
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;If all works after a few seconds you’ll see output similar to the below indicating that the node is syncing and you can browse to your IP and port listed above e.g. &lt;code class=&quot;highlighter-rouge&quot;&gt;localhost:3001&lt;/code&gt; and, while the explorer will not be functional until the sync completes, it will display the progress.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;/home/zcashd/zc/node_modules/bitcore-node-zcash/bin/bitcore-node start
&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;2019-08-11T01:27:58.376Z] info: Using config: /home/zcashd/zc/bitcore-node.json
&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;2019-08-11T01:27:58.377Z] info: Using network: testnet
&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;2019-08-11T01:28:03.956Z] info: ZMQ connected to: tcp://127.0.0.1:28332
&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;2019-08-11T01:28:18.496Z] info: Zcash Height: 133 Percentage: 0.01
&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;2019-08-11T01:28:33.500Z] info: Zcash Height: 241 Percentage: 0.02
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;As we started this in the foreground, closing your terminal without detaching it will kill the process. Therefore it is recommended you set it up to &lt;a href=&quot;https://www.axllent.org/docs/view/nodejs-service-with-systemd/&quot;&gt;run as a service&lt;/a&gt; or at a minimum detach the process from the terminal with an application such as &lt;a href=&quot;https://www.gnu.org/software/screen/manual/screen.html&quot;&gt;screen&lt;/a&gt; or &lt;a href=&quot;https://linux.die.net/man/1/nohup&quot;&gt;nohup&lt;/a&gt;.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;nohup /home/zcashd/zc/node_modules/bitcore-node-zcash/bin/bitcore-node start &amp;gt; explorer.log 2&amp;gt;&amp;amp;1 &amp;amp;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;The above example redirects the output to a file named &lt;code class=&quot;highlighter-rouge&quot;&gt;explorer.log&lt;/code&gt; so to follow the output logs use &lt;code class=&quot;highlighter-rouge&quot;&gt;tail -f explorer.log&lt;/code&gt;.&lt;/p&gt;

&lt;h3 id=&quot;running-on-mainnet&quot;&gt;Running on mainnet&lt;/h3&gt;
&lt;p&gt;If you wish to run on mainnet (or livenet in bitcore parlance), you’ll need to update &lt;code class=&quot;highlighter-rouge&quot;&gt;zcash.conf&lt;/code&gt; to the below and optionally updating the RPC port.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;testnet&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;0 
&lt;span class=&quot;nv&quot;&gt;addnode&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;mainnet.z.cash
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Finally update &lt;code class=&quot;highlighter-rouge&quot;&gt;var testnet = true;&lt;/code&gt; in 
&lt;code class=&quot;highlighter-rouge&quot;&gt;/home/zcashd/zc/node_modules/insight-ui-zcash/public/src/js/app.js&lt;/code&gt; and stop and restart the process.&lt;/p&gt;

&lt;h2 id=&quot;making-the-explorer-publically-available&quot;&gt;Making the explorer publically available&lt;/h2&gt;
&lt;p&gt;If you are running a local instance, you can access your explorer via &lt;code class=&quot;highlighter-rouge&quot;&gt;localhost:3001&lt;/code&gt;, and wait for your node to fully sync for the explorer to function currectly. If on a public IP you can also get access via &lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;lt;your_ip_address:3001&amp;gt;&lt;/code&gt; if your firewall permits access to that port.&lt;/p&gt;

&lt;p&gt;Let’s quickly add to our build to use NGINX to map port 443 to 3001 as a &lt;a href=&quot;https://www.linode.com/docs/web-servers/nginx/use-nginx-reverse-proxy/&quot;&gt;reverse proxy&lt;/a&gt; and add a free &lt;a href=&quot;https://letsencrypt.org/&quot;&gt;Let’s Encrypt certificate&lt;/a&gt;. You’ll need a domain name that has its DNS pointed to the instance IP such as &lt;code class=&quot;highlighter-rouge&quot;&gt;explorer.mydomainname.com&lt;/code&gt;.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;sudo apt install nginx
sudo systemctl start nginx
sudo systemctl &lt;span class=&quot;nb&quot;&gt;enable &lt;/span&gt;nginx &lt;span class=&quot;c&quot;&gt;# optionally enable NGINX as a service&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;At which point you should be able to browse to &lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;lt;your_ip_address&amp;gt;&lt;/code&gt; and see the default NGINX screen. Next, follow the &lt;a href=&quot;https://certbot.eff.org/lets-encrypt/ubuntubionic-nginx.html&quot;&gt;instructions&lt;/a&gt; to add the &lt;a href=&quot;https://certbot.eff.org/lets-encrypt/ubuntubionic-nginx.html&quot;&gt;Certbot PPA&lt;/a&gt; and install Certbot:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;sudo apt-get -y install certbot python-certbot-nginx
sudo certbot --nginx
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Follow the command prompts, enter your domain name for the certificate request, e.g. &lt;code class=&quot;highlighter-rouge&quot;&gt;explorer.mydomainname.com&lt;/code&gt; and choose the option (2) to redirect all traffic to HTTPS. Then edit the default site to pass all traffic through to port 3001.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nb&quot;&gt;cd&lt;/span&gt; /etc/nginx/sites-available
sudo nano default
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Update the &lt;code class=&quot;highlighter-rouge&quot;&gt;location&lt;/code&gt; of the &lt;code class=&quot;highlighter-rouge&quot;&gt;server&lt;/code&gt; block for your domain name to match the below:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;location / &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
                proxy_pass http://localhost:3001/;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Finally, reload NGINX, and your site should be accessible on your domain name and served over HTTPS. While this will work for a low traffic hosted explorer, it would not be recommended for a production instance and never use the instance as a wallet to store actual funds.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;sudo nginx -s reload
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;&lt;img src=&quot;https://garethtdavies-uploads.s3.us-east-1.amazonaws.com/zcash-insight-lets-encrypt.png&quot; alt=&quot;Insight explorer running on custom domain with Let's Encrypt cert&quot; title=&quot;Insight explorer running on custom domain with Let's Encrypt cert&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;examining-transactions&quot;&gt;Examining Transactions&lt;/h2&gt;
&lt;p&gt;Zcash is best known for its &lt;a href=&quot;https://electriccoin.co/blog/anatomy-of-zcash/&quot;&gt;shielded transactions&lt;/a&gt; in which transaction details are not visible on the blockchain. Let’s explore this by examining a fully shielded transaction such as &lt;a href=&quot;https://explorer.testnet.z.cash/tx/5328354a0b14c95b1f8ac26ec99c7b365638cd877a04aa3fb27d19deedc90fb7&quot;&gt;this transaction&lt;/a&gt; via the Insight explorer.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://garethtdavies-uploads.s3.us-east-1.amazonaws.com/zcash-insight-shielded-tx.png&quot; alt=&quot;Fully shielded transaction on the Insight explorer&quot; title=&quot;Fully shielded transaction on the Insight explorer&quot; /&gt;&lt;/p&gt;

&lt;p&gt;As we can see, the only detail available for this fully shielded Sapling transaction is the number of shielded inputs (similar to UTXOs in Bitcoin but known as notes in Zcash) and the number of shielded outputs.&lt;/p&gt;

&lt;p&gt;All of this data is also available on the zcashd instance and we can examine the raw transaction data using the following commands:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;~/zcash/src/zcash-cli getrawtransaction 5328354a0b14c95b1f8ac26ec99c7b365638cd877a04aa3fb27d19deedc90fb7
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;This will output the transaction in hex format. You can decode this by passing the output into the following command:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;~/zcash/src/zcash-cli decoderawtransaction &amp;lt;output of previous &lt;span class=&quot;nb&quot;&gt;command&lt;/span&gt;&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;This will output the &lt;a href=&quot;https://gist.github.com/garethtdavies/dbfa1d04982d908e317e46a70fa90c87&quot;&gt;full transaction detail&lt;/a&gt; that you can compare to the explorer output. There are also &lt;a href=&quot;https://zcash.readthedocs.io/en/latest/rtd_pages/insight_explorer.html&quot;&gt;additional RPC methods&lt;/a&gt; such as to get the address balance, which were not previously available and allow for additional functionality.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;./zcash/src/zcash-cli getaddressbalance &lt;span class=&quot;s1&quot;&gt;'&quot;tmYXBYJj1K7vhejSec5osXK2QsGa5MTisUQ&quot;'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
</description>
        <pubDate>Sun, 11 Aug 2019 12:00:00 +0000</pubDate>
        <link>https://garethtdavies.com/crypto/zcash-insight-blockchain-explorer.html</link>
        <guid isPermaLink="true">https://garethtdavies.com/crypto/zcash-insight-blockchain-explorer.html</guid>
        
        <category>zcash</category>
        
        
        <category>crypto</category>
        
      </item>
    
  </channel>
</rss>
