编程语言
首页 > 编程语言> > Python区块链教程(二)

Python区块链教程(二)

作者:互联网

来源  https://zhuanlan.zhihu.com/p/142136802

 

 

区块链教程将详细介绍区块链背后的理论。区块链是数字货币比特币的基本构建块,此教程将讨论比特币的复杂性,全面解释区块链架构,并建立我们自己的区块链。

本教程将介绍如何构建上述系统,并在市场上推出自己的数字货币。整个区块链项目开发包括3个主要部分:客户(Client)、矿工(Miners)、区块链(Blockchain)。

2. 创建多交易

多个客户进行的交易在系统中排队; 矿工从此队列中提取交易并将其添加到区块中。 然后他们将开采该区块,获胜的矿工将拥有将该区块添加到区块链中的特权,从而为自己赚钱。

我们将在后续讨论区块链创建时描述此挖掘过程。 在编写多个交易代码之前,添加一个函数用来打印给定交易的内容。

2.1 展示交易

display_transaction函数接受交易类型的单参数。 接收到交易中的字典对象被复制到一个名为tsdict的临时变量中,并使用字典键打印对应的值。

def display_transaction(transaction):
    tsdict = transaction.to_dict()
    print("sender: " + tsdict['sender'])
    print('-' * 20)
    print("recipient: " + tsdict['recipient'])
    print('-' * 20)
    print("value: " + str(tsdict['value']))
    print('-' * 20)
    print("time: " + str(tsdict['time']))
    print('-' * 20)

下面我们定义一个交易队列存储交易对象。

2.2 交易队列

为了创建一个队列,我们声明一个名为transactions的全局列表变量:

transactions = []

我们简单地将每个新创建的交易添加到此队列。 注意:为简单起见,本教程中不实现队列管理逻辑。

2.3 创建多客户

我们将开始创建交易。 首先创建4个客户,他们为从他人那里获得各种服务或商品而互相汇款。

Dinesh = Client()
Ramesh = Client()
Seema = Client()
Vijay = Client()

至此,我们有4个客户,分别是Dinesh,Ramesh,Seema和Vijay。 假设每个客户钱包中都持有一些TPCoin可以用于交易。 这些客户的身份将通过这些对象的identity属性来指定。

2.4 创建第一个交易

现在执行第一个交易:

t1 = Transaction(Dinesh, Ramesh.identity, 5.0)

在这个交易中,Dinesh将5个TPCoins发送给Ramesh。 为了使交易成功,必须确保Dinesh钱包中有足够的钱来进行这次付款。 注意:我们需要一个初始(genesis)交易来启动系统中TPCoin的流通。

我们使用Dinesh的私钥签署此交易,并将其添加到交易队列中:

t1.sign_transaction()
transactions.append(t1)

Dinesh完成第一个交易后,我们将在不同客户间创建更多的交易。

2.5 添加更多交易

现在创建更多交易,每笔交易都会向对方转移一些TPCoins。 当有人花钱时,他不必检查钱包中是否有足够的余额。在发起交易时,矿工将验证每个交易发送方所拥有的余额。

余额不足时,矿工将此交易标记为无效,并且不会将其添加到该区块中。

以下代码将创建9个交易并将其添加到我们的队列中。

t2 = Transaction(Dinesh, Seema.identity, 6.0)
t2.sign_transaction()
transactions.append(t2)
t3 = Transaction(Ramesh, Vijay.identity, 2.0)
t3.sign_transaction()
transactions.append(t3)
t4 = Transaction(Seema, Ramesh.identity, 4.0)
t4.sign_transaction()
transactions.append(t4)
t5 = Transaction(Vijay, Seema.identity, 7.0)
t5.sign_transaction()
transactions.append(t5)
t6 = Transaction(Ramesh, Seema.identity, 3.0)
t6.sign_transaction()
transactions.append(t6)
t7 = Transaction(Seema, Dinesh.identity, 8.0)
t7.sign_transaction()
transactions.append(t7)
t8 = Transaction(Seema, Ramesh.identity, 1.0)
t8.sign_transaction()
transactions.append(t8)
t9 = Transaction(Vijay, Dinesh.identity, 5.0)
t9.sign_transaction()
transactions.append(t9)
t10 = Transaction(Vijay, Ramesh.identity, 3.0)
t10.sign_transaction()
transactions.append(t10)

2.6 查看交易

作为区块链管理者,你可能喜欢定期查看交易队列的内容。 为此,可以使用display_transaction函数。 要将所有交易转储到队列中,只需迭代交易列表;然后为每个交易调用display_transaction函数:

for transaction in transactions:
    display_transaction(transaction)
    print ('-' * 20)

由于交易会定期添加到区块中,因此你通常只希望查看尚未开采的交易清单,需要创建适当的for循环来遍历尚未挖掘的交易。

到目前为止,你已经学习了如何创建客户,允许客户之间进行交易,维护待挖掘的未完成的交易队列。

3. Block类

一个区块由不同数量的交易组成。 为简单起见,假设该块由固定数量的交易组成,示例中为3个交易。 由于该块需要存储3个交易的列表,我们声明一个实例变量authenticated_transactions

self.verified_transactions = []

我们将此变量命名为verify_transactions,表示只有经过验证的有效交易才会被添加到该区块中。 每个块还保留前一个块的哈希值,因此块链变得不可变。

为了存储先前的哈希,声明一个实例变量:

self.previous_block_hash = ""

最后,声明一个变量Nonce,用于存储矿工在采矿过程中创建的随机数。

self.Nonce = ""

Block类的定义为:

class Block():
    def __init__(self):
        self.verified_transactions = []
        self.previous_block_hash = ""
        self.Nonce = ""

由于每个块需要前一个块的哈希值,声明一个last_block_hash的全局变量:

last_block_hash = ""

3.1 创建初始区块

下面在区块链中创建第一个块。假设TPCoins的发起者最初向一个已知客户Dinesh发送500个TPCoins。 为此创建一个Dinesh实例:

Dinesh = Client()

然后我们创建初始(genesis)交易,并向Dinesh的公共地址发送500 TPCoins。

t0 = Transaction("Genesis", Dinesh.identity, 500.0)

创建一个Block类的实例:

block0 = Block()

previous_block_hashonce实例变量初始化为None,因为这是存储在区块链中的第一笔交易。

block0.previous_block_hash = None
Nonce = None

t0交易添加到块中的verified_transactions列表中。

block0.verified_transactions.append(t0)

此时,该块完成初始化,可以添加到我们的区块链中。 我们将为此创建区块链。 在将区块添加到区块链之前,我们将对区块进行哈希处理并将其值存储在之前声明的last_block_hash变量中。 该值将由下一个矿工在其区块中使用。

通过如下代码哈希区块并存储其值:

digest = hash(block0)
last_block_hash = digest

3.2 创建区块链

区块链包含彼此链接的区块列表。 为了存储整个列表,创建一个列表变量TPCoins

TPCoins = []

dump_blockchain方法用于转储整个区块链的内容。 首先打印区块链的长度,以便确定当前区块链中存在多少个区块。

def dump_blockchain(self):
    print("Number of blocks in the chain: " + str(len(self)))

随着时间的推移,区块链中的块数可能很多。 当打印区块链的内容时,需要确定要检查的范围。 示例中打印了整个区块链,因为在当前示例不会添加太多块。为了遍历整个链,设置了一个for循环:

for x in range (len(TPCoins)):
    block_temp = TPCoins[x]
    print ("block # " + str(x))

每个引用的块都复制到临时变量block_temp中。

将块号作为每个块的标题。 注意:数字将从零开始,第1个块是编号为1的初始块。

在每个块中,已经将3个交易(初始块除外)的列表存储在变量verified_transactions中。 在for循环中迭代此列表,调用display_transaction显示交易明细。

for transaction in block_temp.verified_transactions:
    display_transaction (transaction)

dump_blockchain方法全部代码为:

def dump_blockchain(self):
    print("Number of blocks in the chain: " + str(len(self)))
    for x in range(len(TPCoins)):
        block_temp = TPCoins[x]
        print("block # " + str(x))
        for transaction in block_temp.verified_transactions:
            display_transaction(transaction)
            print('-' * 10)
        print('=' * 40)

现在已经创建了一个用于存储块的区块链,一个任务是创建块并将其添加到区块链中。 为此,将添加之前已经创建的初始块。

3.3 添加初始块

向区块链添加一个块涉及到将创建的块追加到TPCoins列表中。

TPCoins.append(block0)

注意:与系统中其余的块不同,初始块仅包含一个由TPCoins系统的发起者发起的交易。通过调用函数dump_blockchain转储区块链的内容:

dump_blockchain(TPCoins)

至此,区块链系统就可以使用了。我们将通过为感兴趣的客户提供挖掘功能,使他们成为矿工。

标签:教程,transaction,TPCoins,transactions,Python,创建,区块,交易
来源: https://www.cnblogs.com/wodepingzi/p/14879508.html