def isValidTx(self, tx: Transaction) -> bool: inputSum = decimal.Decimal() pool = copy.deepcopy(self._pool) for (index, inp) in enumerate(tx.inputs): utxo = UTXO(inp.prevTxHash, inp.outputIndex) if not pool.contains(utxo): return False output = pool.getTxOutput(utxo) pubKey = output.address message = tx.getRawDataToSign(index) if not Crypto.verifySignature(pubKey, message, inp.signature): return False inputSum += output.value pool.removeUTXO(utxo) outputSum = decimal.Decimal() for out in tx.outputs: if out.value < 0: return False outputSum += out.value return inputSum >= outputSum
def testTransaction(self): tx = Transaction() tx.addInput(b'genesis', 0) assert tx.numInputs() == 1 opGenesis = Transaction.Output(5, genesisPublicKey) tx.addOutput(opGenesis.value, opGenesis.address) tx.addOutput(5, alicePublicKey) tx.addOutput(10, bobPublicKey) assert tx.numOutputs() == 3 tx.removeInput(0) assert tx.numInputs() == 0 tx.addInput(b'genesis', 0) signature0 = sign(genesisPrivateKey, tx, 0) tx.addSignature(signature0, 0) tx.finalize() print(tx.hash) print(hash(tx.getInput(0))) print(tx.getInput(0).to_dict()) print(hash(tx.getOutput(0))) print(tx.getOutput(0).to_dict()) print(verify(genesisPublicKey, binascii.hexlify(signature0).decode('ascii'), tx.getRawDataToSign(0)))