<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Cassidy Mountjoy</title>
    <description>The latest articles on DEV Community by Cassidy Mountjoy (@cassidymountjoy).</description>
    <link>https://dev.to/cassidymountjoy</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F687722%2F0853b7d1-88ac-4b80-bdc0-fd662d9c24b4.png</url>
      <title>DEV Community: Cassidy Mountjoy</title>
      <link>https://dev.to/cassidymountjoy</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/cassidymountjoy"/>
    <language>en</language>
    <item>
      <title>Immutable File Storage</title>
      <dc:creator>Cassidy Mountjoy</dc:creator>
      <pubDate>Thu, 07 Apr 2022 19:07:13 +0000</pubDate>
      <link>https://dev.to/cassidymountjoy/immutable-file-storage-4lk</link>
      <guid>https://dev.to/cassidymountjoy/immutable-file-storage-4lk</guid>
      <description>&lt;p&gt;&lt;strong&gt;Sensitive files should be stored immutably.&lt;/strong&gt; This seems like a no brainer, but why isn't it being implemented in modern applications?&lt;/p&gt;

&lt;p&gt;I think that many developers are turning to Blockchain technology to solve security problems. Momentum for projects is then soon slowed by the steep learning curve and cost of operating blockchain transactions.&lt;/p&gt;

&lt;p&gt;By improving the security of traditional technologies, such as databases, developers can continue using a familiar stack. Immutable databases are great for storing sensitive files. Using the &lt;a href="https://bsql.org/docs/overview"&gt;bSQL&lt;/a&gt; language you can easily store immutable files. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Immutable data is stored in "pen" not "pencil" and you wouldn't sign a contract in pencil.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Demonstration
&lt;/h2&gt;

&lt;p&gt;This post will demonstrate how to set up immutable file storage in bSQL using &lt;code&gt;Node&lt;/code&gt;. The full code can be found on &lt;a href="https://github.com/blockpointSystems/bsql-file-storage"&gt;GitHub&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;Let’s define the basic workflow of our example application.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Store a file with a description in the database.&lt;/li&gt;
&lt;li&gt;Confirm the file hasn't been illicitly modified.&lt;/li&gt;
&lt;li&gt;Export the file from the DB and read the file and its corresponding description.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Disclamer:&lt;/em&gt; I am relatively new to &lt;code&gt;Node&lt;/code&gt; feel free to make comments and suggestions to help me improve the code.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting Up the Database
&lt;/h2&gt;

&lt;p&gt;In order to store files immutably, you'll need an immutable database. The bSQL community slack channel gives you direct access to engineers to help you get set up, by joining the &lt;a href="https://join.slack.com/t/bsqlcommunity/shared_invite/zt-169oaigpu-R3W1D5_vc6OyNnKy4thNoA"&gt;slack&lt;/a&gt; you'll receive an access code for a free bSQL instance.&lt;/p&gt;

&lt;h2&gt;
  
  
  Establishing the connection
&lt;/h2&gt;

&lt;p&gt;We will be working with the database directly. In order to do so we will need the &lt;a href="https://github.com/blockpointSystems/mdb-odbc-nodejs"&gt;node connector&lt;/a&gt;. The current version is &lt;code&gt;3.20.0&lt;/code&gt;, but you should install the latest. The package requires protobuf, so if you are installing manually you will need to run &lt;code&gt;npm install google-protobuf grpc&lt;/code&gt; &lt;strong&gt;AND&lt;/strong&gt; &lt;code&gt;npm install mdb-server&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Now you can import the package.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;mdb&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;mdb-server&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And establish the connection:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;conn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;mdb&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;CreateConnection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;username&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;your_username&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;password&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;your_password&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;serverAddress&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;0.0.0.0&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;serverPort&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;5461&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;databaseName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;master&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;parameters&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Map&lt;/span&gt;&lt;span class="p"&gt;([[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;interpolateParams&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;]])&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;// Connect to the database&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;conn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Building the Containers
&lt;/h2&gt;

&lt;p&gt;In order to store a description and its corresponding file, we &lt;a href="https://bsql.org/docs/database/create-database"&gt;create a new database&lt;/a&gt; and blockchain to link our descriptions to our files.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;conn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exec&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`CREATE DATABASE &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;dbName&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In bSQL blockchains are like sql tables. There are many different blockchain types, we will be using a &lt;code&gt;HISTORICAL PLUS&lt;/code&gt;. The blockchain created by the &lt;a href="https://bsql.org/docs/management/create-blockchain"&gt;CREATE BLOCKHAIN&lt;/a&gt; command will have the following columns:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;id&lt;/strong&gt; is a primary key that is incremented after each insertion.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;file_id&lt;/strong&gt; references the corresponding file stored in the file store.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;description&lt;/strong&gt; is a packed string that describes the file.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;conn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exec&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`CREATE BLOCKCHAIN &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;dbName&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;.&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;blockchainName&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; HISTORICAL PLUS (
        id UINT64 AUTO INCREMENT PRIMARY,
        file_id UINT64 FOREIGN KEY [document_store.sys_file, sys_file_id],
        description STRING PACKED)`&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Store the local file in the database
&lt;/h2&gt;

&lt;p&gt;bSQL has built in file storage. This makes it very easy to store files. There is no way to delete or update an existing file once it's stored. This ensures that centralized authorities can't illicitly modify sensitive documents.&lt;/p&gt;

&lt;p&gt;This command stores the file &lt;code&gt;blockpoint.png&lt;/code&gt; located in the &lt;code&gt;app&lt;/code&gt; directory. It uses the response to store the &lt;code&gt;file_id&lt;/code&gt; and a &lt;code&gt;despcription&lt;/code&gt; in the reference table.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;resp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;conn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;storeFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;imageName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;app/blockpoint.png&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;png&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;conn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exec&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`INSERT &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;dbName&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;.&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;blockchainName&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; (file_id, description) VALUES 
    (?, ?)`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getLastInsertId&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="nx"&gt;description&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Check the validity of the database
&lt;/h2&gt;

&lt;p&gt;Data in bSQL is hashed and linked together. We can check the recompute hashes and compare them to the hashes stored on insertion by running &lt;a href="https://bsql.org/docs/database/check-validity"&gt;CHECK VALIDITY&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;resp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;conn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exec&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;CHECK VALIDITY&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Export the file and save it to a local directory
&lt;/h2&gt;

&lt;p&gt;Exporting the file is a two-step process. The file will be saved to &lt;code&gt;app/exports/out_image.png&lt;/code&gt; when &lt;code&gt;resp.saveFile()&lt;/code&gt; is called.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;resp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;conn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exportFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;imageName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;app/exports/out_image.png&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;png&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;saveFile&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  File Versioning
&lt;/h2&gt;

&lt;p&gt;If there was an amendment to a document, how could we extend this application to update the file?&lt;/p&gt;

&lt;p&gt;Use cases:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Building Codes&lt;/li&gt;
&lt;li&gt;KYC documents&lt;/li&gt;
&lt;li&gt;Legal Contracts&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You could simply store the new file, run an &lt;a href="https://bsql.org/docs/mutations/amend"&gt;AMEND&lt;/a&gt; statement of the reference blockchain. This would give you access to the new version and the previous version as well.&lt;/p&gt;

&lt;p&gt;How would I access the previous version?&lt;br&gt;
We can set a database session to work with a previous version of the database. I recommend checking out &lt;a href="https://dev.to/cassidymountjoy/hindsight-20-20-querying-any-point-in-time-2noi"&gt;SET TRANSACTION QUERY TIME&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>database</category>
      <category>programming</category>
      <category>sql</category>
      <category>node</category>
    </item>
    <item>
      <title>Connecting bSQL to Tableau!</title>
      <dc:creator>Cassidy Mountjoy</dc:creator>
      <pubDate>Wed, 30 Mar 2022 15:17:49 +0000</pubDate>
      <link>https://dev.to/cassidymountjoy/connecting-bsql-to-tableau-2oei</link>
      <guid>https://dev.to/cassidymountjoy/connecting-bsql-to-tableau-2oei</guid>
      <description>&lt;p&gt;One of the advantages of the &lt;a href="https://bsql.org/" rel="noopener noreferrer"&gt;bSQL&lt;/a&gt; language is that it's both immutable relational. Other ledger database technologies are modifications on document storage. While they may be "SQL compliant" to some degree, these implementations are non-native and lack complex query features and optimization. &lt;/p&gt;

&lt;p&gt;SQL-based technologies, such as Tableau, use SQL to query data. There is immense value in using live database connections. I'll be going over how to connect a bSQL instance to Tableau.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pre-requisites:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://www.tableau.com/products/trial/desktop" rel="noopener noreferrer"&gt;Tableau Desktop&lt;/a&gt; &amp;gt; 2020.4&lt;/li&gt;
&lt;li&gt;A bSQL instance (instructions &lt;a href="https://dev.to/cassidymountjoy/how-to-create-a-database-and-blockchain-in-bsql-hbi"&gt;here&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Download the JDB Driver
&lt;/h2&gt;

&lt;p&gt;The bSQL JDBC driver can be found on the Maven Central Repository &lt;a href="https://search.maven.org/search?q=g:com.blockpointdb" rel="noopener noreferrer"&gt;here&lt;/a&gt;. You will need to download the latest version as a &lt;code&gt;.jar&lt;/code&gt; file.&lt;/p&gt;

&lt;h2&gt;
  
  
  Download the &lt;code&gt;.taco&lt;/code&gt; custom connector
&lt;/h2&gt;

&lt;p&gt;In order to connect your &lt;code&gt;bSQL&lt;/code&gt; instance to Tableau you need the &lt;code&gt;bsql_jdbc&lt;/code&gt; connector. This connector allows for live communication between your bSQL instance and Tableau Desktop. It can be downloaded from the bSQL &lt;a href="https://bsql.org/docs/connecting/bsql-taco" rel="noopener noreferrer"&gt;documentation&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Configuring Tableau Desktop
&lt;/h2&gt;

&lt;p&gt;Tableau desktop can be configured to use custom connectors.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Copy the connector you downloaded into your &lt;code&gt;My Tableau Repository/Connectors&lt;/code&gt; directory.&lt;/li&gt;
&lt;li&gt;Place the .jar file in the folder for your operating system. 

&lt;ul&gt;
&lt;li&gt;Windows: C:\Program Files\Tableau\Drivers&lt;/li&gt;
&lt;li&gt;Mac: ~/Library/Tableau/Drivers&lt;/li&gt;
&lt;li&gt;Linux: /opt/tableau/tableau_driver/jdbc&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h2&gt;
  
  
  Ready to connect
&lt;/h2&gt;

&lt;p&gt;Now when you start Tableau Desktop there should be an option for bSQL: &lt;code&gt;bsql_jdbc&lt;/code&gt;. If the option doesn't show up, double check the file path in which you placed the connector.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Feemwcfi0hx4kpo60gfb0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Feemwcfi0hx4kpo60gfb0.png" alt="bSQL tableau connector"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After choosing the connector, this should open the connection dialogue. From here you can specify the bSQL instance you wish to connect to.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fws97c8tg64qp8u1x6s26.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fws97c8tg64qp8u1x6s26.png" alt="bSQL connection dialogue"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Continuations
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;In the &lt;code&gt;run initial SQL&lt;/code&gt; pane you can add bSQL specific features such as setting the state of the database you want to work by using &lt;a href="https://dev.to/cassidymountjoy/hindsight-20-20-querying-any-point-in-time-2noi"&gt;SET TRANSACTION QUERY TIME&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Using the &lt;code&gt;New Custom SQL&lt;/code&gt; we can generate views on lifetime attributes of tables. For instance, creating.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>database</category>
      <category>datascience</category>
      <category>analytics</category>
      <category>programming</category>
    </item>
    <item>
      <title>Streaming Ethereum Blocks Into bSQL Using Infura and Python</title>
      <dc:creator>Cassidy Mountjoy</dc:creator>
      <pubDate>Wed, 10 Nov 2021 02:05:54 +0000</pubDate>
      <link>https://dev.to/cassidymountjoy/streaming-ethereum-blocks-into-bsql-using-infura-and-python-3dl4</link>
      <guid>https://dev.to/cassidymountjoy/streaming-ethereum-blocks-into-bsql-using-infura-and-python-3dl4</guid>
      <description>&lt;h2&gt;
  
  
  Overview
&lt;/h2&gt;

&lt;p&gt;Blockchain data is secure and tamper proof, but when working with blockchain data in a more traditional environment, let's say a conventional database, it becomes harder to extend these guarantees. Can data be trusted after it has left the blockchain? &lt;/p&gt;

&lt;p&gt;By using a less traditional form of DBMS, an immutable database, we can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Verify that data hasn't been illicitly changed&lt;/li&gt;
&lt;li&gt;Track all changes made to the system&lt;/li&gt;
&lt;li&gt;Easily access old versions of the system&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In this tutorial I will be using &lt;a href="https://blockpointdb.com/" rel="noopener noreferrer"&gt;Blockpoint's&lt;/a&gt; &lt;a href="https://bsql.org/docs/overview" rel="noopener noreferrer"&gt;bSQL&lt;/a&gt;, because it's immutable, relational, structured, and has a rich language. The bSQL storage structure is actually very similar to that of a blockchain in that data pages are hashed and linked together. Data is added, never deleted:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxamso68qnvdo5qdyyvby.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxamso68qnvdo5qdyyvby.png" alt="bSQL data pages"&gt;&lt;/a&gt; &lt;/p&gt;




&lt;h1&gt;
  
  
  Let's Stream Some Ethereum Blocks
&lt;/h1&gt;

&lt;p&gt;We will be using an Infura free trial to access the Ethereum network, Python to filter for new blocks, and bSQL to store blockchain data. In order to do so we will:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Sign up for a free Infura account and obtain an Ethereum endpoint.&lt;/li&gt;
&lt;li&gt;Create a bSQL account and deploy a free instance.&lt;/li&gt;
&lt;li&gt;Write a python script and start streaming Ethereum blocks to the database.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;At any time you can reference the public &lt;a href="https://github.com/blockpointSystems/bsql_eth" rel="noopener noreferrer"&gt;repo&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Setting up Infura
&lt;/h2&gt;

&lt;p&gt;Register for a free Infura account &lt;a href="https://infura.io/" rel="noopener noreferrer"&gt;here&lt;/a&gt;. This will give you access to 100,000 Requests/Day, which is plenty given that this is just a demonstration.&lt;/p&gt;

&lt;p&gt;Once you've set up your Infura account, you can access your project ID, it will be needed to connect to Infura using an endpoint and can be found under your project name.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F14u7q2j5rt3kyog5lx46.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F14u7q2j5rt3kyog5lx46.png" alt="Infura ID"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The endpoint for accessing the data will resemble the following:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;https://mainnet.infura.io/v3/your_project_id&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;We will use this endpoint when we set up our python application.&lt;/p&gt;




&lt;h2&gt;
  
  
  Deploying a bSQL instance
&lt;/h2&gt;

&lt;p&gt;The next step is to set up our bSQL instance by:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Deploying a database using the Blockpoint Portal&lt;/li&gt;
&lt;li&gt;Opening the instance in the IDE&lt;/li&gt;
&lt;li&gt;Creating a database and a blockchain&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In order to create a bSQL account you will need an a unique access token, you can get your access token by messaging me directly or joining the &lt;a href="https://join.slack.com/t/bsqlcommunity/shared_invite/zt-169oaigpu-R3W1D5_vc6OyNnKy4thNoA" rel="noopener noreferrer"&gt;slack&lt;/a&gt;, it's free!&lt;/p&gt;

&lt;p&gt;1.) The tutorial for creating an account and deploying your first instance can be found &lt;a href="https://www.youtube.com/watch?v=Em8b5qXcQew&amp;amp;list=PLdRS5wHN77gWuG71IvaH4pX7IdfZYGd06" rel="noopener noreferrer"&gt;here&lt;/a&gt;. Once completed, a new instance should appear on the blockpoint portal home page.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr0bqpmlohjwq03e9ruz2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr0bqpmlohjwq03e9ruz2.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;2.) Once created, navigate to the home page. To open the IDE, click "Open in IDE" and, when prompted, provide your database credentials.&lt;/p&gt;

&lt;p&gt;3.) Finally we are going to run a few bSQL commands to finish our set up.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;a.&lt;/strong&gt; Create a new database called "eth" by running &lt;code&gt;CREATE &lt;br&gt;
DATABASE eth;&lt;/code&gt; &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;b.&lt;/strong&gt; Interact with the newly created database by running &lt;code&gt;USE &lt;br&gt;
eth;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Next, we are going to want to configure a single blockchain for capturing Ethereum data. A blockchain is a structured container for storing data in bSQL. Once data has been added to the system, it cannot be removed. For a more comprehensive overview on the blockchain structure read the documentation &lt;a href="https://bsql.org/docs/blockchain-overview" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;For the sake of keeping this tutorial simple, we are going to use a single &lt;em&gt;blockchain&lt;/em&gt; called &lt;strong&gt;blocks&lt;/strong&gt; to track new blocks added to the Ethereum network. Using a &lt;em&gt;historical blockchain&lt;/em&gt; we can enforce immutability and check data integrity. Deploy the blockchain by running the following command in the IDE.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CREATE BLOCKCHAIN blocks HISTORICAL (
     time TIMESTAMP,
     number UINT64,
     hash STRING SIZE=66,
     parent_hash STRING SIZE=66,
     nonce STRING SIZE=42,
     sha3_uncles STRING SIZE=66,
     logs_bloom STRING PACKED SIZE=18000,
     transactions_root STRING SIZE=66,
     state_root STRING SIZE=66,
     receipts_root STRING SIZE=66,
     miner STRING SIZE=42,
     difficulty FLOAT64,
     size_of_block INT64,
     extra_data STRING PACKED,
     gas_limit INT64,
     transaction_count INT64,
     base_fee_per_gas INT64
);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Congrats on building your first bSQL blockchain! Now let's start adding data.&lt;/p&gt;




&lt;h2&gt;
  
  
  Setting up your python application.
&lt;/h2&gt;

&lt;p&gt;In order to set up your python applet you will need the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Python downloaded and installed on your computer, I'm using python 3.9.&lt;/li&gt;
&lt;li&gt;A python IDE, I'm using &lt;a href="https://www.jetbrains.com/pycharm/" rel="noopener noreferrer"&gt;Pycharm&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://web3py.readthedocs.io/en/stable/" rel="noopener noreferrer"&gt;web3&lt;/a&gt; for python&lt;/li&gt;
&lt;li&gt;The bSQL &lt;a href="https://bsql.org/docs/connecting/python-odbc" rel="noopener noreferrer"&gt;python bSQL database driver&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Once the follow criteria are met, you can set up a main.py file in your project directory. The code is on &lt;a href="https://github.com/blockpointSystems/bsql_ethk" rel="noopener noreferrer"&gt;Github&lt;/a&gt; although it will not work until the above criteria is met and you have deployed an instance.&lt;/p&gt;

&lt;h2&gt;
  
  
  Connecting to Infura and bSQL
&lt;/h2&gt;

&lt;p&gt;The first step in our code is to define our connections. You will need to fill out the following fields:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;your Infura project id&lt;/li&gt;
&lt;li&gt;your bSQL username, password and public IP address
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;infru&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://mainnet.infura.io/v3/your_project_id&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="c1"&gt;#change me
&lt;/span&gt;&lt;span class="n"&gt;web3&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Web3&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Web3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;HTTPProvider&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;infru&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="n"&gt;conn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;mdb_bp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;username&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;your username&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;#change me
&lt;/span&gt;    &lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;your password&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;#change me
&lt;/span&gt;    &lt;span class="n"&gt;connection_protocol&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;tcp&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;server_address&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;server address&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;#change me
&lt;/span&gt;    &lt;span class="n"&gt;server_port&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;5461&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;database_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;eth&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;parameters&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;interpolateParams&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Defining our main method
&lt;/h2&gt;

&lt;p&gt;The main method defines a filter for the latest Ethereum block and passes it into our loop that we will define next.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="n"&gt;block_filter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;web3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;eth&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;latest&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;loop&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;asyncio&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get_event_loop&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;loop&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run_until_complete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="n"&gt;asyncio&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;gather&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                &lt;span class="nf"&gt;log_loop&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;block_filter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
    &lt;span class="k"&gt;finally&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="c1"&gt;# close loop to free up system resources
&lt;/span&gt;        &lt;span class="n"&gt;loop&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;close&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;__main__&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Defining our Loop
&lt;/h2&gt;

&lt;p&gt;Our loop sleeps for a desired interval, then attempts to pull new entries from the event filter. Every time a new entry is received the event is handled in the &lt;code&gt;handle_event&lt;/code&gt; function.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;log_loop&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;event_filter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;poll_interval&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;PairCreated&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;event_filter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get_new_entries&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
            &lt;span class="nf"&gt;handle_event&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;web3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;eth&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get_block&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;PairCreated&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;asyncio&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;poll_interval&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Defining our Event Handling
&lt;/h2&gt;

&lt;p&gt;Time for the database call. Every time a new block is added to the chain, we print to the console and send an insertion statement to the database, inserting block data into &lt;strong&gt;blocks&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;handle_event&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;block&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;block&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;number&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;exec&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;INSERT blocks VALUES (&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
              &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nf"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;datetime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;datetime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;utcfromtimestamp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;block&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;timestamp&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]))&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
              &lt;span class="nf"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;block&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;number&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
              &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nf"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;block&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;hash&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;hex&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
              &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nf"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;block&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;parentHash&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;hex&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
              &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nf"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;block&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;nonce&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;hex&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
              &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nf"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;block&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;sha3Uncles&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;hex&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
              &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nf"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;block&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;logsBloom&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;hex&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
              &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nf"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;block&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;transactionsRoot&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;hex&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
              &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nf"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;block&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;stateRoot&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;hex&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
              &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nf"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;block&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;receiptsRoot&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;hex&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
              &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nf"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;block&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;miner&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
              &lt;span class="nf"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;block&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;difficulty&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
              &lt;span class="nf"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;block&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;size&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
              &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nf"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;block&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;extraData&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;hex&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
              &lt;span class="nf"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;block&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;gasLimit&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
              &lt;span class="nf"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;block&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;transactions&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]))&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
              &lt;span class="nf"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;block&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;baseFeePerGas&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;)&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And that's all the code needed, so give that baby a run.&lt;/p&gt;

&lt;h2&gt;
  
  
  Putting it all together
&lt;/h2&gt;

&lt;p&gt;After letting my program run for about an hour, I stopped my script and started to do a little data exploration.&lt;/p&gt;

&lt;p&gt;I ran a few queries in the bSQL portal and included them in the &lt;a href="https://github.com/blockpointSystems/bsql_eth/blob/master/example_queries.bsql" rel="noopener noreferrer"&gt;repo&lt;/a&gt;. You can load this file into the bSQL IDE or write your own queries.&lt;/p&gt;

&lt;p&gt;Here's what I came up with:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F14vqezy5f7q2hsdegliu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F14vqezy5f7q2hsdegliu.png" alt="bSQL example queries"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;There you have it. A fun little script for Ethereum data. There is definitely more to explore when it comes to how the data is pulled and even more queries to write.&lt;/p&gt;

&lt;p&gt;Like always, please comment your feedback or any questions you may have.  &lt;/p&gt;

</description>
      <category>blockchain</category>
      <category>python</category>
      <category>database</category>
      <category>web3</category>
    </item>
    <item>
      <title>Building a Smart Contract Application Using bSQL and Daml</title>
      <dc:creator>Cassidy Mountjoy</dc:creator>
      <pubDate>Mon, 11 Oct 2021 16:42:41 +0000</pubDate>
      <link>https://dev.to/cassidymountjoy/building-a-smart-contract-application-using-bsql-and-daml-3o00</link>
      <guid>https://dev.to/cassidymountjoy/building-a-smart-contract-application-using-bsql-and-daml-3o00</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;In this tutorial will demonstrate how to integrate bSQL into an example Daml application. Once set up, data will be sent from the &lt;a href="https://docs.daml.com/app-dev/bindings-java/quickstart.html" rel="noopener noreferrer"&gt;Daml quick-start application&lt;/a&gt; to a bSQL instance in a cloud environment. By querying data from our bSQL instance we can observe contract flow and execution.&lt;/p&gt;

&lt;h2&gt;
  
  
  Background
&lt;/h2&gt;

&lt;p&gt;The Daml environment ensures immutability, but once data exits this environment to, let's say, an analytics database, how do we extend these guarantees?&lt;br&gt;
&lt;a href="https://bsql.org/" rel="noopener noreferrer"&gt;bSQL&lt;/a&gt; stores data immutably. This means that existing data cannot be deleted or updated, instead only new versions are added to the system. This logic aligns with the Daml ledger model. When an action is performed on a contract, the old contract persists, and a new contract takes its place. The bSQL programming language allows us to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Prove that the data hasn't been changed.&lt;/li&gt;
&lt;li&gt;Run optimized queries from structured, immutable data.&lt;/li&gt;
&lt;li&gt;Easily compare database versions and move through time effortlessly.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Application Overview
&lt;/h2&gt;

&lt;p&gt;We will be using the Daml quick-start tutorial to set up a basic application through the following steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Deploy the sample IOU Daml application&lt;/li&gt;
&lt;li&gt;Configure a bSQL instance&lt;/li&gt;
&lt;li&gt;Connect the database to the application using JDBC
4. Work in the UI to populate our database&lt;/li&gt;
&lt;li&gt;Run queries on immutable data&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F805nchyinv7g49eylu2n.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F805nchyinv7g49eylu2n.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Deploying the DAML quick-start application
&lt;/h2&gt;

&lt;p&gt;In order to complete this tutorial there are a few prerequisites:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://maven.apache.org/download.cgi" rel="noopener noreferrer"&gt;Apache Maven&lt;/a&gt; and the &lt;a href="https://www.oracle.com/java/technologies/javase/javase-jdk8-downloads.html" rel="noopener noreferrer"&gt;Java JDK&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;A good JAVA IDEA, I used &lt;a href="https://www.jetbrains.com/idea/" rel="noopener noreferrer"&gt;IntelliJ&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Knowledge of the Daml model and application structure.&lt;/li&gt;
&lt;li&gt;The Daml &lt;a href="https://docs.daml.com/getting-started/installation.html" rel="noopener noreferrer"&gt;SDK&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;After installing, set up the quick-start application by reading the tutorial or by running the following in your command line: &lt;code&gt;daml new quickstart --template quickstart-java&lt;/code&gt;. This command generates a new quick-start application. As a third option, pull the &lt;a href="https://github.com/blockpointSystems/daml-quickstart-bsql" rel="noopener noreferrer"&gt;source code&lt;/a&gt;, however you will still need to deploy a bSQL instance and modify the connection parameters appropriately.&lt;/p&gt;

&lt;p&gt;We will be mostly working in &lt;code&gt;IouMain.java&lt;/code&gt; and make changes to &lt;code&gt;pom.xml&lt;/code&gt; to resolve conflicts.&lt;/p&gt;


&lt;h2&gt;
  
  
  Deploying a bSQL instance
&lt;/h2&gt;

&lt;p&gt;The next step is to deploy and set up our bSQL instance by:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Deploying a database using the Blockpoint Portal&lt;/li&gt;
&lt;li&gt;Opening the instance in the IDE&lt;/li&gt;
&lt;li&gt;Creating a database and a blockchain&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;1.) The tutorial for deploying your first instance can be found &lt;a href="https://www.youtube.com/watch?v=Em8b5qXcQew&amp;amp;list=PLdRS5wHN77gWuG71IvaH4pX7IdfZYGd06" rel="noopener noreferrer"&gt;here&lt;/a&gt;. Once completed, a new instance should appear on the blockpoint portal home page.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr0bqpmlohjwq03e9ruz2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr0bqpmlohjwq03e9ruz2.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;2.) Once created, navigate to the home page. To open the IDE, click "Open in IDE" and, when prompted, provide your database credentials.&lt;/p&gt;

&lt;p&gt;3.) Finally we are going to run a few bSQL commands to finish our set up.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;a.&lt;/strong&gt; Create a new database called "iou" by running &lt;code&gt;CREATE &lt;br&gt;
DATABASE iou;&lt;/code&gt; &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;b.&lt;/strong&gt; Interact with the newly created database by running &lt;code&gt;USE &lt;br&gt;
iou;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Next, we are going to want to configure a single blockchain for capturing contract data. A blockchain is a structured container for storing data in bSQL. Once data has been added to the system, it cannot be removed. For a more comprehensive overview on the blockchain structure read the documentation &lt;a href="https://bsql.org/docs/blockchain-overview" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;For the sake of keeping this tutorial simple, we are going to use a single &lt;em&gt;blockchain&lt;/em&gt; called &lt;strong&gt;contracts&lt;/strong&gt; to track the flow of contracts in the ledger. Using a &lt;em&gt;traditional blockchain&lt;/em&gt; we can track contract versions. Deploy the blockchain by running the following command in the IDE.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CREATE BLOCKCHAIN contracts TRADITIONAL (
     id UINT64 PRIMARY,
     unique_identifier STRING PACKED,
     issuer STRING PACKED,
     owner STRING PACKED,
     currency STRING PACKED,
     amount FLOAT32
);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Connecting the database via JDBC
&lt;/h2&gt;

&lt;p&gt;We are going to use the &lt;a href="https://search.maven.org/artifact/com.blockpointdb/mdb-jdbc/1.0.7/jar" rel="noopener noreferrer"&gt;MDB JDBC&lt;/a&gt; to connect to the database created in the previous step. In order to connect, we must add the JDBC dependency to the &lt;code&gt;pom.xml&lt;/code&gt; file and resolve any conflicting dependencies.&lt;/p&gt;

&lt;p&gt;Only adding the JDBC dependency to the &lt;code&gt;pom.xml&lt;/code&gt; will &lt;strong&gt;not&lt;/strong&gt; work. Because both the Daml Application and the JDBC use different versions of protocol buffers, they must be resolved via the &lt;code&gt;&amp;lt;dependency management&amp;gt;&lt;/code&gt; field in the &lt;code&gt;pom.xml&lt;/code&gt; file. I &lt;strong&gt;highly&lt;/strong&gt; recommend replacing the current &lt;code&gt;pom.xml&lt;/code&gt; file with the example provided instead of doing this manually.&lt;/p&gt;

&lt;p&gt;The current version of the JDBC is &lt;em&gt;1.0.7&lt;/em&gt;,  I recommend using the latest release possible.&lt;/p&gt;




&lt;h2&gt;
  
  
  Connecting to the bSQL client
&lt;/h2&gt;

&lt;p&gt;The next step is defining our connection URL and logic. Define a class &lt;strong&gt;Utils&lt;/strong&gt; by creating a &lt;code&gt;Utils.java&lt;/code&gt; file in the &lt;code&gt;com.daml.quickstart.iou&lt;/code&gt; directory and copying the following code. This class has a single method called &lt;code&gt;connect()&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kn"&gt;package&lt;/span&gt; &lt;span class="nn"&gt;com.daml.quickstart.iou&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.sql.Connection&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.sql.DriverManager&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Utils&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;Connection&lt;/span&gt; &lt;span class="nf"&gt;connect&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;Connection&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;// Remove brackets when specifying info&lt;/span&gt;
            &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;DriverManager&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getConnection&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"jdbc:mdb://{your public bSQL IP address}:5461/iou?user={your bSQL username}&amp;amp;password={your bSQL password}"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Exception&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;printStackTrace&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
            &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;exit&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
        &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"succesfully connected to bSQL!"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt;  &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The connection string on &lt;code&gt;line 9&lt;/code&gt; will be unique to your instance. The following information is needed:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;your public bSQL IP address (this can be found under the "essentials" dropdown above your instance metrics on the home page)&lt;/li&gt;
&lt;li&gt;your username and password&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;After calling the connection method &lt;code&gt;Utils.connect()&lt;/code&gt;; a connection to the database in the instance is returned. This connection can then be used to send data to the &lt;strong&gt;contracts&lt;/strong&gt; blockchain. The rest of the work is done in &lt;code&gt;iouMain.java&lt;/code&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Adding bSQL logic
&lt;/h2&gt;

&lt;p&gt;We will be adding two methods to the &lt;strong&gt;IouMain&lt;/strong&gt; class, the first will be the database logic for adding a contract, the second will be logic for archiving a contract.&lt;/p&gt;

&lt;p&gt;Adding a new contract converts the contract to a simple record, and adds it to the &lt;strong&gt;contracts&lt;/strong&gt; blockchain.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;addContract&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Connection&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Iou&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;Contract&lt;/span&gt; &lt;span class="n"&gt;contract&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Long&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="kd"&gt;throws&lt;/span&gt; &lt;span class="nc"&gt;SQLException&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="nc"&gt;Statement&lt;/span&gt; &lt;span class="n"&gt;stmt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;createStatement&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
            &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;sql&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;format&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
                    &lt;span class="s"&gt;"INSERT iou.contracts VALUES(%d, \"%s\", \"%s\", \"%s\", \"%s\", %f);"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
                    &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
                    &lt;span class="n"&gt;contract&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;contractId&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
                    &lt;span class="n"&gt;contract&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;issuer&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
                    &lt;span class="n"&gt;contract&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;owner&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
                    &lt;span class="n"&gt;contract&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;currency&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
                    &lt;span class="n"&gt;contract&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;amount&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
            &lt;span class="n"&gt;stmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;execute&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sql&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
            &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;commit&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;SQLException&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;printStackTrace&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
            &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;exit&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Lines 195–212 in the &lt;a href="https://github.com/blockpointSystems/daml-quickstart-bsql/blob/master/src/main/java/com/daml/quickstart/iou/IouMain.java" rel="noopener noreferrer"&gt;repo&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Archiving a contract is simple, in order to archive all we have to do is &lt;a href="https://bsql.org/docs/mutations/discontinue" rel="noopener noreferrer"&gt;discontinue&lt;/a&gt; the record from the &lt;strong&gt;contracts&lt;/strong&gt; blockchain.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;archiveContract&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Connection&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;ArchivedEvent&lt;/span&gt; &lt;span class="n"&gt;archivedEvent&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Long&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="kd"&gt;throws&lt;/span&gt; &lt;span class="nc"&gt;SQLException&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;Statement&lt;/span&gt; &lt;span class="n"&gt;stmt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;createStatement&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;sql&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;format&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
            &lt;span class="s"&gt;"DISCONTINUE iou.contracts (id) VALUES (%d)"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;stmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;execute&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sql&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;SQLException&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;printStackTrace&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;exit&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Lines 214–226 in the in the &lt;a href="https://github.com/blockpointSystems/daml-quickstart-bsql/blob/master/src/main/java/com/daml/quickstart/iou/IouMain.java" rel="noopener noreferrer"&gt;repo&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;An important thing to note:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Instead of the traditional SQL statements &lt;em&gt;update&lt;/em&gt; and &lt;em&gt;delete&lt;/em&gt;, bSQL uses the pseudo-mutations &lt;em&gt;amend&lt;/em&gt; and &lt;em&gt;discontinue&lt;/em&gt;. &lt;/li&gt;
&lt;li&gt;Discontinuing a contract in bSQL adds a tombstone record to mark the record as no longer existing. This updates the current state of the &lt;strong&gt;contracts&lt;/strong&gt; blockchain to no longer include the original record, yet the old record will always be accessible in previous states. If this doesn't make sense, move on and see it in action.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Connecting bSQL logic to the application
&lt;/h2&gt;

&lt;p&gt;Now we can use the &lt;strong&gt;Utils&lt;/strong&gt; package we wrote earlier to connect to our bSQL instance. In &lt;code&gt;iouMain.java&lt;/code&gt; at the beginning of the &lt;strong&gt;main&lt;/strong&gt; method, the &lt;em&gt;DamlLedgerClient&lt;/em&gt; is built and the connection is established. The code you need to add is on &lt;em&gt;lines 8–9&lt;/em&gt; in the snippet below. This establishes a connection to the bSQL instance.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Create a client object to access services on the ledger.&lt;/span&gt;
&lt;span class="nc"&gt;DamlLedgerClient&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;DamlLedgerClient&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;newBuilder&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ledgerhost&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ledgerport&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

&lt;span class="c1"&gt;// Connects to the ledger and runs initial validation.&lt;/span&gt;
&lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;connect&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

&lt;span class="c1"&gt;// Establishes a connection to the bSQL instance&lt;/span&gt;
&lt;span class="nc"&gt;Utils&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Utils&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;span class="nc"&gt;Connection&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;connect&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Lines 61–67 in the &lt;a href="https://github.com/blockpointSystems/daml-quickstart-bsql/blob/master/src/main/java/com/daml/quickstart/iou/IouMain.java" rel="noopener noreferrer"&gt;repo&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The next step is to call the &lt;code&gt;addContract&lt;/code&gt; and &lt;code&gt;archiveContract&lt;/code&gt; methods in our application stream, effectively sending information to the bSQL instance every time a contract is added or archived.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If the contract is a created event, we call &lt;code&gt;addContract&lt;/code&gt; after the in-memory maps are updated.&lt;/li&gt;
&lt;li&gt;If the contract is an archived event, we call &lt;code&gt;archiveContract&lt;/code&gt; after the maps are updated.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt; &lt;span class="nc"&gt;Disposable&lt;/span&gt; &lt;span class="n"&gt;ignore&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
        &lt;span class="n"&gt;client&lt;/span&gt;
            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getTransactionsClient&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getTransactions&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;acsOffset&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="o"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;iouFilter&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;forEach&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
                &lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                  &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Event&lt;/span&gt; &lt;span class="n"&gt;event&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getEvents&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;event&lt;/span&gt; &lt;span class="k"&gt;instanceof&lt;/span&gt; &lt;span class="nc"&gt;CreatedEvent&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                      &lt;span class="nc"&gt;CreatedEvent&lt;/span&gt; &lt;span class="n"&gt;createdEvent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;CreatedEvent&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
                      &lt;span class="kt"&gt;long&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;idCounter&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getAndIncrement&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
                      &lt;span class="nc"&gt;Iou&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;Contract&lt;/span&gt; &lt;span class="n"&gt;contract&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Iou&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;Contract&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;fromCreatedEvent&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;createdEvent&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
                      &lt;span class="n"&gt;contracts&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;put&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;contract&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
                      &lt;span class="n"&gt;idMap&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;put&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;contract&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
                      &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                          &lt;span class="n"&gt;addContract&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;contract&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
                      &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Exception&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                          &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;printStackTrace&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
                          &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;exit&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
                      &lt;span class="o"&gt;}&lt;/span&gt;
                    &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;event&lt;/span&gt; &lt;span class="k"&gt;instanceof&lt;/span&gt; &lt;span class="nc"&gt;ArchivedEvent&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                      &lt;span class="nc"&gt;ArchivedEvent&lt;/span&gt; &lt;span class="n"&gt;archivedEvent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;ArchivedEvent&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
                      &lt;span class="kt"&gt;long&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
                          &lt;span class="n"&gt;idMap&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;inverse&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Iou&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ContractId&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;archivedEvent&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getContractId&lt;/span&gt;&lt;span class="o"&gt;()));&lt;/span&gt;
                      &lt;span class="n"&gt;contracts&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;remove&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
                      &lt;span class="n"&gt;idMap&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;remove&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
                      &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                          &lt;span class="n"&gt;archiveContract&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;archivedEvent&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
                      &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;SQLException&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                          &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;printStackTrace&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
                          &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;exit&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
                      &lt;span class="o"&gt;}&lt;/span&gt;
                    &lt;span class="o"&gt;}&lt;/span&gt;
                  &lt;span class="o"&gt;}&lt;/span&gt;
                &lt;span class="o"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Lines 99–132 in the &lt;a href="https://github.com/blockpointSystems/daml-quickstart-bsql/blob/master/src/main/java/com/daml/quickstart/iou/IouMain.java" rel="noopener noreferrer"&gt;repo&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Running the Application
&lt;/h2&gt;

&lt;p&gt;Now that all the logic has been added, we will be running our application and generating data. &lt;br&gt;
Below are the steps for running the application locally as well as the successful responses for reference.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Navigate to the &lt;code&gt;quickstart&lt;/code&gt; directory&lt;/li&gt;
&lt;li&gt;Run &lt;code&gt;daml build&lt;/code&gt; in terminal to generate the .dar file.
&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F61m5o7lcfdo52ukiq3i0.png" alt="image"&gt;
&lt;/li&gt;
&lt;li&gt;Generate java code by running &lt;code&gt;daml codegen java&lt;/code&gt;
&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frkrxsw0whvt6eglq91zu.png" alt="image"&gt;
&lt;/li&gt;
&lt;li&gt;Compile the code using &lt;code&gt;mvn compile&lt;/code&gt;
&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fosuy57wt5fi9zhvxmnve.png" alt="image"&gt;
&lt;/li&gt;
&lt;li&gt;In a separate terminal run &lt;code&gt;daml sandbox .daml/dist/quickstart-0.0.1.dar&lt;/code&gt; to start the the sandbox 
&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbvh1dzda6wi63f7ss6ud.png" alt="image"&gt;
&lt;/li&gt;
&lt;li&gt;In a separate terminal start the java code by running &lt;code&gt;mvn exec:java@run-quickstart&lt;/code&gt;
&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F28ty6apv6wnqvfvz09ch.png" alt="image"&gt;
&lt;/li&gt;
&lt;li&gt;If there was an error and the connection didn't print successfully, check your connection URL in &lt;code&gt;Utils.java&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;In another terminal initialize some contracts by running &lt;code&gt;daml script - dar .daml/dist/quickstart-0.0.1.dar - script-name Main:initialize - ledger-host localhost - ledger-port 6865 - static-time&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;You can then launch the UI by running &lt;code&gt;daml navigator server&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;


&lt;h2&gt;
  
  
  Using the Application
&lt;/h2&gt;

&lt;p&gt;Once the application is running, we will be using the UI on &lt;a href="http://localhost:4000/" rel="noopener noreferrer"&gt;localhost&lt;/a&gt; to generate data. Additionally, we will be using the bSQL IDE to look at the data we generated. To help distinguish between platforms, steps with &lt;strong&gt;N&lt;/strong&gt; refer to using the navigator and steps with &lt;strong&gt;B&lt;/strong&gt; refer to using the bSQL portal.&lt;br&gt;
Create an IOU and begin a transfer.&lt;br&gt;
&lt;strong&gt;1. N:&lt;/strong&gt; Select Alice from the drop down menu&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb1xh2rmnyhvk5vbgxd68.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb1xh2rmnyhvk5vbgxd68.png" alt="image"&gt;&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;2. N:&lt;/strong&gt; Navigate to the &lt;strong&gt;Templates&lt;/strong&gt; page and select the first option &lt;code&gt;Iou:Iou&lt;/code&gt;. Issue yourself one AliceCoin by filling out the template like below and hitting "Submit".&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhdqw9vmu3ywuzv1g4c7e.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhdqw9vmu3ywuzv1g4c7e.png" alt="image"&gt;&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;3. B:&lt;/strong&gt; Once we have chosen to transfer this IOU to Bob, the contract will be archived. When the above contract is discontinued from contracts it no longer appears in the current state. This can be shown by running &lt;code&gt;SELECT * FROM contracts WHERE id = 1;&lt;/code&gt; when no records are returned.&lt;/p&gt;

&lt;p&gt;We can easily access this contract by querying from the lifetime of the contracts blockchain by running &lt;code&gt;SELECT *, sys_timestamp FROM LIFETIME contracts WHERE id = 1;&lt;/code&gt; this provides us with the following records:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvr5815fj2wef6maw8dcu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvr5815fj2wef6maw8dcu.png" alt="image"&gt;&lt;/a&gt;&lt;br&gt;
The first entry is the original contract. The second entry is called a tombstone record, it's used to mark the primary key as no longer existing in the current state. Additionally, since we selected the &lt;code&gt;sys_timestamp&lt;/code&gt; column, a built in column for all blockchains, we can note the time this contract was archived.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;8. N:&lt;/strong&gt; You are now going to switch user to Bob, so you can accept the trades you have just proposed. Start by clicking on the "logout" button next to the username, at the top of the screen. On the login page, select Bob from the dropdown.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;9. N:&lt;/strong&gt; First, accept the transfer of the &lt;em&gt;AliceCoin&lt;/em&gt;. Go to the Iou Transfers page, click on the row of the transfer, and click "IouTransfer_Accept", then "Submit".&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;10. B:&lt;/strong&gt; After logging in as Bob and accepting the IOU transfer for &lt;em&gt;AliceCoin&lt;/em&gt; we can observe the new contract that replaced the archived contract. We can find this contract by reading from the current state by running &lt;code&gt;SELECT * FROM contracts WHERE currency = "AliceCoin";&lt;/code&gt; .&lt;/p&gt;


&lt;h1&gt;
  
  
  What else to run?
&lt;/h1&gt;
&lt;h2&gt;
  
  
  Validating Your Data Hasn't Changed
&lt;/h2&gt;

&lt;p&gt;In bSQL data pages are stored in a blockchain format. They are hashed and linked together. As a database user you can check that the data hasn't been illicitly modified by a bad actor. This can be easily done by checking all data digests - a unique numerical representation of a data page - in the system by running a &lt;a href="https://bsql.org/docs/database/check-validity" rel="noopener noreferrer"&gt;&lt;em&gt;check validity&lt;/em&gt;&lt;/a&gt; command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;USE master;
CHECK VALIDITY;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Additional security is added when we export, distribute, and let others validate the database. This prevents authority illicit changes, where entire chains of data are swapped for seemingly valid ones. To read all digests from the &lt;code&gt;iou&lt;/code&gt; database, run a &lt;a href="https://bsql.org/docs/security/read-digest" rel="noopener noreferrer"&gt;&lt;em&gt;read digest&lt;/em&gt;&lt;/a&gt; command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;USE iou;
READ DIGEST iou;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can download the digest as a CSV and distribute it across technologies for validation later.&lt;/p&gt;

&lt;h2&gt;
  
  
  Lifetime Queries
&lt;/h2&gt;

&lt;p&gt;We can use the lifetime of &lt;strong&gt;contracts&lt;/strong&gt; in more complex queries. For example, I could find the number of contracts &lt;em&gt;ever&lt;/em&gt; owned by each user by running the following query.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT owner, COUNT(*) FROM LIFETIME contracts
    WHERE NOT ISNULL(owner)
  GROUP BY owner;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Selecting from a Specific Version
&lt;/h2&gt;

&lt;p&gt;bSQL allows you to interact with different states of the ledger by setting the transaction &lt;a href="https://bsql.org/docs/transaction/set-transaction" rel="noopener noreferrer"&gt;&lt;em&gt;query time&lt;/em&gt;&lt;/a&gt;. For example, I can set my transaction query time to when I issued &lt;em&gt;Alice&lt;/em&gt; the &lt;em&gt;AliceCoin&lt;/em&gt; by running &lt;code&gt;SET TRANSACTION QUERY TIME "2021–07–28 19:27:51.131868043";&lt;/code&gt; . This sets the scope of the current state back to the time specified, all queries I run after this transaction will interact with the current state as if it was at this time period.&lt;/p&gt;




&lt;h1&gt;
  
  
  Final Thoughts
&lt;/h1&gt;

&lt;p&gt;In this article I showed you how to set up the Daml quick-start application and a bSQL instance. We then added bSQL logic to the application and observed a the lifetime of a contract using bSQL.&lt;/p&gt;

&lt;p&gt;Here are some resources used to write this article:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;a href="https://docs.daml.com/app-dev/bindings-java/quickstart.html" rel="noopener noreferrer"&gt;Daml quick-start tutorial&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;The bSQL &lt;a href="https://bsql.org/docs/overview" rel="noopener noreferrer"&gt;docs&lt;/a&gt; and &lt;a href="https://www.youtube.com/watch?v=Em8b5qXcQew&amp;amp;list=PLdRS5wHN77gWuG71IvaH4pX7IdfZYGd06" rel="noopener noreferrer"&gt;video tutorials&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This was a very simple connection to demonstrate compatibility in logic. There are many ways to use these technologies together.&lt;/p&gt;




&lt;p&gt;Full code is on &lt;a href="https://github.com/blockpointSystems/daml-quickstart-bsql" rel="noopener noreferrer"&gt;github&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>blockchain</category>
      <category>database</category>
      <category>sql</category>
      <category>datascience</category>
    </item>
    <item>
      <title>How do I imbed gifs in my Dev Community comments?</title>
      <dc:creator>Cassidy Mountjoy</dc:creator>
      <pubDate>Fri, 10 Sep 2021 15:35:20 +0000</pubDate>
      <link>https://dev.to/cassidymountjoy/how-do-i-imbed-gifs-in-my-dev-community-comments-nl6</link>
      <guid>https://dev.to/cassidymountjoy/how-do-i-imbed-gifs-in-my-dev-community-comments-nl6</guid>
      <description>&lt;p&gt;Show me the way...&lt;/p&gt;

</description>
      <category>help</category>
    </item>
    <item>
      <title>FAQ: blockchain technology in bSQL</title>
      <dc:creator>Cassidy Mountjoy</dc:creator>
      <pubDate>Tue, 07 Sep 2021 17:24:15 +0000</pubDate>
      <link>https://dev.to/cassidymountjoy/faq-blockchain-technology-in-bsql-3l3p</link>
      <guid>https://dev.to/cassidymountjoy/faq-blockchain-technology-in-bsql-3l3p</guid>
      <description>&lt;h2&gt;
  
  
  Intro
&lt;/h2&gt;

&lt;p&gt;The &lt;a href="https://bsql.org/"&gt;bSQL&lt;/a&gt; language by &lt;a href="https://blockpointdb.com/"&gt;Blockpoint Systems&lt;/a&gt; is a SQL for interfacing with immutable data. bSQL is not a decentralized blockchain, neither is it a traditional database management system. This resource is meant to provide and explanation of "blockchain" in bSQL.&lt;/p&gt;

&lt;h2&gt;
  
  
  How is this blockchain?
&lt;/h2&gt;

&lt;p&gt;The blockchain storage structure is the foundation of data storage in bSQL. This doesn't change the fact that bSQL is a centralized database management system. All data in bSQL is stored in centralized blockchains within a single machine. &lt;/p&gt;

&lt;p&gt;Built-in blockchain storage provides an additional layer of security without compromising data privacy. A blockchain implementation is more secure than traditional systems and provides the following benefits.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Prevents Illicit Changes from Inside Employees&lt;/strong&gt;: Users cannot update or delete physical data.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Detects Illicit Hacker Changes&lt;/strong&gt;: Blockchain detects changes to data by storing a cryptographic digest.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Detects Authority Ordered Illicit Changes&lt;/strong&gt;: MDB digests can be freely distributed publicly. Cover-ups can be detected by comparing the published digest to the current contents.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How do I use the blockchain-ness?
&lt;/h2&gt;

&lt;p&gt;The blockchain aspect of MDB is abstracted from the database user. Every time you read or write blockchain hashes are verified. You can manually validate all hashes by running a &lt;a href="https://bsql.org/docs/database/check-validity"&gt;CHECK VALIDITY&lt;/a&gt; command on the &lt;a href="https://bsql.org/docs/master_database"&gt;master database&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What are the different kinds of blockchains?
&lt;/h2&gt;

&lt;p&gt;Different &lt;a href="https://bsql.org/docs/blockchain-overview"&gt;bSQL blockchains&lt;/a&gt; provide an interface-like method of interfacing with immutable data.&lt;br&gt;
They optimize applications based-off of table / blockchain usage patterns.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;HISTORICAL&lt;/code&gt; → Optimized for historical data collection and logging. The historical blockchain is a bare-bone&lt;br&gt;
ledger optimized for fast insert speeds, large datasets, and non-primary key dependent data.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;HISTORICAL PLUS&lt;/code&gt; → Handles primary key dependent data and is optimized for infrequently updated data with inter-blockchain dependencies.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;TRADITIONAL&lt;/code&gt; → Provides traditional features such as primary and foreign keys as well as blockchain-specific attributes such as time series selection, validity, and lifetime tracking. This container was designed to manage relational data while providing fast access to mutation history.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;SPARSE&lt;/code&gt; → Provides the same functionality as a traditional blockchain but optimizes storage by only storing changed values.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How do I determine which blockchain to use?
&lt;/h2&gt;

&lt;p&gt;The table below illustrates the basic methodology for choosing a blockchain to fit your database needs.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Blockchain&lt;/th&gt;
&lt;th&gt;FREQUENT INSERTIONS&lt;/th&gt;
&lt;th&gt;INFREQUENT INSERTIONS&lt;/th&gt;
&lt;th&gt;FREQUENT UPDATES&lt;/th&gt;
&lt;th&gt;INFREQUENT UPDATES&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;historical&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;✔️&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;✕&lt;/td&gt;
&lt;td&gt;✕&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;historical(+)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;✔️&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;✔️&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;traditional&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;✔️&lt;/td&gt;
&lt;td&gt;✔️&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;✔️&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;sparse&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;✔️&lt;/td&gt;
&lt;td&gt;✔️&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

</description>
      <category>sql</category>
      <category>database</category>
      <category>datascience</category>
    </item>
    <item>
      <title>Decentralized Security From a Centralized Database</title>
      <dc:creator>Cassidy Mountjoy</dc:creator>
      <pubDate>Thu, 02 Sep 2021 18:41:41 +0000</pubDate>
      <link>https://dev.to/cassidymountjoy/decentralized-security-from-a-centralized-database-3nb9</link>
      <guid>https://dev.to/cassidymountjoy/decentralized-security-from-a-centralized-database-3nb9</guid>
      <description>&lt;p&gt;Blockchain technology is great don't get me wrong but does traditional peer-to-peer blockchain fit most business cases? Most businesses would not benefit from publicly distributed data and private blockchain services are very expensive.&lt;/p&gt;

&lt;p&gt;This begs the question... How can I get similar security features from my centralized database?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://blockpointdb.com/" rel="noopener noreferrer"&gt;Blockpoint&lt;/a&gt; is able to prove the authenticity of records by exporting cryptographic digests: a unique, mathematical representation of the data, which allows external sources to validate data without having access to it. In this article we will examine the lifecycle of this validation technique.&lt;/p&gt;

&lt;h2&gt;
  
  
  Exporting Digests
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhtwr1rcz7uxsr52fqxfg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhtwr1rcz7uxsr52fqxfg.png" alt="export digests"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The &lt;em&gt;EXPORT DIGEST&lt;/em&gt; command reads data digests from the specified database object.&lt;/p&gt;

&lt;h3&gt;
  
  
  Syntax
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;READ DIGEST { &amp;lt;datbase_object&amp;gt; }

database_object ::=  
{   
   database_name.blockchain_name   
   | datbase_name    
}  

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Arguments
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;database_name&lt;/em&gt;&lt;br&gt;
The target database to read the digests.  &lt;/p&gt;

&lt;p&gt;&lt;em&gt;blockchain_name&lt;/em&gt;&lt;br&gt;
The target blockchain to read the digests from.&lt;/p&gt;
&lt;h3&gt;
  
  
  Remarks
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;The READ DIGEST command reads page hashes, timestamps, and previous hashes and outputs the data in query format. The command returns a response with the following&lt;br&gt;
columns:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;blockchain_id&lt;/strong&gt;: The internal id of the blockchain.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;page_id&lt;/strong&gt;: The page id of the blockchain.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;timestamp&lt;/strong&gt;: The time that the page was sealed at.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;current_hash&lt;/strong&gt;: The hash of that page as a UINT64.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;previous_hash&lt;/strong&gt;: The hash of the previous page; stored as 0 for the first page in the blockchain.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Only blockchain pages in the archive are read. Blockchain pages are pushed to the archive when the page is full and no currently open transaction have written to that page. This ensures a &lt;a href="https://bsql.org/docs/transaction/rollback" rel="noopener noreferrer"&gt;ROLLBACK&lt;/a&gt; can't change archived data, resealing the page, and changing the hash.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Running a &lt;a href="https://bsql.org/docs/database/check-validity" rel="noopener noreferrer"&gt;CHECK VALIDITY&lt;/a&gt; command before reading a digest ensures that digest is valid within the database and values haven't been illicitly changed.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  A. Reading the digest from a blockchain
&lt;/h3&gt;

&lt;p&gt;The following example reads the digest from the &lt;em&gt;pricing&lt;/em&gt; blockchain.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;READ DIGEST financial.pricing;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Output
&lt;/h4&gt;

&lt;p&gt;The output returned reads the two archived pages in &lt;em&gt;pricing&lt;/em&gt;, if there were no archived pages, no records would be returned. Notice that the previous hash of the first page is 0, because there is no previous page.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;BLOCKCHAIN_ID [UINT16]  PAGE_ID [UINT64]    TIMESTAMP [TIMESTAMP]   CURRENT_HASH [UINT64]   PREVIOUS_HASH [UINT64]
19                      0              2021-05-24 16:46:05.991142800    6006725463818420546  0
19                      1              2021-05-24 16:46:05.992201900    3175351712536806224  6006725463818420546
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Distributing a Digest
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff6n8isoxkxovk4ig0tw8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff6n8isoxkxovk4ig0tw8.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;br&gt;
Distributing a digest is really up to an organizations digression. It safer to distribute digest files over multiple technologies. This can be through email and other messaging or file sharing services.&lt;/p&gt;
&lt;h2&gt;
  
  
  Validating a Digest
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F37q4wyjf3mosf31d8ypj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F37q4wyjf3mosf31d8ypj.png" alt="validating a digest"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;VALIDATE DIGEST&lt;/em&gt; checks the current digest against the provided. &lt;/p&gt;
&lt;h3&gt;
  
  
  Syntax
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;VALIDTATE DIGEST { &amp;lt;datbase_object&amp;gt; } PATH "file_path";

database_object ::=  
{   
   database_name.blockchain_name   
   | datbase_name    
}  

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Arguments
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;database_name&lt;/em&gt;&lt;br&gt;
The target database to be checked against the provided digest.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;blockchain_name&lt;/em&gt;&lt;br&gt;
The target blockchain to be checked against the provided digest.&lt;/p&gt;

&lt;p&gt;PATH "&lt;em&gt;file_path&lt;/em&gt;&lt;br&gt;
The filepath to the provided digests. The provided digests must be in CSV format and follow the column order produced by &lt;br&gt;
the &lt;a href="//read-digest.md"&gt;READ DIGEST&lt;/a&gt; command.&lt;/p&gt;
&lt;h2&gt;
  
  
  Remarks
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Only blockchain pages in the archive are validated. Blockchain pages are pushed to the archive when the page is full and no currently open transaction have written to that page.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If data was added to the blockchain archive after the digest was exported. New data won't be validated.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Running a &lt;a href="https://bsql.org/docs/database/check-validity" rel="noopener noreferrer"&gt;CHECK VALIDITY&lt;/a&gt; command before validating a digest ensures that digest is valid within the database and values haven't been illicitly changed.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A database or blockchain digest can be used to validate a blockchain.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Only a database digest can be used to validate a database.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://bsql.org/docs/management/disconnect-blockchain" rel="noopener noreferrer"&gt;DISCONNECTED&lt;/a&gt; blockchains are still validated as they can be reconnected to the database.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  A. Validating a blockchain digest
&lt;/h3&gt;

&lt;p&gt;The following example validates the digest of the &lt;em&gt;pricing&lt;/em&gt; blockchain. The provided digest can be a blockchain or database digest.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;VALIDATE DIGEST financial.pricing PATH "digests/may_5_digest.csv";
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Output
&lt;/h4&gt;

&lt;p&gt;If valid, the output provides the time at which the digest is valid given the last archived page's sealed time of the uploaded digest.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Database object financial_1.pricing is valid against the stored digests for archived pages before 2021-05-24 16:46:05.992201900
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  B. Validating a database digest
&lt;/h3&gt;

&lt;p&gt;The following example reads all blockchain digests in the entire database.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;VALIDATE DIGEST financial PATH "digests/may_5_digest.csv";
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  C. Invalid digest
&lt;/h3&gt;

&lt;p&gt;The following example illustrates an invalid digest being compared to a valid database.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;VALIDATE DIGEST financial PATH "digests/may_5_bad_digest.csv";
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Output
&lt;/h4&gt;

&lt;p&gt;An invalid digest returns specifics on the failed data. In this case, the timestamp on the first page of the system blockchain &lt;em&gt;syscolumns&lt;/em&gt; has been modified in either the database or the imported digest.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Blockchain syscolumns: timestamp mismatch when verifying digest page 0, digest timestamp 2021-05-21 19:14:14.9512269 +0000 UTC not equal to system timestamp 2021-05-24 16:46:05.9175726 +0000 UTC
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;The digest lifecycle described above allows outside sources to validate that data within a centralized database hasn't been illicitly changed. Nifty!&lt;/p&gt;

</description>
      <category>sql</category>
      <category>database</category>
      <category>datascience</category>
      <category>blockchain</category>
    </item>
    <item>
      <title>Hindsight 20/20: Querying Any Point in Time</title>
      <dc:creator>Cassidy Mountjoy</dc:creator>
      <pubDate>Wed, 01 Sep 2021 14:52:15 +0000</pubDate>
      <link>https://dev.to/cassidymountjoy/hindsight-20-20-querying-any-point-in-time-2noi</link>
      <guid>https://dev.to/cassidymountjoy/hindsight-20-20-querying-any-point-in-time-2noi</guid>
      <description>&lt;p&gt;Today I'll be showing you how to use transactions to simulate snapshots in &lt;a href="https://bsql.org/" rel="noopener noreferrer"&gt;bSQL&lt;/a&gt;. Because of its multi-version protocols users can access old data by running queries with a set &lt;em&gt;query time&lt;/em&gt;. By setting a &lt;em&gt;query time&lt;/em&gt; all subsequent queries run as if they had been run at that time. This allows for analysis of old versions of the database, giving you rich data insights. The following diagram illustrates snapshotting in traditional databases and setting the query time with &lt;a href="https://blockpointdb.com/" rel="noopener noreferrer"&gt;blockpoint's&lt;/a&gt; immutable database.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F08hr0dl9318psvj7nt76.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F08hr0dl9318psvj7nt76.png" alt="snapshot"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Syntax
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SET TRANSACTION 
    QUERY TIME &amp;lt;query_time&amp;gt;

&amp;lt;query_time&amp;gt; ::=
    timestamp
    | STATE
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;QUERY TIME&lt;/code&gt;&lt;br&gt;
Sets queries to run in a snapshot-like environment at the time specified. Values that were &lt;a href="https://bsql.org/docs/mutations/amend" rel="noopener noreferrer"&gt;AMENDED&lt;/a&gt; or &lt;a href="https://bsql.org/docs/mutations/discontinue" rel="noopener noreferrer"&gt;DISCONTINUED&lt;/a&gt; after the specified time will be restored and relational entities are guaranteed to hold.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;[!NOTE]&lt;br&gt;
The query time is currently specified in UTC time format.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;em&gt;STATE&lt;/em&gt; &lt;br&gt;
Specifies that queries should operate normally, on the current state of the system.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Limitations

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://bsql.org/docs/query/time-travel" rel="noopener noreferrer"&gt;LIFETIME queries&lt;/a&gt; and &lt;code&gt;QUERY TIME&lt;/code&gt; are mutually exclusive. An error is thrown if a lifetime query is run on any version other than &lt;code&gt;STATE&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Queryies run on a previous database version always use the &lt;code&gt;READ UNCOMMITTED&lt;/code&gt; isolation level. &lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;timestamp&lt;/em&gt;&lt;br&gt;
The time to read from. &lt;em&gt;timestamp&lt;/em&gt;   can be specified as a timestamp in quotations or an expression that computes to a valid timestamp.&lt;/p&gt;
&lt;h3&gt;
  
  
  Setting the query time.
&lt;/h3&gt;

&lt;p&gt;We can use the &lt;code&gt;QUERY TIME&lt;/code&gt; keyword to simulation a snapshot at the time specified. Because the system continuously tracks changes setting the transaction time should have only a small effect on performance. Although all the statements below were technically committed, we can still view previous states.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="n"&gt;BLOCKCHAIN&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt; &lt;span class="n"&gt;TRADITIONAL&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="n"&gt;UINT64&lt;/span&gt; &lt;span class="n"&gt;AUTO&lt;/span&gt; &lt;span class="k"&gt;INCREMENT&lt;/span&gt; &lt;span class="k"&gt;PRIMARY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="n"&gt;STRING&lt;/span&gt; &lt;span class="n"&gt;PACKED&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;INSERT&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;VALUES&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;"john"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;"jimmy"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;"jeff"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;--Assume Time = "2021-02-26 00:07:10.000000000"&lt;/span&gt;

&lt;span class="n"&gt;DISCONTINUE&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;VALUES&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;"jimmy"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="n"&gt;TRANSACTION&lt;/span&gt; &lt;span class="n"&gt;QUERY&lt;/span&gt; &lt;span class="nb"&gt;TIME&lt;/span&gt; &lt;span class="nv"&gt;"2021-02-26 00:07:10.000000000"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  OUTPUT
&lt;/h3&gt;

&lt;p&gt;Since "jimmy" was inserted into the blockchain before the specified transaction time. The record persists in that state of the database.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;ID&lt;/th&gt;
&lt;th&gt;NAME&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;john&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;jimmy&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;jeff&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;Although this example is trivial, the same logic is used for audits and data analysis. It uses the database structure in a unique way to give users access to data evolution over time.&lt;/p&gt;

</description>
      <category>sql</category>
      <category>database</category>
      <category>datascience</category>
    </item>
    <item>
      <title>How to Create a Database and Blockchain in bSQL</title>
      <dc:creator>Cassidy Mountjoy</dc:creator>
      <pubDate>Mon, 23 Aug 2021 20:52:01 +0000</pubDate>
      <link>https://dev.to/cassidymountjoy/how-to-create-a-database-and-blockchain-in-bsql-hbi</link>
      <guid>https://dev.to/cassidymountjoy/how-to-create-a-database-and-blockchain-in-bsql-hbi</guid>
      <description>&lt;p&gt;In this tutorial we will be introducing how to set up a new database, blockchain, and perform your first mutation. If you&lt;br&gt;
prefer to learn in a video format, you can watch the &lt;a href="https://www.youtube.com/watch?v=xjVNbdk7sp4&amp;amp;list=PLdRS5wHN77gWuG71IvaH4pX7IdfZYGd06&amp;amp;index=2"&gt;tutorial&lt;/a&gt; online.&lt;/p&gt;

&lt;p&gt;You can create a bSQL account through the Blockpoint &lt;a href="https://blockpointdb.com/"&gt;website&lt;/a&gt; or join the &lt;a href="https://join.slack.com/t/bsqlcommunity/shared_invite/zt-169oaigpu-R3W1D5_vc6OyNnKy4thNoA"&gt;slack&lt;/a&gt; for direct assistance from an engineer.&lt;/p&gt;

&lt;p&gt;We will be:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Creating a new database&lt;/li&gt;
&lt;li&gt;Starting a session on that database&lt;/li&gt;
&lt;li&gt;Creating a blockchain&lt;/li&gt;
&lt;li&gt;Populating your blockchain&lt;/li&gt;
&lt;li&gt;Reading from your blockchain&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;
  
  
  Opening the IDE
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--51cLCaCs--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9264cgvibmkgsr2d7bsm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--51cLCaCs--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9264cgvibmkgsr2d7bsm.png" alt="click-on-open-ide" width="880" height="253"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After selecting the "open IDE button" you will automatically navigate to the IDE. A few things are important to note:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You will need to provide your username and password to connect to bSQL&lt;/li&gt;
&lt;li&gt;Once you connect, a session will be started on the &lt;a href="//master_database.md"&gt;master database&lt;/a&gt;, a hub for system metadata where
work and application logic should &lt;strong&gt;not&lt;/strong&gt; be performed&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Creating a database
&lt;/h2&gt;

&lt;p&gt;Once you have the master database open in the IDE we can run a &lt;a href="https://bsql.org/docs/database/create-database"&gt;CREATE DATABASE&lt;/a&gt; command to build a database.&lt;/p&gt;

&lt;p&gt;I will be calling mine &lt;em&gt;marketplace&lt;/em&gt;, and will create a new database by running the following statement:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;DATABASE&lt;/span&gt; &lt;span class="n"&gt;marketplace&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Start a session on the database
&lt;/h2&gt;

&lt;p&gt;After we have created a database, it is bSQL convention to begin a session on our working database. To do this we run a &lt;br&gt;
&lt;a href="https://bsql.org/docs/transaction/use"&gt;USE&lt;/a&gt; statement followed by the name of our database. Now &lt;em&gt;marketplace&lt;/em&gt; is used as the default database&lt;br&gt;
for all subsequent statements.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="n"&gt;USE&lt;/span&gt; &lt;span class="n"&gt;marketplace&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Create a blockchain
&lt;/h2&gt;

&lt;p&gt;Creating an immutable &lt;a href="https://bsql.org/docs/blockchain-overview"&gt;Blockchain&lt;/a&gt; is as simple as creating a table in other SQL databases. There are four types&lt;br&gt;
of blockchain in bSQL. Before defining the schema, we specified that the blockchian would be of type &lt;em&gt;TRADITIONAL&lt;/em&gt;.&lt;br&gt;
Reference the &lt;a href="https://bsql.org/docs/management/create-blockchain"&gt;CREATE BLOCKCHAIN&lt;/a&gt; documentation for full syntax and keywords.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="n"&gt;BLOCKCHAIN&lt;/span&gt; &lt;span class="n"&gt;contracts&lt;/span&gt; &lt;span class="n"&gt;TRADITIONAL&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="n"&gt;UINT64&lt;/span&gt; &lt;span class="k"&gt;PRIMARY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;unique_identifier&lt;/span&gt; &lt;span class="n"&gt;STRING&lt;/span&gt; &lt;span class="n"&gt;PACKED&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;issuer&lt;/span&gt; &lt;span class="n"&gt;STRING&lt;/span&gt; &lt;span class="n"&gt;PACKED&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;owner&lt;/span&gt; &lt;span class="n"&gt;STRING&lt;/span&gt; &lt;span class="n"&gt;PACKED&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;currency&lt;/span&gt; &lt;span class="n"&gt;STRING&lt;/span&gt; &lt;span class="n"&gt;PACKED&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;amount&lt;/span&gt; &lt;span class="n"&gt;FLOAT32&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Data types are explained in &lt;a href="https://bsql.org/docs/system_data_types"&gt;data types&lt;/a&gt;. You can read the columns from the database by writing a&lt;br&gt;
&lt;a href="https://bsql.org/docs/analytics/describe"&gt;DESCRIBE&lt;/a&gt; statement.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;DESCRIBE&lt;/span&gt; &lt;span class="n"&gt;marketplace&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;contracts&lt;/span&gt; &lt;span class="k"&gt;SCHEMA&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can use an &lt;a href="https://bsql.org/docs/mutations/insert"&gt;INSERT&lt;/a&gt; statement to add immutable data to our blockchain. Insert a new contract into the blockchain we&lt;br&gt;
created by running the following statement. Once data is added, it can't be modified or illicitly changed.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;INSERT&lt;/span&gt; &lt;span class="n"&gt;contracts&lt;/span&gt; &lt;span class="k"&gt;VALUES&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nv"&gt;"25c3d24f-0fc3-4a99-a292-98302dc0b5d0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nv"&gt;"bank"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nv"&gt;"joe"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nv"&gt;"USD"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="mi"&gt;120&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If we want to change values in bSQL we can write an &lt;a href="https://bsql.org/docs/mutations/amend"&gt;AMEND&lt;/a&gt; statement. It is important to note that &lt;br&gt;
this statement doesn't modify existing values, only updates the current version relative to the primary key.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="n"&gt;AMEND&lt;/span&gt; &lt;span class="n"&gt;contracts&lt;/span&gt; &lt;span class="k"&gt;VALUES&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nv"&gt;"36e55e77-3ef2-4d8c-9f74-58895f4193b5"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nv"&gt;"joe"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nv"&gt;"kate"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nv"&gt;"USD"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="mi"&gt;120&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To prove that data hasn't been illicitly modified we can run a &lt;a href="//database/check-validity.md"&gt;CHECK VALIDITY&lt;/a&gt; command to &lt;br&gt;
validate our data digests.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CHECK&lt;/span&gt; &lt;span class="n"&gt;VALIDITY&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To query from the current state of the database, use a &lt;a href="https://bsql.org/docs/database/check-validity"&gt;SELECT&lt;/a&gt; statement.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;contracts&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--4ds0G_kh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ye1p56m7jeg8j3hq4j26.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--4ds0G_kh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ye1p56m7jeg8j3hq4j26.png" alt="select_output" width="880" height="54"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Additionally, we can access the record history of the blockchain by applying the &lt;em&gt;LIFETIME&lt;/em&gt; keyword to the &lt;em&gt;contracts&lt;/em&gt; blockchain.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;LIFETIME&lt;/span&gt; &lt;span class="n"&gt;contracts&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Ad7rRNEG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8eh40f2fauparkw1afaz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Ad7rRNEG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8eh40f2fauparkw1afaz.png" alt="select_lifetime_output" width="880" height="79"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>sql</category>
      <category>database</category>
      <category>blockchain</category>
    </item>
    <item>
      <title>Wondering How Your Data is Evolving? Time Travel Queries in bSQL Can Help</title>
      <dc:creator>Cassidy Mountjoy</dc:creator>
      <pubDate>Thu, 19 Aug 2021 15:20:43 +0000</pubDate>
      <link>https://dev.to/cassidymountjoy/wondering-how-your-data-is-evolving-time-travel-queries-in-bsql-can-help-1jp1</link>
      <guid>https://dev.to/cassidymountjoy/wondering-how-your-data-is-evolving-time-travel-queries-in-bsql-can-help-1jp1</guid>
      <description>&lt;h2&gt;
  
  
  What is a Time-Travel Query?
&lt;/h2&gt;

&lt;p&gt;Imagine a database that never forgets, no matter what you throw at it. A place for unbiased facts where all changes are tracked. Now imagine you are roped into an adventure with a crazy data science robot. He puts you in the bSQL time-travel mobile and takes you on a trip down data lane.&lt;/p&gt;

&lt;p&gt;You learn that application data is always evolving as values are added and removed from the database. Through rich record histories, you find yourself accessing a new dimension of data by exploring its evolution over time.&lt;/p&gt;

&lt;p&gt;Enhanced visibility is perhaps one of the most powerful features of bSQL and allows us to answer important questions like: What was this value before I updated it? When did this value get deleted? How does the history of my data affect the current state?&lt;/p&gt;

&lt;p&gt;bSQL allows you to access the history of your data by writing special “time-travel” queries.&lt;/p&gt;

&lt;h2&gt;
  
  
  Financial Data Example
&lt;/h2&gt;

&lt;p&gt;In the financial demo database there are two containers.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;companies&lt;/strong&gt; keeps track of the company metadata such as name, sector, and symbol.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;pricing&lt;/strong&gt; keeps track of the current stock prices.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ever row in &lt;strong&gt;pricing&lt;/strong&gt; references a row in &lt;strong&gt;companies&lt;/strong&gt;. Every time the share price changes an &lt;code&gt;AMEND&lt;/code&gt; statement is sent to the pricing container to make the corresponding updates. Logical right.&lt;/p&gt;

&lt;p&gt;Querying from the &lt;strong&gt;pricing&lt;/strong&gt; container using a basic &lt;code&gt;SELECT&lt;/code&gt; statement reads from the current state of the system. Using our Multi-Version Database, we can run analytics on previous events. In the bSQL language this involves using the &lt;code&gt;LIFETIME&lt;/code&gt; keyword to query from the lifetime of the container.&lt;/p&gt;

&lt;p&gt;For a full description of the financial database check out the bSQL docs &lt;a href="https://bsql.org/docs/demo_database"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Understanding the Lifetime Query
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT symbol, price, timestamp
   FROM LIFETIME financial.pricing;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The above query uses the &lt;code&gt;LIFETIME&lt;/code&gt; keyword to query from the entire record history of the &lt;strong&gt;pricing&lt;/strong&gt; container. The following output is produced:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--C2xDA2ab--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jtgjg3pb1onp96racwh8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--C2xDA2ab--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jtgjg3pb1onp96racwh8.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It is important to notice a couple of things here:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The output is sorted by the primary key of the container, the &lt;strong&gt;symbol&lt;/strong&gt; column.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The records associated with the primary key are ordered by the time the mutation was made in ascending order.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The first entry of the group represents when the record was inserted into the container.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Subsequent entries represent when values were either updated using the &lt;code&gt;AMMEND&lt;/code&gt; command or removed from the current state using the &lt;code&gt;DISCONTINUE&lt;/code&gt; command.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;When a record is removed from the current state of the container using a &lt;code&gt;DISCONTINUE&lt;/code&gt; command, a tombstone record is added to the data.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let’s look at the record history of the symbol &lt;code&gt;A&lt;/code&gt;. When the record was introduced into the container the price was &lt;code&gt;58.42&lt;/code&gt;. The records that follow it show how the price was updated. The final record with a &lt;code&gt;NULL&lt;/code&gt; price value, represents a tombstone record. This means that &lt;code&gt;A&lt;/code&gt; was removed with the &lt;code&gt;DISCONTINUE&lt;/code&gt; command from the current state of the database at &lt;code&gt;2020–11–13 07:26:03.650678200&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--6HPAyDRQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/s818jhi9hxeeorbq8ltc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--6HPAyDRQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/s818jhi9hxeeorbq8ltc.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Discontinued Data
&lt;/h2&gt;

&lt;p&gt;Although it sounds paradoxical, let’s search for deleted data. Here we will use the &lt;code&gt;DISCONTINUED&lt;/code&gt; keyword to filter our previous query.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT * 
     FROM LIFETIME financial.pricing
  WHERE DISCONTINUED(pricing);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The corresponding output is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SYMBOL    PRICE   ...    52_WEEK_HIGH       TIMESTAMP
A         NULL    ...    NULL       2020–11–13 07:26:03.650678200
MMM       NULL    ...    NULL       2020–11–13 07:26:03.670677500
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When a &lt;code&gt;DISCONTINUE&lt;/code&gt; statement is run, a tombstone record is inserted into the target container. Time-travel queries allow us to access the tombstones displayed above. As you can see, the primary key, in this case both &lt;code&gt;MMM&lt;/code&gt; and &lt;code&gt;A&lt;/code&gt;, as well as any timestamp column is preserved in the tombstone. This allows us to embed such statements in more complex queries and preserve discontinued data.&lt;/p&gt;

&lt;h2&gt;
  
  
  Joining and Aggregating Histories
&lt;/h2&gt;

&lt;p&gt;Now let’s look at how we can use the &lt;code&gt;LIFETIME&lt;/code&gt; keyword to gain insight into the history of our data.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT c.name, COUNT(*) AS number_of_versions, AVG(p.price)
    FROM LIFETIME financial.pricing AS p 
       JOIN financial.companies AS c
       ON c.symbol = p.symbol 
    GROUP BY name
FILTER 10;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let’s break down this query:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The complete history of &lt;strong&gt;pricing&lt;/strong&gt; is joined with the current state of &lt;strong&gt;companies&lt;/strong&gt; to retrieve the name metadata.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The records are then grouped by the &lt;code&gt;name&lt;/code&gt; column and the &lt;code&gt;COUNT&lt;/code&gt; and &lt;code&gt;AVG&lt;/code&gt; functions are applied. This will return the number of versions of each primary key, as well as the average price over these versions respectively.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The output is limited to be the first 10 records.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This query returns:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;C.NAME           NUMBER_OF_VERSIONS             AVG(P.PRICE) 
3M Co.           22                             133.92297224564985
ACE Limited      21                             103.51996685209728
AES Corp         21                             18.495395614987327
AFLAC Inc        21                             70.05538577125186
AGL Resources Inc. 21                           56.701499938964844
AMETEK Inc       21                             59.99528685070219
AT&amp;amp;T Inc         21                             25.695445378621418
AbbVie Inc.      21                             57.20997020176479
Abbott Laboratories 21                          45.31997081211635
Accenture        21                             89.67997051420666
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The number of versions tells us the number of &lt;code&gt;INSERT&lt;/code&gt;, &lt;code&gt;AMEND&lt;/code&gt;, and &lt;code&gt;DISCONTINUE&lt;/code&gt; statements that were run on each record. While other companies where changed 21 times, &lt;code&gt;3M Co.&lt;/code&gt; was changed 22 times, this makes sense because &lt;code&gt;3M Co.&lt;/code&gt; was discontinued from the data set, adding the “discontinued” version. We were able to compute the average price across all versions regardless of whether or not the record existed in the current state.&lt;/p&gt;

&lt;h2&gt;
  
  
  Using the Timestamp Column
&lt;/h2&gt;

&lt;p&gt;Let’s see what we can uncover using the timestamp column.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT symbol, MAX(p.price) AS max_price, MIN(p.price) AS min_price,
   MAX(p.timestamp) - MIN(p.timestamp) AS life_span
     FROM LIFETIME financial.pricing AS p
   GROUP BY p.symbol
  ORDER BY life_span DESC
FILTER 10;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let’s take a deeper look at this query.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The complete history of pricing is grouped by the symbol column. We compute the min_price, max_price, and the time since the record was inserted and when it was last amended or discontinued as life_span.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;We ordered the output by the life_span.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;We limited the number of outputs to be the first 10 records.&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SYMBOL          MAX_PRICE         MIN_PRICE           LIFE_SPAN
VLO             52.99             40.63915            182 
VMC             68.85             56.499134           182 
ZMH             98.06             84.10976            182 
VIAB            88.27             75.919136           182 
YUM             77.16             63.209763           182 
XYL             38.64             24.689758           182 
VFC             61.71059          51.781025           182 
XRAY            46.86             32.909756           182 
XOM             94.99             81.03975            182 
V               225.89061         215.96103           182
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Our output produces an interesting dataset that gives us the amount of time between the first insertion and the last mutation in seconds. The dataset we produced allows us to analyze how the life span of a stock affects other target variables. As you can see, the bSQL language allows you to compute rich datasets that leverage the power of an immutable database.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;If you made it this far, hats off to you Sherlock Codes! We are always working on more bSQL features and will continue to post. Our goal at &lt;a href="https://blockpointdb.com/"&gt;blockpoint&lt;/a&gt; is to provide you with with insightful tools to get the most out of immutable databases. Please leave any comments or suggestions down below.&lt;/p&gt;

</description>
      <category>sql</category>
      <category>datascience</category>
      <category>database</category>
    </item>
    <item>
      <title>How immutable data can benefit your data-driven application.</title>
      <dc:creator>Cassidy Mountjoy</dc:creator>
      <pubDate>Wed, 18 Aug 2021 18:32:35 +0000</pubDate>
      <link>https://dev.to/cassidymountjoy/how-immutable-data-can-benefit-your-data-driven-application-28pm</link>
      <guid>https://dev.to/cassidymountjoy/how-immutable-data-can-benefit-your-data-driven-application-28pm</guid>
      <description>&lt;p&gt;The promise of blockchain technology set out to change data systems and revolutionize networks. Blockchain advocates pledged to decentralize voting, registration, commerce, and currency. Although various changes have been made to many of these fields, there is still a lot more work to be done. Don’t get me wrong, CryptoKitties is pretty cool and the cats are so darn cute, but I think blockchain technology is far from reaching its full potential.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Foyq3zif5l1zhqv98j3pi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Foyq3zif5l1zhqv98j3pi.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;One of the fundamental ideas behind blockchain systems is that data is &lt;strong&gt;immutable&lt;/strong&gt;. Immutable data prevents adversaries from changing existing values within the database. This establishes trust and greatly enhances the security of the overall system, preventing data discrepancies that have potentially catastrophic results.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkxtwpx220zkjmyoej2sg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkxtwpx220zkjmyoej2sg.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The Cabinet Dilemma
&lt;/h2&gt;

&lt;p&gt;Traditional industries are becoming digitized, moving their pen and paper operations to applications and electronic storage. This entails trading locked file cabinets for database management systems. While the lock on the cabinet provides the primary layer of security, the documents inside have an additional layer of security, their wet signatures.&lt;/p&gt;

&lt;p&gt;Immutable data is the equivalent of a wet signature. The paper has been signed, there is no going back or “modifying” the signature. On the contrary mutable systems are equivalent to signing the document in pencil and attempting to hide the eraser. If the cabinet is opened, the freedom to re-write data is granted to the adversary.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;With over 80,000 cyber attacks per day, our virtual file cabinets need to be as secure as possible. You wouldn’t sign your documents in pencil would you?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Data breaches are dangerous to your customers, a headache for your engineers, and embarrassing. We should be doing as much as possible to stop such violations of privacy. Blockchain fundamentals, such as immutability, must be applied to traditional systems to add much needed security and create an overall safer environment.&lt;/p&gt;

&lt;h2&gt;
  
  
  Providing Additional Value to Immutable Data
&lt;/h2&gt;

&lt;p&gt;On face value, immutable data deepens insight and enhances the security of your system. When applied to relational databases, immutable data provides other solutions to application demands, here’s why.&lt;/p&gt;

&lt;h3&gt;
  
  
  Speed
&lt;/h3&gt;

&lt;p&gt;While developing an immutable relational database, we learned that storage techniques associated with write-only system are greatly simplified. When adding data to the system becomes a simple procedure, database resources are made more accessible to users.&lt;/p&gt;

&lt;h3&gt;
  
  
  Auditing and Analytics
&lt;/h3&gt;

&lt;p&gt;Immutable data can be used as a trusted resource for auditing. Additionally, analytics teams have access to the complete history, allowing them to run more in-depth queries for analyzing changes over time.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;When we explore blockchain fundamentals a bit deeper, its apparent that immutable data provides many needed benefits to our applications. As traditional industries move their services online, sensitive data should be secured at the lowest level possible. With that being said, immutable systems are a necessity for us to protect our businesses, sensitive information, and quality of life.&lt;/p&gt;

&lt;h2&gt;
  
  
  Blockpoint
&lt;/h2&gt;

&lt;p&gt;At &lt;a href="https://blockpointdb.com/" rel="noopener noreferrer"&gt;blockpoint Systems&lt;/a&gt; we value immutability and think you should too. We developed a multi-version database that brings together blockchain immutability with traditional relational database infrastructure. Check out our website or feel free to reach out to us at &lt;a href="mailto:contact@blockpoint.systems"&gt;contact@blockpoint.systems&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>database</category>
      <category>sql</category>
      <category>blockchain</category>
      <category>security</category>
    </item>
    <item>
      <title>Immutable Databases Are Here to Stay... pun intended</title>
      <dc:creator>Cassidy Mountjoy</dc:creator>
      <pubDate>Tue, 17 Aug 2021 17:55:49 +0000</pubDate>
      <link>https://dev.to/cassidymountjoy/immutable-databases-are-here-to-stay-pun-intended-388g</link>
      <guid>https://dev.to/cassidymountjoy/immutable-databases-are-here-to-stay-pun-intended-388g</guid>
      <description>&lt;p&gt;If understanding the inner workings of SQL and NoSQL databases didn’t leave your head spinning, I’d like to dust off a database relic, the Multi-Version database. These systems are actually a fairly simple concept and have been around for decades. Why haven’t you heard of them? Unless you spend your time reading academic papers it’s probably because they never got traction because of hardware constraints. When Multi-Version databases were introduced, storage was for the 1%… Now that storage is a lot cheaper, Multi-Version systems can be revisited as an applicable and cost-effective database solution.&lt;/p&gt;

&lt;p&gt;Multi-Version databases are important because:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;immutable&lt;/strong&gt; datastores enhance security&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;accessible&lt;/strong&gt; versioning provides in-depth analytics and auditing&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;updates&lt;/strong&gt; to your data are faster&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;On a more technical note they:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;reduce locking overhead&lt;/li&gt;
&lt;li&gt;don’t require pages to be re-packed&lt;/li&gt;
&lt;li&gt;eliminate the need for manual snapshots&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Multi-Version and Data Storage
&lt;/h2&gt;

&lt;p&gt;While Uni-Version Systems (SQL and NoSQL) only keep track of the current state of the database, Multi-Version systems track every change that has occurred in the system. Data is never truly altered or removed, updated data is added to the data files; &lt;strong&gt;data is immutable&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;As a result, an append-only system increases the amount of storage used by an application. Initially, this made Multi-Version systems an expensive data management method.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--JaBhcpm2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ecv1l0squd0j5gzh8yyt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--JaBhcpm2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ecv1l0squd0j5gzh8yyt.png" alt="image"&gt;&lt;/a&gt; &lt;em&gt;Historic prices of hard drive space, from Matt Komorowski.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;In the 1980s, shortly after the Multi-Version database was conceived, storage cost was upwards of $100,000 per Gb…. today storage costs less than $.05 per Gb. The major decrease in storage costs lets us reconsider the Multi-Version database.&lt;/p&gt;

&lt;h2&gt;
  
  
  Updating Your Data
&lt;/h2&gt;

&lt;p&gt;In order to maintain the state of a Uni-Version system, the database management system has to use complicated control measures to coordinate access to recourses and prevent data corruption.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--GAkIQX-f--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/v13uj57s85vuu92b0wjf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--GAkIQX-f--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/v13uj57s85vuu92b0wjf.png" alt="image"&gt;&lt;/a&gt; &lt;em&gt;(Figure 1)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;When access is granted to the resource, the data is said to have a “lock” on it. When User 1 requests to update a value (figure 1), a lock is added to the system. Data can’t be accessed by another source until the lock is released, hence, User 2 has to wait until the lock is released to perform an update. Locking makes resources inaccessible for an undefined period of time. Locking systems require downtime and compute, increasing the overhead associated with large transaction loads.&lt;/p&gt;

&lt;p&gt;Multi-version systems don’t require complex locking mechanisms because data can only be added to the end of the file. In this fashion, requests for updates can be handled concurrently. By eliminating traditional locking, removing and updating data is inherently faster, allowing applications to run at higher speeds and certain data cleaning processes become obsolete.&lt;/p&gt;

&lt;h2&gt;
  
  
  Data Cleaning
&lt;/h2&gt;

&lt;p&gt;When packed data is deleted or updated in a Uni-Version system, the space allotted to the original data is no longer in use and deemed inaccessible.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--dRC2R3Oq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/q1kg23elp00tq509atmo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--dRC2R3Oq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/q1kg23elp00tq509atmo.png" alt="image"&gt;&lt;/a&gt; &lt;em&gt;(figure 2) Red scribbles represent empty space in a data file.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Inaccessible space provides no value until it’s eventually recycled and made usable by the database management system during a process commonly called database “vacuuming”. For example, when updating a specific value, the system deems the old value unusable, appends the updated data to the end of the file, and cleans the empty space during the next vacuum cycle.&lt;/p&gt;

&lt;p&gt;When data is “updated” or “deleted” in a multi-version system, the updated record is simply added to the end of the file. Previous data is never modified, instead, all changes are written to the next free slot. Multi-Version data mutations require only fetching the next free slot, there is no need to find the original tuple. This method decreases the number of data pages that are potentially brought into memory, increasing mutation speed, and reducing the amount of time that resources are locked.&lt;/p&gt;

&lt;h2&gt;
  
  
  Analytics
&lt;/h2&gt;

&lt;p&gt;In traditional systems, snapshots are used to track changes to the database after the snapshot was created. Snapshots are commonly used for time-based analytics and auditing. As an application grows and analytics begin to develop, snapshots become a daily routine for teams.&lt;/p&gt;

&lt;p&gt;Since Multi-Version databases track full database history, fine-grain snapshotting can be easily integrated into the system. Snapshots don’t rely on user commands as all versions of the database are accessible at all times. Fine-grained snapshots provide additional dimensions to your data. For example, in a Multi-Version database, it would be possible to get the state of a table before a specific value was updated. A rich data-history provides the analytics team access to insightful queries that span database versions.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--FoPzUc6z--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/32g5ksbjxnr3lxa022yo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--FoPzUc6z--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/32g5ksbjxnr3lxa022yo.png" alt="image"&gt;&lt;/a&gt;&lt;em&gt;(figure 3) A time travel query.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;In conclusion, database implementations should adapt to the hardware that supports them. We have been relying on the same Uni-Version systems for the past 30 years. Is this the best implementation? How can we adapt our management systems to capitalize on the efficiency of cloud computing? Multi-Version databases were once an unrealistic and expensive solution, yet revisiting them uncovers a lot of programmatic benefits that are no longer constrained by costs. As the emphasis shifts from storage size to speed and analytics, a Multi-Version implementation becomes an effective choice for data-driven applications.&lt;/p&gt;

</description>
      <category>database</category>
    </item>
  </channel>
</rss>
