Comment créer une blockchain à partir de zéro avec Go

introduction

Avec le Web 3.0 et la blockchain qui deviennent de plus en plus courants chaque jour, savez-vous ce qu'est la blockchain? Connaissez-vous ses avantages techniques et ses cas d'utilisation?

L'objectif de ce tutoriel est d'introduire la technologie blockchain d'un point de vue technique en en construisant une à partir de zéro.

Oubliez tout ce que vous avez entendu sur la blockchain sur les réseaux sociaux. Maintenant, vous allez créer un système de blockchain à partir de Ground Zero pour vraiment comprendre les tenants et les aboutissants de cette technologie distribuée peer-to-peer.

Ensuite, faites votre propre opinion sur son avenir et ses avantages. Alerte spoiler: vous tomberez amoureux du logiciel de programmation blockchain.

Comment?

Vous suivrez l'histoire d'un développeur de logiciels qui cherche à révolutionner son bar local en implémentant la technologie blockchain pour son système de paiement.

Bien que la blockchain ait plusieurs cas d'utilisation indéniables, pour le moment, l'application numéro un est le paiement. En effet, les banques fonctionnent toujours sur une infrastructure inefficace vieille de 40 ans, alimentée par des fichiers CSV et FTP.

L'histoire contient beaucoup de faits amusants et intrigants sur l'écosystème global de la blockchain et différents protocoles tels que Bitcoin, Ethereum et XRP.

Que vas-tu construire, apprendre et faire dans ce didacticiel?

  • Vous allez configurer un projet Go sur votre machine locale sans aucune expérience préalable de GoLang
  • Vous allez générer et distribuer vos premiers jetons blockchain
  • Vous développerez une base de données contrôlée par CLI dans Go à partir de zéro
  • Vous découvrirez combien peu de droits les utilisateurs possèdent dans leurs applications préférées
  • Vous découvrirez la principale proposition de valeur de la blockchain
  • Vous rendrez votre base de données immuable à l'aide d'une fonction de hachage cryptographique sécurisée

Alors commençons et plongeons dans notre histoire.

⭐ Rencontrez le protagoniste, Andrej.

Andrej est propriétaire d'un bar la nuit et développeur de logiciels le jour dans une petite ville slovaque appelée Bardejov.

Andrej en a assez de:

  • Programmation d'applications PHP / Java / Javascript solides et à l'ancienne
  • Oublier combien d'argent ses amis et clients lui doivent pour tous les coups de vodka non payés du vendredi soir
  • Passer du temps à collecter et compter les pièces, rendre la monnaie et généralement toucher les factures bancaires exposées au COVID-19
  • Maintenir différentes puces en plastique pour le baby-foot, les fléchettes, le billard et le poker

Andrej adorerait:

  • Avoir un historique vérifiable parfait des activités et des ventes du bar pour rendre son bar conforme à la réglementation fiscale
  • Transformez son bar en un environnement autonome, efficace en matière de paiement, décentralisé et sûr dont ses clients peuvent faire confiance et profiter

Son objectif est d'écrire un programme simple et de conserver tous les soldes de ses clients sous forme virtuelle.

Andrej partage ses pensées ici:

«Chaque nouveau client me donnera de l'argent et je lui créditerai un montant équivalent de mes jetons numériques (pièces / crypto-monnaie). Les jetons représenteront une unité monétaire à l'intérieur et à l'extérieur du bar.

Les utilisateurs utiliseront les jetons pour toutes les fonctionnalités du bar: payer des boissons, les emprunter et les prêter à leurs amis, jouer au tennis de table, au poker et au kicker.

Avoir une barre alimentée par des jetons blockchain générera des tonnes de valeur pour mes clients. Contrairement à mes concurrents et aux autres bars de cette rue, où les clients ne dépensent que de l'argent et obtiennent une gueule de bois en échange, mes clients de bar détenant des jetons de bar auront des droits d'actionnaires.

Semblable à la possession d'une grande partie des actions dans une entreprise comme Apple ou Microsoft, les clients détenant ces jetons de bar pourront décider du fonctionnement du bar en votant et en décidant:

  • prix des boissons
  • Horaires d'ouvertures
  • nouvelles fonctionnalités (TV, Jukebox ...)
  • design intérieur et extérieur
  • répartition des bénéfices
  • etc.

Oh, ce sera un rêve de programmation!

J'appellerai les jetons: les jetons Blockchain Bar, TBB! "

Maintenant qu'Andrej a partagé son rêve, nous allons commencer.

Table des matières

  • Exigences
  • Configurer le projet
  • 01 | La base de données MVP
  • 02 | État de la base de données globale en mutation
  • 03 | Événement monolithique vs transaction
  • 04 | Les humains sont avides
  • 05 | Pourquoi nous avons besoin de Blockchain
  • 06 | L'Hash de Immutable
  • Prochaines étapes

Exigences

Plongeons dans notre tutoriel. Je recommande plus de 2 ans d'expérience en programmation en Java / PHP / Javascript ou dans un autre langage similaire à Go.

If you want to get a good quick intro to go, here's a free course that'll get you started.

You can also complete the official 17 lectures of A Tour Of Go to get familiar with the language syntax and basic concepts (~20 mins).

Why Go?

Because like blockchain, it's a fantastic technology for your overall programming career. Go is a trendy language and Go devs are better paid than the average Java/PHP/Javascript positions.

Go is optimized for multi-core CPU architecture. You can spawn thousands of light-weight threads (Go-routines) without problems. It's extremely practical for highly parallel and concurrent software such as blockchain networks.

By writing your software in Go, you achieve nearly C++ level of performance out of the box without killing yourself for that one time you forgot to free up memory.

Go compile également en binaire, ce qui le rend très portable.

Configurer le projet

Cet article dispose d'un référentiel Github open-source dédié avec le code source complet afin que vous puissiez compiler le code et exécuter le programme sur votre propre machine locale.

Si vous êtes coincé dans un chapitre ou une ligne de code particulière, créez un problème Github dans ce référentiel décrivant votre problème et je vous aiderai dès que possible!

↓ Visitez le référentiel Github et suivez les instructions d'installation ↓

web3coach / the-blockchain-bar-newsletter-edition Le code source des 7 premiers chapitres du livre électronique «The Blockchain Way of Programming». - web3coach / the-blockchain-bar-newsletter-edition web3coach GitHub

01 | La base de données MVP

git checkout c1_genesis_json

Andrej a maîtrisé les bases de données SQL relationnelles dans les années 90. Il sait créer des modèles de données avancés et optimiser les requêtes SQL.

It's time for Andrej to catch up with innovation and start building Web 3.0 software.

Luckily, after reading "The Lean Startup" book last week, Andrej feels like he shouldn't over-engineer the solution just yet. Hence, he chooses a simple but effective JSON file for the bar's MVP database.

In the beginning, there was a primitive centralized database.

? Summary

Blockchain is a database.

User 1, Andrej

Monday, March 18.

Andrej generates 1M utility tokens.

In the blockchain world, tokens are units inside the blockchain database. Their real value in dollars or euro fluctuates based on their demand and popularity.

Every blockchain has a "Genesis" file. The Genesis file is used to distribute the first tokens to early blockchain participants.

It all starts with a simple, dummy genesis.json.

Andrej creates the file ./database/genesis.json where he defines that The Blockchain Bar's database will have 1M tokens and all of them will belong to Andrej:

{ "genesis_time": "2019-03-18T00:00:00.000000000Z", "chain_id": "the-blockchain-bar-ledger", "balances": { "andrej": 1000000 } } 

The tokens need to have a real "utility", that is a use case. Users should be able to pay with them from day 1!

Andrej must comply with law regulators (the SEC). It is illegal to issue unregistered security. On the other hand, utility tokens are fine, so right away he prints and sticks a new pricing white p̶a̶p̶e̶r̶ poster on the bar's door.

Andrej assigns a starting monetary value to his tokens so he can exchange them for euro, dollars, or other fiat currency.

1 TBB token = 1€ | Item | Price | | ------------------------- | ------- | | Vodka shot | 1 TBB | | Orange juice | 5 TBB | | Burger | 2 TBB | | Crystal Head Vodka Bottle | 950 TBB | 

Andrej also decides he should be getting 100 tokens per day for maintaining the database and having such a brilliant disruptive idea.

?Fun Facts

La première genèse Ether (ETH) sur la blockchain Ethereum a été créée et distribuée aux premiers investisseurs et développeurs de la même manière que le jeton utilitaire d'Andrej.En 2017, lors d'un boom des ICO (offres initiales de pièces de monnaie) sur le réseau de blockchain Ethereum, les fondateurs du projet ont écrit et présenté des livres blancs aux investisseurs. Un livre blanc est un document technique décrivant un problème complexe et une solution possible, destiné à éduquer et à élucider une question particulière. Dans le monde des blockchains, un livre blanc sert à décrire les spécifications de l'apparence et du comportement de cette blockchain particulière une fois qu'elle sera développée.Les projets de blockchain ont levé entre 10 et 300 millions d'euros par livre blanc.idée.en échange d'argent (le «financement» de l'OIC), les noms des investisseurs seraient inclus dans les «soldes de genèse» initiaux, comme Andrej l'a fait. Les espoirs des investisseurs à travers une ICO sont que les pièces de la genèse augmentent en valeur et que les équipes fournissent la blockchain décrite. Naturellement, toutes les idées de livres blancs ne se concrétisent pas. Les investissements massifs perdus à cause d'idées peu claires ou incomplètes expliquent pourquoi la blockchain a reçu une couverture négative dans les médias tout au long de ces ICO, et pourquoi certains la considèrent toujours comme un battage médiatique. Mais la technologie blockchain sous-jacente est fantastique et utile, comme vous l'apprendrez plus loin dans ce livre. Il a juste été abusé par de mauvais acteurs.

? Sommaire

Blockchain est une base de données.

L'offre de jetons, les soldes d'utilisateurs initiaux et les paramètres globaux de la blockchain que vous définissez dans un fichier Genesis.

02 | État de la base de données globale en mutation

git checkout c2_db_changes_txt

Fête morte

Monday, March 25.

After a week of work, the bar facilities are ready to accept tokens. Unfortunately, no one shows up, so Andrej orders three shots of vodka for himself and writes the database changes on a piece of paper:

andrej-3; // 3 shots of vodka andrej+3; // technically purchasing from his own bar andrej+700; // Reward for a week of work (7x100 per day) 

To avoid recalculating the latest state of each customer's balance, Andrej creates a ./database/state.json file storing the balances in an aggregated format.

New DB state:

{ "balances": { "andrej": 1000700 } } 

Bonus for BabaYaga

Tuesday, March 26.

To bring traffic to his bar, Andrej announces an exclusive 100% bonus for everyone who purchases the TBB tokens in the next 24 hours.

Bing! He gets his first customer called BabaYaga. BabaYaga pre-purchases 1000€ worth of tokens, and to celebrate, she immediately spends 1 TBB for a vodka shot. She has a drinking problem.

DB transactions written on a piece of paper:

andrej-2000; // transfer to BabaYaga babayaga+2000; // pre-purchase with 100% bonus babayaga-1; andrej+1; andrej+100; // 1 day of sun coming up 

New DB state:

{ "balances": { "andrej": 998801, "babayaga": 1999 } } 

?Fun Facts

Les projets Blockchain ICO (offres initiales de pièces basées sur des livres blancs) distribuent souvent les jetons de genèse avec différents bonus, en fonction du nombre d'entre eux que vous achetez et à quelle heure vous le faites. Les équipes offrent, en moyenne, des bonus de 10 à 40% aux premiers «participants». Le mot «investisseur» est évité, de sorte que les régulateurs de la loi ne considéreront pas les jetons comme une sécurité. Les projets justifieraient que leur produit principal, les jetons de blockchain, fonctionnent comme des «points de fidélité volants». Les «participants» ont ensuite réalisé même 1000% de leur investissement en vendant au public par le biais d'un échange plusieurs mois plus tard.

?Sommaire

Blockchain est une base de données.

L'offre de jetons, les soldes d'utilisateurs initiaux et les paramètres globaux de la blockchain que vous définissez dans un fichier Genesis.

Les soldes Genesis indiquent quel était l'état d'origine de la blockchain et ne sont jamais mis à jour par la suite.

The database state changes are called Transactions (TX).

03 | Monolithic Event vs Transaction

git checkout c3_state_blockchain_component

Developers used to event-sourcing architecture must have immediately recognized the familiar principles behind transactions. They are correct.

Blockchain transactions represent a series of events, and the database is a final aggregated, calculated state after replaying all the transactions in a specific sequence.

Andrej Programming

Tuesday evening, March 26.

It's a relaxing Tuesday evening for Andrej. Celebrating his first client, he decides to play some Starcraft and clean up his local development machine by removing some old pictures.

Unfortunately, he prematurely pressed enter when typing a removal command path in terminal sudo rm -rf /. Oops.

All his files, including the bar's genesis.json and state.json are gone.

Andrej, being a senior developer, repeatedly shouted some f* words very loudly for a few seconds, but he didn't panic!

While he didn't have a backup, he had something better — a piece of paper with all the database transactions. The only thing he needs to do is replay all the transactions one by one, and his database state will get recovered.

Impressed by the advantages of event-based architecture, he decides to extend his MVP database solution. Every bar's activity, such as individual drink purchases, MUST be recorded inside the blockchain database.

Each customer will be represented in DB using an Account Struct:

type Account string 

Each Transaction (TX - a database change) will have the following four attributes: from, to, value and data.

The data attribute with one possible value (reward) captures Andrej's bonus for inventing the blockchain and increases the initial TBB tokens total supply artificially (inflation).

type Tx struct { From Account `json:"from"` To Account `json:"to"` Value uint `json:"value"` Data string `json:"data"` } func (t Tx) IsReward() bool { return t.Data == "reward" } 

The Genesis DB will remain a JSON file:

{ "genesis_time": "2019-03-18T00:00:00.000000000Z", "chain_id": "the-blockchain-bar-ledger", "balances": { "andrej": 1000000 } } 

All the transactions, previously written on a piece of paper, will be stored in a local text-file database called tx.db, serialized in JSON format and separated by line-break character:

{"from":"andrej","to":"andrej","value":3,"data":""} {"from":"andrej","to":"andrej","value":700,"data":"reward"} {"from":"andrej","to":"babayaga","value":2000,"data":""} {"from":"andrej","to":"andrej","value":100,"data":"reward"} {"from":"babayaga","to":"andrej","value":1,"data":""} 

The most crucial database component encapsulating all the business logic will be State:

type State struct { Balances map[Account]uint txMempool []Tx dbFile *os.File } 

The State struct will know about all user balances and who transferred TBB tokens to whom, and how many were transferred.

It's constructed by reading the initial user balances from genesis.json file:

func NewStateFromDisk() (*State, error) { // get current working directory cwd, err := os.Getwd() if err != nil { return nil, err } genFilePath := filepath.Join(cwd, "database", "genesis.json") gen, err := loadGenesis(genFilePath) if err != nil { return nil, err } balances := make(map[Account]uint) for account, balance := range gen.Balances { balances[account] = balance } 

Afterwards, the genesis State balances are updated by sequentially replaying all the database events from tx.db:

 txDbFilePath := filepath.Join(cwd, "database", "tx.db") f, err := os.OpenFile(txDbFilePath, os.O_APPEND|os.O_RDWR, 0600) if err != nil { return nil, err } scanner := bufio.NewScanner(f) state := &State{balances, make([]Tx, 0), f} // Iterate over each the tx.db file's line for scanner.Scan() { if err := scanner.Err(); err != nil { return nil, err } // Convert JSON encoded TX into an object (struct) var tx Tx json.Unmarshal(scanner.Bytes(), &tx) // Rebuild the state (user balances), // as a series of events if err := state.apply(tx); err != nil { return nil, err } } return state, nil } 

The State component is responsible for:

  • Adding new transactions to Mempool
  • Validating transactions against the current State (sufficient sender balance)
  • Changing the state
  • Persisting transactions to disk
  • Calculating accounts balances by replaying all transactions since Genesis in a sequence

Adding new transactions to Mempool:

func (s *State) Add(tx Tx) error { if err := s.apply(tx); err != nil { return err } s.txMempool = append(s.txMempool, tx) return nil } 

Persisting the transactions to disk:

func (s *State) Persist() error { // Make a copy of mempool because the s.txMempool will be modified // in the loop below mempool := make([]Tx, len(s.txMempool)) copy(mempool, s.txMempool) for i := 0; i < len(mempool); i++ { txJson, err := json.Marshal(s.txMempool[i]) if err != nil { return err } if _, err = s.dbFile.Write(append(txJson, '\n')); err != nil { return err } // Remove the TX written to a file from the mempool // Yes... this particular Go syntax is a bit weird s.txMempool = append(s.txMempool[:i], s.txMempool[i+1:]...) } return nil }

Changing, Validating the state:

func (s *State) apply(tx Tx) error { if tx.IsReward() { s.Balances[tx.To] += tx.Value return nil } if tx.Value > s.Balances[tx.From] { return fmt.Errorf("insufficient balance") } s.Balances[tx.From] -= tx.Value s.Balances[tx.To] += tx.Value return nil } 

Building a Command-Line-Interface (CLI)

Tuesday evening, March 26.

Andrej wants to have a convenient way to add new transactions to his DB and list the latest balances of his customers. Because Go programs compile to binary, he builds a CLI for his program.

The easiest way to develop CLI based programs in Go is by using the third party github.com/spf13/cobra library.

Andrej initializes Go's built-in dependency manager for his project, called go modules:

cd $GOPATH/src/github.com/web3coach/the-blockchain-way-of-programming-newsletter-edition

go mod init github.com/web3coach/the-blockchain-way-of-programming-newsletter-edition

The Go modules command will automatically fetch any library you reference within your Go files.

Andrej creates a new directory called: cmd with a subdirectory tbb:

mkdir -p ./cmd/tbb

Inside he creates a main.go file, serving as the program's CLI entry point:

package main import ( "github.com/spf13/cobra" "os" "fmt" ) func main() { var tbbCmd = &cobra.Command{ Use: "tbb", Short: "The Blockchain Bar CLI", Run: func(cmd *cobra.Command, args []string) { }, } err := tbbCmd.Execute() if err != nil { fmt.Fprintln(os.Stderr, err) os.Exit(1) } } 

The Go programs are compiled using the install cmd:

go install ./cmd/tbb/...

go: finding github.com/spf13/cobra v1.0.0 go: downloading github.com/spf13/cobra v1.0.0 go: extracting github.com/spf13/cobra v1.0.0

Go will detect missing libraries and automatically fetch them before compiling the program. Depending on your $GOPATH the resulting program will be saved in the $GOPATH/bin folder.

echo $GOPATH

/home/web3coach/go

which tbb

/home/web3coach/go/bin/tbb

You can run tbb from your terminal now, but it will not do anything because the Run function inside the main.go file is empty.

The first thing Andrej needs is versioning support for his tbb CLI program.

Next to the main.go file, he creates a version.go command:

package main import ( "fmt" "github.com/spf13/cobra" ) const Major = "0" const Minor = "1" const Fix = "0" const Verbal = "TX Add && Balances List" var versionCmd = &cobra.Command{ Use: "version", Short: "Describes version.", Run: func(cmd *cobra.Command, args []string) { fmt.Printf("Version: %s.%s.%s-beta %s", Major, Minor, Fix, Verbal) }, } 

Compiles and runs it:

go install ./cmd/tbb/...

tbb version

Version: 0.1.0-beta TX Add && Balances List

Perfect.

Identically to the version.go file, he creates a balances.go file:

func balancesCmd() *cobra.Command { var balancesCmd = &cobra.Command{ Use: "balances", Short: "Interact with balances (list...).", PreRunE: func(cmd *cobra.Command, args []string) error { return incorrectUsageErr() }, Run: func(cmd *cobra.Command, args []string) { }, } balancesCmd.AddCommand(balancesListCmd) return balancesCmd } 

The balances command will be responsible for loading the latest DB State and printing it to the standard output:

var balancesListCmd = &cobra.Command{ Use: "list", Short: "Lists all balances.", Run: func(cmd *cobra.Command, args []string) { state, err := database.NewStateFromDisk() if err != nil { fmt.Fprintln(os.Stderr, err) os.Exit(1) } defer state.Close() fmt.Println("Accounts balances:") fmt.Println("__________________") fmt.Println("") for account, balance := range state.Balances { fmt.Println(fmt.Sprintf("%s: %d", account, balance)) } }, } 

Andrej verifies if the cmd works as expected. It should print the exact balances defined in the Genesis file because the tx.db file is still empty.

go install ./cmd/tbb/...

tbb balances list

Accounts balances: __________________ andrej: 1000000 

Works well! Now he only needs a cmd for recording the bar's activity.

Andrej creates ./cmd/tbb/tx.go cmd:

func txCmd() *cobra.Command { var txsCmd = &cobra.Command{ Use: "tx", Short: "Interact with txs (add...).", PreRunE: func(cmd *cobra.Command, args []string) error { return incorrectUsageErr() }, Run: func(cmd *cobra.Command, args []string) { }, } txsCmd.AddCommand(txAddCmd()) return txsCmd } 

The tbb tx add cmd uses State.Add(tx) function for persisting the bar's events into the file system:

func txAddCmd() *cobra.Command { var cmd = &cobra.Command{ Use: "add", Short: "Adds new TX to database.", Run: func(cmd *cobra.Command, args []string) { from, _ := cmd.Flags().GetString(flagFrom) to, _ := cmd.Flags().GetString(flagTo) value, _ := cmd.Flags().GetUint(flagValue) fromAcc := database.NewAccount(from) toAcc := database.NewAccount(to) tx := database.NewTx(fromAcc, toAcc, value, "") state, err := database.NewStateFromDisk() if err != nil { fmt.Fprintln(os.Stderr, err) os.Exit(1) } // defer means, at the end of this function execution, // execute the following statement (close DB file with all TXs) defer state.Close() // Add the TX to an in-memory array (pool) err = state.Add(tx) if err != nil { fmt.Fprintln(os.Stderr, err) os.Exit(1) } // Flush the mempool TXs to disk err = state.Persist() if err != nil { fmt.Fprintln(os.Stderr, err) os.Exit(1) } fmt.Println("TX successfully added to the ledger.") }, } 

The tbb tx add cmd has 3 mandatory flags: --from, --to and --value.

cmd.Flags().String(flagFrom, "", "From what account to send tokens") cmd.MarkFlagRequired(flagFrom) cmd.Flags().String(flagTo, "", "To what account to send tokens") cmd.MarkFlagRequired(flagTo) cmd.Flags().Uint(flagValue, 0, "How many tokens to send") cmd.MarkFlagRequired(flagValue) return cmd 

The CLI is done!

Andrej migrates all transactions from paper to his new DB:

tbb tx add --from=andrej --to=andrej --value=3

tbb tx add --from=andrej --to=andrej --value=700

tbb tx add --from=babayaga --to=andrej --value=2000

tbb tx add --from=andrej --to=andrej --value=100 --data=reward

tbb tx add --from=babayaga --to=andrej --value=1

Read all TXs from disk and calculate the latest state:

tbb balances list

Accounts balances: __________________ andrej: 998801 babayaga: 1999 

Bar data successfully restored! Phew, what a night!

About the Cobra CLI library

The good thing about the Cobra lib for CLI programming is the additional features it comes with. For example, you can now run: tbb help cmd and it will print out all TBB registered sub-commands with instructions on how to use them.

 tbb help The Blockchain Bar CLI Usage: tbb [flags] tbb [command] Available Commands: balances Interact with balances (list...). help Help about any command tx Interact with txs (add...). version Describes version. Flags: -h, --help help for tbb Use "tbb [command] --help" for more information about a command. 

?Fun Facts

La perte accidentelle des données des clients est un samedi standard dans le monde de l'entreprise ces jours-ci. La blockchain résout ce problème en décentralisant le stockage des données. L'astuce Andrej a intégré le programme en sautant la vérification du solde pour les TX marqués comme des récompenses. Bitcoin et Ethereum fonctionnent de la même manière. Le solde du compte qui a extrait un bloc augmente à l'improviste en raison de l'inflation totale de l'offre de jetons affectant toute la chaîne. L'offre totale de bitcoins est plafonnée à 21M BTC. Vous en apprendrez plus sur «l'extraction» et les «blocs» dans les chapitres 7 et 10. Les composants State et Mempoolne sont pas uniques à ce programme. Andrej a choisi les noms et les conceptions pour correspondre à un modèle go-Ethereum simplifié afin que vous ayez un aperçu du code source de base d'Ethereum.

? Sommaire

Blockchain est une base de données.

L'offre de jetons, les soldes des utilisateurs initiaux et les paramètres globaux de la blockchain sont définis dans un fichier Genesis.

Les soldes Genesis indiquent quel était l'état d'origine de la blockchain et ne sont jamais mis à jour par la suite.

Les changements d'état de la base de données sont appelés Transactions (TX).

Les transactions sont des événements à l'ancienne qui représentent des actions au sein du système.

⚒ Code d'étude

Commit: 5d4b0b

Parlons de la cupidité.

04 | Les humains sont avides

git checkout c4_caesar_transfer

Gourmandise typique des affaires

Mercredi 27 mars.

BabaYaga a investi un peu trop. Elle a oublié que le paiement de son loyer était au coin de la rue et elle n'a pas l'argent. BabaYaga appelle son propriétaire d'appartement, César.

BabaYaga: Hey Caesar, I am sorry, but I don't have the cash to pay you the rent this month…

Caesar: Why not?

BabaYaga: The Blockchain Bar ICO offered a massive bonus, and I purchased 2000€ worth of tokens for just 1000€. It was a great deal!

Caesar: What the heck are you talking about? What is an ICO? What on earth are tokens? Can you pay me in some other way?

BabaYaga: Oh, not again. I can give you 1000 TBB tokens worth 1000€, and you can use them in the bar to pay for your drinks! Let me call the bar owner, Andrej, and make the transfer!

Caesar: All right... I will take it.

Andrej performs the transfer, but decides to charge an extra 50 TBB tokens for his troubles. He doesn't want to, BUT the bar shareholders who invested in him a few years ago are forcing him to generate profit as soon as possible.

BabaYaga won't notice this relatively small fee most likely anyway, Andrej tells himself. In the end, only he has the DB access.

// Rent payment

tbb tx add --from=babayaga --to=caesar --value=1000

// hidden fee charge

tbb tx add --from=babayaga --to=andrej --value=50

// new reward for another day of maintaining the DB

tbb tx add --from=andrej --to=andrej --value=100 --data=reward

?Fun Facts

Le cas d'utilisation numéro un de la blockchain est la banque. De nombreux projets de blockchain visent à optimiser l'échange d'argent national et international dans différents corridors monétaires (XRP). D'autres projets se concentrent sur la liberté et l'identité auto-souveraine (SSI) - un mouvement numérique qui reconnaît qu'un individu doit posséder et contrôler son identité et son argent sans les autorités administratives intervenantes ou d'autres intermédiaires centralisés. SSI permet aux gens d'interagir dans le monde numérique avec la même liberté et la même capacité de confiance que dans le monde hors ligne. (Bitcoin / Ethereum) Voici quelques faits amusants sur les raisons pour lesquelles la blockchain est la solution idéale pour remplacer l'infrastructure bancaire actuelle de votre banque.La bonne chose à propos des jetons virtuels est leur fongibilité, c'est-à-dire leur capacité à être échangée, chaque unité étant aussi utilisable que le prochain.Effectuer un transfert de compte en compte peut être effectué en modifiant simplement l'état de la base de données. Les crypto-monnaies sont négociables 24h / 24, 7j / 7, vous ne pouvez pas négocier directement des actions. Vous devez passer par un courtier qui prend part à un pourcentage de la transaction totale à titre de frais (1-3% à 7% de profit annuel moyen) .Un virement bancaire international prend entre 3-10 jours ouvrables et peut coûter jusqu'à 5% de la valeur transférée! Si vous envoyez 10 000 $, vous devrez peut-être payer jusqu'à 500 $. La technologie derrière ces 40 dernières années? Fichiers FTP + CSV Pensez-vous que le marché boursier est juste? Les banques, les indices et les actions sont hautement centralisés et contrôlés par les gouvernements et les groupes privés de Wall Street. Marché libre? Wall Street contrôle dans quelle mesure les prix peuvent sauter / baisser en une seule journée. Par exemple, Wall Street a interrompu la négociation de «l'indice S&P 500».après une baisse de 7% pour protéger leurs investisseurs et hedge funds de la perte d'argent des personnes vendant leurs actions en mars 2020 après les nouvelles de COVID. Par la suite, la FED a imprimé des milliards de dollars pour elle-même pour soutenir le cours des actions. Si vous êtes un développeur qui aime économiser de l'argent et éviter les dettes, votre épargne a perdu de la valeur du jour au lendemain d'un pourcentage encore inconnu. De nombreux pays entrent dans des rendements négatifs, un territoire inexploré aux conséquences inconnues. Qu'est-ce que ça veut dire? Bientôt, vous devrez payer la banque pour conserver votre épargne. L'inflation à son meilleur. Vous êtes obligé de dépenser votre argent pour soutenir un système que vous ne contrôlez pas.la FED a imprimé des milliards de dollars pour elle-même pour soutenir le cours des actions. Si vous êtes un développeur qui aime économiser de l'argent et éviter les dettes, votre épargne a perdu de la valeur du jour au lendemain d'un pourcentage encore inconnu. De nombreux pays entrent dans des rendements négatifs, un territoire inexploré aux conséquences inconnues. Qu'est-ce que ça veut dire? Bientôt, vous devrez payer la banque pour conserver votre épargne. L'inflation à son meilleur. Vous êtes obligé de dépenser votre argent pour soutenir un système que vous ne contrôlez pas.la FED a imprimé des milliards de dollars pour elle-même pour soutenir le cours des actions. Si vous êtes un développeur qui aime économiser de l'argent et éviter les dettes, votre épargne a perdu de la valeur du jour au lendemain d'un pourcentage encore inconnu. De nombreux pays entrent dans des rendements négatifs, un territoire inexploré aux conséquences inconnues. Qu'est-ce que ça veut dire? Bientôt, vous devrez payer la banque pour conserver votre épargne. L'inflation à son meilleur. Vous êtes obligé de dépenser votre argent pour soutenir un système que vous ne contrôlez pas.Vous êtes obligé de dépenser votre argent pour soutenir un système que vous ne contrôlez pas.Vous êtes obligé de dépenser votre argent pour soutenir un système que vous ne contrôlez pas.

⚒ Study Code

Commit: 00d6ed

05 | Why We Need Blockchain

git checkout c5_broken_trust

BabaYaga Seeks Justice

Thursday, March 28.

BabaYaga enters the bar for her birthday.

BabaYaga: Hey, Andrej! Today is my birthday! Get me your most expensive bottle!

Andrej: Happy birthday! Here you go: Crystal Head Vodka. But you need to purchase one additional TBB token. The bottle costs 950 tokens, and your balance is 949.

BabaYaga: What?! My balance is supposed to be 999 TBB!

Andrej: The funds transfer to Caesar you requested last week cost you 50 tokens.

BabaYaga: This is unacceptable! I would never agree to such a high fee. You can't do this, Andrej. I trusted your system, but you are as unreliable as every other business owner. Things must change!

Andrej: All right, look. You are my most loyal customer, and I didn't want to charge you, but my shareholders forced me.

Let me re-program my system and make it completely transparent and decentralized. After all, if everyone were able to interact with the bar without going through me, it would significantly improve the bar's efficiency and balance the level of trust!

  • Ordering drinks would take seconds instead of minutes
  • The customers who forgot their wallets at home could borrow or lend tokens to each other
  • I wouldn't have to worry about losing the clients data (again) as everyone would have a copy of it
  • The database would be immutable, so once everyone would agree on a specific state, no one else can change it or maliciously modify the history. Immutability would help with yearly tax audits as well!
  • If shareholders wanted to introduce new fees or raise the current ones, everyone involved in the blockchain system would notice and have to agree with it. The users and business owners would even have to engage in some decentralized governance system together, based on voting, probably. In case of a disagreement, the users walk away with all their data!

BabaYaga: Well, it certainly sounds good, but is this even possible?

Andrej: Yes, I think so. With a bit of hashing, linked lists, immutable data structure, distributed replication, and asymmetric cryptography!

BabaYaga: Je n'ai aucune idée de ce que vous venez de dire mais allez faire votre truc de geek, Andrej!

?Faits amusants

Les mineurs de Bitcoin et d'Ethereum reçoivent également des récompenses toutes les ~ 15 minutes pour l'exécution des serveurs blockchain (nœuds) et la validation des transactions.Toutes les 15 minutes, un mineur de Bitcoin reçoit 12,5 BTC (100000 $ au moment de la rédaction de cette page) pour couvrir le coût de ses serveurs + faire des bénéfices Le réseau Bitcoin consomme autant d'électricité que tout le pays autrichien. Elle représente 0,29% de la consommation électrique annuelle mondiale, elle en consomme 76,84 TWh par an et produit 36,50 Mt d'empreinte carbone CO2 (Nouvelle-Zélande). Source, pourquoi? Vous en apprendrez plus plus tard (au chapitre 11) où vous programmerez un algorithme de minage Bitcoin à partir de zéro! PS: Notre algorithme consommera un peu moins d'électricité :)

? Sommaire

Closed software with centralized access to private data allows for just a handful of people to have a lot of power. Users don’t have a choice, and shareholders are in business to make money.

Blockchain developers aim to develop protocols where applications' entrepreneurs and users synergize in a transparent, auditable relationship. Specifications of the blockchain system should be well-defined from the beginning and only change if its users support it.

Blockchain is a database. The token supply, initial user balances, and global blockchain settings are defined in a Genesis file. The Genesis balances indicate what was the original blockchain state and are never updated afterwards.

The database state changes are called Transactions (TX). Transactions are old fashion Events representing actions within the system.

⚒ Study Code

Commit: 642045

06 | L'Hash de Immutable

git checkout c6_immutable_hash

The technical difficulty starts with this section! The concepts will only get more challenging but at the same time, very exciting. Buckle up :)

How to Program an Immutable Database?

Friday, March 29.

If Andrej wants to figure out how to program an immutable DB, he has to realize why other database systems are mutable by design.

He decides to analyze an all-mighty MySQL DB Table:

| id | name | balance | | -- | -------- | ------- | | 1 | Andrej | 998951 | | 2 | BabaYaga | 949 | | 3 | Caesar | 1000 |

In MySQL DB, anyone with access and a good enough reason can perform a table update such as:

UPDATE user_balance SET balance = balance + 100 WHERE id > 1 

Updating values across different rows is possible because the table rows are independent, mutable, and the latest state is not apparent.

Quelle est la dernière modification de la base de données? Dernière colonne modifiée? Dernière ligne insérée? Si tel est le cas, comment Andrej peut-il savoir quelle ligne a été supprimée récemment? Si les lignes et l'état de la table étaient étroitement couplés, dépendants, c'est-à-dire la mise à jour de la ligne 1 générerait une table complètement nouvelle et différente, Andrej atteindrait son immuabilité.

Comment savoir si un octet d'une base de données a changé?

Immuabilité via les fonctions de hachage

Le hachage consiste à prendre une chaîne d'entrée de longueur arbitraire et à produire une chaîne de hachage de longueur fixe. Tout changement d'entrée entraînera un nouveau hachage différent.

package main import ( "crypto/sha256" "fmt" ) func main()  99896  

Essayez-le: //play.golang.org/p/FTPUa7IhOCE

Andrej nécessite également un certain niveau de sécurité pour sa base de données, il choisit donc une fonction de hachage cryptographique avec les propriétés suivantes:

  • il est déterministe - le même message aboutit toujours au même hachage
  • it is quick to compute the hash value for any given message
  • it is infeasible to generate a message from its hash value except by trying all possible messages
  • a small change to a message should change the hash value so extensively that the new hash value appears uncorrelated with the old hash value
  • it is infeasible to find two different messages with the same hash value

Implementing the DB Content Hashing

Saturday Evening, March 30.

Andrej modifies the Persist() function to return a new content hash, Snapshot, every time a new transaction is persisted.

type Snapshot [32]byte 

The Snapshot is produced by this new sha256 secure hashing function:

func (s *State) doSnapshot() error { // Re-read the whole file from the first byte _, err := s.dbFile.Seek(0, 0) if err != nil { return err } txsData, err := ioutil.ReadAll(s.dbFile) if err != nil { return err } s.snapshot = sha256.Sum256(txsData) return nil } 

The doSnapshot() is called by the modified Persist() function. When a new transaction is written into the tx.db file, the Persist() hashes the entire file content and returns its 32 bytes "fingerprint" hash.

From this moment, everyone can 100% confidently and securely refer to any particular database state (set of data) with a specific snapshot hash.

⚓Practice time

1/4 Run the tbb balances list cmd and check the balances are matching.

tbb balances list

Account balances at 7d4a360f465d... | id | name | balance | | -- | -------- | ------- | | 1 | Andrej | 999251 | | 2 | BabaYaga | 949 | | 3 | Caesar | 1000 |

2/4 Remove the last 2 rows from ./database/tx.db and check the balances again.

tbb balances list

Account balances at 841770dcd3... | id | name | balance | | -- | -------- | ------- | | 1 | Andrej | 999051 | | 2 | BabaYaga | 949 | | 3 | Caesar | 1000 | 

3/4 Reward Andrej for the last 2 days (from 28th to 30th of March):

Reward Transaction 1:

tbb tx add --from=andrej --to=andrej --value=100 --data=reward

Persisting new TX to disk: {"from":"andrej","to":"andrej","value":100,"data":"reward"} New DB Snapshot: ff2470c7043f5a34169b5dd38921ba6825b03b3facb83e426 TX successfully persisted to the ledger. 

Reward Transaction 2:

tbb tx add --from=andrej --to=andrej --value=100 --data=reward

Persisting new TX to disk: {"from":"andrej","to":"andrej","value":100,"data":"reward"} New DB Snapshot: 7d4a360f468b837b662816bcdc52c1869f99327d53ab4a9ca TX successfully persisted to the ledger. 

4/4 Run the tbb balances list cmd and ensure the balances and the snapshot hash is the same as at the beginning.

tbb balances list

Account balances at 7d4a360f465d... | id | name | balance | | -- | -------- | ------- | | 1 | Andrej | 999251 | | 2 | BabaYaga | 949 | | 3 | Caesar | 1000 | 

Done!

Because the cryptographic hash function sha256 produces the same output (given the same inputs (current tx.db and 2x tbb tx add)), if you follow the exact steps on your own computer, you will generate the exact same database state and hashes!

? Summary

Closed software with centralized access to private data puts only a few people to the position of power. Users don’t have a choice, and shareholders are in business to make money.

Blockchain developers aim to develop protocols where applications' entrepreneurs and users synergize in a transparent, auditable relation. Specifications of the blockchain system should be well defined from the beginning and only change if its users support it.

Blockchain is an immutable database. The token supply, initial user balances, and global blockchain settings you define in a Genesis file. The Genesis balances indicate what was the original blockchain state and are never updated afterwards.

The database state changes are called Transactions (TX). Transactions are old fashion Events representing actions within the system.

The database content is hashed by a secure cryptographic hash function. The blockchain participants use the resulted hash to reference a specific database state.

⚒ Study Code

Commit: b99e51

Next steps

You finished the first few chapters! Congratulations!

█▒▒▒▒▒▒▒▒▒ 10%

But this was just a quick warm-up. Blockchain is a very challenging and extensive technology, and you would need an entire book explaining how to build the full system and all of its components from scratch - so I wrote one.

You can continue reading in the next free chapter in my newsletter version of "The Blockchain Way of Programming" eBook.

07 | The Blockchain Programming Model

  • Improving Performance of an Immutable DB
  • Batch + Hash + Linked List ⇒ Blocks
  • Migrating from TX.db to BLOCKS.db

Learning: You redesign and refactor your MVP database into a blockchain architecture.

Continue in the tutorial: //web3.coach#book

Thanks for reading!