Created
December 31, 2016 07:36
-
-
Save 108anup/62425d98f119a2a25fe57845518019be to your computer and use it in GitHub Desktop.
Bitcoin and Cryptocurrency Technologies - Assignment 1
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.util.HashSet; | |
import java.util.ArrayList; | |
public class TxHandler { | |
private UTXOPool utxoPool; | |
/** | |
* Creates a public ledger whose current UTXOPool (collection of unspent transaction outputs) is | |
* {@code utxoPool}. This should make a copy of utxoPool by using the UTXOPool(UTXOPool uPool) | |
* constructor. | |
*/ | |
public TxHandler(UTXOPool utxoPool) { | |
this.utxoPool = new UTXOPool(utxoPool); | |
} | |
/** | |
* @return true if: | |
* (1) all outputs claimed by {@code tx} are in the current UTXO pool, | |
* (2) the signatures on each input of {@code tx} are valid, | |
* (3) no UTXO is claimed multiple times by {@code tx}, | |
* (4) all of {@code tx}s output values are non-negative, and | |
* (5) the sum of {@code tx}s input values is greater than or equal to the sum of its output | |
* values; and false otherwise. | |
*/ | |
public boolean isValidTx(Transaction tx) { | |
ArrayList<Transaction.Input> inputs = tx.getInputs(); | |
ArrayList<Transaction.Output> outputs = tx.getOutputs(); | |
double ipSum = 0; | |
double opSum = 0; | |
for(int i = 0; i<outputs.size(); i++){ | |
//Output value is non negative | |
if(outputs.get(i).value<0) | |
return false; | |
opSum += outputs.get(i).value; | |
} | |
Crypto crypto = new Crypto(); | |
HashSet<UTXO> claimed = new HashSet<UTXO>(); | |
for(int i= 0; i<inputs.size(); i++){ | |
Transaction.Input ip = inputs.get(i); | |
UTXO u = new UTXO(ip.prevTxHash,ip.outputIndex); | |
Transaction.Output correspondingTO = utxoPool.getTxOutput(u); | |
//Output claimed for input is in UTXO Pool | |
if(correspondingTO == null) | |
return false; | |
//The Tx has been verified by the user which is giving the input (taken from corresponding Output in UTXO Pool) | |
if(!crypto.verifySignature(correspondingTO.address,tx.getRawDataToSign(i),ip.signature)) | |
return false; | |
//Check Double Spending aka the same UTXO is not claimed more than once | |
if(claimed.contains(u)) | |
return false; | |
else{ | |
ipSum += correspondingTO.value; | |
claimed.add(u); | |
} | |
} | |
//Output is less than equal to input | |
if(opSum > ipSum) | |
return false; | |
return true; | |
} | |
/** | |
* Handles each epoch by receiving an unordered array of proposed transactions, checking each | |
* transaction for correctness, returning a mutually valid array of accepted transactions, and | |
* updating the current UTXO pool as appropriate. | |
*/ | |
public Transaction[] handleTxs(Transaction[] possibleTxs) { | |
ArrayList<Transaction> maximalSelected = new ArrayList<Transaction>(); | |
for(int j = 0; j<possibleTxs.length; j++){ | |
Transaction tx = possibleTxs[j]; | |
if(isValidTx(tx)){ | |
maximalSelected.add(tx); | |
ArrayList<Transaction.Input> inputs = tx.getInputs(); | |
ArrayList<Transaction.Output> outputs = tx.getOutputs(); | |
//Remove the UTXOs claimed in this transaction | |
for(int i= 0; i<inputs.size(); i++){ | |
Transaction.Input ip = inputs.get(i); | |
UTXO u = new UTXO(ip.prevTxHash,ip.outputIndex); | |
utxoPool.removeUTXO(u); | |
} | |
//Add UTXOs generated in this transaction | |
//These can be used by subsequent transactions | |
for(int i= 0; i<outputs.size(); i++){ | |
UTXO u = new UTXO(tx.getHash(),i); | |
utxoPool.addUTXO(u,outputs.get(i)); | |
} | |
} | |
} | |
return maximalSelected.toArray(new Transaction[maximalSelected.size()]); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment