搜尋
首頁後端開發Python教學使用Python 建立自己的區塊鏈

使用Python 建立自己的區塊鏈

Sep 01, 2020 pm 05:46 PM
python區塊鏈

使用Python 建立自己的區塊鏈

【相關學習推薦:python教學

你會和我一樣,對加密數位貨幣底層的區塊鏈技術非常有興趣,特別想了解他們的運作機制。

但是學習區塊鏈技術並非一帆風順,我看多了大量的影片教學還有各種課程,最終的感覺就是真正可用的實戰課程太少。

我喜歡在實作中學習,尤其喜歡以程式碼為基礎去了解整個工作機制。如果你我一樣喜歡這種學習方式,當你學完本教學時,你將會知道區塊鏈技術是如何運作的。

寫在開始之前

記住,區塊鍊是一個 不可變的、有序的 被稱為區塊的記錄鏈。它們可以包含交易、文件或任何您喜歡的資料。但重要的是,他們用哈希 一起被連結在一起。

如果你不熟悉哈希,這裡有一個解釋。

該指南的目的是什麼?

你可以舒適地閱讀和編寫基礎的Python,因為我們將透過HTTP 與區塊鏈進行討論,所以你也要了解HTTP 的工作原理。

我需要準備什麼?  

確定安裝了Python 3.6 (還有pip) ,你還需要安裝Flask、 Requests 函式庫:

    pip install Flask==0.12.2 requests==2.18.4

對了, 你還需要一個支援HTTP的客戶端, 例如Postman 或cURL,其他也可以。

原始碼在哪裡?
可以點擊這裡

Step 1: 創建一個區塊鏈

打開你最喜歡的文字編輯器或IDE, 我個人比較喜歡PyCharm. 新建一個名為blockchain.py的檔案。我們將只用這一個文件就可以。但是如果你還是不太清楚, 你也可以參考源碼.

描述區塊鏈

我們要創建一個Blockchain 類,他的構造函數創建了一個初始化的空列表(要儲存我們的區塊鏈),並且另一個儲存交易。以下是我們這個類別的實例:

blockchain.py

class Blockchain(object):
    def __init__(self):
        self.chain = []
        self.current_transactions = []

    def new_block(self):
        # Creates a new Block and adds it to the chain
        pass

    def new_transaction(self):
        # Adds a new transaction to the list of transactions
        pass

    @staticmethod
    def hash(block):
        # Hashes a Block
        pass

    @property
    def last_block(self):
        # Returns the last Block in the chain
        pass

我們的Blockchain 類別負責管理鍊式數據,它會儲存交易並且還有添加新的區塊到鍊式數據的Method。讓我們開始擴充更多Method。

區塊是什麼樣的?

每個區塊都有一個 索引#,一個時間戳記(Unix時間戳),一個交易清單, 一個校驗(稍後詳述) 和前一個區塊的雜湊

下面是一個Block的範例:

blockchain.py

block = {
    'index': 1,
    'timestamp': 1506057125.900785,
    'transactions': [
        {
            'sender': "8527147fe1f5426f9dd545de4b27ee00",
            'recipient': "a77f5cdfa2934df3954a5c7c7da5df1f",
            'amount': 5,
        }
    ],
    'proof': 324984774000,
    'previous_hash': "2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824"
}

在這一點上,一個區塊鏈的概念應該是明顯的- 每個新區塊都包含在其內的前一個區塊的雜湊 。這是至關重要的,因為這是區塊鏈 不可改變的原因:如果攻擊者損壞區塊鏈 中較早的區塊,則所有後續區塊將包含不正確的哈希值。

這有道理嗎?如果你還沒想通,花點時間仔細思考 - 這是區塊鏈背後的核心概念。

新增交易到區塊

我們將需要一個添加交易到區塊的方式。我們的 new_transaction() 方法的責任就是這個, 而它非常的簡單:

blockchain.py

class Blockchain(object):
    ...

    def new_transaction(self, sender, recipient, amount):
        """
        Creates a new transaction to go into the next mined Block
        :param sender: <str> Address of the Sender
        :param recipient: <str> Address of the Recipient
        :param amount: <int> Amount
        :return: <int> The index of the Block that will hold this transaction
        """

        self.current_transactions.append({
            'sender': sender,
            'recipient': recipient,
            'amount': amount,
        })

        return self.last_block['index'] + 1</int></int></str></str>

 new_transaction( ) 方法添加了交易到列表,它返回了交易將被添加到的區塊的索引---講開採下一個這對稍後對提交交易的用戶有用。

創建新的區塊

當我們的 Blockchain  被實例化後,我們需要將創世 區塊(一個沒有前導區區塊的區塊)加進去進去。我們還需要在我們的起源區塊中添加一個 證明,這是挖礦的結果(或工作證明)。我們稍後會詳細討論挖礦。

除了在建構子中建立創世 區塊外,我們還會補全 new_block() 、  new_transaction()  和 hash() 函數:

blockchain.py

import hashlib
import json
from time import time

class Blockchain(object):
    def __init__(self):
        self.current_transactions = []
        self.chain = []

        # 创建创世区块
        self.new_block(previous_hash=1, proof=100)

    def new_block(self, proof, previous_hash=None):
        """
        创建一个新的区块到区块链中
        :param proof: <int> 由工作证明算法生成的证明
        :param previous_hash: (Optional) <str> 前一个区块的 hash 值
        :return: <dict> 新区块
        """

        block = {
            'index': len(self.chain) + 1,
            'timestamp': time(),
            'transactions': self.current_transactions,
            'proof': proof,
            'previous_hash': previous_hash or self.hash(self.chain[-1]),
        }

        # 重置当前交易记录
        self.current_transactions = []

        self.chain.append(block)
        return block

    def new_transaction(self, sender, recipient, amount):
        """
        创建一笔新的交易到下一个被挖掘的区块中
        :param sender: <str> 发送人的地址
        :param recipient: <str> 接收人的地址
        :param amount: <int> 金额
        :return: <int> 持有本次交易的区块索引
        """
        self.current_transactions.append({
            'sender': sender,
            'recipient': recipient,
            'amount': amount,
        })

        return self.last_block['index'] + 1

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

    @staticmethod
    def hash(block):
        """
        给一个区块生成 SHA-256 值
        :param block: <dict> Block
        :return: <str>
        """

        # 我们必须确保这个字典(区块)是经过排序的,否则我们将会得到不一致的散列
        block_string = json.dumps(block, sort_keys=True).encode()
        return hashlib.sha256(block_string).hexdigest()</str></dict></int></int></str></str></dict></str></int>

上面的程式碼應該是直白的--- 為了讓程式碼清晰,我會加了一些註釋和文件說明。我們差不多完成了我們的區塊鏈。但在這個時候你一定很疑惑新的塊是怎麼被創造、鍛造或挖掘的。

工作量證明演算法

使用工作量證明(PoW)演算法,來證明是如何在區塊鏈上創建或挖掘新的區塊。 PoW 的目標是計算出一個符合特定條件的數字,這個數字對於所有人而言必須在計算上非常困難,但易於驗證。這是工作證明背後的核心思想。

我們將看到一個簡單的例子幫助你理解:

假设一个整数 x 乘以另一个整数 y 的积的 Hash 值必须以 0 结尾,即 hash(x * y) = ac23dc...0。设 x = 5,求y

用 Python 实现:

from hashlib import sha256
x = 5
y = 0  # We don't know what y should be yet...
while sha256(f'{x*y}'.encode()).hexdigest()[-1] != "0":
    y += 1
print(f'The solution is y = {y}')

结果是:y = 21。因为,生成的 Hash 值结尾必须为 0

hash(5 * 21) = 1253e9373e...5e3600155e860

在比特币中,工作量证明算法被称为 Hashcash ,它和上面的问题很相似,只不过计算难度非常大。这就是矿工们为了争夺创建区块的权利而争相计算的问题。 通常,计算难度与目标字符串需要满足的特定字符的数量成正比,矿工算出结果后,就会获得一定数量的比特币奖励(通过交易)。

验证结果,当然非常容易。

实现工作量证明

让我们来实现一个相似 PoW 算法。规则类似上面的例子:

找到一个数字 P ,使得它与前一个区块的 Proof 拼接成的字符串的 Hash 值以 4 个零开头。

blockchain.py

import hashlib
import json

from time import time
from uuid import uuid4

class Blockchain(object):
    ...

    def proof_of_work(self, last_proof):
        """
        Simple Proof of Work Algorithm:
         - Find a number p' such that hash(pp') contains leading 4 zeroes, where p is the previous p'
         - p is the previous proof, and p' is the new proof
        :param last_proof: <int>
        :return: <int>
        """

        proof = 0
        while self.valid_proof(last_proof, proof) is False:
            proof += 1

        return proof

    @staticmethod
    def valid_proof(last_proof, proof):
        """
        Validates the Proof: Does hash(last_proof, proof) contain 4 leading zeroes?
        :param last_proof: <int> Previous Proof
        :param proof: <int> Current Proof
        :return: <bool> True if correct, False if not.
        """

        guess = f'{last_proof}{proof}'.encode()
        guess_hash = hashlib.sha256(guess).hexdigest()
        return guess_hash[:4] == "0000"</bool></int></int></int></int>

衡量算法复杂度的办法是修改零开头的个数。使用 4 个来用于演示,你会发现多一个零都会大大增加计算出结果所需的时间。

现在 Blockchain 类基本已经完成了,接下来使用 HTTP Requests 来进行交互。

Step 2: Blockchain 作为 API 接口

我们将使用 Python Flask 框架,这是一个轻量 Web 应用框架,它方便将网络请求映射到 Python 函数,现在我们来让 Blockchain 运行在基于 Flask web 上。

我们将创建三个接口:

  • /transactions/new 创建一个交易并添加到区块
  • /mine 告诉服务器去挖掘新的区块
  • /chain 返回整个区块链

创建节点

我们的 Flask 服务器 将扮演区块链网络中的一个节点。我们先添加一些框架代码:

blockchain.py

import hashlib
import json
from textwrap import dedent
from time import time
from uuid import uuid4

from flask import Flask

class Blockchain(object):
    ...

# Instantiate our Node(实例化我们的节点)
app = Flask(__name__)

# Generate a globally unique address for this node(为这个节点生成一个全球唯一的地址)
node_identifier = str(uuid4()).replace('-', '')

# Instantiate the Blockchain(实例化 Blockchain类)
blockchain = Blockchain()

@app.route('/mine', methods=['GET'])
def mine():
    return "We'll mine a new Block"

@app.route('/transactions/new', methods=['POST'])
def new_transaction():
    return "We'll add a new transaction"

@app.route('/chain', methods=['GET'])
def full_chain():
    response = {
        'chain': blockchain.chain,
        'length': len(blockchain.chain),
    }
    return jsonify(response), 200

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000)

简单的说明一下以上代码:

  • 第 15 行:实例化节点。阅读更多关于 Flask 内容。
  • 第 18 行:为节点创建一个随机的名称。.
  • 第 21 行:实例化 Blockchain 类。
  • 第 24--26 行:创建 /mine 接口,GET 方式请求。 
  • 第 28--30 行:创建 /transactions/new 接口,POST 方式请求,可以给接口发送交易数据。
  • 第 32--38 行:创建 /chain 接口,返回整个区块链。
  • 第 40--41 行:服务器运行端口 5000 。

发送交易

发送到节点的交易数据结构如下:

{
 "sender": "my address",
 "recipient": "someone else's address",
 "amount": 5
}

因为我们已经有了添加交易的方法,所以基于接口来添加交易就很简单了。让我们为添加事务写函数:

blockchain.py

import hashlib
import json
from textwrap import dedent
from time import time
from uuid import uuid4

from flask import Flask, jsonify, request

...

@app.route('/transactions/new', methods=['POST'])
def new_transaction():
    values = request.get_json()

    # Check that the required fields are in the POST'ed data
    required = ['sender', 'recipient', 'amount']
    if not all(k in values for k in required):
        return 'Missing values', 400

    # Create a new Transaction
    index = blockchain.new_transaction(values['sender'], values['recipient'], values['amount'])

    response = {'message': f'Transaction will be added to Block {index}'}
    return jsonify(response), 201

挖矿

挖矿正是神奇所在,它很简单,做了一下三件事:

  1. 计算工作量证明 PoW
  2. 通过新增一个交易授予矿工(自己)一个币
  3. 构造新区块并将其添加到链中

blockchain.py

import hashlib
import json

from time import time
from uuid import uuid4

from flask import Flask, jsonify, request

...

@app.route('/mine', methods=['GET'])
def mine():
    # We run the proof of work algorithm to get the next proof...
    last_block = blockchain.last_block
    last_proof = last_block['proof']
    proof = blockchain.proof_of_work(last_proof)

    # We must receive a reward for finding the proof.
    # The sender is "0" to signify that this node has mined a new coin.
    blockchain.new_transaction(
        sender="0",
        recipient=node_identifier,
        amount=1,
    )

    # Forge the new Block by adding it to the chain
    previous_hash = blockchain.hash(last_block)
    block = blockchain.new_block(proof, previous_hash)

    response = {
        'message': "New Block Forged",
        'index': block['index'],
        'transactions': block['transactions'],
        'proof': block['proof'],
        'previous_hash': block['previous_hash'],
    }
    return jsonify(response), 200

注意交易的接收者是我们自己的服务器节点,我们做的大部分工作都只是围绕 Blockchain 类方法进行交互。到此,我们的区块链就算完成了,我们来实际运行下。

Step 3: 运行区块链

你可以使用 cURL 或 Postman 去和 API 进行交互

启动 Server:

$ python blockchain.py
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)

让我们通过请求 http://localhost:5000/mine ( GET )来进行挖矿:

使用Python 建立自己的區塊鏈

用 Postman 发起一个 GET 请求.

创建一个交易请求,请求 http://localhost:5000/transactions/new (POST),如图

使用Python 建立自己的區塊鏈

如果不是使用 Postman,则用一下的 cURL 语句也是一样的:

$ curl -X POST -H "Content-Type: application/json" -d '{
 "sender": "d4ee26eee15148ee92c6cd394edd974e",
 "recipient": "someone-other-address",
 "amount": 5
}' "http://localhost:5000/transactions/new"

在挖了两次矿之后,就有 3 个块了,通过请求 http://localhost:5000/chain 可以得到所有的块信息

{
  "chain": [
    {
      "index": 1,
      "previous_hash": 1,
      "proof": 100,
      "timestamp": 1506280650.770839,
      "transactions": []
    },
    {
      "index": 2,
      "previous_hash": "c099bc...bfb7",
      "proof": 35293,
      "timestamp": 1506280664.717925,
      "transactions": [
        {
          "amount": 1,
          "recipient": "8bbcb347e0634905b0cac7955bae152b",
          "sender": "0"
        }
      ]
    },
    {
      "index": 3,
      "previous_hash": "eff91a...10f2",
      "proof": 35089,
      "timestamp": 1506280666.1086972,
      "transactions": [
        {
          "amount": 1,
          "recipient": "8bbcb347e0634905b0cac7955bae152b",
          "sender": "0"
        }
      ]
    }
  ],
  "length": 3
}

Step 4: 一致性(共识)

我们已经有了一个基本的区块链可以接受交易和挖矿。但是区块链系统应该是分布式的。既然是分布式的,那么我们究竟拿什么保证所有节点有同样的链呢?这就是一致性问题,我们要想在网络上有多个节点,就必须实现一个一致性的算法。

注册节点

在实现一致性算法之前,我们需要找到一种方式让一个节点知道它相邻的节点。每个节点都需要保存一份包含网络中其它节点的记录。因此让我们新增几个接口:

  1. /nodes/register 接收 URL 形式的新节点列表.
  2. /nodes/resolve 执行一致性算法,解决任何冲突,确保节点拥有正确的链.

我们修改下 Blockchain 的 init 函数并提供一个注册节点方法:

blockchain.py

...
from urllib.parse import urlparse
...

class Blockchain(object):
    def __init__(self):
        ...
        self.nodes = set()
        ...

    def register_node(self, address):
        """
        Add a new node to the list of nodes
        :param address: <str> Address of node. Eg. 'http://192.168.0.5:5000'
        :return: None
        """

        parsed_url = urlparse(address)
        self.nodes.add(parsed_url.netloc)</str>

我们用 set 来储存节点,这是一种避免重复添加节点的简单方法.

实现共识算法

就像先前讲的那样,当一个节点与另一个节点有不同的链时,就会产生冲突。 为了解决这个问题,我们将制定最长的有效链条是最权威的规则。换句话说就是:在这个网络里最长的链就是最权威的。 我们将使用这个算法,在网络中的节点之间达成共识。

blockchain.py

...
import requests

class Blockchain(object)
    ...

    def valid_chain(self, chain):
        """
        Determine if a given blockchain is valid
        :param chain: <list> A blockchain
        :return: <bool> True if valid, False if not
        """

        last_block = chain[0]
        current_index = 1

        while current_index  True if our chain was replaced, False if not
        """

        neighbours = self.nodes
        new_chain = None

        # We're only looking for chains longer than ours
        max_length = len(self.chain)

        # Grab and verify the chains from all the nodes in our network
        for node in neighbours:
            response = requests.get(f'http://{node}/chain')

            if response.status_code == 200:
                length = response.json()['length']
                chain = response.json()['chain']

                # Check if the length is longer and the chain is valid
                if length > max_length and self.valid_chain(chain):
                    max_length = length
                    new_chain = chain

        # Replace our chain if we discovered a new, valid chain longer than ours
        if new_chain:
            self.chain = new_chain
            return True

        return False</bool></list>

第一个方法 valid_chain() 负责检查一个链是否有效,方法是遍历每个块并验证散列和证明。

resolve_conflicts() 是一个遍历我们所有邻居节点的方法,下载它们的链并使用上面的方法验证它们。 如果找到一个长度大于我们的有效链条,我们就取代我们的链条。

我们将两个端点注册到我们的API中,一个用于添加相邻节点,另一个用于解决冲突:

blockchain.py

@app.route('/nodes/register', methods=['POST'])
def register_nodes():
    values = request.get_json()

    nodes = values.get('nodes')
    if nodes is None:
        return "Error: Please supply a valid list of nodes", 400

    for node in nodes:
        blockchain.register_node(node)

    response = {
        'message': 'New nodes have been added',
        'total_nodes': list(blockchain.nodes),
    }
    return jsonify(response), 201

@app.route('/nodes/resolve', methods=['GET'])
def consensus():
    replaced = blockchain.resolve_conflicts()

    if replaced:
        response = {
            'message': 'Our chain was replaced',
            'new_chain': blockchain.chain
        }
    else:
        response = {
            'message': 'Our chain is authoritative',
            'chain': blockchain.chain
        }

    return jsonify(response), 200

在这一点上,如果你喜欢,你可以使用一台不同的机器,并在你的网络上启动不同的节点。 或者使用同一台机器上的不同端口启动进程。 我在我的机器上,不同的端口上创建了另一个节点,并将其注册到当前节点。 因此,我有两个节点:http://localhost:5000http://localhost:5001。 注册一个新节点:

使用Python 建立自己的區塊鏈

然后我在节点 2 上挖掘了一些新的块,以确保链条更长。 之后,我在节点1上调用 GET /nodes/resolve,其中链由一致性算法取代:

使用Python 建立自己的區塊鏈

这是一个包,去找一些朋友一起,以帮助测试你的区块链。

我希望本文能激励你创造更多新东西。我之所以对数字货币入迷,是因为我相信区块链会很快改变我们看待事物的方式,包括经济、政府、档案管理等。

更新:我计划在接下来的第2部分中继续讨论区块链交易验证机制,并讨论一些可以让区块链进行生产的方法。

相关推荐:编程视频课程

以上是使用Python 建立自己的區塊鏈的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文轉載於:learnku。如有侵權,請聯絡admin@php.cn刪除
Python:探索其主要應用程序Python:探索其主要應用程序Apr 10, 2025 am 09:41 AM

Python在web開發、數據科學、機器學習、自動化和腳本編寫等領域有廣泛應用。 1)在web開發中,Django和Flask框架簡化了開發過程。 2)數據科學和機器學習領域,NumPy、Pandas、Scikit-learn和TensorFlow庫提供了強大支持。 3)自動化和腳本編寫方面,Python適用於自動化測試和系統管理等任務。

您可以在2小時內學到多少python?您可以在2小時內學到多少python?Apr 09, 2025 pm 04:33 PM

兩小時內可以學到Python的基礎知識。 1.學習變量和數據類型,2.掌握控制結構如if語句和循環,3.了解函數的定義和使用。這些將幫助你開始編寫簡單的Python程序。

如何在10小時內通過項目和問題驅動的方式教計算機小白編程基礎?如何在10小時內通過項目和問題驅動的方式教計算機小白編程基礎?Apr 02, 2025 am 07:18 AM

如何在10小時內教計算機小白編程基礎?如果你只有10個小時來教計算機小白一些編程知識,你會選擇教些什麼�...

如何在使用 Fiddler Everywhere 進行中間人讀取時避免被瀏覽器檢測到?如何在使用 Fiddler Everywhere 進行中間人讀取時避免被瀏覽器檢測到?Apr 02, 2025 am 07:15 AM

使用FiddlerEverywhere進行中間人讀取時如何避免被檢測到當你使用FiddlerEverywhere...

Python 3.6加載Pickle文件報錯"__builtin__"模塊未找到怎麼辦?Python 3.6加載Pickle文件報錯"__builtin__"模塊未找到怎麼辦?Apr 02, 2025 am 07:12 AM

Python3.6環境下加載Pickle文件報錯:ModuleNotFoundError:Nomodulenamed...

如何提高jieba分詞在景區評論分析中的準確性?如何提高jieba分詞在景區評論分析中的準確性?Apr 02, 2025 am 07:09 AM

如何解決jieba分詞在景區評論分析中的問題?當我們在進行景區評論分析時,往往會使用jieba分詞工具來處理文�...

如何使用正則表達式匹配到第一個閉合標籤就停止?如何使用正則表達式匹配到第一個閉合標籤就停止?Apr 02, 2025 am 07:06 AM

如何使用正則表達式匹配到第一個閉合標籤就停止?在處理HTML或其他標記語言時,常常需要使用正則表達式來�...

如何繞過Investing.com的反爬蟲機制獲取新聞數據?如何繞過Investing.com的反爬蟲機制獲取新聞數據?Apr 02, 2025 am 07:03 AM

攻克Investing.com的反爬蟲策略許多人嘗試爬取Investing.com(https://cn.investing.com/news/latest-news)的新聞數據時,常常�...

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
3 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
3 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您聽不到任何人,如何修復音頻
3 週前By尊渡假赌尊渡假赌尊渡假赌
WWE 2K25:如何解鎖Myrise中的所有內容
3 週前By尊渡假赌尊渡假赌尊渡假赌

熱工具

mPDF

mPDF

mPDF是一個PHP庫,可以從UTF-8編碼的HTML產生PDF檔案。原作者Ian Back編寫mPDF以從他的網站上「即時」輸出PDF文件,並處理不同的語言。與原始腳本如HTML2FPDF相比,它的速度較慢,並且在使用Unicode字體時產生的檔案較大,但支援CSS樣式等,並進行了大量增強。支援幾乎所有語言,包括RTL(阿拉伯語和希伯來語)和CJK(中日韓)。支援嵌套的區塊級元素(如P、DIV),

SublimeText3 Linux新版

SublimeText3 Linux新版

SublimeText3 Linux最新版

MantisBT

MantisBT

Mantis是一個易於部署的基於Web的缺陷追蹤工具,用於幫助產品缺陷追蹤。它需要PHP、MySQL和一個Web伺服器。請查看我們的演示和託管服務。

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

Safe Exam Browser

Safe Exam Browser

Safe Exam Browser是一個安全的瀏覽器環境,安全地進行線上考試。該軟體將任何電腦變成一個安全的工作站。它控制對任何實用工具的訪問,並防止學生使用未經授權的資源。