$ python noobchain.py Private and public keys: -----BEGIN EC PRIVATE KEY----- MF8CAQEEGIAnlP0QuZpVjYN8cF1g0VK+QIDhpySdUqAKBggqhkjOPQMBAaE0AzIA BF5wfHb88KlyjGkVeSSnqge/4Q4vxDIlHkwu5BvrszPLaEHs00DVwFEFdmjp5wkv vw== -----END EC PRIVATE KEY-----
-----BEGIN PUBLIC KEY----- MEkwEwYHKoZIzj0CAQYIKoZIzj0DAQEDMgAEXnB8dvzwqXKMaRV5JKeqB7/hDi/E MiUeTC7kG+uzM8toQezTQNXAUQV2aOnnCS+/ -----END PUBLIC KEY-----
defprocessTransaction(self): if self.verifySignature() == False: print"#Transaction Signature failed to verify" returnFalse # 收集交易input(确保他们是未花费的) for i in self.inputs: i.UTXO = config.UTXOs[i.transactionOutputId] # 输入的和不能小于最小交易额 if self.getInputsValue() < config.minimumTransaction: print"#Transaction Inputs too small: " + self.getInputsValue() returnFalse # 产生交易输出 leftOver = self.getInputsValue() - self.value self.transactionId = self.calculateHash() # 发送value给reciptient self.outputs.append(TransactionOutput(self.reciepient, self.value, self.transactionId)) # 发送找零给sender self.outputs.append(TransactionOutput(self.sender, leftOver, self.transactionId)) for o in self.outputs: config.UTXOs[o.id] = o # 从UTXO删除交易inputs当做花费 for i in self.inputs: if i.UTXO == None: continue del config.UTXOs[i.UTXO.id] returnTrue
# 返回输入值的和 defgetInputsValue(self): total = 0 for i in self.inputs: if i.UTXO == None: continue total += i.UTXO.value return total
# 返回输出值的和 defgetOutputsValue(self): total = 0 for o in self.outputs: total += o.value return total
import config from transaction import Transaction, TransactionInput
classWallet: def__init__(self): ... # 计算自己的余额 defgetBalance(self): total = 0 for item in config.UTXOs.items(): UTXO = item[1] if UTXO.isMine(self.publicKey): # 将全局UTXOs中是自己的output添加到自己钱包的UTXOs self.UTXOs[UTXO.id] = UTXO total += UTXO.value return total # 发送金额给其他人 defsendFunds(self, _recipient, value): if self.getBalance() < value: print"#Not Enough funds to send transaction. Transaction Discarded." returnNone inputs = [] total = 0 # 需要引用到的output for item in self.UTXOs.items(): UTXO = item[1] total += UTXO.value inputs.append(TransactionInput(UTXO.id)) if total > value: break # 创建交易 newTransaction = Transaction(self.publicKey, _recipient, value, inputs) newTransaction.generateSignature(self.privateKey) # 删除引用过的output for i in inputs: del self.UTXOs[i.transactionOutputId] return newTransaction
# testing block1 = Block(genesis.hash) print"walletA's balance is: %f" % walletA.getBalance() print"walletA is attempting to send funds (40) to walletB..." block1.addTransaction(walletA.sendFunds(walletB.publicKey, 40)) block1.mineBlock(config.difficulty) config.blockchain.append(block1) print"walletA's balance is: %f" % walletA.getBalance() print"walletB's balance is: %f" % walletB.getBalance()
block2 = Block(block1.hash) print"walletA is attempting to send more funds (1000) than it has..." block2.addTransaction(walletA.sendFunds(walletB.publicKey, 1000)) block2.mineBlock(config.difficulty) config.blockchain.append(block2) print"walletA's balance is: %f" % walletA.getBalance() print"walletB's balance is: %f" % walletB.getBalance()
block3 = Block(block2.hash) print"walletB is attempting to send funds (20) to walletA..." block3.addTransaction(walletB.sendFunds(walletA.publicKey, 20)) print"walletA's balance is: %f" % walletA.getBalance() print"walletB's balance is: %f" % walletB.getBalance()
运行结果:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
$ python noobchain.py Creating and Mining Genesis block... Transaction Successfully added to Block Block Mined!!! : 000ecc366d3c553e131693c972dc77b7f2bb7c8156aa7125bb10c9e4052d8874 walletA's balance is: 100.000000 walletA is attempting to send funds (40) to walletB... Transaction Successfully added to Block Block Mined!!! : 0005af73ad51e2a0fa80444bdd284342c102dc202c9139889f62a3f989d8343d walletA's balance is: 60.000000 walletB's balance is: 40.000000 walletA is attempting to send more funds (1000) than it has... #Not Enough funds to send transaction. Transaction Discarded. Block Mined!!! : 00035606ee8cd61c0afb21c496193fdfc67a17172befd6cae90d7a9410a27d5f walletA's balance is: 60.000000 walletB's balance is: 40.000000 walletB is attempting to send funds (20) to walletA... Transaction Successfully added to Block walletA's balance is: 80.000000 walletB's balance is: 20.000000
defisChainValid(): hashTarget = '0' * config.difficulty tempUTXOs = {} tempUTXOs[genesisTransaction.outputs[0].id] = genesisTransaction.outputs[0] for i inrange(1, len(config.blockchain)): curblock = config.blockchain[i] preblock = config.blockchain[i-1] if curblock.hash != curblock.calculateHash(): print'Current Hashes not equal' returnFalse if preblock.hash != curblock.previousHash: print'Previous Hashes not equal' returnFalse if curblock.hash[:config.difficulty] != hashTarget: print'#This block hasnt been mined' returnFalse for t inrange(len(curblock.transactions)): curTransaction = curblock.transactions[t] ifnot curTransaction.verifySignature(): print'#Signature on Transaction %d is Invalid' % t returnFalse if curTransaction.getInputsValue() != curTransaction.getOutputsValue(): print'#Inputs are not equal to outputs on Transaction %d' % t returnFalse for i in curTransaction.inputs: tempOutput = tempUTXOs[i.transactionOutputId] if tempOutput == None: print'#Referenced input on Transaction %d is Missing' % t returnFalse if i.UTXO.value != tempOutput.value: print'#Referenced input Transaction %d value is Invalid' % t returnFalse del tempUTXOs[i.transactionOutputId] for o in curTransaction.outputs: tempUTXOs[o.id] = o if curTransaction.outputs[0].reciepient != curTransaction.reciepient: print'#Transaction %d output reciepient is not who it should be' % t returnFalse if curTransaction.outputs[1].reciepient != curTransaction.sender: print'#Transaction %d output change is not sender' % t returnFalse print'Blockchain is valid' returnTrue