中文字幕在线观看,亚洲а∨天堂久久精品9966,亚洲成a人片在线观看你懂的,亚洲av成人片无码网站,亚洲国产精品无码久久久五月天

使用 Python 從零開始開發(fā)區(qū)塊鏈應用程序

2018-07-20    來源:編程學習網(wǎng)

容器云強勢上線!快速搭建集群,上萬Linux鏡像隨意使用

本教程將向具有任何編程技能水平的 Python 開發(fā)人員介紹區(qū)塊鏈。通過從零開始實現(xiàn)一個 公有區(qū)塊鏈 并構(gòu)建一個簡單應用程序來利用它,您將了解區(qū)塊鏈到底是什么。

您將能夠使用 Flask 微框架為區(qū)塊鏈的不同功能創(chuàng)建端點,比如添加事務,然后在多個機器上運行腳本來創(chuàng)建一個去中心化網(wǎng)絡。您還將了解如何構(gòu)建一個簡單的用戶界面,以便與區(qū)塊鏈進行交互,并存儲任何用例的信息,比如對等支付、聊天或電子商務。

Python 是一種容易理解的編程語言,這是我在本教程中選擇它的原因。通過學習本教程,您將實現(xiàn)一個公有區(qū)塊鏈并了解它的實際應用。GitHub 上提供了一個完整的樣本應用程序代碼,該應用程序完全是用 Python 編寫的。

獲取代碼

主要邏輯包含在 views.py 文件中。讓我們一起分析一下該邏輯,以便真正全面了解區(qū)塊鏈。

前提條件

  • Python 的基礎編程知識
  • Flask 微框架(用于創(chuàng)建區(qū)塊鏈服務器的端點)

背景

公有區(qū)塊鏈與私有區(qū)塊鏈

公有區(qū)塊鏈網(wǎng)絡 (比如比特幣網(wǎng)絡)完全對公眾開放,任何人都能加入和參與其中。

另一方面,如果企業(yè)對事務的隱私性、安全性和速度有更高的要求,可以選擇采用 私有區(qū)塊鏈網(wǎng)絡 ,參與者需要邀請才能加入該網(wǎng)絡。了解更多信息。

2008 年,一個名叫 Satoshi Nakamoto 的人(或者可能是一個小組)發(fā)表了一篇名為《比特幣:一種對等電子現(xiàn)金系統(tǒng)》的白皮書。該文章結(jié)合了密碼學技術和對等網(wǎng)絡,不需要依靠中心化權(quán)威機構(gòu)(比如銀行)就能在人們之間實現(xiàn)付款。比特幣應運而生。除了比特幣之外,這篇文章還介紹了一種存儲數(shù)據(jù)的分布式系統(tǒng)(即現(xiàn)在廣為人知的“區(qū)塊鏈”),該系統(tǒng)的適用范圍遠不只是付款或加密貨幣。

從那時起,幾乎每個行業(yè)都對區(qū)塊鏈產(chǎn)生了濃厚的興趣。無論是像比特幣這樣的完全數(shù)字化的貨幣、像以太坊這樣的分布式計算技術,還是像 IBM Blockchain Platform 所基于的Hyperledger Fabric 這樣的開源框架,現(xiàn)在都以區(qū)塊鏈作為其背后的基礎技術。

進一步了解 IBM Blockchain Platform Starter Plan(免費使用測試版!)

“區(qū)塊鏈”是什么?

區(qū)塊鏈是一種存儲數(shù)字數(shù)據(jù)的方式。數(shù)據(jù)可以是任何內(nèi)容。對于比特幣,它是事務(在帳戶之間轉(zhuǎn)移比特幣),它甚至可以是文件;這都無關緊要。數(shù)據(jù)是以區(qū)塊形式進行存儲的,區(qū)塊使用哈希值鏈接在一起。因此得名“區(qū)塊鏈”。

區(qū)塊鏈的神奇之處是在其中添加和存儲此類數(shù)據(jù)的方式,該方式造就了一些非常理想的特征:

  • 歷史記錄無法更改
  • 系統(tǒng)無法攻破
  • 數(shù)據(jù)的持久保存
  • 沒有單點故障

那么區(qū)塊鏈如何能夠?qū)崿F(xiàn)這些特征呢?我們將通過實現(xiàn)一個區(qū)塊鏈來深入剖析它。讓我們開始吧。

關于該應用程序

首先定義一下我們將要構(gòu)建的應用程序的用途。我們的目的是構(gòu)建一個允許用戶共享信息的簡單網(wǎng)站。因為內(nèi)容將存儲在區(qū)塊鏈中,所以它無法更改且會永遠存在。

我們將采用自下而上的實現(xiàn)方式。首先定義我們將存儲在區(qū)塊鏈中的數(shù)據(jù)的結(jié)構(gòu)。 一篇帖子(任何用戶在我們的應用程序上發(fā)布的一條消息)將由 3 個基本要素來標識:

  1. 內(nèi)容
  2. 作者
  3. 時間戳

1

將事務存儲到區(qū)塊中

我們將采用一種廣泛使用的格式來將數(shù)據(jù)存儲在區(qū)塊鏈中:JSON。以下是一篇存儲在區(qū)塊鏈中的帖子的格式:

{
    "author": "some_author_name", 
    "content": "Some thoughts that author wants to share", 
    "timestamp": "The time at which the content was created"
}

術語“數(shù)據(jù)”通常在互聯(lián)網(wǎng)上被“事務”一詞所取代。所以,為了避免混淆并保持一致,我們將使用術語“事務”來表示在我們的示例應用程序中發(fā)布的數(shù)據(jù)。

事務被打包到區(qū)塊中。一個區(qū)塊可以包含一個或許多個事務。包含事務的區(qū)塊頻繁地生成并添加到區(qū)塊鏈中。因為可能有多個區(qū)塊,所以每個區(qū)塊都應有一個唯一 ID:

class Block: 
    def __init__(self, index, transactions, timestamp): 
        self.index = [] 
        self.transactions = transactions 
        self.timestamp = timestamp

2

讓區(qū)塊不可更改

我們希望檢測出對區(qū)塊內(nèi)存儲的數(shù)據(jù)的任何篡改。在區(qū)塊鏈中,這是使用一個哈希函數(shù)來實現(xiàn)的。

哈希函數(shù) 接受任何大小的數(shù)據(jù)并生成固定大小的數(shù)據(jù),該結(jié)果通常用于識別輸入。下面是 Python 中的一個使用 sha256 哈希函數(shù)的示例:

>>> from hashlib import sha256
>>> data = "Some variable length data"
>>> sha256(data).hexdigest()
'b919fbbcae38e2bdaebb6c04ed4098e5c70563d2dc51e085f784c058ff208516'
>>> sha256(data).hexdigest() # no matter how many times you run it, the
 result is going to be the same 256 character string
'b919fbbcae38e2bdaebb6c04ed4098e5c70563d2dc51e085f784c058ff208516'

一個理想的哈希函數(shù)包括以下特征:

  • 它應該很容易計算。
  • 哪怕只更改數(shù)據(jù)中的一個位,哈希值也應該完全發(fā)生變化。
  • 應該無法根據(jù)輸出哈希值猜出輸入。

您現(xiàn)在知道哈希函數(shù)是什么了吧。我們將每個區(qū)塊的哈希值都存儲在 Block 對象內(nèi)的一個字段中,其作用類似于它所包含的數(shù)據(jù)的數(shù)字指紋:

from hashlib import sha256
import json

def compute_hash(block):  
     """ 
    A function that creates the hash of the block. 
    """ 
    block_string = json.dumps(self.__dict__, sort_keys=True) 
    return sha256(block_string.encode()).hexdigest()

備注:在大多數(shù)加密貨幣中,甚至對區(qū)塊中的各個事務也進行了哈希運算,從而形成一棵哈希樹(也稱為 二進制哈希樹 ),這棵樹的根可以用作區(qū)塊的哈希值。它不是區(qū)塊鏈正常運作的必要條件,所以我們將省略它,以保持代碼簡潔。

3

鏈接區(qū)塊

我們已設置了區(qū)塊。區(qū)塊鏈應該是一個區(qū)塊集合。我們可以將所有區(qū)塊都存儲在 Python 列表中(等效于數(shù)組)。但這還不夠,因為如果有人故意替換了集合中的一個區(qū)塊該怎么辦?用修改過的事務創(chuàng)建一個新的區(qū)塊,計算哈希值,然后替換任何舊區(qū)塊,這在我們的當前實現(xiàn)中并不是什么難事,因為我們會保持區(qū)塊的不可更改性和順序。

我們需要采用某種途徑來確保對過去的區(qū)塊的任何更改都會造成整個鏈的失效。一種方法是通過哈希值將區(qū)塊鏈接起來。談到鏈接,我們指的是將前一個區(qū)塊的哈希值包含在當前區(qū)塊中。所以,如果任何以前的區(qū)塊的內(nèi)容發(fā)生更改,該區(qū)塊的哈希值也會發(fā)生更改,導致與下一個區(qū)塊中的 previous_hash 字段不匹配。

每個區(qū)塊都通過 previous_hash 字段鏈接到前一個區(qū)塊,但是第一個區(qū)塊該如何處理?第一個區(qū)塊稱為 創(chuàng)始區(qū)塊 ,大多數(shù)情況下,它是手動生成或通過某種獨特邏輯生成的。讓我們將 previous_hash 字段添加到 Block 類中,并實現(xiàn)我們的 Blockchain 類的初始結(jié)構(gòu)(參見清單 1)。

清單 1. 我們的 Blockchain 類的初始結(jié)構(gòu)

from hashlib import sha256
import json
import time
class Block:  
    def__init__(self, index, transactions, timestamp, previous_hash):  
        self.index = index 
        self.transactions = transactions 
        self.timestamp = timestamp
        self.previous_hash = previous_hash 

    def compute_hash(self):  
        block_string = json.dumps(self.__dict__, sort_keys=True) 
        return sha256(block_string.encode()).hexdigest()

這是我們的 Blockchain 類:

class Blockchain: 

    def __init__(self): 
        self.unconfirmed_transactions = [] # data yet to get into blockchain
        self.chain = []
        self.create_genesis_block()

    def create_genesis_block(self): 
        """
        A function to generate genesis block and appends it to
        the chain.The block has index 0, previous_hash as 0, and
        a valid hash.
        """
        genesis_block = Block(0, [], time.time(), "0")
        genesis_block.hash = genesis_block.compute_hash()
        self.chain.append(genesis_block)

    @property
    def last_block(self): 
        return self.chain[-1]

4

實現(xiàn)工作量證明算法

選擇性背書與工作量證明

IBM Blockchain Platform 支持的業(yè)務區(qū)塊鏈中的共識性不是通過挖礦實現(xiàn)的,而是通過一個稱為 選擇性背書 的流程來實現(xiàn)的。網(wǎng)絡成員準確控制由誰來驗證事務,與目前的業(yè)務實現(xiàn)方式大致相同。進一步了解業(yè)務區(qū)塊鏈。

但這里存在一個問題。如果我們更改前一個區(qū)塊,我們可以非常輕松地重新計算所有后續(xù)區(qū)塊的哈希值,并創(chuàng)建一個不同的有效區(qū)塊鏈。為了預防這種情況,我們必須讓計算哈希值的任務變得困難和隨機化。

以下是我們實現(xiàn)此操作的方式。我們不會接受任何區(qū)塊哈希值,而是對它添加某種約束。讓我們來添加一種約束:哈希值應以兩個前導零開始。另外我們知道,除非更改區(qū)塊的內(nèi)容,否則哈希值不會發(fā)生更改。

所以我們將在區(qū)塊中引入一個稱為 隨機數(shù) 的新字段。隨機數(shù)會不斷變化,直到我們獲得滿足約束條件的哈希值。前導零的數(shù)量(在我們的例子中為值 2)決定了工作量證明算法的“難度”。您可能還注意到,我們的工作量證明很難計算,但在我們確定隨機數(shù)后很容易驗證(對于驗證,您只需要再次運行哈希函數(shù)即可):

class Blockchain: 
    # difficulty of PoW algorithm
    difficulty = 2

    """
    Previous code contd..
    """

    def proof_of_work(self, block): 
        """
        Function that tries different values of nonce to get a hash
        that satisfies our difficulty criteria.
        """
        block.nonce = 0

        computed_hash = block.compute_hash()
        while not computed_hash.startswith('0' * Blockchain.difficulty): 
            block.nonce += 1
            computed_hash = block.compute_hash()

        return computed_hash

請注意,沒有明確的邏輯來快速確定隨機數(shù);只能通過暴力破解。

5

將區(qū)塊添加到鏈中

要將區(qū)塊添加到鏈中,首先需要驗證所提供的工作量證明是否正確,以及要添加的區(qū)塊的 previous_hash 字段是否指向鏈中的最新區(qū)塊的哈希值。

讓我們看看將區(qū)塊添加到鏈中的代碼:

class Blockchain: 
    """
    Previous code contd..
    """
    def add_block(self, block, proof): 
        """
        A function that adds the block to the chain after verification.
        """
        previous_hash = self.last_block.hash

        if previous_hash != block.previous_hash: 
            return False

        if not self.is_valid_proof(block, proof): 
            return False

        block.hash = proof
        self.chain.append(block)
        return True

    def is_valid_proof(self, block, block_hash): 
        """
        Check if block_hash is valid hash of block and satisfies
        the difficulty criteria.
        """
        return (block_hash.startswith('0' * Blockchain.difficulty) and
                block_hash == block.compute_hash())

挖礦

事務最初存儲在一個未確認事務池中。將未確認事務放入?yún)^(qū)塊中并計算工作量證明的過程被稱為區(qū)塊 挖礦 。一旦找到滿足我們的約束條件的隨機數(shù),我們就可以說挖到了一個區(qū)塊,這個區(qū)塊就會放入?yún)^(qū)塊鏈中。

在大多數(shù)加密貨幣(包括比特幣)中,作為對耗費算力來計算工作量證明的獎勵,礦工可以獲得一些加密貨幣。以下是我們的挖礦函數(shù)的格式:

class Blockchain: 
    """
    Previous code contd...
    """

    def add_new_transaction(self, transaction): 
            self.unconfirmed_transactions.append(transaction)

    def mine(self): 
        """
        This function serves as an interface to add the pending
        transactions to the blockchain by adding them to the block
        and figuring out Proof of Work.
        """
        if not self.unconfirmed_transactions: 
            return False

        last_block = self.last_block

        new_block = Block(index=last_block.index + 1,
                          transactions=self.unconfirmed_transactions,
                          timestamp=time.time(),
                          previous_hash=last_block.hash)

        proof = self.proof_of_work(new_block)
        self.add_block(new_block, proof)
        self.unconfirmed_transactions = []
        return new_block.index

好了,我們的工作差不多完成了。您可以 在 GitHub 上查看截至目前的合并代碼 。

6

創(chuàng)建接口

現(xiàn)在為我們的節(jié)點創(chuàng)建接口,以便與其他對等節(jié)點以及我們將要構(gòu)建的應用程序進行交互。我們將使用 Flask 創(chuàng)建一個 REST-API 來與我們的節(jié)點進行交互。以下是它的代碼:

from flask import Flask, request
import requests

app =  Flask(__name__)

# the node's copy of blockchain
blockchain = Blockchain()

我們的應用程序需要一個端點來提交新事務。我們的應用程序?qū)⑹褂么硕它c將新數(shù)據(jù)(帖子)添加到區(qū)塊鏈中:

@app.route('/new_transaction', methods=['POST'])
def new_transaction(): 
    tx_data = request.get_json()
    required_fields = ["author", "content"]

    for field in required_fields: 
        if not tx_data.get(field): 
            return "Invlaid transaction data", 404

    tx_data["timestamp"] = time.time()

    blockchain.add_new_transaction(tx_data)

    return "Success", 201

下面是返回節(jié)點的鏈副本的端點。我們的應用程序?qū)⑹褂么硕它c來查詢要顯示的所有帖子:

@app.route('/chain', methods=['GET'])
def get_chain(): 
    chain_data = []
    for block in blockchain.chain: 
        chain_data.append(block.__dict__)
    return json.dumps({"length": len(chain_data),
                       "chain": chain_data})

下面是請求節(jié)點挖掘未確認事務(如果有)的端點。我們將使用此端點從我們的應用程序自身發(fā)起一個挖礦命令:

@app.route('/mine', methods=['GET'])
def mine_unconfirmed_transactions(): 
    result = blockchain.mine()
    if not result: 
        return "No transactions to mine"
    return "Block #{} is mined.".format(result)


# endpoint to query unconfirmed transactions
@app.route('/pending_tx')
def get_pending_tx(): 
    return json.dumps(blockchain.unconfirmed_transactions)


app.run(debug=True, port=8000)

現(xiàn)在,您可以體驗一下我們的區(qū)塊鏈,創(chuàng)建一些事務,然后使用諸如 cURL 或 Postman 之類的工具來挖掘它們。

7

建立共識和去中心化

目前為止,我們實現(xiàn)的代碼只能在單個計算機上運行。即使通過哈希值鏈接了區(qū)塊,我們?nèi)匀徊荒苄湃螁蝹實體。我們需要多個節(jié)點來維護我們的區(qū)塊鏈。 所以讓我們創(chuàng)建一個端點,以便讓一個節(jié)點了解網(wǎng)絡中的其他對等節(jié)點:

# the address to other participating members of the network
peers = set()

# endpoint to add new peers to the network.
@app.route('/add_nodes', methods=['POST'])
def register_new_peers(): 
    nodes = request.get_json()
    if not nodes: 
        return "Invalid data", 400
    for node in nodes: 
        peers.add(node)

    return "Success", 201

您可能已經(jīng)認識到,在多節(jié)點方面存在一個問題。由于故意操縱或意外的原因,一些節(jié)點的鏈副本可能有所不同。在這種情況下,我們需要商定采用鏈的某個版本,以維持整個系統(tǒng)的完整性。我們需要達成共識。

一種簡單的共識算法可能是,在網(wǎng)絡中的不同參與者構(gòu)成的鏈出現(xiàn)分歧時,商定采用最長的有效鏈。選擇此方法的理由是,最長的鏈是對已完成的最多工作量的有效估算:

def consensus(): 
    """
    Our simple consensus algorithm.如果找到一個更長的有效鏈,則用它替換我們的鏈。
    """
    global blockchain

    longest_chain = None
    current_len = len(blockchain)

    for node in peers: 
        response = requests.get('http://{}/chain'.format(node))
        length = response.json()['length']
        chain = response.json()['chain']
        if length > current_len and blockchain.check_chain_validity(chain): 
            current_len = length
            longest_chain = chain

    if longest_chain: 
        blockchain = longest_chain
        return True

    return False

最后,我們需要開發(fā)一種方法,讓任何節(jié)點向網(wǎng)絡宣布它已經(jīng)挖到一個區(qū)塊,以便每個人都能更新他們的區(qū)塊鏈,并繼續(xù)挖掘其他事務。其他節(jié)點可以輕松地驗證工作量證明,并將它添加到各自的鏈中:

# endpoint to add a block mined by someone else to the node's chain.
@app.route('/add_block', methods=['POST'])
def validate_and_add_block(): 
    block_data = request.get_json()
    block = Block(block_data["index"], block_data["transactions"],
                  block_data["timestamp", block_data["previous_hash"]])

    proof = block_data['hash']
    added = blockchain.add_block(block, proof)

    if not added: 
        return "The block was discarded by the node", 400

    return "Block added to the chain", 201
    
    def announce_new_block(block): 
    for peer in peers: 
        url = "http://{}/add_block".format(peer)
        requests.post(url, data=json.dumps(block.__dict__, sort_keys=True))

announce_new_block 方法應在節(jié)點挖到每個區(qū)塊后調(diào)用,以便對等節(jié)點能將該區(qū)塊添加到自己的鏈中。

8

構(gòu)建應用程序

好了,后端都設置好了。您可以 在 GitHub 上查看到目前為止的代碼 。

現(xiàn)在,是時候創(chuàng)建應用程序的接口了。我們使用了 Jinja2 模板來呈現(xiàn)網(wǎng)頁和一些 CSS,讓頁面看起來美觀一些。

我們的應用程序需要連接到區(qū)塊鏈網(wǎng)絡中的某個節(jié)點,以便抓取數(shù)據(jù)和提交新數(shù)據(jù)。也可能存在多個節(jié)點:

import datetime
import json

import requests
from flask import render_template, redirect, request

from app import app

.
CONNECTED_NODE_ADDRESS = "http://127.0.0.1:8000"

posts = []

fetch_posts 函數(shù)從節(jié)點的 / chain 端點獲取數(shù)據(jù),解析該數(shù)據(jù)并將它們存儲在本地。

def fetch_posts(): 
    get_chain_address = "{}/chain".format(CONNECTED_NODE_ADDRESS)
    response = requests.get(get_chain_address)
    if response.status_code == 200: 
        content = []
        chain = json.loads(response.content)
        for block in chain["chain"]: 
            for tx in block["transactions"]: 
                tx["index"] = block["index"]
                tx["hash"] = block["previous_hash"]
                content.append(tx)

        global posts
        posts = sorted(content, key=lambda k: k['timestamp'],
                       reverse=True)

該應用程序有一個 HTML 表單,用于接受用戶輸入,然后向一個已連接的節(jié)點發(fā)出一個 POST 請求,以便將該事務添加到未確認事務池中。然后,通過網(wǎng)絡對該事務進行挖掘,最后在我們刷新網(wǎng)站后抓取該事務:

@app.route('/submit', methods=['POST'])
def submit_textarea(): 
    """
    Endpoint to create a new transaction via our application.
    """
    post_content = request.form["content"]
    author = request.form["author"]

    post_object = {
        'author': author,
        'content': post_content,
    }

    # Submit a transaction
    new_tx_address = "{}/new_transaction".format(CONNECTED_NODE_ADDRESS)

    requests.post(new_tx_address,
                  json=post_object,
                  headers={'Content-type': 'application/json'})

    return redirect('/')

9

運行應用程序

大功告成!可以 在 GitHub 上找到最終代碼 。

要運行該應用程序:

  1. 啟動一個區(qū)塊鏈節(jié)點服務器:
    python node_server.py
  2. 運行該應用程序:
    python run_app.py

您應該能在 http://localhost:5000 上看到正在運行的應用程序。

  1. 嘗試發(fā)布一些數(shù)據(jù),您會看到類似下圖的結(jié)果:

    使用 Python 從零開始開發(fā)區(qū)塊鏈應用程序

     
  2. 單擊 Request to mine 按鈕,您會看到類似下圖的結(jié)果:

    使用 Python 從零開始開發(fā)區(qū)塊鏈應用程序

     
  3. 單擊 Resync 按鈕,您會看到應用程序與鏈重新同步:

    使用 Python 從零開始開發(fā)區(qū)塊鏈應用程序

驗證事務

您可能注意到了應用程序中的一個缺陷:任何人都能更改任何名稱和發(fā)布任何內(nèi)容。解決此問題的一種方法是,使用 公私密鑰加密 來創(chuàng)建帳戶。每個新用戶都需要一個公鑰(類似于用戶名)和私鑰,才能在我們的應用程序中發(fā)布內(nèi)容。這些密鑰可以充當數(shù)字簽名。公鑰只能對使用相應私鑰加密的內(nèi)容進行解密。在將事務添加到任何區(qū)塊之前,會使用作者的公鑰對其進行驗證。這樣,我們就知道是誰寫的這條消息。

結(jié)束語

本教程介紹了公有區(qū)塊鏈的基礎知識。如果您一直在跟隨操作,那么您已經(jīng)從零開始實現(xiàn)了一個區(qū)塊鏈,并構(gòu)建了一個簡單應用程序來允許用戶在該區(qū)塊鏈上共享信息。

后續(xù)行動

您可以在云上創(chuàng)建多個節(jié)點,并完善您構(gòu)建的應用程序。您可以 將任何 Flask 應用程序部署到 IBM Cloud 。

此外,您還可以使用諸如 ngrok 之類的隧道服務為您的 localhost 服務器創(chuàng)建一個公有 URL,然后您就能與多臺機器進行交互。

這一領域還有許多值得探索的地方!您可以通過以下方式繼續(xù)增強您的區(qū)塊鏈技能:

  • 親自體驗新的 IBM Blockchain Platform Starter Plan(免費測試版),繼續(xù)探索區(qū)塊鏈技術。您可以快速建立一個區(qū)塊鏈預生產(chǎn)網(wǎng)絡,部署樣本應用程序,開發(fā)和部署客戶端應用程序。 入門 ! 
  • 訪問 developerWorks 上的 區(qū)塊鏈開發(fā)人員中心 ?梢栽谶@里獲得開發(fā)和部署業(yè)務區(qū)塊鏈解決方案的工具和教程,以及代碼和社區(qū)支持。 
  • 學習 面向開發(fā)人員的區(qū)塊鏈基礎課程 ,了解資產(chǎn)轉(zhuǎn)移的復雜細節(jié)。學完這門持續(xù) 2 小時的免費自學課程后,參加測驗,獲取一枚徽章,并開始為您的業(yè)務網(wǎng)絡規(guī)劃有用的區(qū)塊鏈應用程序。 
  • 繼續(xù)學習 IBM Blockchain 開發(fā)人員基礎課程 ,這門持續(xù) 6 小時的免費課程在“區(qū)塊鏈基礎知識”的基礎上進行了擴展,更詳細地介紹了區(qū)塊鏈業(yè)務網(wǎng)絡的組件和架構(gòu),以及構(gòu)建網(wǎng)絡和創(chuàng)建應用程序的經(jīng)驗。 
  • 查閱許多 區(qū)塊鏈 Code Pattern ,它們提供了解決復雜問題的路線圖,包括概述、架構(gòu)圖、流程、存儲庫指南和其他閱讀材料。

作者簡介

Satwik Kansal 是一位擁有區(qū)塊鏈技術和數(shù)據(jù)科學經(jīng)驗的軟件開發(fā)人員?梢栽 Twitter、 Linkedin 或 他的網(wǎng)站 上聯(lián)系他。

 

來自:http://www.ibm.com/developerworks/cn/cloud/library/cl-develop-blockchain-app-in-python/index.html?ca=drs-

 

標簽: 安全 代碼 電子商務 服務器 互聯(lián)網(wǎng) 腳本 網(wǎng)絡

版權(quán)申明:本站文章部分自網(wǎng)絡,如有侵權(quán),請聯(lián)系:west999com@outlook.com
特別注意:本站所有轉(zhuǎn)載文章言論不代表本站觀點!
本站所提供的圖片等素材,版權(quán)歸原作者所有,如需使用,請與原作者聯(lián)系。

上一篇:RxJS 緩存高級教程

下一篇:編寫高性能 Java 代碼的最佳實踐