0% found this document useful (0 votes)
3 views11 pages

Arun78787 Noobchain Crypt0.Git

The document outlines the structure and code of a simple blockchain implementation named NoobChain, consisting of various Java classes such as Block, Transaction, and Wallet. It includes functionalities for creating blocks, processing transactions, and validating the blockchain. Additionally, it utilizes cryptographic methods for securing transactions and maintaining integrity within the blockchain.

Uploaded by

blade gaming
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
3 views11 pages

Arun78787 Noobchain Crypt0.Git

The document outlines the structure and code of a simple blockchain implementation named NoobChain, consisting of various Java classes such as Block, Transaction, and Wallet. It includes functionalities for creating blocks, processing transactions, and validating the blockchain. Additionally, it utilizes cryptographic methods for securing transactions and maintaining integrity within the blockchain.

Uploaded by

blade gaming
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
You are on page 1/ 11

Directory structure:

└── arun78787-noobchain_crypt0.git/
├── noobchain.iml
└── src/
├── Block.java
├── NoobChain.java
├── StringUtil.java
├── Transaction.java
├── TransactionInput.java
├── TransactionOutput.java
└── Wallet.java

================================================
FILE: noobchain.iml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="module-library">
<library>
<CLASSES>
<root url="jar://$USER_HOME$/Downloads/gson-2.11.0.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</orderEntry>
<orderEntry type="module-library">
<library>
<CLASSES>
<root url="jar://$USER_HOME$/Downloads/bcpkix-jdk18on-1.79.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</orderEntry>
<orderEntry type="module-library">
<library>
<CLASSES>
<root url="jar://$USER_HOME$/Downloads/bcprov-jdk18on-1.79.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</orderEntry>
</component>
</module>

================================================
FILE: src/Block.java
================================================
//work of day 1
import java.util.ArrayList;
import java.util.Date;

public class Block{


public String hash;
public String previousHash;
public String merkleRoot;
public ArrayList<Transaction> transactions = new ArrayList<Transaction>();
public long timeStamp;
// private String data;
private int nonce;

public Block( String previousHash){

this.previousHash = previousHash;
this.timeStamp = new Date().getTime();
this.hash = calculateHash();
}
public String calculateHash(){
String calculatedhash = StringUtil.applySha256(previousHash +
Long.toString(timeStamp) + Integer.toString(nonce) + merkleRoot );
return calculatedhash;
}
public void mineBlock(int difficulty){
merkleRoot = StringUtil.getMerkleRoot((transactions));
String target = StringUtil.getDifficultyString(difficulty);

while(!hash.substring(0,difficulty).equals(target)){
nonce++;
hash = calculateHash();
}
System.out.println("Block Mined!!! : " + hash);
}

public boolean addTransaction(Transaction transaction){


if(transaction == null)
return false;
if((previousHash != "0")){
if((transaction.processTransaction() != true)){
System.out.println("Transaction failed to process. Discarded");
return false;
}
}
transactions.add(transaction);
System.out.println("Transaction Successfully added to Block");
return true;
}

================================================
FILE: src/NoobChain.java
================================================
import java.util.ArrayList;
import java.security.Security;
import java.util.HashMap;

public class NoobChain{


public static ArrayList<Block> blockchain = new ArrayList<Block>();
public static HashMap<String, TransactionOutput> UTXOs = new
HashMap<String,TransactionOutput>();
public static int difficulty = 3;
public static float minimumTransaction = 0.1f;
public static Wallet walletA;
public static Wallet walletB;
public static Transaction genesisTransaction;
// public static float minimumTransaction = 0.1f;
public static void main(String[] args){
// blockchain.add(new Block("hi im the first block","0"));
// System.out.println("Truing to mine block 1...");
// blockchain.get(0).mineBlock(difficulty);
//
// blockchain.add(new Block("yo im the second
block",blockchain.get(blockchain.size()-1).hash));
// System.out.println("Trying to Mine block 2...");
// blockchain.get(1).mineBlock(difficulty);
//
// blockchain.add(new Block("hey im the third
block",blockchain.get(blockchain.size()-1).hash));
// System.out.println("Trying to mine block 3...");
// blockchain.get(2).mineBlock(difficulty);
//
// System.out.println("\nBlockchain is valid: " + isChainValid());
//
// String blockchainJson = new
GsonBuilder().setPrettyPrinting().create().toJson(blockchain);
// System.out.println("\nThe block chain: ");
// System.out.println(blockchainJson);
Security.addProvider(new
org.bouncycastle.jce.provider.BouncyCastleProvider());

walletA = new Wallet();


walletB = new Wallet();
Wallet coinbase = new Wallet();

genesisTransaction = new Transaction(coinbase.publicKey,


walletA.publicKey,100f, null);
genesisTransaction.generateSignature(coinbase.privateKey);
genesisTransaction.transactionId = "0";
genesisTransaction.outputs.add(new
TransactionOutput(genesisTransaction.reciepient,genesisTransaction.value,genesisTra
nsaction.transactionId));
UTXOs.put(genesisTransaction.outputs.get(0).id,
genesisTransaction.outputs.get(0));

System.out.println("Creating and mining Genesis block...");


Block genesis = new Block("0");
genesis.addTransaction(genesisTransaction);
addBlock(genesis);

Block block1 = new Block(genesis.hash);


System.out.println("\nWalletA's balance is: " + walletA.getBalance());
System.out.println("\nWalletA is Attempting to send funds (40) to
WalletB...");
block1.addTransaction(walletA.sendFunds(walletB.publicKey, 40f));
addBlock(block1);
System.out.println("\nWalletA's balance is: " + walletA.getBalance());
System.out.println("\nWalletB's balance is :" + walletB.getBalance());

Block block2 = new Block(block1.hash);


System.out.println("\nWalletA attempting to send more funds (1000) than it
has...");
block2.addTransaction(walletA.sendFunds(walletB.publicKey, 1000f));
addBlock(block2);
System.out.println("\nWalletA;s balance is: " + walletB.getBalance());

Block block3 = new Block(block2.hash);


System.out.println("\nWalletB is attempting to send funds (20) to
WalletA...");
block3.addTransaction(walletB.sendFunds(walletA.publicKey,20));
System.out.println("\nWalletA's balance is: " + walletA.getBalance());
System.out.println("\nWalletB's balance is: " + walletB.getBalance());

isChainValid();

// System.out.println("Private and public keys:");


// System.out.println(StringUtil.getStringFromKey(walletA.privateKey));
// System.out.println(StringUtil.getStringFromKey(walletA.publicKey));
//
// Transaction transaction = new Transaction(walletA.publicKey,
walletB.publicKey, 5, null);
// transaction.generateSignature(walletA.privateKey);
//
// System.out.println("Is signature verified");
// System.out.println(transaction.verifySignature());

public static Boolean isChainValid(){


Block currentBlock;
Block previousBlock;
String hashTarget = new String(new char[difficulty]).replace('\0', '0');
HashMap<String,TransactionOutput> tempUTXOs = new
HashMap<String,TransactionOutput>();

tempUTXOs.put(genesisTransaction.outputs.get(0).id,genesisTransaction.outputs.get(0
));

for(int i=1;i<blockchain.size();i++){
currentBlock = blockchain.get(i);
previousBlock = blockchain.get(i-1);

if(!currentBlock.hash.equals(currentBlock.calculateHash()) ){
System.out.println("current hashes not equal");
return false;
}
if(!previousBlock.hash.equals(currentBlock.previousHash)){
System.out.println("previous hashes not equal");
return false;
}
if(!currentBlock.hash.substring( 0,difficulty).equals(hashTarget)){
System.out.println("this block hasn't been mined");
return false;
}
TransactionOutput tempOutput;
for(int t= 0; t< currentBlock.transactions.size();t++){
Transaction currentTransaction = currentBlock.transactions.get(t);

if(!currentTransaction.verifySignature()){
System.out.println("#Signature on Transaction(" + t + ")is
Invalid");
return false;
}
if(currentTransaction.getInputsValue() !=
currentTransaction.getOutputValue()){
System.out.println("#Inputs are not equal to outputs on
Transaction(" + t + ")");
return false;
}
for(TransactionInput input : currentTransaction.inputs){
tempOutput = tempUTXOs.get(input.transactionOutputId);

if(tempOutput == null){
System.out.println("#Referenced input on Transaction(" + t
+") is MIssion");
return false;
}
if(input.UTXO.value != tempOutput.value){
System.out.println("#Referenced input Transaction(" + t +")
value in invalid");
return false;
}
tempUTXOs.remove(input.transactionOutputId);
}
for(TransactionOutput output: currentTransaction.outputs){
tempUTXOs.put(output.id, output);
}
if( currentTransaction.outputs.get(0).reciepient !=
currentTransaction.reciepient){
System.out.println("#Transaction(" + t + ")output reciepient is
not who it should be");
return false;
}
if(currentTransaction.outputs.get(1).reciepient !=
currentTransaction.sender){
System.out.println("#Transaction(" + t +") output 'change' is
not sender");
return false;
}
}

}
System.out.println("Blockchain is valid");
return true;
}
public static void addBlock(Block newBlock){
newBlock.mineBlock(difficulty);
blockchain.add(newBlock);
}
}

================================================
FILE: src/StringUtil.java
================================================
import java.security.MessageDigest;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.util.Base64;
import java.security.Key;
import java.security.Signature;
import java.util.ArrayList;

public class StringUtil{


public static String applySha256(String input){
try{
MessageDigest digest = MessageDigest.getInstance("SHA-256");
byte[] hash = digest.digest(input.getBytes("UTF-8"));
StringBuffer hexString = new StringBuffer();
for (int i=0;i<hash.length;i++){
String hex = Integer.toHexString(0xff & hash[i]);
if(hex.length() == 1) hexString.append('0');
hexString.append(hex);
}
return hexString.toString();
}
catch(Exception e){
throw new RuntimeException(e);
}
}
public static byte[] applyECDSASig(PrivateKey privateKey, String input){
Signature dsa;
byte[] output = new byte[0];
try{
dsa = Signature.getInstance("ECDSA", "BC");
dsa.initSign(privateKey);
byte[] strByte = input.getBytes();
dsa.update(strByte);
byte[] realSig = dsa.sign();
output = realSig;
} catch(Exception e){
throw new RuntimeException(e);
}
return output;
}
public static boolean verifyECDSASig(PublicKey publicKey, String data, byte[]
signature){
try{
Signature ecdsaVerify = Signature.getInstance("ECDSA", "BC");
ecdsaVerify.initVerify(publicKey);
ecdsaVerify.update(data.getBytes());
return ecdsaVerify.verify(signature);

} catch(Exception e) {
throw new RuntimeException(e);
}
}

public static String getStringFromKey(Key key){


return Base64.getEncoder().encodeToString(key.getEncoded());
}
public static String getMerkleRoot(ArrayList<Transaction> transactions){
int count = transactions.size();
ArrayList<String> previousTreeLayer = new ArrayList<String>();
for(Transaction transaction : transactions){
previousTreeLayer.add(transaction.transactionId);
}
ArrayList<String> treeLayer = previousTreeLayer;
while(count > 1){
treeLayer = new ArrayList<String>();
for(int i=1; i< previousTreeLayer.size(); i++){
treeLayer.add(applySha256(previousTreeLayer.get(i-1) +
previousTreeLayer.get(i)));

}
count = treeLayer.size();
previousTreeLayer = treeLayer;
}
String merkleRoot = (treeLayer.size() == 1) ? treeLayer.get(0) : "";
return merkleRoot;
}
public static String getDifficultyString(int difficulty){
return new String(new char[difficulty]).replace('\0', '0');
}

================================================
FILE: src/Transaction.java
================================================
import java.security.*;
import java.util.ArrayList;

public class Transaction {


public String transactionId;
public PublicKey sender;
public PublicKey reciepient;
public float value;
public byte[] signature;

public ArrayList<TransactionInput> inputs = new ArrayList<TransactionInput>();


public ArrayList<TransactionOutput> outputs = new
ArrayList<TransactionOutput>();
private static int sequence = 0;

public Transaction(PublicKey from, PublicKey to, float value,


ArrayList<TransactionInput> inputs){
this.sender = from;
this.reciepient = to;
this.value = value;
this.inputs = inputs;
}
private String calculateHash(){
sequence++;
return StringUtil.applySha256(
StringUtil.getStringFromKey(sender) +
StringUtil.getStringFromKey(reciepient) + Float.toString(value) + sequence
);
}
public void generateSignature(PrivateKey privateKey){
String data = StringUtil.getStringFromKey(sender) +
StringUtil.getStringFromKey(reciepient) + Float.toString(value);
signature = StringUtil.applyECDSASig(privateKey,data);

}
public boolean verifySignature(){
String data = StringUtil.getStringFromKey(sender) +
StringUtil.getStringFromKey(reciepient) + Float.toString(value);
return StringUtil.verifyECDSASig(sender, data,signature);
}
public boolean processTransaction(){
if(verifySignature() == false){
System.out.println("#Transaction Signature failed to verify");
return false;
}
for(TransactionInput i : inputs){
i.UTXO = NoobChain.UTXOs.get(i.transactionOutputId);

}
if(getInputsValue() < NoobChain.minimumTransaction){
System.out.println("#Transaction Inputs to small: " +
getInputsValue());
return false;
}
float leftOver = getInputsValue() - value;
transactionId = calculateHash();
outputs.add(new TransactionOutput(this.reciepient, value, transactionId));
outputs.add(new TransactionOutput(this.sender,leftOver, transactionId));

for(TransactionOutput o : outputs){
NoobChain.UTXOs.put(o.id, o);
}
for(TransactionInput i: inputs){
if(i.UTXO == null) continue;
NoobChain.UTXOs.remove(i.UTXO.id);
}
return true;
}
public float getInputsValue(){
float total = 0;
for(TransactionInput i : inputs){
if(i.UTXO == null) continue;
total += i.UTXO.value;
}
return total;
}
public float getOutputValue(){
float total = 0;
for(TransactionOutput o : outputs){
total += o.value;
}
return total;
}

================================================
FILE: src/TransactionInput.java
================================================
public class TransactionInput {
public String transactionOutputId;
public TransactionOutput UTXO;

public TransactionInput(String transactionOutputId){


this.transactionOutputId = transactionOutputId;
}
}

================================================
FILE: src/TransactionOutput.java
================================================
import java.security.PublicKey;

public class TransactionOutput {


public String id;
public PublicKey reciepient;
public float value;
public String parentTransactionId;

public TransactionOutput(PublicKey reciepient, float value, String


parentTransactionId) {
this.reciepient = reciepient;
this.value = value;
this.parentTransactionId = parentTransactionId;
this.id = StringUtil.applySha256(StringUtil.getStringFromKey(reciepient) +
Float.toString(value) + parentTransactionId);

}
public boolean isMine(PublicKey publicKey){
return (publicKey == reciepient);
}

================================================
FILE: src/Wallet.java
================================================
//package noobchain;
import java.security.*;
import java.security.spec.ECGenParameterSpec;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
public class Wallet {
public PrivateKey privateKey;
public PublicKey publicKey;

public HashMap<String,TransactionOutput> UTXOs = new HashMap<>();

public Wallet(){
generateKeyPair();
}

public void generateKeyPair(){


try{
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("ECDSA", "BC");
SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
ECGenParameterSpec ecSpec = new ECGenParameterSpec("prime192v1");

keyGen.initialize(ecSpec, random);
KeyPair keyPair = keyGen.generateKeyPair();

privateKey = keyPair.getPrivate();
publicKey = keyPair.getPublic();
}catch(Exception e){
throw new RuntimeException(e);
}
}
public float getBalance(){
float total = 0;
for(Map.Entry<String, TransactionOutput> item:
NoobChain.UTXOs.entrySet()){
TransactionOutput UTXO = item.getValue();
if(UTXO.isMine(publicKey)){
UTXOs.put(UTXO.id, UTXO);
total += UTXO.value;
}
}
return total;
}
public Transaction sendFunds(PublicKey _recipient,float value){
if(getBalance() < value){
System.out.println("#Not enough funds to send transaction.
Transaction Declined");
return null;
}
ArrayList<TransactionInput> inputs = new ArrayList<TransactionInput>();

float total = 0;
for(Map.Entry<String, TransactionOutput> item: UTXOs.entrySet()){
TransactionOutput UTXO = item.getValue();
total += UTXO.value;
inputs.add(new TransactionInput(UTXO.id));
if(total > value) break;
}
Transaction newTransaction = new Transaction(publicKey, _recipient,
value, inputs);
newTransaction.generateSignature(privateKey);

for(TransactionInput input: inputs){


UTXOs.remove(input.transactionOutputId);
}
return newTransaction;
}

You might also like