diff --git a/LFS171x/docs/introduction-to-hyperledger-fabric.md b/LFS171x/docs/introduction-to-hyperledger-fabric.md index b8b997b8..b68367ee 100644 --- a/LFS171x/docs/introduction-to-hyperledger-fabric.md +++ b/LFS171x/docs/introduction-to-hyperledger-fabric.md @@ -1 +1,1552 @@ -# Introduction and Learning Objectives +# Introduction to Hyperledger Fabric + +- [Introduction to Hyperledger Fabric](#introduction-to-hyperledger-fabric) + - [Introduction and Learning Objectives](#introduction-and-learning-objectives) + - [Video: Introduction to Hyperledger Fabric (Alexandra & Arianna Groetsema)](#video-introduction-to-hyperledger-fabric-alexandra--arianna-groetsema) + - [Learning Objectives](#learning-objectives) + - [Addressing Illegal, Unregulated, and Unreported Tuna Fishing (Demonstrated Scenario)](#addressing-illegal-unregulated-and-unreported-tuna-fishing-demonstrated-scenario) + - [Video: About the Demonstrated Scenario (Alexandra & Arianna Groetsema)](#video-about-the-demonstrated-scenario-alexandra--arianna-groetsema) + - [Defining Our Actors](#defining-our-actors) + - [Featured Hyperledger Fabric Elements](#featured-hyperledger-fabric-elements) + - [The Catch](#the-catch) + - [The Incentives](#the-incentives) + - [The Sale](#the-sale) + - [The Regulators](#the-regulators) + - [Gaining Network Membership](#gaining-network-membership) + - [Summary of Demonstrated Scenario](#summary-of-demonstrated-scenario) + - [Key Components and Transaction Flow](#key-components-and-transaction-flow) + - [Video: Introduction to Hyperledger Fabric Architecture (Arianna Groetsema)](#video-introduction-to-hyperledger-fabric-architecture-arianna-groetsema) + - [Roles within a Hyperledger Fabric Network](#roles-within-a-hyperledger-fabric-network) + - [How to Reach Consensus](#how-to-reach-consensus) + - [Transaction Flow (Step 1)](#transaction-flow-step-1) + - [Transaction Flow (Step 2)](#transaction-flow-step-2) + - [Transaction Endorsement](#transaction-endorsement) + - [Transaction Flow (Step 3)](#transaction-flow-step-3) + - [Transaction Flow (Step 4)](#transaction-flow-step-4) + - [Video: Ordering Service (Chris Ferris)](#video-ordering-service-chris-ferris) + - [Ordering (Part I)](#ordering-part-i) + - [Ordering (Part II)](#ordering-part-ii) + - [Transaction Flow (Step 5)](#transaction-flow-step-5) + - [Transaction Flow (Step 6)](#transaction-flow-step-6) + - [Identity Verification](#identity-verification) + - [Transaction Flow Summary](#transaction-flow-summary) + - [Channels](#channels) + - [State Database](#state-database) + - [Smart Contracts](#smart-contracts) + - [Membership Service Provider (MSP)](#membership-service-provider-msp) + - [What Does the MSP Do?](#what-does-the-msp-do) + - [Fabric-Certificate Authority](#fabric-certificate-authority) + - [Installing Hyperledger Fabric](#installing-hyperledger-fabric) + - [Technical Prerequisites](#technical-prerequisites) + - [Installing Hyperledger Fabric Docker Images and Binaries](#installing-hyperledger-fabric-docker-images-and-binaries) + - [Installing Hyperledger Fabric](#installing-hyperledger-fabric) + - [Starting a Test Hyperledger Fabric Network](#starting-a-test-hyperledger-fabric-network) + - [Getting Started with Your First Network](#getting-started-with-your-first-network) + - [Finishing Up and Shutting Down the Network](#finishing-up-and-shutting-down-the-network) + - [Video: Installing Hyperledger Fabric (Demo)](#video-installing-hyperledger-fabric-demo) + - [Understanding Chaincode](#understanding-chaincode) + - [Chaincode](#chaincode) + - [Chaincode Key APIs](#chaincode-key-apis) + - [Overview of a Chaincode Program](#overview-of-a-chaincode-program) + - [Sample Chaincode Decomposed - Dependencies](#sample-chaincode-decomposed---dependencies) + - [Sample Chaincode Decomposed - Struct](#sample-chaincode-decomposed---struct) + - [Sample Chaincode Decomposed - Init Method](#sample-chaincode-decomposed---init-method) + - [Sample Chaincode Decomposed - Invoke Method](#sample-chaincode-decomposed---invoke-method) + - [Sample Chaincode Decomposed - Main Function](#sample-chaincode-decomposed---main-function) + - [Chaincode Walkthrough (Demonstrated Scenario)](#chaincode-walkthrough-demonstrated-scenario) + - [Setting the Stage](#setting-the-stage) + - [Defining the Asset Attributes](#defining-the-asset-attributes) + - [Invoke Method (Part I)](#invoke-method-part-i) + - [Invoke Method (Part II)](#invoke-method-part-ii) + - [Chaincode Methods - queryTuna](#chaincode-methods---querytuna) + - [Chaincode Methods - initLedger](#chaincode-methods---initledger) + - [Chaincode Methods - recordTuna](#chaincode-methods---recordtuna) + - [Writing an Application](#writing-an-application) + - [What Is a Blockchain Application?](#what-is-a-blockchain-application) + - [How Applications Interact with the Network](#how-applications-interact-with-the-network) + - [Fabric Node.js SDK](#fabric-nodejs-sdk) + - [Video: Hyperledger Fabric Tuna Application (Alexandra Groetsema)](#video-hyperledger-fabric-tuna-application-alexandra-groetsema) + - [Getting Started (Part I)](#getting-started-part-i) + - [Getting Started (Part II)](#getting-started-part-ii) + - [File Structure of Application](#file-structure-of-application) + - [Query All Tuna Recorded](#query-all-tuna-recorded) + - [Query a Specific Tuna Recorded](#query-a-specific-tuna-recorded) + - [Change Tuna Holder](#change-tuna-holder) + - [Record a Tuna Catch](#record-a-tuna-catch) + - [Finishing Up](#finishing-up) + - [Application Flow Basics](#application-flow-basics) + - [Application Flow Example](#application-flow-example) + - [Joining the Hyperledger Fabric Community](#joining-the-hyperledger-fabric-community) + - [Becoming Involved with the Hyperledger Fabric Project](#becoming-involved-with-the-hyperledger-fabric-project) + - [Video: The Future of Hyperledger Fabric (Chris Ferris)](#video-the-future-of-hyperledger-fabric-chris-ferris) + - [Community Meetings and Mailing Lists](#community-meetings-and-mailing-lists) + - [JIRA and Gerrit](#jira-and-gerrit) + - [Rocket.Chat](#rocketchat) + - [Knowledge Check](#knowledge-check) + - [Knowledge Check 7.1](#knowledge-check-71) + - [Knowledge Check 7.2](#knowledge-check-72) + - [Knowledge Check 7.3](#knowledge-check-73) + - [Knowledge Check 7.4](#knowledge-check-74) + - [Knowledge Check 7.5](#knowledge-check-75) + - [Knowledge Check 7.6](#knowledge-check-76) + - [Knowledge Check 7.7](#knowledge-check-77) + - [Knowledge Check 7.8](#knowledge-check-78) + - [Knowledge Check 7.9](#knowledge-check-79) + - [Knowledge Check 7.10](#knowledge-check-710) + - [Conclusions & Learning Objectives (Review)](#conclusions--learning-objectives-review) + - [Learning Objectives (Review)](#learning-objectives-revie) + - [Video: Conclusions (Alexandra Groetsema)](#video-conclusions-alexandra-groetsema) + + +## Introduction and Learning Objectives + +### Video: Introduction to Hyperledger Fabric (Alexandra & Arianna Groetsema) + +#### Introduction to Hyperledger Fabric (Alexandra & Arianna Groetsema) + +[![Introduction to Hyperledger Fabric (Alexandra & Arianna Groetsema)](../images/video-image.png)](https://youtu.be/0B2VYDZn9dA) + +### Learning Objectives + +By the end of this chapter you should be able to: + +* Understand the basics of Hyperledger Fabric v1.0. +* Walk through and analyze a demonstrated scenario on Hyperledger Fabric. +* Discuss crucial components of the Hyperledger Fabric architecture, including clients, peers, ordering service and membership service provider. +* Set up a sample network and simple application with a Javascript SDK. +* Discuss Chaincode (Hyperledger Fabric smart contract) and review an example. +* Get involved in the framework discussion and development. + +## Addressing Illegal, Unregulated, and Unreported Tuna Fishing (Demonstrated Scenario) + +### Video: About the Demonstrated Scenario (Alexandra & Arianna Groetsema) + +According to the [World Economic Forum](https://www.weforum.org/agenda/2017/05/can-technology-help-tackle-illegal-fishing/), + +>_"Illegal, unreported, and unregulated (IUU) fishing represents a theft of around 26 million tonnes, or close to $24 billion value of seafood a year."_ + +--- + +#### About the Demonstrated Scenario (Alexandra & Arianna Groetsema) + +[![About the Demonstrated Scenario (Alexandra & Arianna Groetsema)](../images/video-image.png)](https://youtu.be/nwKgqJBWtac) + +### Defining Our Actors + +**Sarah** is the tuna fisher who sustainably and legally catches tuna. + +**Regulators** verify that the tuna has been legally and sustainably caught. + +**Miriam** is a restaurant owner who will serve as the recipient in this situation. + +**Carl** is another restaurant owner fisherman Sarah can sell tuna to. + +|![Fabric_demonstrated_scenario_actors](../images/introduction-to-hyperledger-fabric/Fabric_demonstrated_scenario_actors.png)| +|:--:| +| *Licensed under [CC By 4.0](https://creativecommons.org/licenses/by/4.0/)* | + +Using Hyperledger Fabric, we will be demonstrating how tuna fishing can be improved starting from the source, fisherman Sarah, and the process by which she sells her tuna to Miriam's restaurant. + +### Featured Hyperledger Fabric Elements + +**Channels** are data partitioning mechanisms that allow transaction visibility for stakeholders only. Each channel is an independent chain of transaction blocks containing only transactions for that particular channel. + +The **chaincode** (Smart Contracts) encapsulates both the asset definitions and the business logic (or transactions) for modifying those assets. Transaction invocations result in changes to the ledger. + +The **ledger** contains the current world state of the network and a chain of transaction invocations. A shared, permissioned ledger is an append-only system of records and serves as a single source of truth. + +The **network** is the collection of data processing peers that form a blockchain network. The network is responsible for maintaining a consistently replicated ledger. + +The **ordering service** is a collection of nodes that orders transactions into a block. + +The **world state** reflects the current data about all the assets in the network. This data is stored in a database for efficient access. Current supported databases are LevelDB and CouchDB. + +The **membership service provider** (MSP) manages identity and permissioned access for clients and peers. + +### The Catch + +We will start with Sarah, our licensed tuna fisher, who makes a living selling her tuna to multiple restaurants. Sarah operates as a private business, in which her company frequently makes international deals. Through a client application, Sarah is able to gain entry to a Hyperledger Fabric blockchain network comprised of other fishermen, as well as regulators and restaurant owners. Sarah has the ability to add to and update information in the blockchain network's ledger as tuna pass through the supply chain, while regulators and restaurants have read access to the ledger. + +After each catch, Sarah records information about each individual tuna, including: a unique ID number, the location and time of the catch, its weight, the vessel type, and who caught the fish. For the sake of simplicity, we will stick with these six data attributes. However, in an actual application, many more details would be recorded, from toxicology, to other physical characteristics. + +These details are saved in the world state as a key/value pair based on the specifications of a chaincode contract, allowing Sarah’s application to effectively create a transaction on the ledger. You can see the example below: + +``` +$ var tuna = { id: ‘0001’, holder: ‘Sarah’, location: { latitude: '41.40238', longitude: '2.170328'}, when: '20170630123546', weight: ‘58lbs’, vessel : ‘9548E’ } +``` + +### The Incentives + +Miriam is a restaurant owner looking to source low cost, yet high quality tuna that have been responsibly caught. Whenever Miriam buys tuna, she is always uncertain whether she can trust that the tuna she is purchasing is legally and sustainably caught, given the prominence of illegal and unreported tuna fishing. + +At the same time, as a legitimate and experienced fisherman, Sarah strives to make a living selling her tuna at a reasonable price. She would also like autonomy over who she sells to and at what price. + +Luckily for both Sarah and Miriam, Hyperledger Fabric can help! + +### The Sale + +Normally, Sarah sells her tuna to restaurateurs, such as Carl, for $80 per pound. However, Sarah agrees to give Miriam a special price of $50 per pound of tuna, rather than her usual rate. In a traditional public blockchain, once Sarah and Miriam have completed their transaction, the entire network is able to view the details of this agreement, especially the fact that Sarah gave Miriam a special price. As you can imagine, having other restaurateurs, such as Carl, aware of this deal is not economically advantageous for Sarah. + +|![fabric_sale_scenario](../images/introduction-to-hyperledger-fabric/fabric_sale_scenario.png)| +|:--:| +| *Licensed under [CC By 4.0](https://creativecommons.org/licenses/by/4.0/)* | + +To remedy this, Sarah wants the specifics of her deal to not be available to everyone on the network, but still have every actor in the network be able to view the details of the fish she is selling. Using Hyperledger Fabric's feature of **channels**, Sarah can privately agree on the terms with Miriam, such that only the two of them can see them, without anyone else knowing the specifics. + +Additionally, other fishermen, who are not part of Sarah and Miriam’s transaction, will not see this transaction on their ledger. This ensures that another fisherman cannot undercut the bid by having information about the prices that Sarah is charging different restaurateurs. + +### The Regulators + +Regulators will also gain entry to this Hyperledger Fabric blockchain network to confirm, verify, and view details from the ledger. Their application will allow these actors to query the ledger and see the details of each of Sarah’s catches to confirm that she is legally catching her fish. Regulators only need to have query access, and do not need to add entries to the ledger. With that being said, they may be able to adjust who can gain entry to the network and/or be able to remove fishermen from the network, if found to be partaking in illegal activities. + +### Gaining Network Membership + +Hyperledger Fabric is a permissioned network, meaning that only participants who have been approved can gain entry to the network. To handle network membership and identity, **membership service providers** (MSP) manage user IDs, and authenticate all the participants in the network. A Hyperledger Fabric blockchain network can be governed by one or more MSPs. This provides modularity of membership operations, and interoperability across different membership standards and architectures. + +In our scenario, the regulator, the approved fishermen, and the approved restaurateurs should be the only ones allowed to join the network. To achieve this, a membership service provider (MSP) is defined to accommodate membership for all members of this supply chain. In configuring this MSP, certificates and membership identities are created. Policies are then defined to dictate the read/write policies of a channel, or the endorsement policies of a chaincode. + +Our scenario has two separate chaincodes, which are run on three separate channels. The two chaincodes are: one for the price agreement between the fisherman and the restaurateur, and one for the transfer of tuna. The three channels are: one for the price agreement between Sarah and Miriam; one for the price agreement between Sarah and Carl; and one for the transfer of tuna. Each member of this network knows about each other and their identity. The channels provide privacy and confidentiality of transactions. + +In Hyperledger Fabric, MSPs also allow for dynamic membership to add or remove members to maintain integrity and operation of the supply chain. For example, if Sarah was found to be catching her fish illegally, she can have her membership revoked, without compromising the rest of the network. This feature is critical, especially for enterprise applications, where business relationships change over time. + +### Summary of Demonstrated Scenario + +Below is a summary of the tuna catch scenario presented in this section: + + 1. Sarah catches a tuna and uses the supply chain application’s user interface to record all the details about the catch to the ledger. Before it reaches the ledger, the transaction is passed to the endorsing peers on the network, where it is then endorsed. The endorsed transaction is sent to the ordering service, to be ordered into a block. This block is then sent to the committing peers in the network, where it is committed after being validated. + 2. As the tuna is passed along the supply chain, regulators may use their own application to query the ledger for details about specific catches (excluding price, since they do not have access to the price-related chaincode). + 3. Sarah may enter into an agreement with a restaurateur Carl, and agree on a price of $80 per pound. They use the blue channel for the chaincode contract stipulating $80/lb. The blue channel's ledger is updated with a block containing this transaction. + 4. In a separate business agreement, Sarah and Miriam agree on a special price of $50 per pound. They use the red channel's chaincode contract stipulating $50/lb. The red channel's ledger is updated with a block containing this transaction. + +|![Demonstrated_Tuna_Fishing_Scenario](../images/introduction-to-hyperledger-fabric/Demonstrated_Tuna_Fishing_Scenario.png)| +|:--:| +| *Licensed under [CC By 4.0](https://creativecommons.org/licenses/by/4.0/)* | + +## Key Components and Transaction Flow + +### Video: Introduction to Hyperledger Fabric Architecture (Arianna Groetsema) + +#### Introduction to Hyperledger Fabric (Alexandra & Arianna Groetsema) + +[![Introduction to Hyperledger Fabric (Alexandra & Arianna Groetsema)](../images/video-image.png)](https://youtu.be/nyNUvtsmZNE) + +### Roles within a Hyperledger Fabric Network + +There are three different types of roles within a Hyperledger Fabric network: + + - **Clients** +
Clients are applications that act on behalf of a person to propose transactions on the network. + - **Peers** +
Peers maintain the state of the network and a copy of the ledger. There are two different types of peers: endorsing and committing peers. However, there is an overlap between endorsing and committing peers, in that endorsing peers are a special kind of committing peers. All peers commit blocks to the distributed ledger. +
\- _Endorsers_ simulate and endorse transactions +
\- _Committers_ verify endorsements and validate transaction results, prior to committing transactions to the blockchain. + - **Ordering Service** +
The ordering service accepts endorsed transactions, orders them into a block, and delivers the blocks to the committing peers. + +### How to Reach Consensus + +In a distributed ledger system, **consensus** is the process of reaching agreement on the next set of transactions to be added to the ledger. In Hyperledger Fabric, consensus is made up of three distinct steps: + + - Transaction endorsement + - Ordering + - Validation and commitment. + +These three steps ensure the policies of a network are upheld. We will explore how these steps are implemented by exploring the transaction flow. + +### Transaction Flow (Step 1) + +Within a Hyperledger Fabric network, transactions start out with client applications sending transaction proposals, or, in other words, proposing a transaction to endorsing peers. + +|![Key_Components_-_Transaction_Proposal](../images/introduction-to-hyperledger-fabric/Key_Components_-_Transaction_Proposal.png)| +|:--:| +| *Licensed under [CC By 4.0](https://creativecommons.org/licenses/by/4.0/)* | + +**Client applications** are commonly referred to as **applications** or **clients**, and allow people to communicate with the blockchain network. Application developers can leverage the Hyperledger Fabric network through the application SDK. + +### Transaction Flow (Step 2) + +Each endorsing peer simulates the proposed transaction, without updating the ledger. The endorsing peers will capture the set of **R**ead and **W**ritten data, called **RW Sets**. These RW sets capture what was read from the current world state while simulating the transaction, as well as what would have been written to the world state had the transaction been executed. These RW sets are then signed by the endorsing peer, and returned to the client application to be used in future steps of the transaction flow. + +|![Transaction_flow_step_2](../images/introduction-to-hyperledger-fabric/Transaction_flow_step_2.png)| +|:--:| +| *Licensed under [CC By 4.0](https://creativecommons.org/licenses/by/4.0/)* | + +Endorsing peers must hold smart contracts in order to simulate the transaction proposals. + +### Transaction Endorsement + +A transaction endorsement is a signed response to the results of the simulated transaction. The method of transaction endorsements depends on the endorsement policy which is specified when the chaincode is deployed. An example of an endorsement policy would be "the majority of the endorsing peers must endorse the transaction". Since an endorsement policy is specified for a specific chaincode, different channels can have different endorsement policies. + +### Transaction Flow (Step 3) + +The application then submits the endorsed transaction and the RW sets to the ordering service. Ordering happens across the network, in parallel with endorsed transactions and RW sets submitted by other applications. + +|![Transaction_flow_step_3](../images/introduction-to-hyperledger-fabric/Transaction_flow_step_3.png)| +|:--:| +| *Licensed under [CC By 4.0](https://creativecommons.org/licenses/by/4.0/)* | + +### Transaction Flow (Step 4) + +The ordering service takes the endorsed transactions and RW sets, orders this information into a block, and delivers the block to all committing peers. + +|![Transaction_Flow_Step_4](../images/introduction-to-hyperledger-fabric/Transaction_Flow_Step_4.png)| +|:--:| +| *Licensed under [CC By 4.0](https://creativecommons.org/licenses/by/4.0/)* | + +The **ordering service**, which is made up of a cluster of orderers, does not process transactions, smart contracts, or maintains the shared ledger. The ordering service accepts the endorsed transactions and specifies the order in which those transactions will be committed to the ledger. The Fabric v1.0 architecture has been designed such that the specific implementation of 'ordering' (Solo, Kafka, BFT) becomes a pluggable component. The default ordering service for Hyperledger Fabric is Kafka. Therefore, the ordering service is a modular component of Hyperledger Fabric. + +### Video: Ordering Service (Chris Ferris) + +#### Ordering Service (Chris Ferris) + +[![Ordering Service (Chris Ferris)](../images/video-image.png)](https://youtu.be/mwIMxMRZFL4) + +### Ordering (Part I) + +_Transactions within a timeframe are sorted into a block and are committed in sequential order._ + +In a blockchain network, transactions have to be written to the shared ledger in a consistent order. The order of transactions has to be established to ensure that the updates to the world state are valid when they are committed to the network. Unlike the Bitcoin blockchain, where ordering occurs through the solving of a cryptographic puzzle, or _mining_, Hyperledger Fabric allows the organizations running the network to choose the ordering mechanism that best suits that network. This modularity and flexibility makes Hyperledger Fabric incredibly advantageous for enterprise applications. + +### Ordering (Part II) + +Hyperledger Fabric provides three ordering mechanisms: SOLO, Kafka, and Simplified Byzantine Fault Tolerance (SBFT), the latter of which has not yet been implemented in Fabric v1.0. + + - **SOLO** is the Hyperledger Fabric ordering mechanism most typically used by developers experimenting with Hyperledger Fabric networks. SOLO involves a single ordering node. + - **Kafka** is the Hyperledger Fabric ordering mechanism that is recommended for production use. This ordering mechanism utilizes Apache Kafka, an open source stream processing platform that provides a unified, high-throughput, low-latency platform for handling real-time data feeds. In this case, the data consists of endorsed transactions and RW sets. The Kafka mechanism provides a crash fault-tolerant solution to ordering. + - **SBFT** stands for Simplified Byzantine Fault Tolerance. This ordering mechanism is both crash fault-tolerant and byzantine fault-tolerant, meaning that it can reach agreement even in the presence of malicious or faulty nodes. The Hyperledger Fabric community has not yet implemented this mechanism, but it is on their roadmap. + +These three ordering mechanisms provide alternate methodologies for agreeing on the order of transactions. + +### Transaction Flow (Step 5) + +The committing peer validates the transaction by checking to make sure that the RW sets still match the current world state. Specifically, that the Read data that existed when the endorsers simulated the transaction is identical to the current world state. When the committing peer validates the transaction, the transaction is written to the ledger, and the world state is updated with the Write data from the RW Set. + +|![Transaction_Flow_Step_5](../images/introduction-to-hyperledger-fabric/Transaction_Flow_Step_5.png)| +|:--:| +| *Licensed under [CC By 4.0](https://creativecommons.org/licenses/by/4.0/)* | + +If the transaction fails, that is, if the committing peer finds that the RW set does not match the current world state, the transaction ordered into a block will still be included in that block, but it will be marked as invalid, and the world state will not be updated. + +Committing peers are responsible for adding blocks of transactions to the shared ledger and updating the world state. They may hold smart contracts, but it is not a requirement. + +### Transaction Flow (Step 6) + +Lastly, the committing peers asynchronously notify the client application of the success or failure of the transaction. Applications will be notified by each committing peer. + +|![Transaction_Flow_Step_6](../images/introduction-to-hyperledger-fabric/Transaction_Flow_Step_6.png)| +|:--:| +| *Licensed under [CC By 4.0](https://creativecommons.org/licenses/by/4.0/)* | + +### Identity Verification + +In addition to the multitude of endorsement, validity, and versioning checks that take place, there are also ongoing identity verifications happening during each step of the transaction flow. Access control lists are implemented on the hierarchical layers of the network (from the ordering service down to channels), and payloads are repeatedly signed, verified, and authenticated as a transaction proposal passes through the different architectural components. + +### Transaction Flow Summary + +It is important to note that the state of the network is maintained by peers, and not by the ordering service or the client. Normally, you will design your system such that different machines in the network play different roles. That is, machines that are part of the ordering service should not be set up to also endorse or commit transactions, and vice versa. However, there is an overlap between endorsing and committing peers on the system. Endorsing peers must have access to and hold smart contracts, in addition to fulfilling the role of a committing peer. Endorsing peers do commit blocks, but committing peers do not endorse transactions. + +Endorsing peers verify the client signature, and execute a chaincode function to simulate the transaction. The output is the chaincode results, a set of key/value versions that were read in the chaincode (Read set), and the set of keys/values that were written by the chaincode. The proposal response gets sent back to the client, along with an endorsement signature. These proposal responses are sent to the orderer to be ordered. The orderer then orders the transactions into a block, which it forwards to the endorsing and committing peers. The RW sets are used to verify that the transactions are still valid before the content of the ledger and world state is updated. Finally, the peers asynchronously notify the client application of the success or failure of the transaction. + +### Channels + +Channels allow organizations to utilize the same network, while maintaining separation between multiple blockchains. Only the members of the channel on which the transaction was performed can see the specifics of the transaction. In other words, channels partition the network in order to allow transaction visibility for stakeholders only. This mechanism works by delegating transactions to different ledgers. Only the members of the channel are involved in consensus, while other members of the network do not see the transactions on the channel. + +|![Key_Components_Channels](../images/introduction-to-hyperledger-fabric/Key_Components_Channels.png)| +|:--:| +| *Licensed under [CC By 4.0](https://creativecommons.org/licenses/by/4.0/)* | + +The diagram above shows three distinct channels -- blue, orange, and grey. Each channel has its own application, ledger, and peers. + +Peers can belong to multiple networks or channels. Peers that do participate in multiple channels simulate and commit transactions to different ledgers. The ordering service is the same across any network or channel. + +A few things to remember: + + - The network setup allows for the creation of channels. + - The same chaincode logic can be applied to multiple channels. + - A given user can participate in multiple channels. + +### State Database + +The current state data represents the latest values for all assets in the ledger. Since the current state represents all the committed transactions on the channel, it is sometimes referred to as world state. + +Chaincode invocations execute transactions against the current state data. To make these chaincode interactions extremely efficient, the latest key/value pairs for each asset are stored in a state database. The state database is simply an indexed view into the chain’s committed transactions. It can therefore be regenerated from the chain at any time. The state database will automatically get recovered (or generated, if needed) upon peer startup, before new transactions are accepted. The default state database, **LevelDB**, can be replaced with **CouchDB**. + + - LevelDB is the default key/value state database for Hyperledger Fabric, and simply stores key/value pairs. + - CouchDB is an alternative to LevelDB. Unlike LevelDB, CouchDB stores JSON objects. CouchDB is unique in that it supports keyed, composite, key range, and full data-rich queries. + +Hyperledger Fabric’s LevelDB and CouchDB are very similar in their structure and function. Both LevelDB and CouchDB support core chaincode operations, such as getting and setting key assets, and querying based on these keys. With both, keys can be queried by range, and composite keys can be modeled to enable equivalence queries against multiple parameters. But, as a JSON document store, CouchDB additionally enables rich query against the chaincode data, when chaincode values (e.g. assets) are modeled as JSON data. + +|![State_Database](../images/introduction-to-hyperledger-fabric/State_Database.png)| +|:--:| +| *Licensed under [CC By 4.0](https://creativecommons.org/licenses/by/4.0/)* | + +### Smart Contracts + +As a reminder, smart contracts are computer programs that contain logic to execute transactions and modify the state of the assets stored within the ledger. Hyperledger Fabric smart contracts are called **chaincode** and are written in Go. The chaincode serves as the business logic for a Hyperledger Fabric network, in that the chaincode directs how you manipulate assets within the network. We will discuss more about chaincode in the _Understanding Chaincode_ section. + +### Membership Service Provider (MSP) + +The membership service provider, or MSP, is a component that defines the rules in which identities are validated, authenticated, and allowed access to a network. The MSP manages user IDs and authenticates clients who want to join the network. This includes providing credentials for these clients to propose transactions. The MSP makes use of a _Certificate Authority_, which is a pluggable interface that verifies and revokes user certificates upon confirmed identity. The default interface used for the MSP is the **Fabric-CA API**, however, organizations can implement an External Certificate Authority of their choice. This is another feature of Hyperledger Fabric that is modular. Hyperledger Fabric supports many credential architectures, which allows for many types of External Certificate Authority interfaces to be used. As a result, a single Hyperledger Fabric network can be controlled by multiple MSPs, where each organization brings their favorite. + +### What Does the MSP Do? + +To start, users are authenticated using a certificate authority. The certificate authority identifies the application, peer, endorser, and orderer identities, and verifies these credentials. A signature is generated through the use of a _Signing Algorithm_ and a _Signature Verification Algorithm_. + +Specifically, generating a signature starts with a _Signing Algorithm_, which utilizes the credentials of the entities associated with their respective identities, and outputs an endorsement. A signature is generated, which is a byte array that is bound to a specific identity. Next, the _Signature Verification Algorithm_ takes the identity, endorsement, and signature as inputs, and outputs 'accept' if the signature byte array corresponds with a valid signature for the inputted endorsement, or outputs 'reject' if not. If the output is 'accept', the user can see the transactions in the network and perform transactions with other actors in the network. If the output is 'reject', the user has not been properly authenticated, and is not able to submit transactions to the network, or view any previous transactions. + +|![The_role_of_membership_service_provider](../images/introduction-to-hyperledger-fabric/The_role_of_membership_service_provider.jpg)| +|:--:| +| *Licensed under [CC By 4.0](https://creativecommons.org/licenses/by/4.0/)* | + +### Fabric-Certificate Authority + +In general, _Certificate Authorities_ manage enrollment certificates for a permissioned blockchain. **Fabric-CA** is the default certificate authority for Hyperledger Fabric, and handles the registration of user identities. The Fabric-CA certificate authority is in charge of issuing and revoking Enrollment Certificates (E-Certs). The current implementation of Fabric-CA only issues E-Certs, which supply long term identity certificates. E-Certs, which are issued by the Enrollment Certificate Authority (E-CA), assign peers their identity and give them permission to join the network and submit transactions. + +## Installing Hyperledger Fabric + +### Technical Prerequisites + +In order to successfully install Hyperledger Fabric, you should be familiar with Go and Node.js programming languages, and have the following features installed on your computer: cURL, Node.js, npm package manager, Go language, Docker, and Docker Compose. + +If you need further details on these prerequisites, visit Chapter 4, _Technical Requirements_. + +### Installing Hyperledger Fabric Docker Images and Binaries + +Next, we will download the latest released Docker images for Hyperledger Fabric, and tag them with the **`latest`** tag. Execute the command from within the directory into which you will extract the platform-specific binaries: + +``` +$ curl -sSL https://goo.gl/6wtTN5 | bash -s 1.1.0 +``` + +__**NOTE:**__ Check [http://hyperledger-fabric.readthedocs.io/en/release-1.1/samples.html#binaries](http://hyperledger-fabric.readthedocs.io/en/release-1.1/samples.html#binaries) for the latest URL (the blue portion in the above curl command) to pull in binaries. + +This command downloads binaries for **`cryptogen`**, **`configtxgen`**, **`configxlator`**, **`peer`** AND downloads the Hyperledger Fabric Docker images. These assets are placed in a **`bin`** subdirectory of the current working directory. + +To confirm and see the list of Docker images you’ve just downloaded, run: + +``` +$ docker images +``` + +The expected response is: + +|![Fabric_installation_1](../images/introduction-to-hyperledger-fabric/Fabric_installation_1.jpg)| +|:--:| +| *Licensed under [CC By 4.0](https://creativecommons.org/licenses/by/4.0/)* | + +**Note** the tags for each of the repositories above boxed in red. If the Docker images are not already tagged with the **`latest`** tag, perform the following command for each of the Docker images: + +``` +$ docker tag hyperledger/fabric-tools:x86_64-1.0.2 hyperledger/fabric-tools:latest +``` + +Swap out the blue portion with the tags you see in your list of repositories. Also, swap out the red portion with the name of the Docker image you are switching the tag for (e.g.: **`fabric-tools`**, **`fabric-ccenv`**, **`fabric-orderer`**, etc.). Repeat this step for all Docker images you see in the list. + +In the screenshot above, the Docker images are already tagged. If this is the case for you, you do not need to do this extra step. + +### Installing Hyperledger Fabric + +As an additional measure, you may want to add the bin subdirectory to your PATH environment variable, so these can be picked up without needing to qualify the PATH to each binary. You can do this by running the following: + +``` +$ export PATH=$PWD/bin:$PATH +``` + +To install the Hyperledger Fabric sample code which will be used in the tutorials, do: + +``` +$ git clone https://github.com/hyperledger/fabric-samples.git + +$ cd fabric-samples/first-network +``` + +### Starting a Test Hyperledger Fabric Network + +Now that we have successfully installed Hyperledger Fabric, we can walk through setting up a simple network that has two members. To refer back to our demonstrated scenario, the network includes asset management of each tuna verified, transferred, and purchased between Sarah, the fisherman, and Miriam, the restaurateur. We’ll create a simple two member network consisting of two organizations (effectively, Sarah and Miriam), each maintaining two peers and an ordering service. + +We will use Docker images to bootstrap our first Hyperledger Fabric network. It will also launch a container to run a scripted execution that will join peers to a channel, deploy, and instantiate the chaincode, and execute transactions against the chaincode. + +### Getting Started with Your First Network + +Are you ready to get started? Run this command ( within the **`first-network`** folder ): + +``` +$ ./byfn.sh -m generate +``` + +A brief description will appear, along with a **`Y/N`** command line prompt. Respond with a **`Y \`** to continue. + +This step generates all of the certificates and keys for all our various network entities, including the genesis block used to bootstrap the ordering service and a collection of configuration transactions required to create a channel. + +Next, you can start the network with the following command: + +``` +$ ./byfn.sh -m up +``` + +Another command line will appear, reply with **`Y \`** to continue. + +Logs will appear in the command line, showing containers being launched, channels being created and joined, chaincode being installed, instantiated, and invoked on all the peers, as well as various transaction logs. + +**Troubleshooting Note:** +If you have difficulties with the two previous commands and you suspect that your Docker images may be at fault, you can start back from scratch, which will delete and untag the Docker images. + +``` +$ docker rmi -f $(docker images -q) +``` + +Once you run this command, return to the _Installing Hyperledger Fabric Docker Images and Binaries_ page, at the beginning of this section. + +### Finishing Up and Shutting Down the Network + +Finally, let’s test bringing down this network. + +Within the same terminal, do **`Control+C`** to exit the current execution. + +Then, run the following command: + +``` +$ ./byfn.sh -m down +``` + +Another command line will appear, reply with **`Y \`** to continue. + +This command will kill your containers, remove the crypto material and four artifacts, and delete the chaincode images from your Docker Registry. + +And that’s it for a simple demonstration! + +These simple steps show how we can easily spin up and bring down a Hyperledger Fabric network, given the code we have. In the next section, we will learn more about chaincode. + +### Video: Installing Hyperledger Fabric (Demo) + +#### Installing Hyperledger Fabric (Demo) + +[![Installing Hyperledger Fabric (Demo)](../images/video-image.png)](https://youtu.be/eM6HIOpexGE) + +## Understanding Chaincode + +### Chaincode + +In Hyperledger Fabric, **chaincode** is the 'smart contract' that runs on the peers and creates transactions. More broadly, it enables users to create transactions in the Hyperledger Fabric network's shared ledger and update the world state of the assets. + +Chaincode is programmable code, written in Go, and instantiated on a channel. Developers use chaincode to develop business contracts, asset definitions, and collectively-managed decentralized applications. The chaincode manages the ledger state through transactions invoked by applications. Assets are created and updated by a specific chaincode, and cannot be accessed by another chaincode. + +Applications interact with the blockchain ledger through the chaincode. Therefore, the chaincode needs to be installed on every peer that will endorse a transaction and instantiated on the channel. + +There are two ways to develop smart contracts with Hyperledger Fabric: + + - Code individual contracts into standalone instances of chaincode + - (More efficient way) Use chaincode to create decentralized applications that manage the lifecycle of one or multiple types of business contracts, and let the end users instantiate instances of contracts within these applications. + +### Chaincode Key APIs + +An important interface that you can use when writing your chaincode is defined by Hyperledger Fabric - [_ChaincodeStub_](https://godoc.org/github.com/hyperledger/fabric/core/chaincode/shim#Chaincode) and [_ChaincodeStubInterface_](https://godoc.org/github.com/hyperledger/fabric/core/chaincode/shim#ChaincodeStub). The ChaincodeStub provides functions that allow you to interact with the underlying ledger to query, update, and delete assets. The key APIs for chaincode include: + + - **`func (stub \*ChaincodeStub) GetState(key string) ([]byte, error)`** +
Returns the value of the specified _key_ from the ledger. Note that **`GetState`** doesn't read data from the Write set, which has not been committed to the ledger. In other words, **`GetState`** doesn't consider data modified by **`PutState`** that has not been committed. If the key does not exist in the state database, + **\(nil, nil)** is returned. + - **`func (stub \*ChaincodeStub) PutState(key string, value []byte) error`** +
Puts the specified _key_ and _value_ into the transaction's Write set as a data-write proposal. **`PutState`** doesn't affect the ledger until the transaction is validated and successfully committed. + - **`func (stub \*ChaincodeStub) DelState(key string) error`** +
Records the specified key to be deleted in the Write set of the transaction proposal. The _key_ and its _value_ will be deleted from the ledger when the transaction is validated and successfully committed. + +### Overview of a Chaincode Program + +When creating a chaincode, there are two methods that you will need to implement: + + - **Init** +
Called when a chaincode receives an **_instantiate_** or **_upgrade_** transaction. This is where you will initialize any application state. + - **Invoke** +
Called when the **_invoke_** transaction is received to process any transaction proposals. + +As a developer, you must create both an **Init** and an **Invoke** method within your chaincode. The chaincode must be installed using the **`peer chaincode install`** command, and instantiated using the **`peer chaincode instantiate`** command before the chaincode can be invoked. Then, transactions can be created using the **`peer chaincode invoke`** or peer **`chaincode query commands`**. + +### Sample Chaincode Decomposed - Dependencies + +Let’s now walk through a sample chaincode written in Go, piece by piece: + +```golang + package main + + import ( + + "fmt" + + "github.com/hyperledger/fabric/core/chaincode/shim" + + "github.com/hyperledger/fabric/protos/peer" + + ) +``` + +The **`import`** statement lists a few dependencies that you will need for your chaincode to build successfully. + + - **`fmt`** - contains **`Println`** for debugging/logging + - **`github.com/hyperledger/fabric/core/chaincode/shim`** - contains the definition for the chaincode interface and the chaincode stub, which you will need to interact with the ledger, as we described in the _Chaincode Key APIs_ section + - **`github.com/hyperledger/fabric/protos/peer`** - contains the peer protobuf package. + +### Sample Chaincode Decomposed - Struct + +```golang +type SampleChaincode struct { + +} +``` + +This might not look like much, but this is the statement that begins the definition of an object/class in Go. **`SampleChaincode`** implements a simple chaincode to manage an asset. + +### Sample Chaincode Decomposed - Init Method + +Next, we’ll implement the **Init** method. **Init** is called during the chaincode instantiation to initialize data required by the application. In our sample, we will create the initial key/value pair for an asset, as specified on the command line: + +```golang +func (t *SampleChaincode) Init(stub shim.ChainCodeStubInterface) peer.Response { + + // Get the args from the transaction proposal + + args := stub.GetStringArgs() + + if len(args) != 2 { + + return shim.Error("Incorrect arguments. Expecting a key and a value") + + } + + // We store the key and the value on the ledger + + err := stub.PutState(args[0], []byte(args[1])) + + if err != nil { + + return shim.Error(fmt.Sprintf("Failed to create asset: %s", args[0])) + + } + + return shim.Success(nil) + +} +``` + +The Init implementation accepts two parameters as inputs, and proposes to write a key/value pair to the ledger by using the **`stub.PutState`** function. **`GetStringArgs`** retrieves and checks the validity of arguments which we expect to be a key/value pair. Therefore, we check to ensure that there are two arguments specified. If not, we return an error from the **Init** method, to indicate that something went wrong. Once we have verified the correct number of arguments, we can store the initial state in the ledger. In order to accomplish this, we call the **`stub.PutState`** function, specifying the first argument as the key, and the second argument as the value for that key. If no errors are returned, we will return success from the **Init** method. + +### Sample Chaincode Decomposed - Invoke Method + +Now, we’ll explore the **Invoke** method, which gets called when a transaction is proposed by a client application. In our sample, we will either get the value for a given asset, or propose to update the value for a specific asset. + +```golang +func (t *SampleChaincode) Invoke(stub shim.ChaincodeStubInterface) peer.Response { + + // Extract the function and args from the transaction proposal + + fn, args := stub.GetFunctionAndParameters() + + var result string + + var err error + + if fn == "set" { + + result, err = set(stub, args) + + } else { // assume 'get' even if fn is nil + + result, err = get(stub, args) + + } + + if err != nil { //Failed to get function and/or arguments from transaction proposal + + return shim.Error(err.Error()) + + } + + // Return the result as success payload + + return shim.Success([]byte(result)) + +} +``` + +There are two basic actions a client can invoke: _get_ and _set_. + + - The _get_ method will be used to query and return the value of an existing asset. + - The _set_ method will be used to create a new asset or update the value of an existing asset. + +To start, we’ll call **`GetFunctionandParameters`** to isolate the function name and parameter variables. Each transaction is either a _set_ or a _get_. Let's first look at how the set method is implemented: + +```golang +func set(stub shim.ChaincodeStubInterface, args []string) (string, error) { + + if len(args) != 2 { + + return "", fmt.Errorf("Incorrect arguments. Expecting a key and a value") + + } + + err := stub.PutState(args[0], []byte(args[1])) + + if err != nil { + + return "", fmt.Errorf("Failed to set asset: %s", args[0]) + + } + + return args[1], nil + +} +``` + +The set method will create or modify an asset identified by a key with the specified value. The set method will modify the world state to include the key/value pair specified. If the key exists, it will override the value with the new one, using the **`PutState`** method; otherwise, a new asset will be created with the specified value. + +Next, let's look at how the _get_ method is implemented: + +```golang +func get(stub shim.ChaincodeStubInterface, args []string) (string, error) { + + if len(args) != 1 { + + return "", fmt.Errorf("Incorrect arguments. Expecting a key") + + } + + value, err := stub.GetState(args[0]) + + if err != nil { + + return "", fmt.Errorf("Failed to get asset: %s with error: %s", args[0], err) + + } + + if value == nil { + + return "", fmt.Errorf("Asset not found: %s", args[0]) + + } + + return string(value), nil + +} +``` + +The _get_ method will attempt to retrieve the value for the specified key. If the application does not pass in a single key, an error will be returned; otherwise, the **`GetState`** method will be used to query the world state for the specified key. If the key has not yet been added to the ledger (and world state), then an error will be returned; otherwise, the value that was set for the specified key is returned from the method. + +### Sample Chaincode Decomposed - Main Function + +The last piece of code in this sample is the **`main`** function, which will call the **`Start`** function. The **`main`** function starts the chaincode in the container during instantiation. + +```golang +func main() { + + err := shim.Start(new(SampleChaincode)) + + if err != nil { + + fmt.Println("Could not start SampleChaincode") + + } else { + + fmt.Println("SampleChaincode successfully started") + + } + +} +``` + +## Chaincode Walkthrough (Demonstrated Scenario) + +### Setting the Stage + +Now that we have a general idea of how chaincode is coded, we will walk through a simple chaincode that creates assets on a ledger, based on our demonstrated scenario of creating records for tuna fish. + +Sometimes, code snippets can get lost in translation, especially if the context doesn’t make much sense. In hopes of avoiding this, we have adjusted our example chaincode to address our demonstration scenario. The chaincode we will be examining in this section will record a tuna catch by storing it to the ledger, as well as allow for queries and updates to tuna catch records. + +### Defining the Asset Attributes + +Here are the four example attributes of tuna fish that we will be recording on the ledger: + + - Vessel (string) + - Location (string) + - Date and Time (datetime) + - Holder (string) + +We create a Tuna Structure that has four properties. Structure tags are used by the **encoding/json** library. + +```golang +type Tuna struct { + + Vessel string ‘json:"vessel"’ + + Datetime string ‘json:"datetime"’ + + Location string ‘json:"location"’ + + Holder string ‘json:"holder"’ + +} +``` + +### Invoke Method (Part I) + +As described earlier, the **Invoke** method is the one which gets called when a transaction is proposed by a client application. Within this method, we have three different types of transactions -- _recordTuna_, _queryTuna_, and _changeTunaHolder_, which we will look at a little later. + +As a reminder, Sarah, the fisherman, will invoke the _recordTuna_ when she catches each tuna. + +|![Invoke_method_recordTuna](../images/introduction-to-hyperledger-fabric/Invoke_method_recordTuna.png)| +|:--:| +| *Licensed under [CC By 4.0](https://creativecommons.org/licenses/by/4.0/)* | + +_changeTunaHolder_ can be invoked by Miriam, the restaurateur, when she confirms receiving and passing on a particular tuna fish as it passes through the supply chain. _queryTuna_ can be invoked by Miriam, the restaurateur, to view the state of a particular tuna. + +|![Invoke_method_queryTuna_and_changeTuna](../images/introduction-to-hyperledger-fabric/Invoke_method_queryTuna_and_changeTuna.png)| +|:--:| +| *Licensed under [CC By 4.0](https://creativecommons.org/licenses/by/4.0/)* | + +Regulators will invoke _queryTuna_ and _queryAllTuna_ based on their need to verify and check for sustainability of the supply chain. + +|![Invoke_method_queryTuna_and_queryAllTuna](../images/introduction-to-hyperledger-fabric/Invoke_method_queryTuna_and_queryAllTuna.png)| +|:--:| +| *Licensed under [CC By 4.0](https://creativecommons.org/licenses/by/4.0/)* | + +### Invoke Method (Part II) + +We’ll be getting into the different tuna chaincode methods in the following sections. But here is the **Invoke** method. As you can see, this method will look at the first parameter to determine which function should be called, and invoke the appropriate tuna chaincode method. + +```golang +func (s *SmartContract) Invoke(APIstub shim.ChaincodeStubInterface) sc.Response { + + // Retrieve the requested Smart Contract function and arguments + + function, args := APIstub.GetFunctionAndParameters() + + // Route to the appropriate handler function to interact with the ledger appropriately + + if function == "queryTuna" { + + return s.queryTuna(APIstub, args) + + } else if function == "initLedger" { + + return s.initLedger(APIstub) + + } else if function == "recordTuna" { + + return s.recordTuna(APIstub, args) + + } else if function == "queryAllTuna" { + + return s.queryAllTuna(APIstub) + + } else if function == "changeTunaHolder" { + + return s.changeTunaHolder(APIstub, args) + + } + + return shim.Error("Invalid Smart Contract function name.") + +} +``` + +### Chaincode Methods - queryTuna + +The _queryTuna_ method would be used by a fisherman, regulator, or restaurateur to view the record of one particular tuna. It takes one argument - the key for the tuna in question. + +```golang +func (s *SmartContract) queryTuna(APIstub shim.ChaincodeStubInterface, args []string) sc.Response { + + if len(args) != 1 { + + return shim.Error("Incorrect number of arguments. Expecting 1") + + } + + tunaAsBytes, _ := APIstub.GetState(args[0]) + + if tunaAsBytes == nil { + + return shim.Error(“Could not locate tuna”) + + } + + return shim.Success(tunaAsBytes) + +} +``` + +### Chaincode Methods - initLedger + +The _initLedger_ method will add test data to our network. + +```golang +func (s *SmartContract) initLedger(APIstub shim.ChaincodeStubInterface) sc.Response { + + tuna := []Tuna{ + + Tuna{Vessel: "923F", Location: "67.0006, -70.5476", Timestamp: "1504054225", Holder: "Miriam"}, + + Tuna{Vessel: "M83T", Location: "91.2395, -49.4594", Timestamp: "1504057825", Holder: "Dave"}, + + Tuna{Vessel: "T012", Location: "58.0148, 59.01391", Timestamp: "1493517025", Holder: "Igor"}, + + Tuna{Vessel: "P490", Location: "-45.0945, 0.7949", Timestamp: "1496105425", Holder: "Amalea"}, + + Tuna{Vessel: "S439", Location: "-107.6043, 19.5003", Timestamp: "1493512301", Holder: "Rafa"}, + + Tuna{Vessel: "J205", Location: "-155.2304, -15.8723", Timestamp: "1494117101", Holder: "Shen"}, + + Tuna{Vessel: "S22L", Location: "103.8842, 22.1277", Timestamp: "1496104301", Holder: "Leila"}, + + Tuna{Vessel: "EI89", Location: "-132.3207, -34.0983", Timestamp: "1485066691", Holder: "Yuan"}, + + Tuna{Vessel: "129R", Location: "153.0054, 12.6429", Timestamp: "1485153091", Holder: "Carlo"}, + + Tuna{Vessel: "49W4", Location: "51.9435, 8.2735", Timestamp: "1487745091", Holder: "Fatima"}, + + } + + i := 0 + + for i < len(tuna) { + + fmt.Println("i is ", i) + + tunaAsBytes, _ := json.Marshal(tuna[i]) + + APIstub.PutState(strconv.Itoa(i+1), tunaAsBytes) + + fmt.Println("Added", tuna[i]) + + i = i + 1 + + } + + return shim.Success(nil) + +} +``` + +### Chaincode Methods - recordTuna + +The _recordTuna_ method is the method a fisherman like Sarah would use to record each of her tuna catches. This method takes in five arguments (attributes to be saved in the ledger). + +```golang +func (s *SmartContract) recordTuna(APIstub shim.ChaincodeStubInterface, args []string) sc.Response { + + if len(args) != 5 { + + return shim.Error("Incorrect number of arguments. Expecting 5") + + } + + var tuna = Tuna{ Vessel: args[1], Location: args[2], Timestamp: args[3], Holder: args[4]} + + tunaAsBytes, _ := json.Marshal(tuna) + + err := APIstub.PutState(args[0], tunaAsBytes) + + if err != nil { + + return shim.Error(fmt.Sprintf("Failed to record tuna catch: %s", args[0])) + + } + + return shim.Success(nil) + +} +``` + +### Chaincode Methods - queryAllTuna + +The _queryAllTuna_ method allows for assessing all the records; in this case, all the Tuna records added to the ledger. This method does not take any arguments. It will return a JSON string containing the results. + +```golang +func (s *SmartContract) queryAllTuna(APIstub shim.ChaincodeStubInterface) sc.Response { + + startKey := "0" + + endKey := "999" + + resultsIterator, err := APIstub.GetStateByRange(startKey, endKey) + + if err != nil { + + return shim.Error(err.Error()) + + } + + defer resultsIterator.Close() + + // buffer is a JSON array containing QueryResults + + var buffer bytes.Buffer + + buffer.WriteString("[") + + bArrayMemberAlreadyWritten := false + + for resultsIterator.HasNext() { + + queryResponse, err := resultsIterator.Next() + + if err != nil { + + return shim.Error(err.Error()) + + } + + // Add a comma before array members, suppress it for the first array member + + if bArrayMemberAlreadyWritten == true { + + buffer.WriteString(",") + + } + + buffer.WriteString("{\"Key\":") + + buffer.WriteString("\"") + + buffer.WriteString(queryResponse.Key) + + buffer.WriteString("\"") + + buffer.WriteString(", \"Record\":") + + // Record is a JSON object, so we write as-is + + buffer.WriteString(string(queryResponse.Value)) + + buffer.WriteString("}") + + bArrayMemberAlreadyWritten = true + + } + + buffer.WriteString("]") + + fmt.Printf("- queryAllTuna:\n%s\n", buffer.String()) + + return shim.Success(buffer.Bytes()) + +} +``` + +### Chaincode Methods - changeTunaHolder + +As the tuna fish is passed to different parties in the supply chain, the data in the world state can be updated with who has possession. The _changeTunaHolder_ method takes in 2 arguments, **tuna id** and **new holder name**. + +```golang +func (s *SmartContract) changeTunaHolder(APIstub shim.ChaincodeStubInterface, args []string) sc.Response { + + if len(args) != 2 { + + return shim.Error("Incorrect number of arguments. Expecting 2") + + } + + tunaAsBytes, _ := APIstub.GetState(args[0]) + + if tunaAsBytes != nil { + + return shim.Error("Could not locate tuna") + + } + + tuna := Tuna{} + + json.Unmarshal(tunaAsBytes, &tuna) + + // Normally check that the specified argument is a valid holder of tuna but here we are skipping this check for this example. + + tuna.Holder = args[1] + + tunaAsBytes, _ = json.Marshal(tuna) + + err := APIstub.PutState(args[0], tunaAsBytes) + + if err != nil { + + return shim.Error(fmt.Sprintf("Failed to change tuna holder: %s", args[0])) + + } + + return shim.Success(nil) + +} +``` + +### Conclusion + +We hope you now have a better idea of how chaincode is constructed and written, especially when applied to a simple example. To see all the code snippets, visit the educational GitHub repository: [https://github.com/hyperledger/education/blob/master/LFS171x/fabric-material/chaincode/tuna-app/tuna-chaincode.go.](https://github.com/hyperledger/education/blob/master/LFS171x/fabric-material/chaincode/tuna-app/tuna-chaincode.go.) + +## Writing an Application + +### What Is a Blockchain Application? + +In a blockchain application, the blockchain will store the state of the system, in addition to the immutable record of transactions that created that state. A client application will be used to send transactions to the blockchain. The smart contracts will encode some (if not all) of the business logic. + +### How Applications Interact with the Network + +Applications use APIs to run smart contracts. In Hyperledger Fabric, these smart contracts are called chaincode. These contracts are hosted on the network, and identified by name and version. APIs are accessible with a software development kit, or SDK. Currently, Hyperledger Fabric has three options for developers: Node.js SDK, Java SDK, and CLI. + +### Fabric Node.js SDK + +In this exercise, we will be using the Node.js SDK ([https://fabric-sdk-node.github.io/](https://fabric-sdk-node.github.io/)) to interact with the network, and, therefore, the ledger. The Hyperledger Fabric Client SDK makes it easy to use APIs to interact with a Hyperledger Fabric blockchain. This section will help you write your first application, starting with a test Hyperledger Fabric network, then learning the parameters of the sample smart contract, and lastly, developing the application to query and update ledger records. + +For additional information, visit the Hyperledger Fabric Node SDK documentation: [https://fabric-sdk-node.github.io/tutorial-app-dev-env-setup.html](https://fabric-sdk-node.github.io/tutorial-app-dev-env-setup.html). + +### Video: Hyperledger Fabric Tuna Application (Alexandra Groetsema) + +The tuna application is going to demonstrate the creation and transfer of tuna fish shipments between actors leveraging Hyperledger Fabric in the supply chain. + +The application will be written in Node.js. The chaincode that we will be using is the demonstrated scenario chaincode that we walked through in the previous section. Interacting with the chaincode is done by using the gRPC protocol to a peer on the network. The details of the gRPC protocol are taken care of by the Hyperledger Fabric Client Node.js SDK. + +#### Hyperledger Fabric Tuna Application (Alexandra Groetsema) + +[![Hyperledger Fabric Tuna Application (Alexandra Groetsema)](../images/video-image.png)](https://youtu.be/rXuwfAl7EkA) + +### Getting Started (Part I) + +In case you haven’t downloaded the **`education`** repository for this course, follow the below directions in your terminal window: + +``` +$ git clone https://github.com/hyperledger/education.git + +$ cd education/LFS171x/fabric-material/tuna-app +``` + +Make sure you have Docker running on your machine before you run the next command. If you do not have Docker installed, return to Chapter 4, _Technical Requirements_. + +Also, make sure that you have completed the _Installing Hyperledger Fabric_ section in this chapter before moving on to this application section, as you will likely experience errors. + +First, remove any pre-existing containers, as it may conflict with commands in this tutorial: + +``` +$ docker rm -f $(docker ps -aq) +``` +Then, let’s start the Hyperledger Fabric network with the following command: + +``` +$ ./startFabric.sh +``` + +**Troubleshooting**: If, after running the above you are getting an error similar to the following: + +``` +ERROR: failed to register layer: rename +/var/lib/docker/image/overlay2/layerdb/tmp/write-set-091347846 /var/lib/docker/image/overlay2/layerdb/sha256/9d3227c1793b7494e598caafd0a5013900e17dcdf1d7bdd31d39c82be04fcf28: file exists +``` + +try running the following command: + +``` +$ rm -rf ~/Library/Containers/com.docker.docker/Data/* + +``` + +### Getting Started (Part II) + +Install the required libraries from the **`package.json`** file, register the **`Admin`** and **`User`** components of our network, and start the client application with the following commands: + +``` +$ npm install + +$ node registerAdmin.js + +$ node registerUser.js + +$ node server.js +``` + +Load the client simply by opening **`localhost:8000`** in any browser window of your choice, and you should see the user interface for our simple application at this URL (as in the screenshot below). + +|![fabric-application1](../images/introduction-to-hyperledger-fabric/fabric-application1.png)| +|:--:| +| *Licensed under [CC By 4.0](https://creativecommons.org/licenses/by/4.0/)* | + +**Troubleshooting**: If you are getting an error similar to the one below while attempting to perform any of the functions on the application: + +``` +Error: [client-utils.js]: sendPeersProposal - Promise is rejected: Error: Connect Failed + +error from query = { Error: Connect Failed + + at /Desktop/prj/education/LFS171x/fabric-material/tuna-app/node_modules/grpc/src/node/src/client.js:554:15 code: 14, metadata: Metadata { _internal_repr: {} } } +``` + +try running the following commands: + +``` +$ cd ~ + +$ rm -rf .hfc-key-store/ +``` + +Then, run the commands above starting with: + +``` +$ node registerAdmin.js +``` + +### File Structure of Application + +Here you can see the file structure of the Fabric application: + +|![fabric-filestructure](../images/introduction-to-hyperledger-fabric/fabric-filestructure.png)| +|:--:| +| *Licensed under [CC By 4.0](https://creativecommons.org/licenses/by/4.0/)* | + +### Query All Tuna Recorded + +``` + 1. // queryAllTuna - requires no arguments + 2. const request = { + 3. chaincodeId:’tuna-app’, + 4. txId: tx_id, + 5. fcn: 'queryAllTuna', + 6. args: [''] + 7. }; + 8. return channel.queryByChaincode(request); +``` + +(Reference: The code comes from **`..src/queryAllTuna.js`**) + +Now, let’s query our database, where there should be some sample entries already, since our chaincode smart contract initiated the ledger with 10 previous catches. This function takes no arguments, as we see on line 6. Instead, it takes an empty array. + +The query response you should see in the user interface is 10 pre-populated entries with the attributes for each catch. + +|![fabric-queryAll](../images/introduction-to-hyperledger-fabric/fabric-queryAll.png)| +|:--:| +| *Licensed under [CC By 4.0](https://creativecommons.org/licenses/by/4.0/)* | + +### Query a Specific Tuna Recorded + +``` + 1. // queryTuna - requires 1 argument + 2. const request = { + 3. chaincodeId:’tuna-app’, + 4. txId: tx_id, + 5. fcn: 'queryTuna', + 6. args: ['1'] + 7. }; + 8. return channel.queryByChaincode(request); +``` + +(Reference: The co de comes from **`..src/queryTuna.js`**) + +Now, let’s query for a specific tuna catch. This function takes 1 argument, as you can see on line 6 above, an example would be ['1']. In this example, we are using the key to query for catches. + +You should see the following query response detailing the attributes recorded for one particular catch. + +|![fabric-query](../images/introduction-to-hyperledger-fabric/fabric-query.png)| +|:--:| +| *Licensed under [CC By 4.0](https://creativecommons.org/licenses/by/4.0/)* | + +### Change Tuna Holder + +``` + 1. // changeTunaHolder - requires 2 argument + 2. var request = { + 3. chaincodeId:’tuna-app’, + 4. fcn: 'changeTunaHolder', + 5. args: ['1', 'Alex'], + 6. chainId: 'mychannel', + 7. txId: tx_id + 8. }; + 9. return channel.sendTransactionProposal(request); +``` + +(Reference: The code comes from **`..src/changeHolder.js`**) + +Now, let’s change the name of the person in possession of a given tuna. This function takes 2 arguments: the key for the particular catch, and the new holder, as we can see on line 5 in the example above. Ex: **`args: ['1', 'Alex']`**. + +You may be able to see a similar success response in your terminal window: + +``` +The transaction has been committed on peer localhost:7053 + event promise all complete and testing complete + +Successfully sent transaction to the orderer. +Successfully sent Proposal and received ProposalResponse: Status - 200, message - "OK", metadata - "", endorsement signature: 0D 9 +``` + +This indicates we have sent a proposal from our application via the SDK, and the peer has been endorsed, committed, and the ledger has been updated. + +|![fabric-changeTunaHolder](../images/introduction-to-hyperledger-fabric/fabric-changeTunaHolder.png)| +|:--:| +| *Licensed under [CC By 4.0](https://creativecommons.org/licenses/by/4.0/)* | + +You should see that the holder has indeed been changed by querying for key **`['1']`** again. Now, the **`holder`** attribute has been changed from **`Miriam`** to **`Alex`**, for example. + +|![fabric-changedRecord](../images/introduction-to-hyperledger-fabric/fabric-changedRecord.png)| +|:--:| +| *Licensed under [CC By 4.0](https://creativecommons.org/licenses/by/4.0/)* | + +### Record a Tuna Catch + +``` + 1. // recordTuna - requires 5 argument + 2. var request = { + 3. chaincodeId:’tuna-app’, + 4. fcn: 'recordTuna', + 5. args: ['11', '239482392', '28.012, 150.225', '0923T', "Hansel"], + 6. chainId: 'mychannel', + 7. txId: tx_id + 8. }; + 9. return channel.sendTransactionProposal(request); +``` + +(Reference: The code comes from **`..src/recordTuna.js`**) + +Lastly, we will practice recording a new tuna catch, and adding it to the ledger by invoking the **`recordTuna`** function. This function takes 5 arguments, itemizing each of the attributes of a new catch. You can see an example submission on line 5: **`args: ['11','239482392', '28.012, 150.225', '0923T', "Hansel"]`**. + +|![fabric-createTunaRecord](../images/introduction-to-hyperledger-fabric/fabric-createTunaRecord.png)| +|:--:| +| *Licensed under [CC By 4.0](https://creativecommons.org/licenses/by/4.0/)* | + +Check and you should see that the holder has indeed been changed by querying all the tuna catches. Now, you should see an additional entry at the bottom of the table: + +|![fabric-queryAfterCreate](../images/introduction-to-hyperledger-fabric/fabric-queryAfterCreate.png)| +|:--:| +| *Licensed under [CC By 4.0](https://creativecommons.org/licenses/by/4.0/)* | + +### Finishing Up + +Remove all Docker containers and images that we created in this tutorial with the following command in the **`tuna-app`** folder: + +``` +$ docker rm -f $(docker ps -aq) + +$ docker rmi -f $(docker images -a -q) +``` + +### Application Flow Basics + +|![fabric-application-flowbasics](../images/introduction-to-hyperledger-fabric/fabric-application-flowbasics.png)| +|:--:| +| *Licensed under [CC By 4.0](https://creativecommons.org/licenses/by/4.0/)* | + + 1. A developer creates an application and smart contract. + 2. The application will invoke calls within the smart contract via the Hyperledger Fabric Client SDK. + 3. These calls are processed by the business logic within the chaincode smart contract. + 4. A **`put`** or **`delete`** command will go through the consensus process and will be added to the blockchain within the ledger. + 5. A **`get`** command can only read from the world state, but it is not recorded on the blockchain. + 6. The application can access blockchain information via APIs. + +### Application Flow Example + +|![fabric-application-flow](../images/introduction-to-hyperledger-fabric/fabric-application-flow.png)| +|:--:| +| *Licensed under [CC By 4.0](https://creativecommons.org/licenses/by/4.0/)* | + + 1. Various users (fisherman, regulators, or restaurateurs etc.) will interact with the Node.js application. + 2. The client JS will send messages to the backend when the user interacts with the application. + 3. Reading or writing the ledger is known as a proposal (for example, querying a specific Tuna catch - **`queryTuna`**- or recording a tuna catch - **`recordTuna`**). This proposal is built by our application via the SDK, and then sent to the endorsing peers. + 4. The endorsing peers will use the application-specific chaincode smart contract to simulate the transaction. If there are no issues, the transaction will be endorsed, and sent back to our application. + 5. Our application will then send the endorsed proposal to the ordering service via the SDK. The orderer will package many proposals from the whole network into a block. Then, it will broadcast the new block to the committing peers in the network. + 6. Finally, each committing peer will validate the block and write it to its ledger (shown in teal above). The transaction has now been committed, and any reads will reflect this change. + +## Joining the Hyperledger Fabric Community + +### Becoming Involved with the Hyperledger Fabric Project + +Hyperledger Fabric is an open source project, where ideas and code can be publicly discussed, created, and reviewed. There are many ways to join the Hyperledger Fabric community. Next, we will highlight some of the ways to get involved, either from a technical standpoint, or from an ideas/issues creation perspective. + +### Video: The Future of Hyperledger Fabric (Chris Ferris) + +#### The Future of Hyperledger Fabric (Chris Ferris) + +[![The Future of Hyperledger Fabric (Chris Ferris)](../images/video-image.png)](https://youtu.be/SAhiVfOa6tA) + +### Community Meetings and Mailing Lists + +You can join the the weekly meeting on Fabric Documentation, or other Hyperledger Fabric-related meetings. The [Hyperledger Community Meetings Calendar](https://calendar.google.com/calendar/embed?src=linuxfoundation.org_nf9u64g9k9rvd9f8vp4vur23b0@group.calendar.google.com&ctz=America/SanFrancisco&pli=1) is a great resource to learn the timing for these meetings. + +You can join the Hyperledger Fabric mailing lists for technical discussions and announcements: [https://lists.hyperledger.org/mailman/listinfo/hyperledger-fabric](https://lists.hyperledger.org/mailman/listinfo/hyperledger-fabric). + +### JIRA and Gerrit + +If you have a bug to report, you can submit an issue using JIRA (you must have a Linux Foundation ID to access JIRA): [https://jira.hyperledger.org/secure/Dashboard.jspa?selectPageId=10104](https://jira.hyperledger.org/secure/Dashboard.jspa?selectPageId=10104). You can also find and review a list of existing issues, and can pick one that interests you and start working on it: [https://jira.hyperledger.org/browse/FAB-5491?filter=10580](https://jira.hyperledger.org/browse/FAB-5491?filter=10580). You can learn how to use the JIRA documentation at [https://wiki.hyperledger.org/community/jira-navigation](https://wiki.hyperledger.org/community/jira-navigation). + +Gerrit is used for submitting PRs and managing code reviews and checkins. All code is forkable and viewable: [https://gerrit.hyperledger.org/r/#/admin/projects/](https://gerrit.hyperledger.org/r/#/admin/projects/). You can get a primer on working with Gerrit at [https://hyperledger-fabric.readthedocs.io/en/latest/Gerrit/gerrit.html](https://hyperledger-fabric.readthedocs.io/en/latest/Gerrit/gerrit.html). + +### Rocket.Chat + +You can join the live conversations on Rocket.Chat (which is an alternative to Slack), using your Linux Foundation ID: [https://chat.hyperledger.org/home](https://chat.hyperledger.org/home). There are over 24 channels specific to the Hyperledger Fabric project. The [#fabric](https://chat.hyperledger.org/channel/fabric) channel is used to discuss the Hyperlerdger Fabric project. You can find a guide for these channels here: [https://wiki.hyperledger.org/community/chat_channels](https://wiki.hyperledger.org/community/chat_channels). + +## Knowledge Check + +### Knowledge Check 7.1 + +What are some of the advantages of a platform like Hyperledger Fabric? Select all answers that apply. + +
    +
  1. Modular architecture for pluggable implementations
  2. +
  3. Security through a membership services provider
  4. +
  5. Proof of Work to verify identity
  6. +
  7. Privacy through channels
  8. +
+ +### Knowledge Check 7.2 + +Which of the following options correctly describes what chaincode is in the context of Hyperledger Fabric? + +
    +
  1. A smart contract
  2. +
  3. Executable logic written in Go that determines the state of the ledger
  4. +
  5. Initializes and manages the ledger state through transactions submitted by applications
  6. +
  7. All of the above
  8. +
+ +### Knowledge Check 7.3 + +Hyperledger Fabric is a framework that provides a modular architecture for consensus and membership services. True or False? + +
    +
  1. True
  2. +
  3. False
  4. +
+ +### Knowledge Check 7.4 + +In the demonstrated scenario, which Hyperledger Fabric component allows Sarah, the fisherman, to have separate transactions that are only seen by the parties involved (such as restaurateurs for Tuna purchases)? + +
    +
  1. Blockchain
  2. +
  3. Distributed ledger technology
  4. +
  5. Ordering service
  6. +
  7. Channels
  8. +
+ +### Knowledge Check 7.5 + +What do the membership service providers do? + +
    +
  1. Create a way for issuing and validating certificates and user authentication
  2. +
  3. Create wallets for peers
  4. +
  5. Create a way for the chaincode to interact with the ledger
  6. +
+ +### Knowledge Check 7.6 + +What aspects of the Hyperledger Fabric application flow are built by a developer? + +
    +
  1. Application and SDK
  2. +
  3. Application and cached state
  4. +
  5. Application and chaincode smart contract
  6. +
  7. SDK and chaincode smart contract
  8. +
+ +### Knowledge Check 7.7 + +Refer to the function below from the chaincode contract used in the demonstrated scenario presented earlier in this chapter. This method is used during chaincode instantiation to initialize data. True or False? + +```golang +func (s *SmartContract) Invoke(APIstub shim.ChaincodeStubInterface) sc.Response { + + function, args := APIstub.GetFunctionAndParameters() + + if function == "queryTuna" { + + return s.queryTuna(APIstub, args) + + } else if function == "initLedger" { + + return s.initLedger(APIstub) + + } else if function == "recordTuna" { + + return s.recordTuna(APIstub, args) + + } else if function == "queryAllTuna" { + + return s.queryAllTuna(APIstub) + + } else if function == "changeTunaHolder" { + + return s.changeTunaHolder(APIstub, args) + + } + + return shim.Error("Invalid Smart Contract function name.") + +} +``` + +
    +
  1. True
  2. +
  3. False
  4. +
+ +### Knowledge Check 7.8 + +What are the three main roles within a Hyperledger Fabric network? Select all answers that apply. + +
    +
  1. Endorser
  2. +
  3. Enroller
  4. +
  5. Orderer
  6. +
  7. Committer
  8. +
+ +### Knowledge Check 7.9 + +Using the dropdown option below, match the following types of roles in a Hyperledger Fabric network with their descriptions. + 1. Endorsing Peer +
Select an option +
    +
  1. Orders all transaction blocks into the ledger
  2. +
  3. Approves or declines transaction proposals and must hold smart contracts
  4. +
  5. Maintain ledger and state and commits transactions
  6. +
+
+ + 2. Ordering Service +
Select an option +
    +
  1. Orders all transaction blocks into the ledger
  2. +
  3. Approves or declines transaction proposals and must hold smart contracts
  4. +
  5. Maintain ledger and state and commits transactions
  6. +
+
+ + 3. Committing Peer +
Select an option +
    +
  1. Orders all transaction blocks into the ledger
  2. +
  3. Approves or declines transaction proposals and must hold smart contracts
  4. +
  5. Maintain ledger and state and commits transactions
  6. +
+
+ +### Knowledge Check 7.10 + +What is the correct order of the four steps to consensus? + +
    +
  1. Validation, Ordering, Transaction Endorsement, Commitment
  2. +
  3. Transaction Endorsement, Ordering, Validation, Commitment
  4. +
  5. Commitment, Transaction Endorsement, Validation, Ordering
  6. +
  7. Ordering, Transaction Endorsement, Validation, Commitment
  8. +
+ +## Conclusions & Learning Objectives (Review) + +### Learning Objectives (Review) + +You should now be able to: + + - Understand the basics of Hyperledger Fabric v1.0. + - Walk through and analyze a demonstrated scenario on Hyperledger Fabric. + - Discuss crucial components of the Hyperledger Fabric architecture, including clients, peers, ordering service and membership service provider. + - Set up a sample network and simple application with a Javascript SDK. + - Discuss Chaincode (Hyperledger Fabric smart contract) and review an example. + - Get involved in the framework discussion and development. + +### Video: Conclusions (Alexandra Groetsema) + +#### Conclusions (Alexandra Groetsema) + +[![Conclusions (Alexandra Groetsema)](../images/video-image.png)](https://youtu.be/G_WUi0FElGw) diff --git a/LFS171x/docs/introduction-to-hyperledger-sawtooth.md b/LFS171x/docs/introduction-to-hyperledger-sawtooth.md index b8b997b8..e88a66dc 100644 --- a/LFS171x/docs/introduction-to-hyperledger-sawtooth.md +++ b/LFS171x/docs/introduction-to-hyperledger-sawtooth.md @@ -1 +1,979 @@ -# Introduction and Learning Objectives +# Introduction to Hyperledger Sawtooth + +- [Introduction to Hyperledger Sawtooth](#introduction-to-hyperledger-sawtooth) + - [Introduction & Learning Objectives](#introduction--learning-objectives) + - [Video: Introduction to Hyperledger Sawtooth (Alexandra & Arianna Groetsema)](#video-introduction-to-hyperledger-sawtooth-alexandra--arianna-groetsema) + - [Introduction to Hyperledger Sawtooth (Alexandra & Arianna Groetsema)](#introduction-to-hyperledger-sawtooth-alexandra--arianna-groetsema) + - [Learning Objectives](#learning-objectives) + - [Addressing Illegal, Unregulated, and Unreported Tuna Fishing (Demonstrated Scenario)](#addressing-illegal-unregulated-and-unreported-tuna-fishing-demonstrated-scenario) + - [Video: About the Demonstrated Scenario (Alexandra & Arianna Groetsema)](#video-about-the-demonstrated-scenario-alexandra--arianna-groetsema) + - [About the Demonstrated Scenario (Alexandra & Arianna Groetsema)](#about-the-demonstrated-scenario-alexandra--arianna-groetsema) + - [Defining Our Actors](#defining-our-actors) + - [Featured Hyperledger Sawtooth Elements](#featured-hyperledger-sawtooth-elements) + - [Why Sawtooth?](#why-sawtooth) + - [The Supply Chain](#the-supply-chain) + - [The Tuna Asset](#the-tuna-asset) + - [Recording a Catch](#recording-a-catch) + - [Reaching Consensus](#reaching-consensus) + - [Other Actors in the Supply Chain](#other-actors-in-the-supply-chain) + - [Summary of Supply Chain Flow](#summary-of-supply-chain-flow) + - [Key Components and Transaction Flow](#key-components-and-transaction-flow) + - [Video: Hyperledger Sawtooth Key Components (Arianna Groetsema)](#video-hyperledger-sawtooth-key-components-arianna-groetsema) + - [Hyperledger Sawtooth Key Components (Arianna Groetsema)](#hyperledger-sawtooth-key-components-arianna-groetsema) + - [Requirements Supported by Hyperledger Sawtooth](#requirements-supported-by-hyperledger-sawtooth) + - [Transaction Batching](#transaction-batching) + - [Validators](#validators) + - [Consensus Interface](#consensus-interface) + - [Introducing Proof of Elapsed Time (PoET)](#introducing-proof-of-elapsed-time-poet) + - [How Proof of Elapsed Time Works](#how-proof-of-elapsed-time-works) + - [Forks](#forks) + - [Sawtooth Applications](#sawtooth-applications) + - [Transaction Processors](#transaction-processors) + - [Sawtooth Node](#sawtooth-node) + - [Installing Hyperledger Sawtooth](#installing-hyperledger-sawtooth) + - [Technical Prerequisites](#technical-prerequisites) + - [Installing Hyperledger Sawtooth](#installing-hyperledger-sawtooth) + - [Starting Hyperledger Sawtooth](#starting-hyperledger-sawtooth) + - [Logging into the Client Container](#logging-into-the-client-container) + - [Stopping Hyperledger Sawtooth](#stopping-hyperledger-sawtooth) + - [Video: Bringing Up a Sample Hyperledger Sawtooth Network (Demo)](#video-bringing-up-a-sample-hyperledger-sawtooth-network-demo) + - [Change Bringing Up a Sample Hyperledger Sawtooth Network (Demo)](#change-bringing-up-a-sample-hyperledger-sawtooth-network-demo) + - [Writing an Application](#writing-an-application) + - [Applications](#applications) + - [Video: Designing an Application (Alexandra Groetsema)](#video-designing-an-application-alexandra-groetsema) + - [Designing an Application (Alexandra Groetsema)](#designing-an-application-alexandra-groetsema) + - [Review of Hyperledger Sawtooth Components](#review-of-hyperledger-sawtooth-components) + - [Sawtooth TunaChain Application](#sawtooth-tunachain-application) + - [Cloning the Repository](#cloning-the-repository) + - [File Structure of the TunaChain Application](#file-structure-of-the-tunachain-application) + - [Running the Application](#running-the-application) + - [Sawtooth TunaChain State](#sawtooth-tunachain-state) + - [Sawtooth TunaChain Addressing](#sawtooth-tunachain-addressing) + - [Sawtooth TunaChain Transaction Payload](#sawtooth-tunachain-transaction-payload) + - [Browser Client](#browser-client) + - [Creating a New Holder](#creating-a-new-holder) + - [Creating a Record of Tuna](#creating-a-record-of-tuna) + - [Transferring a Tuna](#transferring-a-tuna) + - [Accepting or Rejecting Transfers](#accepting-or-rejecting-transfers) + - [TunaChain Transaction Processor](#tunachain-transaction-processor) + - [Shutting Down Sawtooth](#shutting-down-sawtooth) + - [Summary of TunaChain Application Flow](#summary-of-tunachain-application-flow) + - [Joining the Hyperledger Sawtooth Community](#joining-the-hyperledger-sawtooth-community) + - [Learning More about Hyperledger Sawtooth](#learning-more-about-hyperledger-sawtooth) + - [Becoming Involved with the Hyperledger Sawtooth Project](#becoming-involved-with-the-hyperledger-sawtooth-project) + - [Community Meetings and Mailing Lists](#community-meetings-and-mailing-lists) + - [GitHub and Rocket.Chat](#github-and-rocketchat) + - [Knowledge Check](#knowledge-check) + - [Knowledge Check 6.1](#knowledge-check-61) + - [Knowledge Check 6.2](#knowledge-check-62) + - [Knowledge Check 6.3](#knowledge-check-63) + - [Knowledge Check 6.4](#knowledge-check-64) + - [Knowledge Check 6.5](#knowledge-check-65) + - [Knowledge Check 6.6](#knowledge-check-66) + - [Knowledge Check 6.7](#knowledge-check-67) + - [Knowledge Check 6.8](#knowledge-check-68) + - [Knowledge Check 6.9](#knowledge-check-69) + - [Knowledge Check 6.10](#knowledge-check-610) + - [Conclusions & Learning Objectives (Review)](#conclusions--learning-objectives-review) + - [Learning Objectives (Review)](#learning-objectives-review) + - [Video: Conclusions (Ariana Groetsema)](#video-conclusions-ariana-groetsema) + - [Conclusions (Ariana Groetsema)](#conclusions-ariana-groetsema) + + +## Introduction & Learning Objectives + +### Video: Introduction to Hyperledger Sawtooth (Alexandra & Arianna Groetsema) + +--- + +The Hyperledger Sawtooth chapter has been updated to Sawtooth v1.0 (as of May 2018). At this time, we were unable to update the videos introducing each section, so there may be some discrepancies. We apologize for the inconvenience, and we will update these videos in a future course version. + +--- + +#### Introduction to Hyperledger Sawtooth (Alexandra & Arianna Groetsema) + +[![Introduction to Hyperledger Sawtooth (Alexandra & Arianna Groetsema)](../images/video-image.png)](https://youtu.be/oFUMUJOjLj4) + +### Learning Objectives + +By the end of this chapter you should be able to: + +* Understand the basics of Hyperledger Sawtooth v1.0. +* Walk through a demonstrated scenario highlighting aspects of Hyperledger Sawtooth. +* Discuss crucial components of Hyperledger Sawtooth, including the consensus algorithm Proof of Elapsed Time, transaction processors, batches, and validators. +* Set up a running Hyperledger Sawtooth network and test an application. +* Get involved in the Sawtooth community for application or framework discussion and development. + +## Addressing Illegal, Unregulated, and Unreported Tuna Fishing (Demonstrated Scenario) + +### Video: About the Demonstrated Scenario (Alexandra & Arianna Groetsema) + +According to the [World Economic Forum](https://www.weforum.org/agenda/2017/05/can-technology-help-tackle-illegal-fishing/), + +>_"Illegal, unreported, and unregulated (IUU) fishing represents a theft of around 26 million tonnes, or close to $24 billion value of seafood a year."_ + +--- + +The Hyperledger Sawtooth chapter has been updated to Sawtooth v1.0 (as of May 2018). At this time, we were unable to update the videos introducing each section, so there may be some discrepancies. We apologize for the inconvenience, and we will update these videos in a future course version. + +--- + +#### About the Demonstrated Scenario (Alexandra & Arianna Groetsema) + +[![About the Demonstrated Scenario (Alexandra & Arianna Groetsema)](../images/video-image.png)](https://youtu.be/ZzZN0bY2CSo) + +### Defining Our Actors + +**Sarah** is the tuna fisher who sustainably and legally catches tuna. + +**Tuna processing plant** processes and bags the tuna after they have been caught. + +**Regulators** verify that the tuna has been legally and sustainably caught. + +**Miriam** is a restaurant owner who will serve as the recipient in this situation. + +|![2_-__Sawtooth__Demonstrated_Scenario__1_](../images/introduction-to-hyperledger-sawtooth/2_-__Sawtooth__Demonstrated_Scenario__1_.jpg)| +|:--:| +| *Licensed under [CC By 4.0](https://creativecommons.org/licenses/by/4.0/)* | + +We will be describing how tuna fishing can be improved starting from the source, tuna fisher Sarah, and the process by which her tuna ends up at Miriam's restaurant. + +### Featured Hyperledger Sawtooth Elements + +Hyperledger is a modular platform for building networks and running distributed ledger applications. Sawtooth simplifies application development by separating the core system from the application level. Application developers can specify the business logic for their applications, using the programming languages of their choice, without needing to know the underlying design of the core system. + +**Sawtooth validators** validate transactions. Validators are responsible for combining batches of transactions into blocks, submitting them to the ledger, and approving valid blocks according to the network's consensus algorithm. + +**Sawtooth applications** are distributed applications, such as smart contracts, that are separate from the core framework. An application provides a _transaction family_ to define the operations that can be applied to transactions, and the meaning of the transaction contents. An application consists of both a _transaction processor_ (the server-side logic) and one or more clients (for use from Web, CLI command line, or mobile applications). + +**Transaction processors** provide server-side business logic. Most nodes run several transaction processors, one for each specific use case or application. Each node in the Sawtooth network must run an identical set of transaction processors. + +**Batches** are clusters of transactions that are submitted together. A batch can contain a single transaction or several related transactions that are all committed to state together. If one transaction fails, the other transactions in that batch also fail. + +**The network layer** is responsible for communicating between validators in a Hyperledger Sawtooth network, including performing initial connectivity, peer discovery, and message handling. + +**Global state** contains the current state of the ledger and a chain of transaction invocations. The state for all applications running on the network is represented on each node. The process of transaction validation on each node ensures that the same transactions result in the same state transitions, and that the resulting ledger data is the same for all participants in the network. The state is split into application-specific namespaces, which allow flexibility for application authors to define, share, and reuse global state data between transaction processors. + +**Proof of Elapsed Time (PoET)** is a consensus algorithm in Hyperledger Sawtooth that implements time-based consensus, which reduces energy consumption on large distributed networks when compared to other algorithms such as Proof of Work. + +### Why Sawtooth? + +Miriam is a restaurant owner looking to source high quality tuna, that have been caught responsibly. Whenever Miriam buys tuna, she cannot be sure whether she can trust that the tuna she is purchasing is legally and sustainably caught, given the prominence of illegal and unreported tuna fishing. Luckily, Hyperledger Sawtooth can help! + +Hyperledger Sawtooth is ideal for this scenario because of its ability to track the provenance and journey of an asset (in this case, tuna). The ability to batch transactions together allows for all tuna within a catch to be entered as a whole. The distributed state agreement, novel consensus algorithm, and decoupled business logic from the consensus layer allow Miriam to be confident that she is buying tuna that has been legally caught. + +### The Supply Chain + +Hyperledger Sawtooth is extremely scalable and able to withstand high throughput of data, which makes it a great option for production supply chain scenarios. + +We will start with Sarah, our licensed tuna fisher, who sells her tuna to multiple restaurants. Sarah operates as a private business, in which her company frequently makes international deals. Through an application, Sarah is able to gain entry to a Hyperledger Sawtooth blockchain network comprised of other fishermen, as well as processing plants, regulators, and restaurant owners. Sarah, as well as the processing plants, have the ability to add and update information to this ledger as tuna passes through the supply chain, while regulators and restaurants have read access to ledger records. + +### The Tuna Asset + +With each catch, Sarah records some information about each individual tuna, including a unique ID number, the location and time of the catch, its weight, and who caught the fish. For the sake of simplicity, we will stick with these data attributes. However, in an actual application, many more details would be recorded, from toxicology, to other physical characteristics, such as the temperature of the tuna. + +These details are saved in the global state as **_key/value pairs_** based on the specifications of a **_Sawtooth application_**, while the **_transaction processor_** allows Sarah's application to effectively create a transaction on the ledger. Please see the example below: + +``` +var tuna = { + id: ‘0002’, + holder: ‘Sarah’, + location: { latitude: '15.623036831528264', longitude: '-158.466796875'}, + when: '20170635123546', + weight: ‘58lbs’ +} +``` + +### Recording a Catch + +After Sarah catches her tuna and records data for each tuna, she is able to treat a haul of tuna as a single **_batch_** of transactions. As a reminder, a **_batch_** is a cluster of transactions that are committed to state together. Using a batch, Sarah is able to record many tuna together, while still being able to specify data for each tuna. If one of the tuna transactions is invalid, the entire shipment is invalidated; that is, no tuna within the batch of tuna is validated. + +### Reaching Consensus + +After a batch of many transactions is submitted to the network, the network’s consensus algorithm chooses a node to publish this batch as a block on the ledger (possibly along with other batches). If the **_Proof of Elapsed Time_** consensus algorithm is used, the **_validator_** with the shortest wait time publishes the transaction block. (We'll discuss this in more detail later in the course.) The transaction block is then broadcasted to the publishing nodes. + +Each node within the network receives the transaction block, and validators verify whether the transaction is valid or not. If the transaction is validated, the global state is updated. + +Hyperledger Sawtooth provides full distributed state agreement, where every node in the system has the same understanding of information. As the supply chain matures, the data stored remains consistent across the network. + +With the global state adjusted, the processing plant, the regulator, and Miriam are able to see the details of the catch and who the current holder is, thus keeping the supply chain transparent and verifiable. + +### Other Actors in the Supply Chain + +Before Sarah's tuna can reach Miriam's restaurant, they need to go through a tuna processing plant. Also, regulators will need to verify and view details from the ledger. Therefore, both parties will gain entry to this Sawtooth blockchain. The regulators will need to query the ledger to confirm that Sarah is legally catching her fish. At the same time, tuna processing plants will need to record their processing and shipping of the tuna on the ledger. + +### Summary of Supply Chain Flow + +Now, let's review the summary of the transaction flow. + +|![Sarah_uses_the_client_application_to_record_all_caught_tuna_to_the_ledger](../images/introduction-to-hyperledger-sawtooth/Sarah_uses_the_client_application_to_record_all_caught_tuna_to_the_ledger.jpg)| +|:--:| +| *Licensed under [CC By 4.0](https://creativecommons.org/licenses/by/4.0/)* | + +Sarah catches a tuna and uses the client application to record all the details about the catch to the ledger. An entire haul of tuna can be treated as a transaction batch, with each individual tuna registered as a transaction within the batch. + +|![The_processing_plant_may_use_the_client_application_to_query_the_ledger](../images/introduction-to-hyperledger-sawtooth/The_processing_plant_may_use_the_client_application_to_query_the_ledger.jpg)| +|:--:| +| *Licensed under [CC By 4.0](https://creativecommons.org/licenses/by/4.0/)* | + +After the details of the catch are saved to the ledger and the tuna is passed along the supply chain, the processing plant may use the client application to query the ledger for details about specific catches, such as weight. The processing plant will add details reflecting the processing date and time, as well as other relevant information. + +|![Regulators_may_use_the_client_application_to_query_the_ledger__to_verify_legitimacy](../images/introduction-to-hyperledger-sawtooth/Regulators_may_use_the_client_application_to_query_the_ledger__to_verify_legitimacy.jpg)| +|:--:| +| *Licensed under [CC By 4.0](https://creativecommons.org/licenses/by/4.0/)* | + +As the tuna is passed along the supply chain, the regulators may use the client application to query the ledger for details about specific catches, such as the owner and location of the catch, to verify legitimacy. + +|![Miriam_can_use_the_client_application_to_query_the_ledger](../images/introduction-to-hyperledger-sawtooth/Miriam_can_use_the_client_application_to_query_the_ledger.jpg)| +|:--:| +| *Licensed under [CC By 4.0](https://creativecommons.org/licenses/by/4.0/)* | + +Lastly, when the haul of tuna arrives at Miriam's restaurant, Miriam is able to use the client application to query the ledger, to make sure Sarah was truthful in her account of where each fish was sourced. This, in turn, guarantees Miriam's restaurant is serving their customers the sustainably caught fish they advertise. + +## Key Components and Transaction Flow + +### Video: Hyperledger Sawtooth Key Components (Arianna Groetsema) + +--- + +The Hyperledger Sawtooth chapter has been updated to Sawtooth v1.0 (as of May 2018). At this time, we were unable to update the videos introducing each section, so there may be some discrepancies. We apologize for the inconvenience, and we will update these videos in a future course version. + +--- + +#### Hyperledger Sawtooth Key Components (Arianna Groetsema) + +[![Hyperledger Sawtooth Key Components (Arianna Groetsema)](../images/video-image.png)](https://youtu.be/5KO8jSSx7w8) + +### Requirements Supported by Hyperledger Sawtooth + +Hyperledger Sawtooth is a blockchain framework with potential in IoT, manufacturing, finance, and enterprise. Hyperledger Sawtooth supports diverse requirements, including both permissioned and permissionless deployments, and a pluggable consensus algorithm. This framework also provides a revolutionary consensus algorithm, Proof of Elapsed Time (PoET), that allows for versatility and scalability suited for a variety of solutions. + +Hyperledger Sawtooth supports many different infrastructural requirements, such as: + +* Permissioned and permissionless infrastructure +* Modular blockchain architecture +* Scalability, which is good for larger blockchain networks due to higher throughput +* Many languages for transaction logic +* On-chain governance that allows peers to vote on blockchain configuration +* An advanced transaction execution engine that can process transactions in parallel to accelerate block creation and validation +* Ethereum contract support with Seth, which allows participants to run Solidity smart contracts and integrate with Ethereum tooling +* Dynamic consensus lets you upgrade or swap blockchain consensus protocol on the fly as the network grows. + +### Transaction Batching + +In Hyperledger Sawtooth, **batches** are clusters of transactions that are committed to state together. If one transaction in the batch cannot be committed, none of the transactions are committed. As a result, transaction batches are often described as an atomic unit of change, since a group of transactions are treated as one, and are committed to the state as one. Every single transaction in Hyperledger Sawtooth is submitted within a batch. Batches can contain as little as a single transaction. + +When a transaction is created by a client, the batch is submitted to the validator (which we will cover more in-depth in the next section). Transactions are organized into a batch in the order they are intended to be committed. The validator then, in turn, applies each transaction within the batch, leading to a change in the global state. The batch is committed to the state. If one transaction within the batch is invalid, then none of the transactions within that batch are committed. + +In summary, transaction batching allows a group of transactions to be applied in a specific order, and if any are invalid, then none of the transactions are applied. This is a powerful tool that can be utilized by many enterprise solutions, as it provides greater efficiency and control for end users. + +### Validators + +In any blockchain network, modifying the global state requires creating and applying a transaction. In Hyperledger Sawtooth, **validators** apply batches of transactions that cause changes in the state. More specifically, validators group batches into blocks, submit the blocks, and ensure that transactions result in state changes that are consistent across all participants in the network. + +To start, a user creates a batch containing one or more transactions, and submits it to a validator, usually via a client that communicates with a REST API. The validator then checks the transactions and applies the batch if all transactions are considered valid, resulting in a change to the state. In terms of our demonstrated scenario, Sarah, the tuna fisher, creates a batch to record information about a group of tuna catches. The validator then applies the transactions, and the state is updated if all appropriate attributes are present: a unique ID number, location and time of the catch, weight, and who caught the fish. If any of these elements are missing, the transactions within the batch would not be applied, and the state would not be updated. + +|![Hyperledger_Sawtooth_Components](../images/introduction-to-hyperledger-sawtooth/Hyperledger_Sawtooth_Components.png)| +|:--:| +| *Licensed under [CC By 4.0](https://creativecommons.org/licenses/by/4.0/)* | + +### Consensus Interface + +A key feature of Hyperledger Sawtooth is its flexibility in allowing different consensus algorithms. As a reminder, the consensus algorithm determines which node on the network will publish the next block on the ledger. Hyperledger Sawtooth provides an abstract interface that supports both PBFT and Nakamoto-style algorithms. Consensus in Hyperledger Sawtooth is modular, meaning that the consensus algorithm can be easily modified. + +Currently, Hyperledger Sawtooth supports the following consensus implementations: + +* **Proof of Elapsed Time**, or **PoET**, a Nakamoto-style consensus algorithm that is designed to be a production-grade protocol capable of supporting large networks. +* **Dev mode**, a simplified random-leader algorithm that is useful for development and testing on single-node or small networks. + +PoET is available in two versions: + +* **PoET-SGX**, which relies on Intel® Software Guard Extensions (SGX) to implement a leader-election lottery system +* **PoET simulator**, which is the PoET consensus algorithm deployed on an SGX simulator. + +### Introducing Proof of Elapsed Time (PoET) + +The **Proof of Elapsed Time (PoET)** consensus algorithm impartially determines who will commit a transaction to state using a lottery function that elects a leader from many different distributed nodes. + +Hyperledger Sawtooth’s PoET algorithm differs from the Proof of Work algorithm implemented by the Bitcoin blockchain in that Proof of Work relies on vast amounts of power, while Proof of Elapsed Time is able to ensure trust and randomness in electing a leader without the high power consumption. PoET allows for increased scalability and participation, as every node in the network has an equal opportunity to create the next block on the chain. + +### How Proof of Elapsed Time Works + +To start, each validator within the network requests a wait time from an enclave, or a trusted function. This is where the 'Elapsed Time' comes into play. The validator with the shortest wait time for a specific block is appointed the leader, and creates the block to be committed to the ledger. As a result, a truly random leader is elected, and the amount of power or type of hardware you have will not give you an advantage. Using simple functions, the network can verify that the winning validator did indeed 'win', by proving that it had the shortest time to wait before assuming the leadership position. + +### Forks + +While PoET provides many benefits and aids tremendously with scalability, there is a downside to the PoET consensus algorithm. And that is the issue of **forks**. The PoET algorithm may lead to forking, in which two 'winners' propose a block. Each fork has to be resolved by validators, and this results in a delay in reaching consistency across the network. + +### Sawtooth Applications + +As with any blockchain framework, transaction updates need to be approved and shared between many untrusted parties. In Hyperledger Sawtooth, the business logic for an application, the data model that is used to record and store state data, and the client logic are defined as a **Sawtooth application**, also called a _transaction family_. An application consists of both a transaction processor (the server-side logic) and one or more clients (for use from the Web, CLI command line, or mobile applications). + +A transaction family defines a set of operations or _transaction types_ that are allowed on the shared ledgers. This allows for flexibility in the level of versatility and risk that exists on a network. Transaction families can provide 'safer' smart contracts, because they specify a predefined set of acceptable smart contract templates, as opposed to programming smart contracts from scratch. + +|![Sawtooth_Application](../images/introduction-to-hyperledger-sawtooth/Sawtooth_Application.png)| +|:--:| +| *Licensed under [CC By 4.0](https://creativecommons.org/licenses/by/4.0/)* | + +### Transaction Processors + +A **transaction processor** provides the server-side business logic that operates on assets within a network. Because Hyperledger Sawtooth separates the application layer from the consensus and core framework layer, businesses are able to develop transaction processors that do exactly what their applications need. + +Each node within the Hyperledger Sawtooth network runs at least one transaction processor (most networks run several). Each transaction processor handles its own incoming transactions as submitted by authorized clients. Hyperledger Sawtooth allows application developers to specify a **_namespace_** for each transaction processor (an application-specific range of addresses in state), which provides flexibility in defining, sharing, and reusing data between transaction processors. Using namespaces in global state lets programmers focus on developing application logic, as opposed to building communication mechanisms between transaction processors. + +Hyperledger Sawtooth's transaction processors can be written in a variety of languages, including Javascript, Java, Rust, Python, and Go, which allows flexibility for businesses to create their own applications. Hyperledger Sawtooth provides SDKs in several common languages. + +Later in this chapter, in the _Writing an Application_ section, you will be able to explore exactly how transaction processors interact with a client and other Hyperledger Sawtooth components. + +### Sawtooth Node + +Each organization that enters the Hyperledger Sawtooth network runs at least one validator node, and receives blocks that are broadcasted by peer nodes. Each validator node runs the following things: + +* The **validator** process +* The **REST API** (optional) listening for requests such as transaction posts or state queries +* One or more **transaction processors** + +A REST API on each node is optional. Clients can use an external REST API or communicate directly with the validator using ZeroMQ and protocol buffers (protobufs). + +|![Sawtooth_Network](../images/introduction-to-hyperledger-sawtooth/Sawtooth_Network.png)| +|:--:| +| *Licensed under [CC By 4.0](https://creativecommons.org/licenses/by/4.0/)* | + +## Installing Hyperledger Sawtooth + +### Technical Prerequisites + +In order to successfully install Hyperledger Sawtooth, you should have the following software installed on your computer: cURL, Git, Docker, and Docker Compose. + +If you need further details on these prerequisites, visit Chapter 4, _Technical Requirements_. + +### Installing Hyperledger Sawtooth + +Hyperledger Sawtooth is a suite that permits the creation and utilization of a distributed ledger. Installing Hyperledger Sawtooth will involve adding signing keys for the software creator to our environment, including the repository that contains the code to our system, and performing a typical update/install. + +A Hyperledger Sawtooth validator node can be run either from pre-built Docker images, or natively using Ubuntu 16.04. In this tutorial, we will demonstrate how to set up Hyperledger Sawtooth using Docker. + +Our example Sawtooth environment is a single validator node using the dev mode consensus, a REST API, three transaction processors, and a client container. + +### Starting Hyperledger Sawtooth + +First, download the following Docker Compose file as **sawtooth-default.yaml**: + +[https://raw.githubusercontent.com/hyperledger/education/master/LFS171x/sawtooth-material/sawtooth-default.yaml](https://raw.githubusercontent.com/hyperledger/education/master/LFS171x/sawtooth-material/sawtooth-default.yaml) + +Next, open a terminal window. + +Then, change your working directory to the same directory where the **sawtooth-default.yaml** Docker Compose file is saved. + +**Note:** Make sure you do **not** have anything else running on port 8008 or port 4004. + +Also, make sure to have Docker running on your device before running the commands in this section. Otherwise, when you run **docker-compose** in the next step, you will get a similar error to the one below: + +``` +ERROR: Couldn't connect to Docker daemon. You might need to start Docker for Mac. +``` + +Run the following command: + +``` +$ docker-compose -f sawtooth-default.yaml up +``` + +This command will download the Docker images that comprise the Hyperledger Sawtooth demo environment. The download will take several minutes. The terminal will start to display containers registering and creating initial blocks. + +### Logging into the Client Container + +The client container is used to run Sawtooth commands, which are used to configure the Sawtooth network and run client functions from the command line. + +Open a new terminal window and navigate to the directory where the **sawtooth-default.yaml** Docker Compose file is saved. + +Log into the client container by running the following command: + +``` +$ docker exec -it sawtooth-shell-default bash +``` + +In your terminal, you will see something similar to the following: + +``` +root@75b380886502:/# +``` + +Your environment is now set up and you are ready to start experimenting with the network. But first, let’s confirm that our validator is up and running, and reachable from the client container. To do this, run the following command: + +``` +$ curl http://rest-api:8008/blocks +``` + +After running this command, you should see a **json** object response with “data”, array of batches, header, etc. + +To check the connectivity from the host computer to the Docker container, run the following command in a new terminal window (it does not need to be the same directory as mentioned previously in this section): + +``` +$ curl http://localhost:8008/blocks +``` + +After running this command, you should see a **json** object response with “data”, array of batches, header, etc. + +### Stopping Hyperledger Sawtooth + +First, press **Ctrl+C** from the window where you originally ran **docker-compose**. + +Then, in the terminal, you will see containers stopping. After that, run the following command: + +``` +$ docker-compose -f sawtooth-default.yaml down +``` +### Video: Bringing Up a Sample Hyperledger Sawtooth Network (Demo) + +#### Change Bringing Up a Sample Hyperledger Sawtooth Network (Demo) + +[![Change Bringing Up a Sample Hyperledger Sawtooth Network (Demo)](../images/video-image.png)](https://youtu.be/0a_vPhCj-So) + +## Writing an Application + +### Applications + +In a Sawtooth application, the ledger will store the state of the system, in addition to the immutable record of transactions that created that state. An application typically consists of two parts: + +* **Client Application**
+ Sends transactions to the blockchain, typically through the Sawtooth REST API.
+ Provides a user interface for the application. A client can be a command-line interface, a web page, a mobile app, an IoT sensor, or most any other kind of interface capable of sending HTTP requests. + +* **Transaction Processor**
+ Encodes the business logic of the application.
+ Communicates with the validator, which sends transactions received from the client to the transaction processor for validation. + +### Video: Designing an Application (Alexandra Groetsema) + +--- + +The Hyperledger Sawtooth chapter has been updated to Sawtooth v1.0 (as of May 2018). At this time, we were unable to update the videos introducing each section, so there may be some discrepancies. We apologize for the inconvenience, and we will update these videos in a future course version. + +--- + +#### Designing an Application (Alexandra Groetsema) + +[![Designing an Application (Alexandra Groetsema)](../images/video-image.png)](https://youtu.be/ZlXh6riRKZs) + +### Review of Hyperledger Sawtooth Components + +**Sawtooth validators** validate transactions, combine batches of transactions into blocks, submit them to the ledger, and approve valid blocks according to the network's consensus algorithm. + +**Sawtooth applications** are distributed applications (also called transaction families) that consist of a transaction processor for the server-side logic and a client for use from Web, CLI, or mobile applications. + +**Transaction processors** provide the server-side business logic. + +**Batches** are clusters of transactions that are submitted together. If one transaction fails, the other transactions in that batch also fail. + +The **network layer** is responsible for communicating between validator nodes in a Hyperledger Sawtooth network, including performing initial connectivity, peer discovery, and message handling. + +The **global state** contains the current state of the ledger and a chain of transaction invocations. The state for all applications running on the network s is represented on each node. The state is split into application-specific namespaces, which allows applications to share and reuse global state data between transaction processors. + +### Sawtooth TunaChain Application + +Let’s get our feet wet with an example of a simple Hyperledger Sawtooth blockchain application that relates to the tuna supply scenario we discussed in our demonstrated scenario. Sawtooth TunaChain allows a user to create named assets (_Tuna_), and transfer them between different _Holders_ designated by a public key. + +In our example, we will look at: + +* A **transaction processor** +* A simple browser-based client. + +The TunaChain transaction processor is written using the Python 3 Sawtooth SDK. It interfaces with a Sawtooth validator in order to validate transactions. + +The client is a simple browser-based user interface written using the Sawtooth Javascript SDK. It allows the user to manage public/private key pairs and submit transactions using the Sawtooth REST API. + +### Cloning the Repository + +If you have not done so, you must clone the hyperledger/education GitHub repository. This repository contains the code for the Sawtooth TunaChain example application. + +To clone the repository, open a terminal window, navigate to your projects folder, and enter the following commands: + +``` +$ git clone https://github.com/hyperledger/education.git +$ cd education/LFS171x/sawtooth-material/sawtooth-tuna +``` + +Now you are in the folder that contains the code for the Sawtooth TunaChain example. + +### File Structure of the TunaChain Application + +Here you can see the file structure of the Sawtooth TunaChain application: + +|![File_structure_of_TunaChain_Application](../images/introduction-to-hyperledger-sawtooth/File_structure_of_TunaChain_Application.jpeg)| +|:--:| +| *Licensed under [CC By 4.0](https://creativecommons.org/licenses/by/4.0/)* | + +### Running the Application + +Make sure you have Docker running on your machine before you run the next command. If you do not have Docker installed, you should review Chapter 4, _Technical Requirements_. + +**Note:** Make sure you are in the **`sawtooth-tuna`** folder + +We will use the provided **`docker-compose.yaml`** file to create and run Docker containers for the required Sawtooth and TunaChain components. + +Run the following command to start Sawtooth with our TunaChain application: + +``` +$ docker-compose up +``` + +At this point, your terminal window should show that these containers are running: **`sawtooth-validator`**, **`tunachain-shell`**, **`sawtooth-settings-tp`**, **`tunachain-tp`**, **`sawtooth-rest-api`**, and **`tunachain-client`**. + +You should also see messages showing that **`sawtooth-settings-tp`** and **`tunachain-tp`** have registered with the validator, that the REST API has connected to the validator at port 4004, and that the client has been built inside the **`tunachain-shell`** container. + +If all of these conditions are true, and no other errors occur, you have successfully started a single-node Sawtooth network running the TunaChain demo application. + +### Sawtooth TunaChain State + +There are two kinds of state entries within the TunaChain application: _Assets_ and _Transfers_. These state entries are represented as UTF-8 encoded JSON objects with sorted keys. + +Asset state entries are formatted as follows: + +``` +{ + # Name of the Asset + "name": "name", +} +``` + +Transfer state entries are formatted as follows: + +``` +{ + # Name of the Asset + "asset": "asset", + + # Public key of the proposed recipient of the Asset + "owner": "owner", +} +``` +### Sawtooth TunaChain Addressing + +In Hyperledger Sawtooth, **_namespaces_** define the addressing scheme for application data. All Sawtooth applications store data in the state dictionary at 35-byte (70 hex-character) addresses. The addresses for TunaChain resources are generated as follows: + + 1. The first 3 bytes of any Sawtooth state address are reserved for the application namespace. For the TunaChain application, the namespace prefix is generated by taking the first 6 characters of a SHA-512 hash of the + application name "transfer-chain": + ``` + 19d832 + ``` + 2. The next byte of a TunaChain address specifies which type of resource is stored at the address:
+ Asset + ``` + 00 + ``` + Transfer + ``` + 01 + ``` + + 3. The final 31 bytes of a TunaChain address are the first 62 characters of a SHA-512 hash of the name of the + asset. + +For example, the TunaChain address of an Asset with the name "tuna4" would be generate as follows: + +``` +>>> hashlib.sha512('transfer-chain'.encode('utf-8')).hexdigest()[:6] + '00' + hashlib.sha512('tuna4'.encode('utf-8')).hexdigest()[:62]'19d83200714923803714eeb557276759eab2ce605c929dee093e7aa4359ee6f29a8880' +``` + +### Sawtooth TunaChain Transaction Payload + +Each TunaChain transaction payload is represented as a JSON object with the following format: + +``` +{ + # Action the transaction takes, either "create", "transfer", "accept", or + # "reject" + "action": "action", + + # Name of the Asset to be affected by the transaction + "asset": "asset", + + # Public key of the proposed new owner for a "transfer" transaction + "owner": "owner" +} +``` + +### Browser Client + +We are now ready to test our application through the user interface. In order to use the TunaChain client application, use a browser to navigate to **`localhost:8000`**. + +There are four different things we can do within the application: + +- **Select Holder** allows us to select a public key or create a new public/private key pair, which is referenced as a _Holder_ +- **Create Tuna Record** submits a transaction to create a new _Tuna_ entry in state, which is held by the currently selected _Holder_ +- **Transfer Tuna** submits a transaction to create a new _Transfer_ entry in state, which can be accepted or rejected by the potential recipient of the _Tuna_ asset +- **Accept Tuna** shows a list of the current _Transfers_ with the currently selected _Holder_ listed as a recipient, as well as options to either **Accept** or **Reject** the _Transfer_. + +Also, there is a **Tuna List** table that shows all of the current _Tuna_ assets in state with their respective _Holders_. + +Note: The application is running inside the **`tunachain-client`** Docker container, but the port that it is running on is exposed at port 8000 on the host machine. + +### Creating a New Holder + +In order to submit transactions to the REST API, we need to create a new _Holder_. For the TunaChain application, _Holders_ are just public/private key pairs which are stored in your browser's local storage. + +Within the user interface, you can create these keys from the _Select Holder_ dropdown list. You can use this same dropdown list to switch between multiple users in local storage. + +|![Tuna_Holder_drop_down](../images/introduction-to-hyperledger-sawtooth/Tuna_Holder_drop_down.png)| +|:--:| +| *Licensed under [CC By 4.0](https://creativecommons.org/licenses/by/4.0/)* | + +|![Tuna_Create_New_Key_Pair](../images/introduction-to-hyperledger-sawtooth/Tuna_Create_New_Key_Pair.png)| +|:--:| +| *Licensed under [CC By 4.0](https://creativecommons.org/licenses/by/4.0/)* | + +This user interface element invokes the following function within the client code: + +```javascript +// Select User +$('[name="keySelect"]').on('change', function () { + if (this.value === 'new') { + app.user = makeKeyPair() + app.keys.push(app.user) + saveKeys(app.keys) + addOption(this, app.user.public, true) + addOption('[name='transferSelect']', app.user.public) + } else if (this.value === 'none') { + app.user = null + } else { + app.user = app.keys.find(key => key.public ===this.value) + app.refresh() + } +}) +``` +_app.js: Select User_ + +```javascript +//Create new key-pair +const makeKeyPair = () => { + const context = createContext('secp256k1') + const privateKey = context.newRandomPrivateKey() + return { + public: context.getPublicKey(privateKey).asHex(), + private: privateKey.asHex() + } +} +``` +_state.js: makeKeyPair_ + +This function uses the JavaScript Client Signing SDK to create a random 256-bit private key represented as a 64-char hex string. This key should not be shared with anyone else. + +Next, the function derives a public key from the 256-bit private key created above. This is the key that is safe to share. + +It returns this key pair to the application, where it calls the following function to save the key pair to local storage: + +```javascript +//Save key-pairs to localStorage +const saveKeys = keys => { + const paired = keys.map(pair => [pair.public, pair.private].join(',')) + localStorage.setItem(KEY_NAME, paired.join(';')) +} +``` +_state.js: saveKeys_ + +**Note: This method of saving the key pair is for demonstration purposes only. This method is not recommended for a production environment.** + +### Creating a Record of Tuna + +Within the user interface, select the owner of the new _Asset_ in the **Select Holder** dropdown, then provide a unique name for the tuna in the **_Create Tuna Record_** text box. Lastly, click the **Create** button. + +|![Tuna_Create](../images/introduction-to-hyperledger-sawtooth/Tuna_Create.png)| +|:--:| +| *Licensed under [CC By 4.0](https://creativecommons.org/licenses/by/4.0/)* | + +After clicking the **Create** button, the following function is called within the client: + +```javascript +//Create Asset +$('#createSubmit').on('click', function () { + const asset = $('#createName').val() + if (asset) app.update('create', asset) +}) +``` +_apps.js: Create Asset_ + +Each user interface element that needs to make a change to state will call the **app.update()** function. This function formats the transaction payload and sends it to the **submitUpdate()** function in **state.js**. + +```javascript +app.update = function (action, asset, owner) { + if (this.user) { + submitUpdate( + { action, asset, owner }, + this.user.private, + success => success ? this.refresh() : null + ) + } +} +``` +_app.js: app.update()_ + +The **submitUpdate()** function handles the process of creating a transaction, adding it to a batch, submitting the batch to the REST API, and waiting for a response. + +If the transaction was successfully executed by the transaction processor, added to a block, and published by the validator, state will be updated with the new entry. After refreshing the page, you will see the tuna _Asset_ show up in the **Tuna List**, along with its associated _Holder's_ public key. + +|![Tuna_List](../images/introduction-to-hyperledger-sawtooth/Tuna_List.png)| +|:--:| +| *Licensed under [CC By 4.0](https://creativecommons.org/licenses/by/4.0/)* | + +### Transferring a Tuna + +Any _Asset_ assigned to a particular _Holder_ can be transferred to another Holder by using the dropdowns under **_Transfer Tuna_**. Note that the transfer must be accepted by the recipient before it is finalized. + +|![Tuna_Transfer](../images/introduction-to-hyperledger-sawtooth/Tuna_Transfer.png)| +|:--:| +| *Licensed under [CC By 4.0](https://creativecommons.org/licenses/by/4.0/)* | + +In the above example, we are proposing to transfer the ownership of **tuna4** from the current owner (identified by the key starting with **02ddf8de...**) to a new owner (identified by the key starting with **03b241b1...**). + +After clicking the **Transfer** button, the following function is called within the client: + +```javascript +//Transfer Asset +$('#transferSubmit').on('click', function () { + const asset = $('[name="assetSelect"]').val() + const owner = $('[name="transferSelect"]').val() + if (asset && owner) app.update('transfer', asset, owner) +}) +``` +_apps.js: Transfer Asset_ + +This function calls **app.update()**, which in turn calls **submitUpdate()** to submit the transaction to create a new _Transfer entry_ in state. + +### Accepting or Rejecting Transfers + +Once a _Transfer_ has been created, go to the **Select Holder** dropdown and select the public key of the potential recipient. This will reload the page and populate the **Accept Tuna** section with all of the _Transfers_ in state with the selected _Holder_ as the potential recipient, as shown below: + +|![Accept_Tuna](../images/introduction-to-hyperledger-sawtooth/Accept_Tuna.jpg)| +|:--:| +| *Licensed under [CC By 4.0](https://creativecommons.org/licenses/by/4.0/)* | + +Clicking **Accept** or **Reject** will invoke one of the following functions: + +```javascript +//Accept Asset +$('#transferList').on('click', '.accept', function () { + const asset = $(this).prev().text() + if (asset) app.update('accept', asset) +}) +``` +_app.js: Accept Asset_ + +```javascript +//Reject Asset +$('#transferList').on('click', '.reject', function () { + const asset = $(this).prev().prev().text() + if (asset) app.update('reject', asset) +}) +``` +_app.js: Reject Asset_ + +After accepting or rejecting the _Transfer_, the _Transfer_ will be removed from the **Accept Tuna** section. If the _Transfer_ was accepted, the **Tuna List** table will be updated to show the new owner. If it was rejected, the **Tuna List** table will be unchanged indicating that a transfer did not take place. + +### TunaChain Transaction Processor + +To review, there are two main components of a **transaction processor**: + +- **TransactionProcessor** class
+ A general purpose class that is provided by the Sawtooth SDK. It handles the connection between the transaction processor and the validator. +- **TransactionHandler** class
+ A base class that is extended with specific validation logic for each application. In addition to several metadata methods, it has an **apply()** method which encompasses the logic for validating and executing a transaction.
+ The **apply()** method gets called with two arguments, **transaction** and **context**. The argument **transaction** holds the command that is to be executed, while **context** stores information about the current state. + +To separate details of state encoding and payload handling from validation logic, the TunaChain transaction processor utilizes two additional classes: + +- **TunachainPayload** has **action**, **asset**, and **owner** fields, and is responsible for validating that the transaction payload was properly formed. +- **TunachainState** contains a reference to **context**, and has additional methods for generating state addresses, as well as getting and setting values in state. + +The code for the TunaChain transaction processor can be found here: [https://github.com/hyperledger/education/tree/master/LFS171x/sawtooth-material/sawtooth-tuna/processor](https://github.com/hyperledger/education/tree/master/LFS171x/sawtooth-material/sawtooth-tuna/processor) + +### Shutting Down Sawtooth + +**Note:** When we are done with this tutorial, run the following command to shut down the Docker containers running the Sawtooth components: + +``` +$ docker-compose down +``` + +### Summary of TunaChain Application Flow + +The example TunaChain application demonstrates Hyperledger Sawtooth features with a simple browser-based client for the user interface and a transaction processor for the business logic. + +|![Application_Flow](../images/introduction-to-hyperledger-sawtooth/Application_Flow.png)| +|:--:| +| *Licensed under [CC By 4.0](https://creativecommons.org/licenses/by/4.0/)* | + +Hyperledger Sawtooth allows entities to securely update and read the distributed ledger without involving a central authority. Developers create application and transaction processor business logic (smart contract). + +Through the client application, users (tuna fisher, regulator, restaurant) are able to modify the state by creating and applying transactions. + +Through a REST API, the client application creates a batch containing a single transaction, and submits it to the validator. + +The validator applies the transaction using the transaction processor, which makes a change to the state (e.g., creating a record of a tuna catch). + +## Joining the Hyperledger Sawtooth Community + +### Learning More about Hyperledger Sawtooth + +See the Hyperledger Sawtooth project page for links to code, documentation, examples, and latest news: + +[https://www.hyperledger.org/projects/sawtooth](https://www.hyperledger.org/projects/sawtooth) + +### Becoming Involved with the Hyperledger Sawtooth Project + +Hyperledger Sawtooth is an open source project, where ideas and code can be publicly discussed, created, and reviewed. There are many ways to join the Hyperledger Sawtooth community. The next few pages highlight some of the ways to get involved, either from a technical standpoint, or from an ideas/issues-creation perspective. + +### Community Meetings and Mailing Lists + +You can join the Sawtooth mailing list for technical discussions and announcements: [https://lists.hyperledger.org/g/sawtooth](https://lists.hyperledger.org/g/sawtooth). + +The Hyperledger Community Meetings calendar includes online application developer forums and sprint planning meetings for Hyperledger Sawtooth: [https://calendar.google.com/calendar/embed?src=linuxfoundation.org_nf9u64g9k9rvd9f8vp4vur23b0%40group.calendar.google.com&ctz=America/SanFrancisco](https://calendar.google.com/calendar/embed?src=linuxfoundation.org_nf9u64g9k9rvd9f8vp4vur23b0%40group.calendar.google.com&ctz=America/SanFrancisco). + +Some of the recordings of previous virtual tech forums on Hyperledger Sawtooth can be found here: [https://drive.google.com/drive/folders/0B_NJV6eJXAA1VnFUakRzaG1raXc](https://drive.google.com/drive/folders/0B_NJV6eJXAA1VnFUakRzaG1raXc). + +### GitHub and Rocket.Chat + +You can also get involved with the Hyperledger Sawtooth community on GitHub and Rocket.Chat. + +Hyperledger Sawtooth code is available in GitHub repositories. All code available on GitHub is forkable and viewable: + +- [https://github.com/hyperledger/sawtooth-core](https://github.com/hyperledger/sawtooth-core) +- [https://github.com/hyperledger/sawtooth-supply-chain](https://github.com/hyperledger/sawtooth-supply-chain) +- [https://github.com/hyperledger/sawtooth-seth](https://github.com/hyperledger/sawtooth-seth) + +You can also join the live conversations on Hyperledger Chat (powered by Rocket.Chat, an alternative to Slack), using your Linux Foundation ID: + +- [https://chat.hyperledger.org/channel/sawtooth](https://chat.hyperledger.org/channel/sawtooth) +- [https://chat.hyperledger.org/channel/sawtooth-consensus](https://chat.hyperledger.org/channel/sawtooth-consensus) +- [https://chat.hyperledger.org/channel/sawtooth-seth](https://chat.hyperledger.org/channel/sawtooth-seth) + +## Knowledge Check + +### Knowledge Check 6.1 + +Which of the following is a consensus algorithm introduced in Hyperledger Sawtooth? + +
    +
  1. Proof of Stake
  2. +
  3. Proof of Work
  4. +
  5. Proof of Elapsed Time
  6. +
  7. PBFT
  8. +
+ +### Knowledge Check 6.2 + +What are some of the advantages of a platform like Hyperledger Sawtooth? + +
    +
  1. It is highly modular, enabling different consensus algorithms to be plugged in
  2. +
  3. It allows for permissionless or permissioned deployments
  4. +
  5. Transaction Batching
  6. +
  7. All of the above
  8. +
+ +### Knowledge Check 6.3 + +Which of the following correctly describes an application (a transaction family) in the context of Hyperledger Sawtooth? + +
    +
  1. Separates framework from transaction logic
  2. +
  3. Communicates between the client and validator
  4. +
  5. Provides the business logic and operations for assets within a network
  6. +
  7. Contains the state of the ledger and transaction processors
  8. +
+ +### Knowledge Check 6.4 + +Validators validate transactions and ensure that changes in data are equivalent for all participants in the network. True or False? + +
    +
  1. True
  2. +
  3. False
  4. +
+ +### Knowledge Check 6.5 + +Thinking back to the demonstrated scenario we used in this chapter, what is the difference between what a regulator can do and what tuna fisher Sarah can do? + +
    +
  1. There is no difference between these two users
  2. +
  3. Sarah is able to perform all actions, including read and write to the ledger, while the regulator only has the ability to read the ledger
  4. +
  5. The regulator has full access to the ledger to read and write, while Sarah is only allowed to write to the ledger
  6. +
  7. None of the above
  8. +
+ +### Knowledge Check 6.6 + +Which of the following correctly describes batches in the context of Hyperledger Sawtooth? + +
    +
  1. Transactions can be organized into batches, where each transaction may or may not be committed
  2. +
  3. Transactions are organized into batches, where either all transactions in a batch are committed, or none are committed
  4. +
  5. Transactions are combined into a block, and all transactions within the block are committed
  6. +
+ +### Knowledge Check 6.7 + +What are the two main components of a transaction processor? + +
    +
  1. Processor class and handler class
  2. +
  3. Processor class and transaction families
  4. +
  5. Handler class and validator
  6. +
  7. Processor class and transaction batches
  8. +
+ +### Knowledge Check 6.8 + +In the TunaChain application, the web client can be used to submit a transaction to create a new tuna _Asset_ in state, and the owner of a newly created Asset is the public key of the user who signed the transaction. True or False? + +
    +
  1. True
  2. +
  3. False
  4. +
+ +### Knowledge Check 6.9 + +Which of the following plays the main role within a Hyperledger Sawtooth network? + +
    +
  1. Transaction processors
  2. +
  3. Nodes
  4. +
  5. Peers
  6. +
  7. Validators
  8. +
+ +### Knowledge Check 6.10 + +What aspects of the Hyperledger Sawtooth application flow are created by a developer? + +
    +
  1. Validator and application
  2. +
  3. Application client and transaction processor
  4. +
  5. Transaction processor and validator
  6. +
  7. Application client and state
  8. +
+ +## Conclusions & Learning Objectives (Review) + +### Learning Objectives (Review) + +You should now be able to: + +- Understand the basics of Hyperledger Sawtooth v1.0. +- Walk through a demonstrated scenario highlighting aspects of Hyperledger Sawtooth. +- Discuss crucial components of Hyperledger Sawtooth, including the consensus algorithm _Proof of Elapsed Time_, transaction processors, batches, and validators. +- Set up a running Hyperledger Sawtooth network and test an application. +- Get involved in the Hyperledger Sawtooth application or framework discussion and development. + +### Video: Conclusions (Ariana Groetsema) + +--- + +The Hyperledger Sawtooth chapter has been updated to Sawtooth v1.0 (as of May 2018). At this time, we were unable to update the videos introducing each section, so there may be some discrepancies. We apologize for the inconvenience, and we will update these videos in a future course version. + +--- + +#### Conclusions (Ariana Groetsema) + +[![Conclusions (Ariana Groetsema)](../images/video-image.png)](https://youtu.be/ZYFPDKsQovg) \ No newline at end of file diff --git a/LFS171x/docs/welcome-intro.md b/LFS171x/docs/welcome-intro.md new file mode 100644 index 00000000..78ad31c4 --- /dev/null +++ b/LFS171x/docs/welcome-intro.md @@ -0,0 +1,210 @@ + + +- [Welcome & Introduction](#welcome-introduction) + - [Welcome to LFS171x](#welcome-to-lfs171x) + - [Video: A Word from Brian Behlendorf, Executive Director at Hyperledger](#video-a-word-from-brian-behlendorf-executive-director-at-hyperledger) + - [Course Learning Objectives](#course-learning-objectives) + - [Before You Begin](#before-you-begin) + - [Syllabus and Grading](#syllabus-and-grading) + - [Course Timing](#course-timing) + - [Course Progress & Completion](#course-progress-completion) + - [Guidelines to Discussions](#guidelines-to-discussions) + - [Learning Aids](#learning-aids) + - [Video: Inspiration Behind the Course (Brian Behlendorf)](#video-inspiration-behind-the-course-brian-behlendorf) + - [A Note from the Authors](#a-note-from-the-authors) + - [Hyperledger](#hyperledger) + - [The Linux Foundation](#the-linux-foundation) + - [The Linux Foundation Events](#the-linux-foundation-events) + - [The Linux Foundation Training](#the-linux-foundation-training) + - [Copyright](#copyright) + + + +# Welcome & Introduction + +## Welcome to LFS171x +Discover the power of business blockchains and distributed ledger technologies with an overview of Hyperledger and introductions to its key frameworks. Blockchains have quickly gained popularity in several industries. This introductory course is carefully curated for both nontechnical and technical audiences. It examines blockchains for the enterprise and a number of pertinent use cases. Hyperledger is a group of open source blockchain-based projects organized by The Linux Foundation. Industries are researching how blockchains may increase efficiency and solve business problems associated with data privacy, security, information sharing, and inclusion. What are blockchain & distributed ledger technologies and how might they impact global business? + +The course covers key features of blockchain technologies and the differentiators between various types of Hyperledger blockchain frameworks. We shall start with ‘What is blockchain?’ and open the discussion on where blockchain technology is suitable for your business requirements. We then take a deep dive into the enterprise-ready Hyperledger blockchain frameworks by guiding students through a demonstrated scenario. + +Students with a technical background should be able to perform clean installations of Hyperledger Sawtooth and Hyperledger Fabric, as well as, develop simple applications on top of these frameworks. They will gain an understanding of various types of blockchains and which one is most suitable for any particular project. + +Students with a business background should gain an understanding of how blockchains work and how they can create value for their business through cost savings and efficiencies in terms of speed and simplicity. They will view how information is generated, stored, and shared in various blockchains, as well as, gain tools to evaluate whether or not a blockchain solution would be suitable for their particular business case. + +## Video: A Word from Brian Behlendorf, Executive Director at Hyperledger +[![A Word from Brian Behlendorf, Executive Director at Hyperledger](../images/video-image.png)](https://youtu.be/aenPNayMKd8) + +## Course Learning Objectives +By taking this course, you will be able to: + +* Describe Business Blockchain and Distributed Ledger Technologies. +* Gain familiarity with current Hyperledger projects and cross-industry use cases. +* Perform clean installations of the Hyperledger Sawtooth and Hyperledger Fabric frameworks. +* Explore a sample use case/application in the context of the Hyperledger Sawtooth and Hyperledger Fabric frameworks. +* Build simple applications on top of Hyperledger Sawtooth and Hyperledger Fabric. +* Become involved in and contribute to the open source Hyperledger projects. + +## Before You Begin +If you are using edX for the first time, we strongly encourage you to start by taking a free 'how to use edX' course that the team at edX has made available. [Click here](https://www.edx.org/course/edx/edx-edxdemo101-edx-demo-1038) to register and you will be on your way. You will find the edX platform simple and intuitive. You can use the *Table of Contents* under the **Course** tab to navigate between *Chapters* and *Sections*. Once you are in a chapter/section, you can use the ribbon at the top of the screen to navigate the units within that *Section* or *Chapter*. You can always go back to the *Table of Contents* by clicking on the *Course* in the ribbon. + +This course is self-paced, meaning there is no structured instructor availability. However, you will find the Discussion board (see the **Discussion** tab at the top of each page) to be very helpful, as a means of asking or answering questions and interacting with your peers taking the course. The Discussion board is moderated by The Linux Foundation. + +For any technical issues with the edX platform (including login problems and issues with the Verified Certificate), please use the *Support* icon located on the right side of your screen. + +![help icon](../images/welcome-intro/help.png) + +## Syllabus and Grading +The outline for this course can be downloaded [here](https://prod-edxapp.edx-cdn.org/assets/courseware/v1/f78e55f0cfc90346abab4ae5096007d2/asset-v1:LinuxFoundationX+LFS171x+3T2017+type@asset+block/LFS171x_-_Blockchain_for_Business_-_An_Introduction_to_Hyperledger_Technologies_Outline.pdf). Since this course is entirely self-paced, we include demos and questions to help you practice the skills as you are acquiring them. At the end of each chapter, you will have a set of graded knowledge check questions, that are meant to further check your understanding of the material presented. The grades obtained by answering these knowledge check questions will represent 20% of your final grade. + +At the end of the course, you are required to pass a final exam, which consists of 30 questions. The remaining 80% of your final grade is represented by the score obtained in the final exam. + +**In order to complete this course with a passing grade, you must obtain a passing score (Knowledge Check and Final Exam) of minimum 70%.** + +![Passing grade](../images/welcome-intro/70_percent_passing_grade.jpg) + +You will have a maximum of 2 attempts to answer each knowledge check and exam question (other than true/false answers, in which case, you have only 1 attempt). The knowledge check questions and the exam questions are open book (meaning that you are free to reference your notes, screens from the course, etc.), and there is no time limit on how long you can spend on a question. You can always skip a question and come back to it later. + +**Getting your Certificate of Completion** + +If you are enrolled in a Verified track, Verified Certificates of completion are available once you achieve a passing score on the final exam. Once you have earned an overall grade of 70% or higher, you will be able to request your certificate directly from your Progress page. Once the request is completed (which may take up to 48 hours), you can then return to the same place and download your certificate. There are no certificates available for Audit tracks. + +## Course Timing +This course is entirely self-paced; there is no fixed schedule for going through the material. You can go through the course at your own pace, and you will always be returned to exactly where you left off when you come back to start a new session. However, we still suggest you avoid long breaks in between periods of work, as learning will be faster and content retention improved. + +The chapters in the course have been designed to build on one another. It is probably best to work through them in sequence; if you skip or only skim some chapters quickly, you may find there are topics being discussed you have not been exposed to yet. But this is all self-paced and you can always go back, so you can thread your own path through the material. + +![Timing](../images/welcome-intro/time-624686_640.jpg) + +## Course Progress & Completion +The goal of this course is to introduce you to the concept of Hyperledger technology. In order to check your understanding of the content, you will be asked to answer the Knowledge Check questions located at the end of each chapter and participate in the Final Exam. + +The Knowledge Check questions are graded, and, as such, they do count towards your final passing grade (they represent 20% of your final grade). The Final Exam represents 80% of your passing grade. Once you complete the exam, you will want to know if you have passed. You will be able to see your completion status using the *Progress* tab at the top of your screen, which will clearly indicate whether or not you have achieved a passing score. Click [here](https://prod-edxapp.edx-cdn.org/assets/courseware/v1/89830391ed822d4d3a3dfd33b4250dbc/asset-v1:LinuxFoundationX+LFS171x+3T2017+type@asset+block/LFS171x-Progress_Bar.png) to view a sample of this screen in a new tab. + +Certificates of completion (Verified Certificates) are available once you achieve a passing score of 70% on your course. Once you have done so, you can request the certificate on your *Progress* page. Once the request is completed (which may take up to 48 hours), you can then return to the same place and download your certificate. The visuals below provide a guide to what this will look like. + +![Progress](../images/welcome-intro/Course_progress_.png) + +![Certificate available](../images/welcome-intro/Your_certificate_is_available.png) + +## Guidelines to Discussions +One great way to interact with peers taking this course is via the Discussion boards. These boards can be used in the following ways: + +* To discuss concepts, tools, and technologies presented in this course, or related to the topics discussed in the course material. +* To ask questions about course content. +* To share resources and ideas related to blockchain and Hyperledger technologies. + +We strongly encourage you not only to ask questions, but to share with your peers opinions about the course content, as well as valuable related resources. The Discussion boards will be reviewed periodically by The Linux Foundation staff, but it is primarily a community resource, not an 'ask the instructor' service. To learn more tips about using the Discussion boards, click [here](http://blog.edx.org/getting-most-out-edx-discussion-forums). + +## Learning Aids +Besides simple exposition through text and figures, this course uses several types of learning aids to enhance your learning experience. + +**Videos** + +There are numerous videos in which the instructors discuss concepts and tools related to Hyperledger technologies. You may want to click on the CC button to see closed captioning. + +**External Resources** + +You will also have many opportunities to expand your knowledge of Hyperledger by accessing the external hyperlinks we provide throughout the entire course. + +**Check Your Understanding** + +At the end of each chapter, you will find a series of Knowledge Check questions. These questions were designed with one main goal in mind: to help you better comprehend the course content and reinforce what you have learned. It is important to point out that the **knowledge check questions are graded and they count towards your passing grade.** We would also like to emphasize that **you will be required to take a final exam to complete this course.** + +**Glossary** + +We use numerous key concepts throughout the entire course. To make it easier to understand and reference them, we have compiled a list of of these concepts, along with their definitions. This list is quickly accessible from anywhere in the course, just click on the **Glossary** tab above. + +**Recommended Resources & References** + +On this page, we present a summary of resources and references recommended in the course. The resources and references will be quickly accessible from anywhere within the course, just click on the **Recommended Resources** tab above. + +![Learning Aids](../images/welcome-intro/Learning_Aids.jpg) + +## Video: Inspiration Behind the Course (Brian Behlendorf) +[![Inspiration Behind the Course (Brian Behlendorf)](../images/video-image.png)](https://youtu.be/kSNvd9B8A0g) + +## A Note from the Authors +The idea for this course blossomed from a lively conversation between Brian Behlendorf, Robert Schwentker, and Jeff Flowers at the Hackfest in San Francisco, February 2017, about creating a Hyperledger MOOC for edX. + +We adopted a personalized, multi-disciplinary approach to teaching blockchain business and technical content, while bringing key people within the Hyperledger Community to the fore. There were many people who contributed to this initial release of the course. First of all, we would like to thank The Linux Foundation Hyperledger project team, especially Tracy Kuhrt, David Huseby, Flavia Cioanca, and Clyde Seepersad, for multiple reviews, detailed suggestions, and everything they did to make this course a reality. + +We are grateful to Jeff Flowers, who helped curate the architecture of the course, by sharing his erudite approach to MOOC development. Jeff created a challenging level set with the technical chapters, providing mentorship, and sharing insights into the methodology for setting up and configuring Hyperledger Sawtooth. + +We are equally grateful to everyone who worked behind-the-scenes, and to the experts featured in the course videos - whom you will meet in each chapter. We would like to thank Jonathan Levi for his guidance and responsiveness to our business and technical questions. + +We would also like to acknowledge key contributions made by Shorouq Aljohani towards the early drafts of the technical chapter on Hyperledger Iroha. She created foundational content for the chapter, drawing from her technical expertise. + +Finally, we would also like to thank the masters of the craft, Jefree Anderson and Ted Hoppe, who produced the dozens of videos featured throughout the course. Lillian Chan graciously helped with the video content, and provided fantastic support on set. + +And to Brian Behlendorf himself, who believed we could make it happen. + +We hope you will enjoy the course and may your learning journey be fruitful! + +Sincerely, + +Robert, Alexandra, Arianna, Navroop & Nathalie + +## Hyperledger +Hyperledger is the umbrella open source project that The Linux Foundation has created and hosted since 2015. It aims at advancing and promoting cross-industry blockchain technologies to ensure accountability, transparency, and trust among business partners. As a result, Hyperledger makes business network and transactions more efficient. + +These benefits are valued by leaders across many industries, including technology, finance, healthcare, supply chain, and automotive, among several others. + +Hyperledger offers different blockchain platforms. This course will present three of them: Iroha, Sawtooth, and Fabric. + +To learn more about the Hyperledger, click [here](https://www.hyperledger.org/). + +![Hyperledger logo](../images/Hyperledger_logo.png) + +## The Linux Foundation +The Linux Foundation partners with the world's leading developers and companies to solve the hardest technology problems and accelerate open technology development and commercial adoption. The Linux Foundation makes it its mission to provide experience and expertise to any initiative working to solve complex problems through open source collaboration, providing the tools to scale open source projects: security best practices, governance, operations and ecosystem development, training and certification, licensing, and promotion. + +Linux is the world's largest and most pervasive open source software project in history. The Linux Foundation is home to Linux creator Linus Torvalds and lead maintainer Greg Kroah-Hartman, and provides a neutral home where Linux kernel development can be protected and accelerated for years to come. The success of Linux has catalyzed growth in the open source community, demonstrating the commercial efficacy of open source and inspiring countless new projects across all industries and levels of the technology stack. + +The Linux Foundation's work today extends far beyond Linux, fostering innovation at every layer of the software stack. The Linux Foundation is the umbrella organization for many critical open source projects that power corporations today, spanning all industry sectors: + +* Big data and analytics: [ODPi](https://www.odpi.org/), [R Consortium](https://www.r-consortium.org/) +* Networking: [OpenDaylight](https://www.opendaylight.org/), [OPNFV](https://www.opnfv.org/) +* Embedded: [Dronecode](https://www.dronecode.org/), [Zephyr](https://www.zephyrproject.org/) +* Web tools: [JS Foundation](https://js.foundation/), [Node.js](https://nodejs.org/en/) +* Cloud computing: [Cloud Foundry](https://www.cloudfoundry.org/), [Cloud Native Computing Foundation](https://cncf.io/), [Open Container Initiative](https://www.opencontainers.org/) +* Automotive: [Automotive Grade Linux](https://www.automotivelinux.org/) +* Security: [The Core Infrastructure Initiative](https://www.coreinfrastructure.org/) +* Blockchain: [Hyperledger](https://www.hyperledger.org/) +* And many more. + +To learn more about The Linux Foundation, [click here](https://www.linuxfoundation.org/). + +## The Linux Foundation Events +The Linux Foundation hosts an increasing number of events each year, including: + +* Open Source Summit North America, Europe, Japan, and China +* MesosCon North America, Europe, China +* Embedded Linux Conference/ OpenIoT Summit North America, Europe +* Open Source Leadership Summit +* Automotive Linux Summit +* Apache: Big Data North America & ApacheCon +* KVM Forum +* Linux Storage Filesystem & Memory Management Summit +* Vault +* Open Networking Summit. + +## The Linux Foundation Training +The Linux Foundation offers several types of training: + +* Classroom +* Online +* On-Site +* Events Based. + +To get more information about specific courses offered by The Linux Foundation: + +* [Linux Programming & Development Training](http://training.linuxfoundation.org/linux-courses/development-training) +* [Enterprise IT & Linux System Administration Courses](http://training.linuxfoundation.org/linux-courses/system-administration-training) +* [Open Source Compliance Courses](http://training.linuxfoundation.org/linux-courses/open-source-compliance-courses) + +For additional information, including technical requirements and other logistics, see [training.linuxfoundation.org](http://training.linuxfoundation.org/). + +## Copyright +![Copyright](../images/welcome-intro/Copyright.jpg) + +**Copyright 2017-2018, The Linux Foundation and Hyperledger. The course content is licensed under a [Creative Commons Attribution 4.0 International License](https://creativecommons.org/licenses/by/4.0/). The source code used in the course examples is licensed under [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0).** diff --git a/LFS171x/docs/whats-next.md b/LFS171x/docs/whats-next.md index 5de89c98..8ce0325b 100644 --- a/LFS171x/docs/whats-next.md +++ b/LFS171x/docs/whats-next.md @@ -1 +1,66 @@ # What's Next? + + +- [What's Next?](#whats-next) + - [Hyperledger Community](#hyperledger-community) + - [Joining the Hyperledger Community](#joining-the-hyperledger-community) + - [Hyperledger Working Groups](#hyperledger-working-groups) + - [Video: Hyperledger Community (Tracy Kuhrt)](#video-hyperledger-community-tracy-kuhrt) + - [Video: Hackfests (Brian Behlendorf)](#video-hackfests-brian-behlendorf) + - [Video: Rewards and Challenges (Brian Behlendorf)](#video-rewards-and-challenges-brian-behlendorf) + - [Video: Jonathan Levi Talks about His Hyperledger Journey](#video-jonathan-levi-talks-about-his-hyperledger-journey) + - [Conclusions](#conclusions) + + +## Hyperledger Community + +The development of the Hyperledger projects is led by a diverse group of technical, open source contributors. We are always looking for help to build an open source ecosystem of business blockchain technologies. If you are interested in contributing to and learning from the community, we welcome you to [join the Hyperledger](https://www.hyperledger.org/community) effort. + +## Joining the Hyperledger Community + +You too can join the Hyperledger Community: + +- **For developers** + Read the Hyperledger code on [GitHub](https://github.com/hyperledger/hyperledger). Join the Hyperledger discussion at [Rocket.Chat](https://chat.hyperledger.org/home). Search for open bugs, or report a new one in the [Hyperledger’s bug database](https://jira.hyperledger.org/secure/Dashboard.jspa). +- **For business leaders** + For key updates from Hyperledger, join the [mailing list](https://lists.hyperledger.org/g/main). Explore all Hyperledger [business solutions](https://www.hyperledger.org/projects). +- **For educators and community leaders** + You can start or join a [Hyperledger meetup](https://www.meetup.com/pro/hyperledger/). Development updates from Wiki can be found [here](https://wiki.hyperledger.org/). + +|![Hyperledger Global Meetups](../images/whats-next/Hyperledger_Global_Meetups.png)| +|:--:| +|*Licensed under [CC By 4.0](https://creativecommons.org/licenses/by/4.0/)*| + +## Hyperledger Working Groups + +The Hyperledger Community’s working groups are open to the public. Developers and tech leaders can engage with any of the Hyperledger’s open community channels at this [page](https://wiki.hyperledger.org/community/calendar-public-meetings). + +Below, you can see an overview of Hyperledger’s working groups. + +|![Hyperledger Working Groups](../images/whats-next/Hyperledger_Working_Groups.png)| +|:--:| +|*Licensed under [CC By 4.0](https://creativecommons.org/licenses/by/4.0/)*| + +## Video: Hyperledger Community (Tracy Kuhrt) + +[![Hyperledger Community (Tracy Kuhrt)](../images/video-image.png)](https://youtu.be/kW94LHpi_7E) + +## Video: Hackfests (Brian Behlendorf) + +[![Hackfests (Brian Behlendorf)](../images/video-image.png)](https://youtu.be/p5GEF1uxOSM) + +## Video: Rewards and Challenges (Brian Behlendorf) + +[![Rewards and Challenges (Brian Behlendorf)](../images/video-image.png)](https://youtu.be/xtCdbgZ1YGg) + +## Video: Jonathan Levi Talks about His Hyperledger Journey + +[![Rewards and Challenges (Brian Behlendorf)](../images/video-image.png)](https://youtu.be/UOkv_ZxCQnE) + +## Conclusions + +This concludes the _Blockchain for Business: An Introduction to Hyperledger Technologies_ course! We have introduced you to the current Hyperledger frameworks and modules, we have highlighted some of the business blockchain applications, we have guided you through a more in-depth tour on three of the most mature frameworks (Hyperledger Iroha, Hyperledger Sawtooth, and Hyperledger Fabric), and we also provided deep-dive tutorials for Hyperledger Sawtooth and Hyperleger Fabric. + +We hope this course inspires you and helps you continue your journey into the business blockchain technology world. Whether you are an engineer, entrepreneur, developer, educator, or business person, we look forward to seeing what you build, as well as hearing from you in the course forum. + +Good luck to all of you in your future endeavors! \ No newline at end of file diff --git a/LFS171x/images/Hyperledger_logo.png b/LFS171x/images/Hyperledger_logo.png new file mode 100644 index 00000000..30b37209 Binary files /dev/null and b/LFS171x/images/Hyperledger_logo.png differ diff --git a/LFS171x/images/introduction-to-hyperledger-fabric/Demonstrated_Tuna_Fishing_Scenario.png b/LFS171x/images/introduction-to-hyperledger-fabric/Demonstrated_Tuna_Fishing_Scenario.png new file mode 100644 index 00000000..63a2444d Binary files /dev/null and b/LFS171x/images/introduction-to-hyperledger-fabric/Demonstrated_Tuna_Fishing_Scenario.png differ diff --git a/LFS171x/images/introduction-to-hyperledger-fabric/Fabric_demonstrated_scenario_actors.png b/LFS171x/images/introduction-to-hyperledger-fabric/Fabric_demonstrated_scenario_actors.png new file mode 100644 index 00000000..e5979f04 Binary files /dev/null and b/LFS171x/images/introduction-to-hyperledger-fabric/Fabric_demonstrated_scenario_actors.png differ diff --git a/LFS171x/images/introduction-to-hyperledger-fabric/Fabric_installation_1.jpg b/LFS171x/images/introduction-to-hyperledger-fabric/Fabric_installation_1.jpg new file mode 100644 index 00000000..a9d30326 Binary files /dev/null and b/LFS171x/images/introduction-to-hyperledger-fabric/Fabric_installation_1.jpg differ diff --git a/LFS171x/images/introduction-to-hyperledger-fabric/Invoke_method_queryTuna_and_changeTuna.png b/LFS171x/images/introduction-to-hyperledger-fabric/Invoke_method_queryTuna_and_changeTuna.png new file mode 100644 index 00000000..bec6116a Binary files /dev/null and b/LFS171x/images/introduction-to-hyperledger-fabric/Invoke_method_queryTuna_and_changeTuna.png differ diff --git a/LFS171x/images/introduction-to-hyperledger-fabric/Invoke_method_queryTuna_and_queryAllTuna.png b/LFS171x/images/introduction-to-hyperledger-fabric/Invoke_method_queryTuna_and_queryAllTuna.png new file mode 100644 index 00000000..a1d0f091 Binary files /dev/null and b/LFS171x/images/introduction-to-hyperledger-fabric/Invoke_method_queryTuna_and_queryAllTuna.png differ diff --git a/LFS171x/images/introduction-to-hyperledger-fabric/Invoke_method_recordTuna.png b/LFS171x/images/introduction-to-hyperledger-fabric/Invoke_method_recordTuna.png new file mode 100644 index 00000000..4c0a0ea4 Binary files /dev/null and b/LFS171x/images/introduction-to-hyperledger-fabric/Invoke_method_recordTuna.png differ diff --git a/LFS171x/images/introduction-to-hyperledger-fabric/Key_Components_-_Transaction_Proposal.png b/LFS171x/images/introduction-to-hyperledger-fabric/Key_Components_-_Transaction_Proposal.png new file mode 100644 index 00000000..dff8e9a1 Binary files /dev/null and b/LFS171x/images/introduction-to-hyperledger-fabric/Key_Components_-_Transaction_Proposal.png differ diff --git a/LFS171x/images/introduction-to-hyperledger-fabric/Key_Components_Channels.png b/LFS171x/images/introduction-to-hyperledger-fabric/Key_Components_Channels.png new file mode 100644 index 00000000..6f8120df Binary files /dev/null and b/LFS171x/images/introduction-to-hyperledger-fabric/Key_Components_Channels.png differ diff --git a/LFS171x/images/introduction-to-hyperledger-fabric/State_Database.png b/LFS171x/images/introduction-to-hyperledger-fabric/State_Database.png new file mode 100644 index 00000000..415ef69f Binary files /dev/null and b/LFS171x/images/introduction-to-hyperledger-fabric/State_Database.png differ diff --git a/LFS171x/images/introduction-to-hyperledger-fabric/The_role_of_membership_service_provider.jpg b/LFS171x/images/introduction-to-hyperledger-fabric/The_role_of_membership_service_provider.jpg new file mode 100644 index 00000000..135dfc1c Binary files /dev/null and b/LFS171x/images/introduction-to-hyperledger-fabric/The_role_of_membership_service_provider.jpg differ diff --git a/LFS171x/images/introduction-to-hyperledger-fabric/Transaction_Flow_Step_4.png b/LFS171x/images/introduction-to-hyperledger-fabric/Transaction_Flow_Step_4.png new file mode 100644 index 00000000..0445c746 Binary files /dev/null and b/LFS171x/images/introduction-to-hyperledger-fabric/Transaction_Flow_Step_4.png differ diff --git a/LFS171x/images/introduction-to-hyperledger-fabric/Transaction_Flow_Step_5.png b/LFS171x/images/introduction-to-hyperledger-fabric/Transaction_Flow_Step_5.png new file mode 100644 index 00000000..daf52dcf Binary files /dev/null and b/LFS171x/images/introduction-to-hyperledger-fabric/Transaction_Flow_Step_5.png differ diff --git a/LFS171x/images/introduction-to-hyperledger-fabric/Transaction_Flow_Step_6.png b/LFS171x/images/introduction-to-hyperledger-fabric/Transaction_Flow_Step_6.png new file mode 100644 index 00000000..7c30012c Binary files /dev/null and b/LFS171x/images/introduction-to-hyperledger-fabric/Transaction_Flow_Step_6.png differ diff --git a/LFS171x/images/introduction-to-hyperledger-fabric/Transaction_flow_step_2.png b/LFS171x/images/introduction-to-hyperledger-fabric/Transaction_flow_step_2.png new file mode 100644 index 00000000..cdb0942c Binary files /dev/null and b/LFS171x/images/introduction-to-hyperledger-fabric/Transaction_flow_step_2.png differ diff --git a/LFS171x/images/introduction-to-hyperledger-fabric/Transaction_flow_step_3.png b/LFS171x/images/introduction-to-hyperledger-fabric/Transaction_flow_step_3.png new file mode 100644 index 00000000..0e94d2e2 Binary files /dev/null and b/LFS171x/images/introduction-to-hyperledger-fabric/Transaction_flow_step_3.png differ diff --git a/LFS171x/images/introduction-to-hyperledger-fabric/fabric-application-flow.png b/LFS171x/images/introduction-to-hyperledger-fabric/fabric-application-flow.png new file mode 100644 index 00000000..8da6c85e Binary files /dev/null and b/LFS171x/images/introduction-to-hyperledger-fabric/fabric-application-flow.png differ diff --git a/LFS171x/images/introduction-to-hyperledger-fabric/fabric-application-flowbasics.png b/LFS171x/images/introduction-to-hyperledger-fabric/fabric-application-flowbasics.png new file mode 100644 index 00000000..60423efb Binary files /dev/null and b/LFS171x/images/introduction-to-hyperledger-fabric/fabric-application-flowbasics.png differ diff --git a/LFS171x/images/introduction-to-hyperledger-fabric/fabric-application1.png b/LFS171x/images/introduction-to-hyperledger-fabric/fabric-application1.png new file mode 100644 index 00000000..07aa3872 Binary files /dev/null and b/LFS171x/images/introduction-to-hyperledger-fabric/fabric-application1.png differ diff --git a/LFS171x/images/introduction-to-hyperledger-fabric/fabric-changeTunaHolder.png b/LFS171x/images/introduction-to-hyperledger-fabric/fabric-changeTunaHolder.png new file mode 100644 index 00000000..25555694 Binary files /dev/null and b/LFS171x/images/introduction-to-hyperledger-fabric/fabric-changeTunaHolder.png differ diff --git a/LFS171x/images/introduction-to-hyperledger-fabric/fabric-changedRecord.png b/LFS171x/images/introduction-to-hyperledger-fabric/fabric-changedRecord.png new file mode 100644 index 00000000..739b2ceb Binary files /dev/null and b/LFS171x/images/introduction-to-hyperledger-fabric/fabric-changedRecord.png differ diff --git a/LFS171x/images/introduction-to-hyperledger-fabric/fabric-createTunaRecord.png b/LFS171x/images/introduction-to-hyperledger-fabric/fabric-createTunaRecord.png new file mode 100644 index 00000000..f2bd92f4 Binary files /dev/null and b/LFS171x/images/introduction-to-hyperledger-fabric/fabric-createTunaRecord.png differ diff --git a/LFS171x/images/introduction-to-hyperledger-fabric/fabric-filestructure.png b/LFS171x/images/introduction-to-hyperledger-fabric/fabric-filestructure.png new file mode 100644 index 00000000..09f090ac Binary files /dev/null and b/LFS171x/images/introduction-to-hyperledger-fabric/fabric-filestructure.png differ diff --git a/LFS171x/images/introduction-to-hyperledger-fabric/fabric-query.png b/LFS171x/images/introduction-to-hyperledger-fabric/fabric-query.png new file mode 100644 index 00000000..d2e61804 Binary files /dev/null and b/LFS171x/images/introduction-to-hyperledger-fabric/fabric-query.png differ diff --git a/LFS171x/images/introduction-to-hyperledger-fabric/fabric-queryAfterCreate.png b/LFS171x/images/introduction-to-hyperledger-fabric/fabric-queryAfterCreate.png new file mode 100644 index 00000000..9c3ed82d Binary files /dev/null and b/LFS171x/images/introduction-to-hyperledger-fabric/fabric-queryAfterCreate.png differ diff --git a/LFS171x/images/introduction-to-hyperledger-fabric/fabric-queryAll.png b/LFS171x/images/introduction-to-hyperledger-fabric/fabric-queryAll.png new file mode 100644 index 00000000..98b1191f Binary files /dev/null and b/LFS171x/images/introduction-to-hyperledger-fabric/fabric-queryAll.png differ diff --git a/LFS171x/images/introduction-to-hyperledger-fabric/fabric_sale_scenario.png b/LFS171x/images/introduction-to-hyperledger-fabric/fabric_sale_scenario.png new file mode 100644 index 00000000..591bd406 Binary files /dev/null and b/LFS171x/images/introduction-to-hyperledger-fabric/fabric_sale_scenario.png differ diff --git a/LFS171x/images/introduction-to-hyperledger-sawtooth/2_-__Sawtooth__Demonstrated_Scenario__1_.jpg b/LFS171x/images/introduction-to-hyperledger-sawtooth/2_-__Sawtooth__Demonstrated_Scenario__1_.jpg new file mode 100644 index 00000000..e2a13e54 Binary files /dev/null and b/LFS171x/images/introduction-to-hyperledger-sawtooth/2_-__Sawtooth__Demonstrated_Scenario__1_.jpg differ diff --git a/LFS171x/images/introduction-to-hyperledger-sawtooth/Accept_Tuna.jpg b/LFS171x/images/introduction-to-hyperledger-sawtooth/Accept_Tuna.jpg new file mode 100644 index 00000000..6ba745de Binary files /dev/null and b/LFS171x/images/introduction-to-hyperledger-sawtooth/Accept_Tuna.jpg differ diff --git a/LFS171x/images/introduction-to-hyperledger-sawtooth/Application_Flow.png b/LFS171x/images/introduction-to-hyperledger-sawtooth/Application_Flow.png new file mode 100644 index 00000000..8589850b Binary files /dev/null and b/LFS171x/images/introduction-to-hyperledger-sawtooth/Application_Flow.png differ diff --git a/LFS171x/images/introduction-to-hyperledger-sawtooth/File_structure_of_TunaChain_Application.jpeg b/LFS171x/images/introduction-to-hyperledger-sawtooth/File_structure_of_TunaChain_Application.jpeg new file mode 100644 index 00000000..97ea6c89 Binary files /dev/null and b/LFS171x/images/introduction-to-hyperledger-sawtooth/File_structure_of_TunaChain_Application.jpeg differ diff --git a/LFS171x/images/introduction-to-hyperledger-sawtooth/Hyperledger_Sawtooth_Components.png b/LFS171x/images/introduction-to-hyperledger-sawtooth/Hyperledger_Sawtooth_Components.png new file mode 100644 index 00000000..2eeaf9fc Binary files /dev/null and b/LFS171x/images/introduction-to-hyperledger-sawtooth/Hyperledger_Sawtooth_Components.png differ diff --git a/LFS171x/images/introduction-to-hyperledger-sawtooth/Miriam_can_use_the_client_application_to_query_the_ledger.jpg b/LFS171x/images/introduction-to-hyperledger-sawtooth/Miriam_can_use_the_client_application_to_query_the_ledger.jpg new file mode 100644 index 00000000..e2885986 Binary files /dev/null and b/LFS171x/images/introduction-to-hyperledger-sawtooth/Miriam_can_use_the_client_application_to_query_the_ledger.jpg differ diff --git a/LFS171x/images/introduction-to-hyperledger-sawtooth/Regulators_may_use_the_client_application_to_query_the_ledger__to_verify_legitimacy.jpg b/LFS171x/images/introduction-to-hyperledger-sawtooth/Regulators_may_use_the_client_application_to_query_the_ledger__to_verify_legitimacy.jpg new file mode 100644 index 00000000..07615d4b Binary files /dev/null and b/LFS171x/images/introduction-to-hyperledger-sawtooth/Regulators_may_use_the_client_application_to_query_the_ledger__to_verify_legitimacy.jpg differ diff --git a/LFS171x/images/introduction-to-hyperledger-sawtooth/Sarah_uses_the_client_application_to_record_all_caught_tuna_to_the_ledger.jpg b/LFS171x/images/introduction-to-hyperledger-sawtooth/Sarah_uses_the_client_application_to_record_all_caught_tuna_to_the_ledger.jpg new file mode 100644 index 00000000..085b8667 Binary files /dev/null and b/LFS171x/images/introduction-to-hyperledger-sawtooth/Sarah_uses_the_client_application_to_record_all_caught_tuna_to_the_ledger.jpg differ diff --git a/LFS171x/images/introduction-to-hyperledger-sawtooth/Sawtooth_Application.png b/LFS171x/images/introduction-to-hyperledger-sawtooth/Sawtooth_Application.png new file mode 100644 index 00000000..3ff6adc6 Binary files /dev/null and b/LFS171x/images/introduction-to-hyperledger-sawtooth/Sawtooth_Application.png differ diff --git a/LFS171x/images/introduction-to-hyperledger-sawtooth/Sawtooth_Network.png b/LFS171x/images/introduction-to-hyperledger-sawtooth/Sawtooth_Network.png new file mode 100644 index 00000000..d2a34c68 Binary files /dev/null and b/LFS171x/images/introduction-to-hyperledger-sawtooth/Sawtooth_Network.png differ diff --git a/LFS171x/images/introduction-to-hyperledger-sawtooth/The_processing_plant_may_use_the_client_application_to_query_the_ledger.jpg b/LFS171x/images/introduction-to-hyperledger-sawtooth/The_processing_plant_may_use_the_client_application_to_query_the_ledger.jpg new file mode 100644 index 00000000..c7fc2f8f Binary files /dev/null and b/LFS171x/images/introduction-to-hyperledger-sawtooth/The_processing_plant_may_use_the_client_application_to_query_the_ledger.jpg differ diff --git a/LFS171x/images/introduction-to-hyperledger-sawtooth/Tuna_Create.png b/LFS171x/images/introduction-to-hyperledger-sawtooth/Tuna_Create.png new file mode 100644 index 00000000..0d04d780 Binary files /dev/null and b/LFS171x/images/introduction-to-hyperledger-sawtooth/Tuna_Create.png differ diff --git a/LFS171x/images/introduction-to-hyperledger-sawtooth/Tuna_Create_New_Key_Pair.png b/LFS171x/images/introduction-to-hyperledger-sawtooth/Tuna_Create_New_Key_Pair.png new file mode 100644 index 00000000..70aceb38 Binary files /dev/null and b/LFS171x/images/introduction-to-hyperledger-sawtooth/Tuna_Create_New_Key_Pair.png differ diff --git a/LFS171x/images/introduction-to-hyperledger-sawtooth/Tuna_Holder_drop_down.png b/LFS171x/images/introduction-to-hyperledger-sawtooth/Tuna_Holder_drop_down.png new file mode 100644 index 00000000..e105e063 Binary files /dev/null and b/LFS171x/images/introduction-to-hyperledger-sawtooth/Tuna_Holder_drop_down.png differ diff --git a/LFS171x/images/introduction-to-hyperledger-sawtooth/Tuna_List.png b/LFS171x/images/introduction-to-hyperledger-sawtooth/Tuna_List.png new file mode 100644 index 00000000..60b80eb1 Binary files /dev/null and b/LFS171x/images/introduction-to-hyperledger-sawtooth/Tuna_List.png differ diff --git a/LFS171x/images/introduction-to-hyperledger-sawtooth/Tuna_Transfer.png b/LFS171x/images/introduction-to-hyperledger-sawtooth/Tuna_Transfer.png new file mode 100644 index 00000000..b798e13b Binary files /dev/null and b/LFS171x/images/introduction-to-hyperledger-sawtooth/Tuna_Transfer.png differ diff --git a/LFS171x/images/welcome-intro/70_percent_passing_grade.jpg b/LFS171x/images/welcome-intro/70_percent_passing_grade.jpg new file mode 100644 index 00000000..cbe584b3 Binary files /dev/null and b/LFS171x/images/welcome-intro/70_percent_passing_grade.jpg differ diff --git a/LFS171x/images/welcome-intro/Copyright.jpg b/LFS171x/images/welcome-intro/Copyright.jpg new file mode 100644 index 00000000..6a212b7a Binary files /dev/null and b/LFS171x/images/welcome-intro/Copyright.jpg differ diff --git a/LFS171x/images/welcome-intro/Course_progress_.png b/LFS171x/images/welcome-intro/Course_progress_.png new file mode 100644 index 00000000..238e8314 Binary files /dev/null and b/LFS171x/images/welcome-intro/Course_progress_.png differ diff --git a/LFS171x/images/welcome-intro/Learning_Aids.jpg b/LFS171x/images/welcome-intro/Learning_Aids.jpg new file mode 100644 index 00000000..29a2ece0 Binary files /dev/null and b/LFS171x/images/welcome-intro/Learning_Aids.jpg differ diff --git a/LFS171x/images/welcome-intro/Your_certificate_is_available.png b/LFS171x/images/welcome-intro/Your_certificate_is_available.png new file mode 100644 index 00000000..49b2e6fa Binary files /dev/null and b/LFS171x/images/welcome-intro/Your_certificate_is_available.png differ diff --git a/LFS171x/images/welcome-intro/help.png b/LFS171x/images/welcome-intro/help.png new file mode 100644 index 00000000..d33f5401 Binary files /dev/null and b/LFS171x/images/welcome-intro/help.png differ diff --git a/LFS171x/images/welcome-intro/time-624686_640.jpg b/LFS171x/images/welcome-intro/time-624686_640.jpg new file mode 100644 index 00000000..2b83480c Binary files /dev/null and b/LFS171x/images/welcome-intro/time-624686_640.jpg differ diff --git a/LFS171x/images/whats-next/Hyperledger_Global_Meetups.png b/LFS171x/images/whats-next/Hyperledger_Global_Meetups.png new file mode 100644 index 00000000..1431c0c2 Binary files /dev/null and b/LFS171x/images/whats-next/Hyperledger_Global_Meetups.png differ diff --git a/LFS171x/images/whats-next/Hyperledger_Working_Groups.png b/LFS171x/images/whats-next/Hyperledger_Working_Groups.png new file mode 100644 index 00000000..e128189d Binary files /dev/null and b/LFS171x/images/whats-next/Hyperledger_Working_Groups.png differ