Skip to content
This repository has been archived by the owner on Jan 22, 2020. It is now read-only.

Latest commit

 

History

History
228 lines (173 loc) · 8.51 KB

File metadata and controls

228 lines (173 loc) · 8.51 KB

Cryptomoji Client

In many ways building a web app as a client to a Sawtooth blockchain is not much different than building a web app for any server. You will create some React components that will display the data you GET from a REST API. Users will fill out forms and you will take that information and POST it. Of course, everything you GET will be a base64 encoded binary file, and all of your POSTs will be cryptographically signed transactions. But that's where the fun is!

Contents

Getting Started

This component uses npm to manage dependencies, so the first thing you should do is install them:

cd code/part-two/client/
npm install

Once that's done, you will need to build your front-end code with webpack. This will use source/index.jsx as an entry point, and pull in all of your other modules from there to create a bundle saved at public/bundle.js. Anything in the public/ directory will be served at localhost:3000, so when you run docker-compose up (see Using Docker), you should be able to view it from your browser. In order to run the build, there are a few commands you can use.

You can build the production code:

npm run build:prod

However, most of the time you will probably what to build your code in dev-mode. It builds faster, includes more debugging information, and will even automatically rebuild every time you save changes:

npm run build:dev

And you can go a step further and serve the dev code from a live-reload server at localhost:3001. Good news, you won't have to refresh your page! Bad news, you won't be able to make any API calls or interact with the blockchain at all:

npm run watch

Running Tests

Like other components, the front-end uses Mocha/Chai for testing. Unlike other components, there is a pretty sweet browser-based test runner. To pull it up, simply run:

npm test

The Project

Before you start in on this part of the project make sure you have reviewed the Sawtooth Curriculum, in particular the sections on build and submitting transactions, as well as Signing from part one.

01 Signing

Module: source/services/signing.js

If you completed part one, this section should be pretty much done. Both Sawtooth and your DIY blockchain use Secp256k1 for signing, so you will be able to copy over most of your code.

There is one slight difference to keep in mind. While you signed strings in part one, you will be signing encoded transactions in part two (i.e. Buffers). This probably won't make much of a difference, but depending on how you implemented sign the first time, it may require some changes.

02 Encoding

Module: source/services/encoding.js

Next you will want to build a module to encode/decode transactions and state data. Remember from the design, that we are using sorted JSON strings encoded in a Node Buffer. Webpack will allow you to use Buffers in the browser just fine, but you could also use UInt8Arrays if you prefer.

03 Transactions

Module: source/services/transactions.js

Useful APIs:

This is the first really Sawtooth specific module. You will need to take your encoded payloads, and wrap them in a transaction. Then one or more transactions get wrapped in a batch, and one or more batches get wrapped in a batch list, which is finally serialized as bytes so it can be sent to the REST API. All of these data structures are Google Protobufs, which are a somewhat complex, but very efficient way of serializing data. You don't need to become a protobuf expert to use Sawtooth, but you should probably familarize yourself with the, Protobuf.js API, which is what the Sawtooth SDK uses under the hood.

In particular, be ready to use:

  • TransactionHeader.encode(headerData).finish()
  • Transaction.create(transactionData)
  • BatchHeader.encode(batchHeaderData).finish()
  • Batch.create(batchData)
  • BatchList.encode(batchListData).finish()

04 Addressing

Module: source/services/addressing.js

The last module you will complete stub functions for is one to generate addresses for entities in state. You will need these in order to fetch any data from the REST API.

05 Requests

Module: None Useful APIs:

The design and execution of the rest of the client is entirely up to you. There are no more tests. One thing you will definitely need to do though is send GET/POST requests to the blockchain. If you like, you could incorporate this functionality throughout the rest of your app. However, it will likely make sense for you to create another services module to encapsulate interactions with the REST API.

Either way, one perk of the docker setup for serving this client, is that the Sawtooth REST API has been proxied under the api/ path, so you can access every REST API route using a relative path. There are three routes/queries you are likely to be concerned with.

GET /api/state/{address}

This fetches a base64 encoded entity from state. Sawtooth puts your data in a JSON envelope under the data key, which axios automatically decodes for you, and stores under the . . . data key. This means the data you want will be in response.data.data.

GET /api/state?address={partial address}

The merkle tree that Sawtooth data is stored in allows you to fetch multiple entities at once if they are under the same address prefix. So for example, you could fetch /api/state?address=5f4d76 to get every entity in state, or /api/state?address=5f4d7600 to get every collection. These entities will be in a JSON array with this format:

[
    {
        "address": "<string, full address>",
        "data": "<base64 string, encoded entity>"
    }
]

And yes, that means the base64 string you want to decode is at response.data.data[i].data.

¯\_(ツ)_/¯

POST /api/batches

This is the endpoint to which you will actually post your serialized batch lists. Include them directly in the body of your request, and don't forget to set the Content-Type header to application/octet-stream.

06 The User Interface

Module: source/index.jsx

Requirements:

  • Allow users to generate new private keys and create collections
  • Allow users to "sign in" by copying/pasting in their private key
  • Allow users to View all cryptomoji in state
  • Allow users to view just their own cryptomoji
  • Allow users to select a sire from their collection
  • Allow users to view all available sires
  • Allow users to breed one of their cryptomoji with a sire

There are no tests for the UI. It is up to you to design and build an interface you are happy with that satisfies all of these requirements. Have fun!

Note that a parseDna method is provided, which will convert a DNA string into a real kaomoji for display. Make sure you use it!

Extra Credit

Requirements:

  • Allow users to create/cancel offers from their cryptomoji
  • Allow users to view all available offers
  • Allow users to add/cancel responses to outstanding offers
  • Allow users to accept responses, executing a trade
  • Allow users to view detailed information on a cryptomoji, like their family tree and "tags" (generated by parseDna)
  • Dynamically alter the way a cryptomoji is styled based on its tags
  • Allow users to filter/sort lists of cryptomoji by tags and/or other factors (e.g. "number of times sired")

Also don't forget to remove the .skip from Line 96 of tests/04-Addressing.js!