fcn從頭開始_如何使用Go從頭開始構建區塊鏈

fcn從頭開始

介紹 (Introduction)

With Web 3.0 and blockchain becoming more mainstream every day, do you know what blockchain is? Do you know its technical advantages and use-cases?

隨著Web 3.0和區塊鏈每天變得越來越主流,您知道什么是區塊鏈嗎? 您知道它的技術優勢和用例嗎?

The goal of this tutorial is to introduce blockchain technology from a technical perspective by building one from scratch.

本教程的目的是通過從頭開始構建區塊鏈技術,從技術角度介紹區塊鏈技術。

Forget everything you've heard about blockchain from social media. Now, you will build a blockchain system from ground zero to really understand the ins and outs of this peer-to-peer, distributed technology.

忘記您從社交媒體上聽到的有關區塊鏈的所有信息。 現在,您將從零開始構建一個區塊鏈系統,以真正了解這種對等分布式技術的來龍去脈。

Afterwards, make your own mind up about its future and advantages. Spoiler alert: you will fall in love with programming blockchain software.

然后,自己決定其未來和優勢。 劇透警報:您將愛上編程區塊鏈軟件。

怎么樣? (How?)

You will follow the story of a software developer who is looking to revolutionize his local bar by implementing blockchain technology for its payment system.

您將跟隨一個軟件開發人員的故事,該軟件開發人員希望通過為其支付系統實施區塊鏈技術來革新其本地律師事務所。

Although blockchain has several undeniable use-cases, at the moment, the number one application is payments. This is because banks are still running on an inefficient, 40 year old infrastructure powered by CSV files and FTP.

盡管區塊鏈有多個不可否認的用例,但目前,排名第一的應用是支付。 這是因為銀行仍在使用CSV文件和FTP的低效率,已有40年歷史的基礎架構上運行。

The story comes with a lot of fun and intriguing facts about the overall blockchain ecosystem and different protocols such as Bitcoin, Ethereum and XRP.

這個故事帶來了關于整個區塊鏈生態系統以及比特幣,以太坊和XRP等不同協議的許多有趣有趣的事實。

您將在本教程中構建,學習和做什么? (What will you build, learn, and do in this tutorial?)

  • You'll setup a Go project on your local machine without any prior GoLang experience

    您將在沒有任何GoLang經驗的情況下在本地計算機上設置Go項目
  • You'll generate and distribute your first blockchain tokens

    您將生成并分發您的第一個區塊鏈令牌
  • You'll develop a CLI controlled database in Go from scratch

    您將在Go中從頭開始開發CLI控制的數據庫
  • You'll find out how few rights users posses in their favourite apps

    您會發現在他們最喜歡的應用中,有多少位權限用戶擁有
  • You'll discover the blockchain's main value proposition

    您會發現區塊鏈的主要價值主張
  • You'll make your DB immutable using a secure cryptographic hash function

    您將使用安全的加密哈希函數使數據庫不可變

So let's get started and jump into our story.

因此,讓我們開始吧,進入我們的故事。

?認識主角安德烈(Andrej)。 (? Meet the protagonist, Andrej.)

Andrej is a bar owner by night and a software developer by day in a small Slovakian town called Bardejov.

Andrej晚上在斯洛伐克的一個叫Bardejov的小鎮里是酒吧的老板,白天是軟件開發人員。

Andrej is tired of:

安德烈(Andrej)厭倦了:

  • Programming solid, old fashion PHP/Java/Javascript applications

    編程可靠的老式PHP / Java / Javascript應用程序

  • Forgetting how much money his friends and clients owe him for all the unpaid Friday night vodka shots

    忘記了他的朋友和客戶欠他周五晚上所有未付的伏特加酒花多少錢
  • Spending time collecting and counting coins, returning change and generally touching COVID-19-exposed bank bills

    花費時間收集和計數硬幣,退還找零錢并且通常接觸COVID-19暴露的銀行票據
  • Maintaining different plastic chips for table football, darts, billiard and poker

    維護用于桌上足球,Dart,臺球和撲克的不同塑料芯片

Andrej would love to:

安德烈(Andrej)希望:

  • Have a perfect auditable history of the bar's activities and sales to make his bar compliant with tax regulations

    對酒吧的活動和銷售有完善的可審計歷史,以使其酒吧符合稅收法規

  • Transform his bar into an autonomous, payment-efficient, decentralized and safe environment his customers can trust and profit from

    將他的律師事務所轉變為客戶可以信任并從中獲利的自治,付款高效,去中心化和安全的環境

His goal is to write a simple program and keep all the balances of his clients in virtual form.

他的目標是編寫一個簡單的程序,并以虛擬形式保留其客戶的所有余額。

Andrej shares his thoughts here:

安德烈(Andrej)在這里分享他的想法:

"Every new customer will give me cash, and I will credit them an equivalent amount of my digital tokens (coins/cryptocurrency). The tokens will represent a monetary unit within and outside the bar.

“每個新客戶都會給我現金, 我會把他們等值的我的數字代幣(硬幣/加密貨幣)記入貸方。代幣將代表條形圖內外的貨幣單位。

The users will use the tokens for all bar functionalities from paying for drinks, borrowing and lending them to their friends, and playing table tennis, poker and kicker.

用戶將把令牌用于所有酒吧功能,包括支付酒水,將其借貸給朋友,打乒乓球,玩撲克和踢球。

Having a bar powered by blockchain tokens will generate tons of value for my customers. Contrary to my competition and other bars on this street, where the customers only spend money and get a hangover in exchange, my bar customers holding bar's tokens will have shareholders rights.

擁有由區塊鏈令牌驅動的酒吧將為我的客戶帶來大量價值。 與我在這條街上的競爭對手和其他酒吧相反,那里的顧客只花錢并得到宿醉作為交換, 我持有酒吧代幣的酒吧顧客將擁有股東權利。

Similar to owning a large portion of stocks in a company like Apple or Microsoft, the customers holding these bar tokens will be able to decide how the bar will operate by voting and deciding on:

與在Apple或Microsoft這樣的公司中擁有大量股票類似,持有這些條形碼令牌的客戶將能夠通過投票并決定以下內容來決定條形碼的運作方式:

  • drinks prices

    飲料價格
  • opening hours

    營業時間
  • new features (TV, Jukebox...)

    新功能(電視,自動點唱機...)
  • interior and exterior design

    室內和外部設計
  • profits allocation

    利潤分配
  • etc.

    等等

Oh, this will be a programming dream!

哦,這將是一個編程夢想!

I will call the tokens: The Blockchain Bar tokens, TBB!"

我將這些代幣稱為:區塊鏈酒吧代幣, TBB!

Now that Andrej has shared his dream, we'll get started.

現在,安德烈(Andrej)分享了他的夢想,我們將開始。

目錄 (Table of Contents)

  • Requirements

    要求

  • Setup the project

    設置項目

  • 01 | The MVP Database

    01 | MVP數據庫

  • 02 | Mutating Global DB State

    02 | 突變全球數據庫狀態

  • 03 | Monolithic Event vs Transaction

    03 | 整體事件與交易

  • 04 | Humans Are Greedy

    04 | 人類貪婪

  • 05 | Why We Need Blockchain

    05 | 為什么我們需要區塊鏈

  • 06 | L'Hash de Immutable

    06 | 不可改變的哈希

  • Next steps

    下一步

要求 (Requirements)

Let's dive into our tutorial. I recommend 2+ years of programming experience in Java/PHP/Javascript, or another language similar to Go.

讓我們深入研究我們的教程。 我推薦2年以上Java / PHP / Javascript或類似于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).

您也可以完成A Tour Of Go的 17場官方講座,以熟悉語言語法和基本概念(約20分鐘)。

為什么去? (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是一種流行的語言,Go開發人員的薪水比平均Java / PHP / Javascript職位高。

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.

Go針對多核CPU架構進行了優化。 您可以生成數千個輕量級線程(Go例程)而不會出現問題。 對于高度并行和并發的軟件(例如區塊鏈網絡),這是極其實用的。

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編寫軟件,您可以立即獲得接近C ++的性能,而不會因為忘記釋放內存而喪生。

Go also compiles to binary which makes it very portable.

Go還可以編譯為二進制文件,這使其非常易于移植。

設置項目 (Setup the project)

This article has a dedicated open-sourced Github repository with full source code so you can compile the code and run the program on your own local machine.

本文具有專用的開源Github存儲庫,其中包含完整的源代碼,因此您可以編譯代碼并在自己的本地計算機上運行程序。

If you get stuck at any chapter or a particular line of code, create a Github Issue in this repository describing your problem and I will help you out ASAP!

如果您陷入任何一章或特定的代碼行中,請在此存儲庫中創建一個描述您的問題的Github問題,我會盡快幫助您!

↓ Visit the Github repository and follow the installation instructions ↓

↓訪問Github存儲庫并按照安裝說明進行操作↓

01 | MVP數據庫 (01 | The MVP Database)

? git checkout c1_genesis_json

git checkout c1_genesis_json

Andrej mastered relational SQL databases in the 90s. He knows how to make advanced data models and how to optimize the SQL queries.

Andrej在90年代掌握了關系SQL數據庫。 他知道如何制作高級數據模型以及如何優化SQL查詢。

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

現在是Andrej趕上創新并開始構建Web 3.0軟件的時候了。

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.

幸運的是,安德烈(Andrej)在上周閱讀了《精益創業》(The Lean Startup)一書后,覺得他現在還不應該過度設計解決方案。 因此,他為酒吧的MVP數據庫選擇了一個簡單但有效的JSON文件。

In the beginning, there was a primitive centralized database.

最初,有一個原始的集中式數據庫。

📌總結 (📌 Summary)

Blockchain is a database.

區塊鏈是一個數據庫。

用戶1,Andrej (User 1, Andrej)

Monday, March 18.

3月18日,星期一

Andrej generates 1M utility tokens.

Andrej生成1M實用程序令牌。

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.

每個區塊鏈都有一個“ Genesis”文件。 Genesis文件用于將第一個令牌分發給早期的區塊鏈參與者。

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

這一切都始于一個簡單的虛擬的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:

Andrej創建文件./database/genesis.json ,他在其中定義Blockchain Bar的數據庫將具有1M令牌,并且所有令牌都屬于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)必須遵守法律法規(SEC)。 發行未注冊的安全性是非法的。 另一方面,實用程序令牌很好,因此他立即在酒吧的門上打印并粘貼了新的定價白色p?a?p?e?r?海報。

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

安德烈(Andrej)為代幣分配初始貨幣價值,以便他可以將其兌換為歐元,美元或其他法定貨幣。

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.

Andrej還決定, 他每天應該獲得100個令牌,以維護數據庫并擁有如此出色的破壞性想法。

💡有趣的事實 (💡Fun Facts)

The first genesis Ether (ETH) on Ethereum blockchain was created and distributed to early investors and developers in the same way as Andrej's utility token.
以太坊區塊鏈上的第一個起源以太(ETH)是以與Andrej的效用代幣相同的方式創建并分發給早期投資者和開發商的。
In 2017, during an ICO (initial coin offerings) boom on the Ethereum blockchain network, project founders wrote and presented whitepapers to investors. A whitepaper is a technical document outlining a complex issue and possible solution, meant to educate and elucidate a particular matter. In the world of blockchains, a white paper serves to outline the specifications of how that particular blockchain will look and behave once it is developed.
2017年,在以太坊區塊鏈網絡上的ICO(初始代幣發行)熱潮期間,項目創始人撰寫并向投資者介紹了白皮書。 白皮書是一份技術文檔,概述了一個復雜的問題和可能的解決方案,旨在教育和闡明特定問題。 在區塊鏈領域,白皮書概述了該特定區塊鏈一旦開發后將如何表現和行為的規范。

Blockchain projects raised between €10M to €300M per whitepaper idea.

區塊鏈項目為每個白皮書構想籌集了1000萬至3億歐元。

in exchange for money (the ICO "funding"), investor names ?would be included in the initial "genesis balances", similar to how Andrej did it. Investors' hopes through an ICO are the genesis coins go up in value and that the teams deliver the outlined blockchain.
為了換錢(ICO“資金”),投資者名稱將包括在初始“創始余額”中,這與Andrej的做法類似。 投資者通過ICO寄予的希望是,創世幣的價值有所增加,并且團隊可以提供概述的區塊鏈。
Naturally, not all whitepaper ideas come to fruition. Massive investments lost to unclear or incomplete ideas are why blockchain received negative coverage in the media throughout these ICOs, and why some still considered it a hype. But the underlying blockchain technology is fantastic and useful, as you will learn further in this book. It's just been abused by some bad actors.
自然,并非所有白皮書的想法都能實現。 由于不清楚或不完整的想法而損失的大量投資是為什么區塊鏈在整個ICO中受到媒體的負面報道,以及為什么有些人仍將其視為炒作。 但是底層的區塊鏈技術是神奇而有用的,因為您將在本書中進一步學習。 它只是被一些壞演員濫用。

📌總結 (📌 Summary)

Blockchain is a database.

區塊鏈是一個數據庫。

The token supply, initial user balances, and global blockchain settings you define in a Genesis file.

您在Genesis文件中定義的令牌供應,初始用戶余額和全局區塊鏈設置。

02 | 突變全球數據庫狀態 (02 | Mutating Global DB State)

? git checkout c2_db_changes_txt

git checkout c2_db_changes_txt

死黨 (Dead Party)

Monday, March 25.

3月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)為自己訂購了三杯伏特加酒,并將數據庫更改寫在紙上:

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.

為了避免重新計算每個客戶余額的最新狀態,Andrej創建了一個./database/state.json文件,以匯總格式存儲了余額。

New DB state:

新的數據庫狀態:

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

BabaYaga的獎勵 (Bonus for BabaYaga)

Tuesday, March 26.

3月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.

為了將流量帶入他的酒吧,Andrej宣布了在接下來的24小時內向購買TBB代幣的每個人提供100%的獨家獎勵。

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.

! 他得到了第一個客戶BabaYaga 。 BabaYaga預購了價值1000歐元的代幣,為了慶祝,她立即花了1湯匙TBB喝了伏特加。 她有飲酒問題。

DB transactions written on a piece of paper:

DB事務寫在紙上:

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)

Blockchain ICO (initial coin offerings based on whitepapers) projects often distribute the genesis tokens with different bonuses, depending on how many of them you buy and how early you do it. Teams offer, on average, 10-40% bonuses to early "participants".
區塊鏈ICO(基于白皮書的初始代幣發行)項目通常會分配具有不同獎勵的創世代幣,具體取決于您購買了多少代幣以及您有多早完成了代幣。 團隊平均為早期的“參與者”提供10-40%的獎金。
The word "investor" is avoided, so law regulators won't consider the tokens as a security. Projects would reason their main product, blockchain tokens, function as "flying, loyalty points."
避免使用“投資者”這個詞,因此法律監管機構不會將代幣視為證券。 項目會推論其主要產品區塊鏈令牌的作用是“飛行,忠誠度積分”。
The "participants" later made even 1000% on their investment selling to the public through an exchange several months later.
幾個月后,“參與者”甚至通過交易所向公眾出售其投資的1000%。

📌總結 (📌Summary)

Blockchain is a database.

區塊鏈是一個數據庫。

The token supply, initial user balances, and global blockchain settings you define in a Genesis file.

您在Genesis文件中定義的令牌供應,初始用戶余額和全局區塊鏈設置。

The Genesis balances indicate what was the original blockchain state and are never updated afterwards.

創世余額表明最初的區塊鏈狀態是什么,以后再也不會更新。

The database state changes are called Transactions (TX).

數據庫狀態更改稱為事務(TX)。

03 | 整體事件與交易 (03 | Monolithic Event vs Transaction)

? git checkout c3_state_blockchain_component

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)編程 (Andrej Programming)

Tuesday evening, March 26.

3月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.

這對安德烈(Andrej)來說是個輕松的星期二晚上。 為了慶祝他的第一個客戶,他決定玩一些《 星際爭霸》,并通過刪除一些舊照片來清理自己的本地開發機器。

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

不幸的是,他在終端sudo rm -rf /鍵入刪除命令路徑時過早按下Enter鍵。 哎呀。

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

他的所有文件,包括酒吧的genesis.jsonstate.json都不見了。

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

作為高級開發人員的安德烈(Andrej)反復大聲喊了幾句f *字,但他并沒有驚慌!

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.

他對基于事件的體系結構的優勢印象深刻,因此決定擴展其MVP數據庫解決方案。 每個酒吧的活動,例如個人飲料購買,都必須記錄在區塊鏈數據庫中。

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.

每個事務 (TX-數據庫更改)將具有以下四個屬性: 從,到,值數據

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).

具有一個可能值( 獎勵 )的數據屬性捕獲了安德烈(Andrej)發明區塊鏈的獎金,并人為地增加了初始TBB代幣的總供應量(通貨膨脹)。

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數據庫將保留為JSON文件:

{"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:

所有以前寫在紙上的交易都將存儲在一個名為tx.db的本地文本文件數據庫中,該數據庫以JSON格式序列化并以換行符分隔:

{"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:

封裝所有業務邏輯的最關鍵的數據庫組件將是State

type State struct {Balances   map[Account]uinttxMempool []TxdbFile *os.File
}

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

State結構將了解所有用戶余額以及誰將TBB令牌轉讓給了誰,以及轉讓了多少。

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

通過從genesis.json文件中讀取初始用戶余額來genesis.json

func NewStateFromDisk() (*State, error) {// get current working directorycwd, 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:

然后,通過順序重播tx.db所有數據庫事件來更新創始State余額:

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 linefor scanner.Scan() {if err := scanner.Err(); err != nil {return nil, err}// Convert JSON encoded TX into an object (struct)var tx Txjson.Unmarshal(scanner.Bytes(), &tx)// Rebuild the state (user balances),// as a series of eventsif err := state.apply(tx); err != nil {return nil, err}}return state, nil
}

The State component is responsible for:

State部門負責:

  • Adding new transactions to Mempool

    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:

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 belowmempool := 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 weirds.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.Valuereturn nil}if tx.Value > s.Balances[tx.From] {return fmt.Errorf("insufficient balance")}s.Balances[tx.From] -= tx.Values.Balances[tx.To] += tx.Valuereturn nil
}

構建命令行界面(CLI) (Building a Command-Line-Interface (CLI))

Tuesday evening, March 26.

3月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.

Andrej希望有一種方便的方法將新交易添加到他的數據庫并列出其客戶的最新余額。 由于Go程序會編譯為二進制文件,因此他會為其程序構建一個CLI。

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

在Go中開發基于CLI的程序的最簡單方法是使用第三方github.com/spf13/cobra庫。

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

Andrej為其項目初始化Go的內置依賴項管理器,稱為go modules

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

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

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.

Go modules命令將自動獲取您在Go文件中引用的任何庫。

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

Andrej創建了一個新目錄: cmd和一個子目錄tbb

?mkdir -p ./cmd/tbb

mkdir -p ./cmd/tbb

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

在其中,他創建了一個main.go文件,用作該程序的CLI入口點:

package mainimport ("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程序使用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.

Go將檢測缺少的庫并在編譯程序之前自動獲取它們。 根據您的$GOPATH ,結果程序將保存在$GOPATH/bin文件夾中。

?echo $GOPATH

echo $GOPATH

/home/web3coach/go

?which tbb

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.

您現在可以從終端運行tbb ,但由于main.go文件中的Run函數為空,因此它不會執行任何操作。

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

Andrej首先需要的是對其tbb CLI程序的版本控制。

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

main.go文件旁邊,他創建了version.go命令:

package mainimport ("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

編譯并運行它:? go install ./cmd/tbb/... tbb version

Version: 0.1.0-beta TX Add && Balances List

Version: 0.1.0-beta TX Add && Balances List

Perfect.

完善。

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

version.go文件相同,他創建了balances.go文件:

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:

balances命令將負責加載最新的數據庫狀態并將其打印到標準輸出:

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.

Andrej驗證cmd是否按預期工作。 由于tx.db文件仍然為空,因此應打印在Genesis文件中定義的確切余額。

? go install ./cmd/tbb/...

? go install ./cmd/tbb/...

? tbb balances list

tbb balances list

Accounts balances:
__________________
andrej: 1000000

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

效果很好! 現在,他只需要一個cmd即可記錄酒吧的活動。

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

Andrej創建./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:

tbb tx add cmd使用State.Add(tx)函數將欄的事件持久化到文件系統中:

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 diskerr = 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.

tbb tx add cmd具有3個強制性標志: --from --to ,-- --to--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!

CLI已完成!

Andrej migrates all transactions from paper to his new DB:

Andrej將所有交易從紙本遷移到他的新數據庫:

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

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

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

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

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

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

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

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

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

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

Read all TXs from disk and calculate the latest state:

從磁盤讀取所有TX,并計算最新狀態:

? tbb balances list

tbb balances list

Accounts balances:
__________________
andrej: 998801
babayaga: 1999

Bar data successfully restored! Phew, what a night!

條數據成功恢復! ew,真是個晚上!

關于Cobra CLI庫 (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.

關于Cobra lib進行CLI編程的好處是它附帶的其他功能。 例如,您現在可以運行: tbb help cmd,它將打印出所有TBB注冊的子命令以及有關如何使用它們的說明。

tbb helpThe Blockchain Bar CLIUsage:tbb [flags]tbb [command]Available Commands:balances    Interact with balances (list...).help        Help about any commandtx          Interact with txs (add...).version     Describes version.Flags:-h, --help   help for tbbUse "tbb [command] --help" for more information about a command.

💡有趣的事實 (💡Fun Facts)

Accidentally losing customers' data is a standard Saturday in the corporate world these days. Blockchain fixes this by decentralizing the data storage.
這些天,意外丟失客戶數據是企業界的一個標準星期六。 區塊鏈通過分散數據存儲來解決此問題。

The trick Andrej baked into the program by skipping balance verification for TXs marked as rewards. Bitcoin and Ethereum work in the same way. The balance of the Account who mined a block increases out of the blue as a subject of total tokens supply inflation affecting the whole chain. The total supply of bitcoins is capped at 21M BTC. You will learn more about "mining" and "blocks" in chapters 7 and 10.

安德烈(Andrej)通過跳過標記為獎勵的TX的余額驗證來進入程序。 比特幣和以太坊以相同的方式工作。 開采區塊的賬戶余額突然增加,這是總代幣供應膨脹影響整個鏈條的主題。 比特幣的總供應量上限為2100萬比特幣。 您將在第7章和第10章中了解有關“采礦”和“障礙物”的更多信息。

The components State and Mempool are not unique to this program. Andrej chose the names and designs to match a simplified go-Ethereum, model so you have a glance inside the core Ethereum source code.

StateMempool組件不是此程序唯一的。 Andrej選擇了名稱和設計來匹配簡化的以太坊模型,因此您可以一窺以太坊核心源代碼。

📌總結 (📌 Summary)

Blockchain is a database.

區塊鏈是一個數據庫。

The token supply, initial user balances, and global blockchain settings are defined in a Genesis file.

代幣供應,初始用戶余額和全局區塊鏈設置在Genesis文件中定義。

The Genesis balances indicate what the original blockchain state was and are never updated afterwards.

創世余額表明最初的區塊鏈狀態是什么,以后再也不會更新。

The database state changes are called Transactions (TX).

數據庫狀態更改稱為事務(TX)。

Transactions are old fashion Events representing actions within the system.

事務是老式的事件,代表系統內的動作。

?學習代碼 (? Study Code)

Commit: 5d4b0b

提交: 5d4b0b

Let's talk about greed.

讓我們談談貪婪。

04 | 人類貪婪 (04 | Humans Are Greedy)

? git checkout c4_caesar_transfer

git checkout c4_caesar_transfer

典型的商業貪婪 (Typical business greediness)

Wednesday, March 27.

3月27日,星期三。

BabaYaga invested a bit too much. She forgot her flat rent payment was around the corner, and she doesn't have the money. BabaYaga calls her flat owner, Caesar.

BabaYaga投入了太多。 她忘記了即將支付的固定租金,而且她沒有錢。 BabaYaga打電話給她的單位老板凱撒(Caesar)。

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

BabaYaga:凱撒,很抱歉,但我沒有現金支付您本月的租金…

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!

BabaYaga:區塊鏈酒吧ICO提供了巨大的獎金,我以1000歐元的價格購買了價值2000歐元的代幣。 真是太好了!

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?

凱撒:你到底在說什么? 什么是ICO? 代幣到底是什么? 你可以用其他方式付我錢嗎?

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!

BabaYaga:哦,不再。 我可以給您1000枚價值1000歐元的TBB代幣,您可以在酒吧使用它們來購買飲品! 讓我打電話給酒吧老板安德烈(Andrej),進行轉讓!

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.

安德烈(Andrej)進行了轉讓, 但決定為自己的麻煩收取額外的50枚TBB代幣。 他不想,但幾年前投資他的律師大股東卻強迫他盡快創造利潤。

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

無論如何,BabaYaga最有可能不會注意到這筆相對較小的費用,Andrej告訴自己。 最后,只有他具有數據庫訪問權限。

// Rent payment

//租金支付

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

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

// hidden fee charge

//隱藏費用

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

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

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

💡有趣的事實 (💡Fun Facts)

The number one blockchain use-case is banking. Many blockchain projects aim to optimize the domestic and international exchange of money across different currency corridors (XRP).
區塊鏈的第一個用例是銀行業務。 許多區塊鏈項目旨在優化跨不同貨幣通道(XRP)的國內和國際貨幣交換。
Other projects focus on freedom and self-sovereign identity (SSI) - a digital movement that recognizes an individual should own and control their identity and money without the intervening administrative authorities or other centralized intermediaries. SSI allows people to interact in the digital world with the same freedom and capacity for trust as they do in the offline world. (Bitcoin / Ethereum)
其他項目則側重于自由和自我主權(SSI)-一種數字運動,它認識到個人應擁有并控制自己的身份和金錢,而無需干預行政當局或其他中央中介機構。 SSI允許人們在數字世界中以與離線世界相同的自由度和信任度進行交互。 (比特幣/以太坊)
Here are few fun facts why blockchain is a perfect fit for replacing your bank's current banking infrastructure.
以下是一些有趣的事實,為什么區塊鏈非常適合替代您銀行現有的銀行基礎設施。
The good thing about virtual tokens is their fungibility - i.e., their ability to be traded, with each unit being as usable as the next. Performing a transfer from account to account can be done by simply changing the database state. Cryptocurrencies are tradeable 24/7.
虛擬代幣的優點在于它們的可替代性-即它們的交易能力,每個單位都可以使用下一個單位。 只需更改數據庫狀態即可完成帳戶之間的轉移。 加密貨幣可以24/7交易。
You can't trade stocks directly. You need to go through a broker who takes part a percentage of the total transaction as a fee (1-3% to 7% average yearly profit).
您不能直接交易股票。 您需要經過一個經紀人,該經紀人作為費用收取總交易額的一部分(平均年利潤的1-3%至7%)。

An international bank transfer takes between 3-10 business days and can cost as much 5% of the transferred value! If you’re sending $10,000, you may have to pay up to $500. The technology behind for the last 40 years? FTP + CSV files.

國際銀行轉賬需要3到10個工作日,并且可能要花費轉賬金額的5%! 如果您要匯款$ 10,000,則可能最多需要支付$ 500。 過去40年中落后的技術? FTP + CSV文件。

Do you think the stock market is fair? Banks, indexes, and stocks are highly centralized and controlled by governments and private Wall Street groups. Free market? Wall Street controls how much can prices jump/fall in a single day.
您認為股市公平嗎? 銀行,指數和股票高度集中,并由政府和華爾街私人集團控制。 自由市場? 華爾街控制價格在一天之內可以上漲/下跌多少。
As an example, Wall Street halted the trading of "S&P 500 Index" after a 7% drop to protect their investors and hedge funds from losing money from people selling their stocks during March 2020 after COVID news. Afterward, the FED printed trillions of dollars for themselves to support the stock price. If you are a developer who likes to save money and avoid debt, your savings just lost value overnight by a yet unknown percentage.
例如,華爾街在下跌7%之后停止了“標準普爾500指數”的交易,以保護其投資者和對沖基金避免在2020年3月COVID消息傳出后拋售股票的人蒙受損失。 后來,美聯儲自己印制了數萬億美元來支撐股價。 如果您是喜歡節省金錢并避免債務的開發人員,那么您的儲蓄在一夜之間損失了價值,但未知的百分比。
Many countries are going into negative yields, an unexplored territory with unknown consequences. What does this mean? Soon you will have to pay the bank to keep your savings. Inflation at its best. You are being forced to spend your money to support a system you don't control.
許多國家正處于負收益狀態,這是一個尚未開發的領域,后果不明。 這是什么意思? 很快,您將不得不向銀行付款以保留您的積蓄。 通貨膨脹處于最佳狀態。 您被迫花錢支持不受控制的系統。

?學習代碼 (? Study Code)

Commit: 00d6ed

提交: 00d6ed

05 | 為什么我們需要區塊鏈 (05 | Why We Need Blockchain)

? git checkout c5_broken_trust

git checkout c5_broken_trust

BabaYaga尋求正義 (BabaYaga Seeks Justice)

Thursday, March 28.

3月28日,星期四。

BabaYaga enters the bar for her birthday.

BabaYaga生日那天進入酒吧。

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

BabaYaga:嗨,安德烈! 今天是我的生日! 給我你最貴的瓶子!

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.

安德烈:生日快樂! 在這里,您去了:水晶頭伏特加酒。 但是您需要另外購買一個TBB令牌。 該瓶子的價格為950個令牌,您的余額為949。

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

BabaYaga:什么?! 我的余額應該是999 TBB!

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

安德烈(Andrej):您上周向凱撒(Caesar)進行的資金轉帳花費了您50個令牌。

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!

BabaYaga:這是不可接受的! 我永遠不會同意這么高的費用。 你不能做到這一點,安德烈(Andrej)。 我信任您的系統,但是您和其他企業主一樣不可靠。 事情必須改變!

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?

BabaYaga:嗯,聽起來確實不錯,但這是否可能?

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

安德烈:是的,我是這樣認為的。 帶有一些散列,鏈表,不變的數據結構,分布式復制和非對稱密碼!

BabaYaga: I have no idea what you have just said but go and do your geeky thing, Andrej!

BabaYaga:我不知道你剛才說了什么,但是去做你的怪異事,Andrej!

💡有趣的事實 (💡Fun Facts)

Bitcoin and Ethereum miners also receive rewards every ~15 minutes for running the blockchain servers (nodes) and validating transactions.
比特幣和以太坊礦工還通過運行區塊鏈服務器(節點)和驗證交易每15分鐘獲得獎勵。
Every 15 minutes, one Bitcoin miner receives 12.5 BTC ($100k at the moment of writing this page) to cover his servers cost + make some profit.
每15分鐘,一名比特幣礦工獲得12.5 BTC(在撰寫此頁面時為10萬美元)以支付他的服務器成本+獲利。
The Bitcoin network consumes as much electricity as the entire country of Austria. It accounts for 0.29% of the world's annual electricity consumption.
比特幣網絡消耗的電量與整個奧地利國家一樣多。 它占世界年度用電量的0.29%。

Annually it consumes 76.84 TWh, producing 36.50 Mt CO2 carbon footprint (New Zealand). Source.

每年消耗76.84 TWh,產生36.50 Mt的二氧化碳足跡(新西蘭)。 資源。

Why? You will learn more later (in Chapter 11) where you will program a Bitcoin mining algorithm from scratch!
為什么? 您將在后面的第11章中了解更多信息,從頭開始編寫比特幣挖掘算法!
PS: Our algorithm will consume a bit less electricity :)
PS:我們的算法將消耗更少的電量:)

📌總結 (📌 Summary)

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.

區塊鏈是一個數據庫。 代幣供應,初始用戶余額和全局區塊鏈設置在Genesis文件中定義。 創世余額表明最初的區塊鏈狀態是什么,以后再也不會更新。

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

數據庫狀態更改稱為事務(TX)。 事務是老式的事件,代表系統內的動作。

?學習代碼 (? Study Code)

Commit: 642045

提交: 642045

06 | 不可改變的哈希 (06 | L'Hash de Immutable)

? git checkout c6_immutable_hash

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.

3月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.

如果Andrej想弄清楚如何編寫一個不變的DB,他必須意識到為什么其他數據庫系統在設計上是可變的。

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

他決定分析一個全能MySQL數據庫表:

| 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:

在MySQL DB中,具有訪問權限并有充分理由的任何人都可以執行表更新,例如:

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.

跨表更新值是可能的,因為表行是獨立的,可變的,并且最新狀態不明顯。

What’s the latest DB change? Last column changed? Last row inserted? If so, how can Andrej know what row was deleted recently? If the rows and table state were tightly coupled, dependent, a.k.a, updating row 1 would generate a completely new, different table, Andrej would achieve his immutability.

最新的數據庫更改是什么? 最后一欄改變了? 最后插入行? 如果是這樣,Andrej如何知道最近刪除了哪一行? 如果行和表的狀態緊密耦合,相互依賴(也稱為更新),則更新第1行將生成一個全新的不同表,Andrej將實現其不變性。

How can you tell if any byte in a database has changed?
您如何判斷數據庫中的任何字節是否已更改?

通過哈希函數實現不變性 (Immutability via Hash Functions)

Hashing is process of taking a string input of arbitrary length and producing a hash string of fixed length. Any change in input, will result in a new, different hash.

散列是獲取任意長度的字符串輸入并生成固定長度的散列字符串的過程。 輸入的任何更改都將導致新的不同哈希值。

package mainimport ("crypto/sha256""fmt"
)func main() {balancesHash := sha256.Sum256([]byte("| 1 | Andrej | 99895 |"))fmt.Printf("%x\n", balancesHash)// Output: 6a04bd8e2...f70a3902374f21e089ae7cc3b200751// Change balance from 99895 -> 99896balancesHashDiff := sha256.Sum256([]byte("| 1 | Andrej | 99896 |"))fmt.Printf("%x\n", balancesHashDiff)// Output: d04279207...ec6d280f6c7b3e2285758030292d5e1
}

Try it: https://play.golang.org/p/FTPUa7IhOCE

嘗試一下: https : //play.golang.org/p/FTPUa7IhOCE

Andrej also requires some level of security for his database, so he decides for a Cryptographic Hash Function with the following properties:

Andrej還要求其數據庫具有某種程度的安全性,因此他決定使用具有以下屬性的加密散列函數

  • it is deterministic - the same message always results in the same hash

    它是確定性的 -相同的消息始終導致相同的哈希

  • 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.

3月30日,星期六晚上。

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

每當新事務持久化時,Andrej都會修改Persist()函數以返回新的內容哈希Snapshot

type Snapshot [32]byte

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

Snapshot由此新的sha256 secure hashing函數生成:

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.

doSnapshot()由修改后的Persist()函數調用。 當將新事務寫入tx.db文件時, Persist()將對整個文件內容進行哈希處理并返回其32個字節的“指紋”哈希值。

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

從這一刻起,每個人都可以100%自信和安全地使用特定的快照哈希引用任何特定的數據庫狀態(數據集)。

?實踐時間 (?Practice time)

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

1/4運行tbb balances list cmd并檢查余額是否匹配。

? tbb balances list

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.

2/4./database/tx.db刪除最后2行, ./database/tx.db再次檢查余額。

? tbb balances list

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):

最后2天(3月28日至30日)的3/4獎勵安德烈:

Reward Transaction 1:

獎勵交易1:

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

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:

獎勵交易2:

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

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.

4/4運行tbb balances list cmd,并確保余額和快照哈希與開頭相同。

? tbb balances list

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!

因為加密散列函數sha256產生相同的輸出(給定相同的輸入(當前tx.db和2x tbb tx add )),所以如果您在自己的計算機上執行確切的步驟,則將生成完全相同的數據庫狀態和哈希!

📌總結 (📌 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.

區塊鏈是一個不變的數據庫。 您在Genesis文件中定義的令牌供應,初始用戶余額和全局區塊鏈設置。 創世余額表明最初的區塊鏈狀態是什么,以后再也不會更新。

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

數據庫狀態更改稱為事務(TX)。 事務是老式的事件,代表系統內的動作。

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

提交: b99e51

?下一步 (?Next steps)

You finished the first few chapters! Congratulations!

您完成了前幾章! 恭喜你!

█????????? 10%

█??????????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.

您可以繼續在我的通訊版本“ The Blockchain Way of Programming”電子書的下一個免費章節中繼續閱讀。

07 | The Blockchain Programming Model

07 | 區塊鏈編程模型

  • Improving Performance of an Immutable DB

    提高不可變數據庫的性能
  • Batch + Hash + Linked List ? Blocks

    批處理+哈希+鏈接列表?塊
  • Migrating from TX.db to BLOCKS.db

    從TX.db遷移到BLOCKS.db

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

學習:您將MVP數據庫重新設計和重構為區塊鏈架構。

繼續本教程: https://web3.coach#book (Continue in the tutorial: https://web3.coach#book)

Thanks for reading!

謝謝閱讀!

翻譯自: https://www.freecodecamp.org/news/build-a-blockchain-in-golang-from-scratch/

fcn從頭開始

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/390168.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/390168.shtml
英文地址,請注明出處:http://en.pswp.cn/news/390168.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

java實現無序數組結構

一、數組的2種定義方式 數據類型 [] 數組名稱 new 數據類型[數組長度]; 這里 [] 可以放在數組名稱的前面&#xff0c;也可以放在數組名稱的后面&#xff0c;一般放在名稱的前面 數據類型 [] 數組名稱 {數組元素1&#xff0c;數組元素2&#xff0c;......} 這種方式聲明數組的…

Android App 的主角:Activity

Android App 程序主要由4種類型組成&#xff1a; 1.Activity&#xff08;活動&#xff09;&#xff1a;主要負責屏幕顯示畫面&#xff0c;并處理與用戶的互動。每個Android App至少都會有一個Activity&#xff0c;在程序一啟動時顯示主畫面供用戶操作。 2.Service&#xff08;后…

通過構建Paint App學習React Hooks

According to people in the know, React Hooks are hot, hot, hot. In this article, we follow Christian Jensens 14-part tutorial to find out about the basics of this new feature of React. Follow along to find out more! 據知情人士稱&#xff0c;React Hooks很熱&…

正則表達式 匹配常用手機號 (13、15\17\18開頭的十一位手機號)

原文:正則表達式 匹配常用手機號 &#xff08;13、15\17\18開頭的十一位手機號&#xff09;^1[3578]\d{9}$ ^1表示以1開頭&#xff0c;[3578]表示第二位的數字為3578中的任意一個&#xff0c;\d{9}表示0~9范圍內的數字匹配九次,$表示結束&#xff0c;12位以上的數字不匹配。

Npoi導出excel整理(附源碼)

前些日子做了一個簡單的winform程序&#xff0c;需要導出的功能&#xff0c;剛開始省事直接使用微軟的組件&#xff0c;但是導出之后發現效率極其低下&#xff0c;絕對像web那樣使用npoi組件&#xff0c;因此簡單的進行了整理&#xff0c;包括直接根據DataTable導出excel及Data…

44. 通配符匹配

44. 通配符匹配 給定一個字符串 (s) 和一個字符模式 &#xff0c;實現一個支持 ‘?’ 和 ‘*’ 的通配符匹配。 ? 可以匹配任何單個字符。 * 可以匹配任意字符串&#xff08;包括空字符串&#xff09;。 兩個字符串完全匹配才算匹配成功。說明: s 可能為空&#xff0c;且…

遞歸javascript_使用freeCodeCamp挑戰解釋了JavaScript中的遞歸

遞歸javascriptIn this article I will touch on a few important ideas to help you understand Recursion in JavaScript. I’m not going to give a full definition here, but you can take a look at what Wikipedia has to say. 在本文中&#xff0c;我將介紹一些重要的想…

入庫成本與目標成本對比報表中我學到的東西

1、SQL方面&#xff1a; &#xff08;1&#xff09;、用DECODE函數解決除數為零的情況 具體語法&#xff1a; DECODE&#xff08;參數&#xff0c;0&#xff0c;1&#xff0c;參數&#xff09; ->DECODE(TAB1.A8&#xff0c;0&#xff0c;1&#xff0c;TAB1.A8) &#xff08…

J - Borg Maze

J - Borg Maze 思路&#xff1a;bfs最小生成樹。#include<queue> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define MAXN 110 using namespace std; int fa[MAXN]; struct nond{int x,y,z; }v[MAXN*MAXN]; s…

1095. 山脈數組中查找目標值

1095. 山脈數組中查找目標值 &#xff08;這是一個 交互式問題 &#xff09; 給你一個 山脈數組 mountainArr&#xff0c;請你返回能夠使得 mountainArr.get(index) 等于 target 最小 的下標 index 值。 如果不存在這樣的下標 index&#xff0c;就請返回 -1。 何為山脈數組…

【小摘抄】關于C++11下 string各類用法(持續更新)

http://blog.csdn.net/autocyz/article/details/42391155 提供了最簡單的詳解 下列對本人近期開發中的一些心得體會進行摘抄 1.string按照字符進行截取 示例代碼&#xff1a; string teststring "#12313#kajlkfdsa";//通訊消息示例&#xff0c;結合string的內置函數…

sql綜合練習題

一、表關系 年級表&#xff1a;class_grade create table class_grade(gid int primary key auto_increment,gname varchar(20) not null); insert into class_grade(gname) values(一年級),(二年級),(三年級); 班級表&#xff1a;class create table class(cid int primary ke…

javascript原型_在JavaScript中凍結原型時會發生什么

javascript原型Have you wondered what happens when you freeze the prototype of an object? Lets find out together.您是否想過凍結對象的原型時會發生什么&#xff1f; 讓我們一起找出答案。 對象 (Objects) In JavaScript, objects are dynamic collections of propert…

遲來的2017總結

明天就是年后第一天上班了&#xff08;過年期間請了6天假&#xff09;&#xff0c; 打算今天寫一下2017的總結&#xff0c;本來還想寫2018的愿景的&#xff0c;不過想想還是算了&#xff0c;現在沒什么想法&#xff0c;不想敷衍了事。 先貼一個2017的提升計劃&#xff1a; http…

tomcat啟動卡住

新部署的項目啟動tomcat后一直停在org.apache.catalina.core.StandardEngine.startInternal Starting Servlet Engine: Apache Tomcat/8.5.16&#xff0c;卡在了org.apache.catalina.startup.HostConfig.deployDirectory Deploying web application directory [/opt/tomcat/web…

怎樣準備阿里技術面試_如何準備技術面試

怎樣準備阿里技術面試In June 2020 I watched an inspiring talk by Anthony D. Mays, a technical coach and founder at Morgan Latimerco. He came on a Facebook Developer Circles Benin live session and talked about how to prepare for a technical interview. 2020年…

通過一個簡單例子理解 RecyclerView.ItemDecoration

一、前言 RecyclerView 是從5.0推出的 MD 風格的控件。RecyclerView 之前有 ListView、GridView&#xff0c;但是功能很有限&#xff0c;例如 ListView 只能實現垂直方向上的滑動等。但是存在則合理&#xff0c;ListView 卻沒有被官方標記為 Deprecated&#xff0c;有興趣的同學…

Entity Framework Logging and Intercepting Database Operations (EF6 Onwards)

參考官方文檔&#xff1a;https://msdn.microsoft.com/en-us/library/dn469464(vvs.113).aspx轉載于:https://www.cnblogs.com/liandy0906/p/8473110.html

面試題 17.14. 最小K個數

面試題 17.14. 最小K個數 設計一個算法&#xff0c;找出數組中最小的k個數。以任意順序返回這k個數均可。 示例&#xff1a; 輸入&#xff1a; arr [1,3,5,7,2,4,6,8], k 4 輸出&#xff1a; [1,2,3,4] 提示&#xff1a; 0 < len(arr) < 1000000 < k < min(1…

這是您現在可以免費獲得的115張Coursera證書(在冠狀病毒大流行期間)

At the end of March, the world’s largest Massive Open Online Course provider Coursera announced that they are offering 100 free courses in response to the impact of the COVID-19 pandemic. 3月底&#xff0c;全球最大的大規模在線公開課程提供商Coursera 宣布 &a…