juneja-codebase 4.1.0__tar.gz → 4.1.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- juneja_codebase-4.1.2/MANIFEST.in +1 -0
- {juneja_codebase-4.1.0 → juneja_codebase-4.1.2}/PKG-INFO +1 -1
- {juneja_codebase-4.1.0 → juneja_codebase-4.1.2}/juneja_codebase/__init__.py +1 -1
- {juneja_codebase-4.1.0 → juneja_codebase-4.1.2}/juneja_codebase/main.py +1 -1
- juneja_codebase-4.1.2/juneja_codebase/templates/Blockchain Codes/.vscode/tasks.json +28 -0
- juneja_codebase-4.1.2/juneja_codebase/templates/Blockchain Codes/pythonic version/q10_hyperledger_chaincode.js +273 -0
- juneja_codebase-4.1.2/juneja_codebase/templates/Blockchain Codes/pythonic version/q1_sha256_digest.py +16 -0
- juneja_codebase-4.1.2/juneja_codebase/templates/Blockchain Codes/pythonic version/q2_sha256_encrypt_decrypt.py +40 -0
- juneja_codebase-4.1.2/juneja_codebase/templates/Blockchain Codes/pythonic version/q3_rsa.py +103 -0
- juneja_codebase-4.1.2/juneja_codebase/templates/Blockchain Codes/pythonic version/q4_pow_blockchain.py +69 -0
- juneja_codebase-4.1.2/juneja_codebase/templates/Blockchain Codes/pythonic version/q5_digital_signature.py +104 -0
- juneja_codebase-4.1.2/juneja_codebase/templates/Blockchain Codes/pythonic version/q6_blockchain_transactions.py +78 -0
- juneja_codebase-4.1.2/juneja_codebase/templates/Blockchain Codes/pythonic version/q7_five_nodes_hash.py +55 -0
- juneja_codebase-4.1.2/juneja_codebase/templates/Blockchain Codes/pythonic version/q8_five_nodes_validity.py +94 -0
- juneja_codebase-4.1.2/juneja_codebase/templates/Blockchain Codes/pythonic version/q9_SimpleBank.sol +144 -0
- juneja_codebase-4.1.2/juneja_codebase/templates/HackingScripts/ads.txt +171 -0
- juneja_codebase-4.1.2/juneja_codebase/templates/HackingScripts/ads_much_shorter_now.txt +86 -0
- juneja_codebase-4.1.2/juneja_codebase/templates/HackingScripts/john_ripper.txt +97 -0
- juneja_codebase-4.1.2/juneja_codebase/templates/HackingScripts/metaspoitable.txt +185 -0
- juneja_codebase-4.1.2/juneja_codebase/templates/HackingScripts/nw_scanning_recon.txt +282 -0
- juneja_codebase-4.1.2/juneja_codebase/templates/HackingScripts/sql_injection_dvwa.txt +227 -0
- juneja_codebase-4.1.2/juneja_codebase/templates/HackingScripts/zap_juiceshop.txt +129 -0
- {juneja_codebase-4.1.0 → juneja_codebase-4.1.2}/juneja_codebase.egg-info/PKG-INFO +1 -1
- {juneja_codebase-4.1.0 → juneja_codebase-4.1.2}/juneja_codebase.egg-info/SOURCES.txt +18 -0
- {juneja_codebase-4.1.0 → juneja_codebase-4.1.2}/setup.cfg +1 -1
- {juneja_codebase-4.1.0 → juneja_codebase-4.1.2}/setup.py +1 -1
- juneja_codebase-4.1.0/MANIFEST.in +0 -0
- {juneja_codebase-4.1.0 → juneja_codebase-4.1.2}/LICENSE +0 -0
- {juneja_codebase-4.1.0 → juneja_codebase-4.1.2}/README.md +0 -0
- {juneja_codebase-4.1.0 → juneja_codebase-4.1.2}/juneja_codebase/templates/Blockchain Codes/AnshJuneja_LabExercise1_Blockchain +0 -0
- {juneja_codebase-4.1.0 → juneja_codebase-4.1.2}/juneja_codebase/templates/Blockchain Codes/AnshJuneja_LabExercise1_Blockchain.cpp +0 -0
- {juneja_codebase-4.1.0 → juneja_codebase-4.1.2}/juneja_codebase/templates/Blockchain Codes/AnshJuneja_LabExercise2_Blockchain +0 -0
- {juneja_codebase-4.1.0 → juneja_codebase-4.1.2}/juneja_codebase/templates/Blockchain Codes/AnshJuneja_LabExercise2_Blockchain.cpp +0 -0
- {juneja_codebase-4.1.0 → juneja_codebase-4.1.2}/juneja_codebase/templates/Blockchain Codes/AnshJuneja_LabExercise3-1_Blockchain +0 -0
- {juneja_codebase-4.1.0 → juneja_codebase-4.1.2}/juneja_codebase/templates/Blockchain Codes/AnshJuneja_LabExercise3-1_Blockchain.cpp +0 -0
- {juneja_codebase-4.1.0 → juneja_codebase-4.1.2}/juneja_codebase/templates/Blockchain Codes/AnshJuneja_LabExercise3-2_Blockchain +0 -0
- {juneja_codebase-4.1.0 → juneja_codebase-4.1.2}/juneja_codebase/templates/Blockchain Codes/AnshJuneja_LabExercise3-2_Blockchain.cpp +0 -0
- {juneja_codebase-4.1.0 → juneja_codebase-4.1.2}/juneja_codebase/templates/Blockchain Codes/AnshJuneja_LabExercise3-3_Blockchain +0 -0
- {juneja_codebase-4.1.0 → juneja_codebase-4.1.2}/juneja_codebase/templates/Blockchain Codes/AnshJuneja_LabExercise3-3_Blockchain.cpp +0 -0
- {juneja_codebase-4.1.0 → juneja_codebase-4.1.2}/juneja_codebase/templates/Blockchain Codes/AnshJuneja_LabExercise4_Blockchain +0 -0
- {juneja_codebase-4.1.0 → juneja_codebase-4.1.2}/juneja_codebase/templates/Blockchain Codes/AnshJuneja_LabExercise4_Blockchain.cpp +0 -0
- {juneja_codebase-4.1.0 → juneja_codebase-4.1.2}/juneja_codebase/templates/Blockchain Codes/AnshJuneja_LabExercise5_Blockchain +0 -0
- {juneja_codebase-4.1.0 → juneja_codebase-4.1.2}/juneja_codebase/templates/Blockchain Codes/AnshJuneja_LabExercise5_Blockchain.cpp +0 -0
- {juneja_codebase-4.1.0 → juneja_codebase-4.1.2}/juneja_codebase/templates/Blockchain Codes/AnshJuneja_LabExercise6_Blockchain +0 -0
- {juneja_codebase-4.1.0 → juneja_codebase-4.1.2}/juneja_codebase/templates/Blockchain Codes/AnshJuneja_LabExercise6_Blockchain.cpp +0 -0
- {juneja_codebase-4.1.0 → juneja_codebase-4.1.2}/juneja_codebase/templates/Blockchain Codes/AnshJuneja_LabExercise7_Blockchain +0 -0
- {juneja_codebase-4.1.0 → juneja_codebase-4.1.2}/juneja_codebase/templates/Blockchain Codes/AnshJuneja_LabExercise7_Blockchain.cpp +0 -0
- {juneja_codebase-4.1.0 → juneja_codebase-4.1.2}/juneja_codebase/templates/Blockchain Codes/AnshJuneja_LabExercise8-1_Blockchain.sol +0 -0
- {juneja_codebase-4.1.0 → juneja_codebase-4.1.2}/juneja_codebase/templates/Blockchain Codes/AnshJuneja_LabExercise8-2_Blockchain.sol +0 -0
- {juneja_codebase-4.1.0 → juneja_codebase-4.1.2}/juneja_codebase/templates/Blockchain Codes/AnshJuneja_LabExercise8-3_Blockchain.sol +0 -0
- {juneja_codebase-4.1.0 → juneja_codebase-4.1.2}/juneja_codebase/templates/compiler_design/AnshJuneja_Practical10_CD.l +0 -0
- {juneja_codebase-4.1.0 → juneja_codebase-4.1.2}/juneja_codebase/templates/compiler_design/AnshJuneja_Practical10_CD.y +0 -0
- {juneja_codebase-4.1.0 → juneja_codebase-4.1.2}/juneja_codebase/templates/compiler_design/AnshJuneja_Practical11_CD.l +0 -0
- {juneja_codebase-4.1.0 → juneja_codebase-4.1.2}/juneja_codebase/templates/compiler_design/AnshJuneja_Practical11_CD.y +0 -0
- {juneja_codebase-4.1.0 → juneja_codebase-4.1.2}/juneja_codebase/templates/compiler_design/AnshJuneja_Practical12_CD.l +0 -0
- {juneja_codebase-4.1.0 → juneja_codebase-4.1.2}/juneja_codebase/templates/compiler_design/AnshJuneja_Practical12_CD.y +0 -0
- {juneja_codebase-4.1.0 → juneja_codebase-4.1.2}/juneja_codebase/templates/compiler_design/AnshJuneja_Practical13_CD.l +0 -0
- {juneja_codebase-4.1.0 → juneja_codebase-4.1.2}/juneja_codebase/templates/compiler_design/AnshJuneja_Practical13_CD.y +0 -0
- {juneja_codebase-4.1.0 → juneja_codebase-4.1.2}/juneja_codebase/templates/compiler_design/AnshJuneja_Practical1_CD.l +0 -0
- {juneja_codebase-4.1.0 → juneja_codebase-4.1.2}/juneja_codebase/templates/compiler_design/AnshJuneja_Practical2_CD.l +0 -0
- {juneja_codebase-4.1.0 → juneja_codebase-4.1.2}/juneja_codebase/templates/compiler_design/AnshJuneja_Practical3_CD.l +0 -0
- {juneja_codebase-4.1.0 → juneja_codebase-4.1.2}/juneja_codebase/templates/compiler_design/AnshJuneja_Practical4_CD.l +0 -0
- {juneja_codebase-4.1.0 → juneja_codebase-4.1.2}/juneja_codebase/templates/compiler_design/AnshJuneja_Practical5_CD.l +0 -0
- {juneja_codebase-4.1.0 → juneja_codebase-4.1.2}/juneja_codebase/templates/compiler_design/AnshJuneja_Practical6_CD.l +0 -0
- {juneja_codebase-4.1.0 → juneja_codebase-4.1.2}/juneja_codebase/templates/compiler_design/AnshJuneja_Practical7_CD.l +0 -0
- {juneja_codebase-4.1.0 → juneja_codebase-4.1.2}/juneja_codebase/templates/compiler_design/AnshJuneja_Practical8_CD.l +0 -0
- {juneja_codebase-4.1.0 → juneja_codebase-4.1.2}/juneja_codebase/templates/compiler_design/AnshJuneja_Practical9_CD.l +0 -0
- {juneja_codebase-4.1.0 → juneja_codebase-4.1.2}/juneja_codebase/templates/compiler_design/AnshJuneja_Practical9_CD.y +0 -0
- {juneja_codebase-4.1.0 → juneja_codebase-4.1.2}/juneja_codebase/templates/deep_learning/Denoised_Autoencoders.ipynb +0 -0
- {juneja_codebase-4.1.0 → juneja_codebase-4.1.2}/juneja_codebase/templates/deep_learning/Fashion_Mnist_DenseNet201_VGG19_PreTModel.ipynb +0 -0
- {juneja_codebase-4.1.0 → juneja_codebase-4.1.2}/juneja_codebase/templates/deep_learning/Image_Compression_Autoencoders.ipynb +0 -0
- {juneja_codebase-4.1.0 → juneja_codebase-4.1.2}/juneja_codebase/templates/deep_learning/boston_housing.ipynb +0 -0
- {juneja_codebase-4.1.0 → juneja_codebase-4.1.2}/juneja_codebase/templates/deep_learning/cnn_fashionmnist.ipynb +0 -0
- {juneja_codebase-4.1.0 → juneja_codebase-4.1.2}/juneja_codebase/templates/deep_learning/posneg_imdb_ffnn..ipynb +0 -0
- {juneja_codebase-4.1.0 → juneja_codebase-4.1.2}/juneja_codebase/templates/deep_learning/reuters.ipynb +0 -0
- {juneja_codebase-4.1.0 → juneja_codebase-4.1.2}/juneja_codebase/templates/deep_learning/rnnlstm_timeseries_imdb.ipynb +0 -0
- {juneja_codebase-4.1.0 → juneja_codebase-4.1.2}/juneja_codebase/templates/social_network_analysis/1_try.ipynb +0 -0
- {juneja_codebase-4.1.0 → juneja_codebase-4.1.2}/juneja_codebase/templates/social_network_analysis/2_try.ipynb +0 -0
- {juneja_codebase-4.1.0 → juneja_codebase-4.1.2}/juneja_codebase/templates/social_network_analysis/3_try.ipynb +0 -0
- {juneja_codebase-4.1.0 → juneja_codebase-4.1.2}/juneja_codebase/templates/social_network_analysis/4_try.ipynb +0 -0
- {juneja_codebase-4.1.0 → juneja_codebase-4.1.2}/juneja_codebase/templates/social_network_analysis/5_try.ipynb +0 -0
- {juneja_codebase-4.1.0 → juneja_codebase-4.1.2}/juneja_codebase/templates/social_network_analysis/6_try.ipynb +0 -0
- {juneja_codebase-4.1.0 → juneja_codebase-4.1.2}/juneja_codebase/templates/social_network_analysis/new.ipynb +0 -0
- {juneja_codebase-4.1.0 → juneja_codebase-4.1.2}/juneja_codebase.egg-info/dependency_links.txt +0 -0
- {juneja_codebase-4.1.0 → juneja_codebase-4.1.2}/juneja_codebase.egg-info/entry_points.txt +0 -0
- {juneja_codebase-4.1.0 → juneja_codebase-4.1.2}/juneja_codebase.egg-info/top_level.txt +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
recursive-include juneja_codebase/templates *
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
{
|
|
2
|
+
"tasks": [
|
|
3
|
+
{
|
|
4
|
+
"type": "cppbuild",
|
|
5
|
+
"label": "C/C++: gcc build active file",
|
|
6
|
+
"command": "/usr/bin/gcc",
|
|
7
|
+
"args": [
|
|
8
|
+
"-fdiagnostics-color=always",
|
|
9
|
+
"-g",
|
|
10
|
+
"${file}",
|
|
11
|
+
"-o",
|
|
12
|
+
"${fileDirname}/${fileBasenameNoExtension}"
|
|
13
|
+
],
|
|
14
|
+
"options": {
|
|
15
|
+
"cwd": "${fileDirname}"
|
|
16
|
+
},
|
|
17
|
+
"problemMatcher": [
|
|
18
|
+
"$gcc"
|
|
19
|
+
],
|
|
20
|
+
"group": {
|
|
21
|
+
"kind": "build",
|
|
22
|
+
"isDefault": true
|
|
23
|
+
},
|
|
24
|
+
"detail": "Task generated by Debugger."
|
|
25
|
+
}
|
|
26
|
+
],
|
|
27
|
+
"version": "2.0.0"
|
|
28
|
+
}
|
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Q10. Create a simple permissioned blockchain using Hyperledger Fabric
|
|
5
|
+
*
|
|
6
|
+
* This is a Chaincode (Smart Contract) for Hyperledger Fabric written in JavaScript.
|
|
7
|
+
* It implements an Asset Management system on a permissioned blockchain.
|
|
8
|
+
*
|
|
9
|
+
* Features demonstrated:
|
|
10
|
+
* - Permissioned access (only authorized organizations can perform actions)
|
|
11
|
+
* - Create, Read, Update, Delete (CRUD) operations on assets
|
|
12
|
+
* - Asset transfer between owners
|
|
13
|
+
* - Transaction history retrieval
|
|
14
|
+
* - World State ledger interaction
|
|
15
|
+
*
|
|
16
|
+
* ── Setup & Run Instructions ───────────────────────────────────────────────
|
|
17
|
+
*
|
|
18
|
+
* Prerequisites:
|
|
19
|
+
* - Docker & Docker Compose installed
|
|
20
|
+
* - Node.js >= 14.x installed
|
|
21
|
+
* - Hyperledger Fabric binaries and samples installed:
|
|
22
|
+
* curl -sSL https://bit.ly/2ysbOFE | bash -s
|
|
23
|
+
*
|
|
24
|
+
* Step 1: Navigate to the Fabric test network
|
|
25
|
+
* cd fabric-samples/test-network
|
|
26
|
+
*
|
|
27
|
+
* Step 2: Start the network with a channel
|
|
28
|
+
* ./network.sh up createChannel -c mychannel -ca
|
|
29
|
+
*
|
|
30
|
+
* Step 3: Deploy this chaincode
|
|
31
|
+
* ./network.sh deployCC -ccn assetcc -ccp ../chaincode/asset -ccl javascript
|
|
32
|
+
*
|
|
33
|
+
* Step 4: Set environment variables for Org1 (peer admin)
|
|
34
|
+
* export PATH=${PWD}/../bin:$PATH
|
|
35
|
+
* export FABRIC_CFG_PATH=$PWD/../config/
|
|
36
|
+
* export CORE_PEER_TLS_ENABLED=true
|
|
37
|
+
* export CORE_PEER_LOCALMSPID="Org1MSP"
|
|
38
|
+
* export CORE_PEER_TLS_ROOTCERT_FILE=${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt
|
|
39
|
+
* export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp
|
|
40
|
+
* export CORE_PEER_ADDRESS=localhost:7051
|
|
41
|
+
*
|
|
42
|
+
* Step 5: Invoke chaincode functions
|
|
43
|
+
*
|
|
44
|
+
* Initialize ledger:
|
|
45
|
+
* peer chaincode invoke ... -c '{"function":"InitLedger","Args":[]}'
|
|
46
|
+
*
|
|
47
|
+
* Create an asset:
|
|
48
|
+
* peer chaincode invoke ... -c '{"function":"CreateAsset","Args":["ASSET1","Laptop","Alice","5000"]}'
|
|
49
|
+
*
|
|
50
|
+
* Read an asset:
|
|
51
|
+
* peer chaincode query ... -c '{"function":"ReadAsset","Args":["ASSET1"]}'
|
|
52
|
+
*
|
|
53
|
+
* Update an asset:
|
|
54
|
+
* peer chaincode invoke ... -c '{"function":"UpdateAsset","Args":["ASSET1","Desktop","Alice","4000"]}'
|
|
55
|
+
*
|
|
56
|
+
* Transfer an asset:
|
|
57
|
+
* peer chaincode invoke ... -c '{"function":"TransferAsset","Args":["ASSET1","Bob"]}'
|
|
58
|
+
*
|
|
59
|
+
* Get all assets:
|
|
60
|
+
* peer chaincode query ... -c '{"function":"GetAllAssets","Args":[]}'
|
|
61
|
+
*
|
|
62
|
+
* Get transaction history:
|
|
63
|
+
* peer chaincode query ... -c '{"function":"GetAssetHistory","Args":["ASSET1"]}'
|
|
64
|
+
*
|
|
65
|
+
* Delete an asset:
|
|
66
|
+
* peer chaincode invoke ... -c '{"function":"DeleteAsset","Args":["ASSET1"]}'
|
|
67
|
+
*
|
|
68
|
+
* Step 6: Shut down the network
|
|
69
|
+
* ./network.sh down
|
|
70
|
+
*
|
|
71
|
+
* ──────────────────────────────────────────────────────────────────────────
|
|
72
|
+
*/
|
|
73
|
+
|
|
74
|
+
const { Contract } = require('fabric-contract-api');
|
|
75
|
+
|
|
76
|
+
class AssetContract extends Contract {
|
|
77
|
+
|
|
78
|
+
// ── Helper: Check if an asset exists ──────────────────────
|
|
79
|
+
|
|
80
|
+
async AssetExists(ctx, assetId) {
|
|
81
|
+
const assetJSON = await ctx.stub.getState(assetId);
|
|
82
|
+
return assetJSON && assetJSON.length > 0;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// ── Helper: Get caller's MSP ID (Organization) ────────────
|
|
86
|
+
|
|
87
|
+
getCallerMSP(ctx) {
|
|
88
|
+
return ctx.clientIdentity.getMSPID();
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// ── Helper: Permissioned access check ────────────────────
|
|
92
|
+
// Only Org1MSP and Org2MSP members are allowed to transact
|
|
93
|
+
|
|
94
|
+
checkPermission(ctx) {
|
|
95
|
+
const mspID = this.getCallerMSP(ctx);
|
|
96
|
+
const allowedOrgs = ['Org1MSP', 'Org2MSP'];
|
|
97
|
+
if (!allowedOrgs.includes(mspID)) {
|
|
98
|
+
throw new Error(`Permission denied: Organization '${mspID}' is not authorized.`);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// ── 1. Initialize the ledger with sample assets ───────────
|
|
103
|
+
|
|
104
|
+
async InitLedger(ctx) {
|
|
105
|
+
this.checkPermission(ctx);
|
|
106
|
+
|
|
107
|
+
const assets = [
|
|
108
|
+
{ assetId: 'ASSET001', name: 'Laptop', owner: 'Alice', value: 5000 },
|
|
109
|
+
{ assetId: 'ASSET002', name: 'Smartphone', owner: 'Bob', value: 1500 },
|
|
110
|
+
{ assetId: 'ASSET003', name: 'Tablet', owner: 'Carol', value: 800 },
|
|
111
|
+
];
|
|
112
|
+
|
|
113
|
+
for (const asset of assets) {
|
|
114
|
+
asset.docType = 'asset';
|
|
115
|
+
await ctx.stub.putState(asset.assetId, Buffer.from(JSON.stringify(asset)));
|
|
116
|
+
console.log(`Asset ${asset.assetId} initialized on ledger.`);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
console.log('Ledger initialized successfully.');
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// ── 2. Create a new asset ─────────────────────────────────
|
|
123
|
+
|
|
124
|
+
async CreateAsset(ctx, assetId, name, owner, value) {
|
|
125
|
+
this.checkPermission(ctx);
|
|
126
|
+
|
|
127
|
+
const exists = await this.AssetExists(ctx, assetId);
|
|
128
|
+
if (exists) {
|
|
129
|
+
throw new Error(`Asset '${assetId}' already exists.`);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
const asset = {
|
|
133
|
+
docType : 'asset',
|
|
134
|
+
assetId : assetId,
|
|
135
|
+
name : name,
|
|
136
|
+
owner : owner,
|
|
137
|
+
value : parseInt(value),
|
|
138
|
+
createdBy: this.getCallerMSP(ctx),
|
|
139
|
+
createdAt: new Date().toISOString(),
|
|
140
|
+
};
|
|
141
|
+
|
|
142
|
+
await ctx.stub.putState(assetId, Buffer.from(JSON.stringify(asset)));
|
|
143
|
+
console.log(`Asset ${assetId} created by ${asset.createdBy}`);
|
|
144
|
+
return JSON.stringify(asset);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// ── 3. Read an asset ──────────────────────────────────────
|
|
148
|
+
|
|
149
|
+
async ReadAsset(ctx, assetId) {
|
|
150
|
+
this.checkPermission(ctx);
|
|
151
|
+
|
|
152
|
+
const assetJSON = await ctx.stub.getState(assetId);
|
|
153
|
+
if (!assetJSON || assetJSON.length === 0) {
|
|
154
|
+
throw new Error(`Asset '${assetId}' does not exist.`);
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
console.log(`Asset ${assetId} retrieved.`);
|
|
158
|
+
return assetJSON.toString();
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
// ── 4. Update an existing asset ───────────────────────────
|
|
162
|
+
|
|
163
|
+
async UpdateAsset(ctx, assetId, name, owner, value) {
|
|
164
|
+
this.checkPermission(ctx);
|
|
165
|
+
|
|
166
|
+
const exists = await this.AssetExists(ctx, assetId);
|
|
167
|
+
if (!exists) {
|
|
168
|
+
throw new Error(`Asset '${assetId}' does not exist.`);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
const updatedAsset = {
|
|
172
|
+
docType : 'asset',
|
|
173
|
+
assetId : assetId,
|
|
174
|
+
name : name,
|
|
175
|
+
owner : owner,
|
|
176
|
+
value : parseInt(value),
|
|
177
|
+
updatedBy : this.getCallerMSP(ctx),
|
|
178
|
+
updatedAt : new Date().toISOString(),
|
|
179
|
+
};
|
|
180
|
+
|
|
181
|
+
await ctx.stub.putState(assetId, Buffer.from(JSON.stringify(updatedAsset)));
|
|
182
|
+
console.log(`Asset ${assetId} updated by ${updatedAsset.updatedBy}`);
|
|
183
|
+
return JSON.stringify(updatedAsset);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
// ── 5. Transfer an asset to a new owner ───────────────────
|
|
187
|
+
|
|
188
|
+
async TransferAsset(ctx, assetId, newOwner) {
|
|
189
|
+
this.checkPermission(ctx);
|
|
190
|
+
|
|
191
|
+
const assetJSON = await ctx.stub.getState(assetId);
|
|
192
|
+
if (!assetJSON || assetJSON.length === 0) {
|
|
193
|
+
throw new Error(`Asset '${assetId}' does not exist.`);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
const asset = JSON.parse(assetJSON.toString());
|
|
197
|
+
const oldOwner = asset.owner;
|
|
198
|
+
asset.owner = newOwner;
|
|
199
|
+
asset.transferredBy = this.getCallerMSP(ctx);
|
|
200
|
+
asset.transferredAt = new Date().toISOString();
|
|
201
|
+
|
|
202
|
+
await ctx.stub.putState(assetId, Buffer.from(JSON.stringify(asset)));
|
|
203
|
+
console.log(`Asset ${assetId} transferred from '${oldOwner}' to '${newOwner}'`);
|
|
204
|
+
return `Asset '${assetId}' transferred from '${oldOwner}' to '${newOwner}'.`;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
// ── 6. Delete an asset ────────────────────────────────────
|
|
208
|
+
|
|
209
|
+
async DeleteAsset(ctx, assetId) {
|
|
210
|
+
this.checkPermission(ctx);
|
|
211
|
+
|
|
212
|
+
const exists = await this.AssetExists(ctx, assetId);
|
|
213
|
+
if (!exists) {
|
|
214
|
+
throw new Error(`Asset '${assetId}' does not exist.`);
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
await ctx.stub.deleteState(assetId);
|
|
218
|
+
console.log(`Asset ${assetId} deleted by ${this.getCallerMSP(ctx)}`);
|
|
219
|
+
return `Asset '${assetId}' deleted successfully.`;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
// ── 7. Get all assets from the ledger ─────────────────────
|
|
223
|
+
|
|
224
|
+
async GetAllAssets(ctx) {
|
|
225
|
+
this.checkPermission(ctx);
|
|
226
|
+
|
|
227
|
+
const allResults = [];
|
|
228
|
+
// Range query with empty start/end key retrieves all assets
|
|
229
|
+
const iterator = await ctx.stub.getStateByRange('', '');
|
|
230
|
+
|
|
231
|
+
let result = await iterator.next();
|
|
232
|
+
while (!result.done) {
|
|
233
|
+
const strValue = Buffer.from(result.value.value.toString()).toString('utf8');
|
|
234
|
+
let record;
|
|
235
|
+
try {
|
|
236
|
+
record = JSON.parse(strValue);
|
|
237
|
+
} catch (err) {
|
|
238
|
+
record = strValue;
|
|
239
|
+
}
|
|
240
|
+
allResults.push(record);
|
|
241
|
+
result = await iterator.next();
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
console.log(`Retrieved ${allResults.length} asset(s) from ledger.`);
|
|
245
|
+
return JSON.stringify(allResults);
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
// ── 8. Get full transaction history of an asset ───────────
|
|
249
|
+
|
|
250
|
+
async GetAssetHistory(ctx, assetId) {
|
|
251
|
+
this.checkPermission(ctx);
|
|
252
|
+
|
|
253
|
+
const historyIterator = await ctx.stub.getHistoryForKey(assetId);
|
|
254
|
+
const history = [];
|
|
255
|
+
|
|
256
|
+
let result = await historyIterator.next();
|
|
257
|
+
while (!result.done) {
|
|
258
|
+
const record = {
|
|
259
|
+
txId : result.value.txId,
|
|
260
|
+
timestamp : result.value.timestamp,
|
|
261
|
+
isDelete : result.value.isDelete,
|
|
262
|
+
value : result.value.value.toString('utf8'),
|
|
263
|
+
};
|
|
264
|
+
history.push(record);
|
|
265
|
+
result = await historyIterator.next();
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
console.log(`History for asset '${assetId}': ${history.length} transaction(s).`);
|
|
269
|
+
return JSON.stringify(history);
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
module.exports = AssetContract;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Q1. Using SHA-256, obtain the message digest of string "Blockchain Developer"
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import hashlib
|
|
6
|
+
|
|
7
|
+
message = "Blockchain Developer"
|
|
8
|
+
|
|
9
|
+
# Encode the string and compute SHA-256 digest
|
|
10
|
+
sha256_hash = hashlib.sha256(message.encode())
|
|
11
|
+
|
|
12
|
+
# Get the message digest in hexadecimal
|
|
13
|
+
message_digest = sha256_hash.hexdigest()
|
|
14
|
+
|
|
15
|
+
print("Message :", message)
|
|
16
|
+
print("SHA-256 Digest :", message_digest)
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Q2. Write a program to encrypt and decrypt the message "Hello World" using SHA256.
|
|
3
|
+
|
|
4
|
+
Note: SHA-256 is a cryptographic hash function, not a symmetric cipher.
|
|
5
|
+
It is used here to derive an encryption key (via XOR stream cipher),
|
|
6
|
+
which is a standard academic approach to demonstrate SHA-256 in encryption.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
import hashlib
|
|
10
|
+
|
|
11
|
+
def encrypt(message, key):
|
|
12
|
+
# Generate SHA-256 hash of the key
|
|
13
|
+
key_hash = hashlib.sha256(key.encode()).digest() # 32 bytes
|
|
14
|
+
message_bytes = message.encode()
|
|
15
|
+
# XOR each byte of the message with the key hash (cyclic)
|
|
16
|
+
encrypted = bytes([message_bytes[i] ^ key_hash[i % len(key_hash)]
|
|
17
|
+
for i in range(len(message_bytes))])
|
|
18
|
+
return encrypted
|
|
19
|
+
|
|
20
|
+
def decrypt(encrypted_bytes, key):
|
|
21
|
+
# Generate SHA-256 hash of the key
|
|
22
|
+
key_hash = hashlib.sha256(key.encode()).digest() # 32 bytes
|
|
23
|
+
# XOR again with same key to reverse encryption
|
|
24
|
+
decrypted = bytes([encrypted_bytes[i] ^ key_hash[i % len(key_hash)]
|
|
25
|
+
for i in range(len(encrypted_bytes))])
|
|
26
|
+
return decrypted.decode()
|
|
27
|
+
|
|
28
|
+
# ── Main ──────────────────────────────────────────────────────
|
|
29
|
+
message = "Hello World"
|
|
30
|
+
key = "secretkey"
|
|
31
|
+
|
|
32
|
+
print("Original Message :", message)
|
|
33
|
+
|
|
34
|
+
# Encrypt
|
|
35
|
+
encrypted = encrypt(message, key)
|
|
36
|
+
print("Encrypted (hex) :", encrypted.hex())
|
|
37
|
+
|
|
38
|
+
# Decrypt
|
|
39
|
+
decrypted = decrypt(encrypted, key)
|
|
40
|
+
print("Decrypted Message :", decrypted)
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Q3. Implement RSA Cryptographic Algorithm
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
# # RSA Implementation from scratch (no external crypto libraries)
|
|
6
|
+
|
|
7
|
+
# def gcd(a, b):
|
|
8
|
+
# while b:
|
|
9
|
+
# a, b = b, a % b
|
|
10
|
+
# return a
|
|
11
|
+
|
|
12
|
+
# def mod_inverse(e, phi):
|
|
13
|
+
# # Extended Euclidean Algorithm to find modular inverse
|
|
14
|
+
# original_phi = phi
|
|
15
|
+
# x0, x1 = 0, 1
|
|
16
|
+
# if phi == 1:
|
|
17
|
+
# return 0
|
|
18
|
+
# while e > 1:
|
|
19
|
+
# q = e // phi
|
|
20
|
+
# phi, e = e % phi, phi
|
|
21
|
+
# x0, x1 = x1 - q * x0, x0
|
|
22
|
+
# if x1 < 0:
|
|
23
|
+
# x1 += original_phi
|
|
24
|
+
# return x1
|
|
25
|
+
|
|
26
|
+
# def is_prime(n):
|
|
27
|
+
# if n < 2:
|
|
28
|
+
# return False
|
|
29
|
+
# for i in range(2, int(n**0.5) + 1):
|
|
30
|
+
# if n % i == 0:
|
|
31
|
+
# return False
|
|
32
|
+
# return True
|
|
33
|
+
|
|
34
|
+
# def generate_keys():
|
|
35
|
+
# # Two prime numbers p and q
|
|
36
|
+
# p = 61
|
|
37
|
+
# q = 53
|
|
38
|
+
|
|
39
|
+
# n = p * q # n = 3233
|
|
40
|
+
# phi = (p - 1) * (q - 1) # phi = 3120
|
|
41
|
+
|
|
42
|
+
# # Choose e such that 1 < e < phi and gcd(e, phi) = 1
|
|
43
|
+
# e = 17
|
|
44
|
+
# while gcd(e, phi) != 1:
|
|
45
|
+
# e += 2
|
|
46
|
+
|
|
47
|
+
# # Compute d such that d*e ≡ 1 (mod phi)
|
|
48
|
+
# d = mod_inverse(e, phi)
|
|
49
|
+
|
|
50
|
+
# public_key = (e, n)
|
|
51
|
+
# private_key = (d, n)
|
|
52
|
+
# return public_key, private_key
|
|
53
|
+
|
|
54
|
+
# def encrypt(message, public_key):
|
|
55
|
+
# e, n = public_key
|
|
56
|
+
# # Convert each character to its ASCII value, then apply RSA: c = m^e mod n
|
|
57
|
+
# encrypted = [pow(ord(char), e, n) for char in message]
|
|
58
|
+
# return encrypted
|
|
59
|
+
|
|
60
|
+
# def decrypt(encrypted, private_key):
|
|
61
|
+
# d, n = private_key
|
|
62
|
+
# # Reverse RSA: m = c^d mod n, then convert back to character
|
|
63
|
+
# decrypted = ''.join([chr(pow(char, d, n)) for char in encrypted])
|
|
64
|
+
# return decrypted
|
|
65
|
+
|
|
66
|
+
# # ── Main ──────────────────────────────────────────────────────
|
|
67
|
+
# public_key, private_key = generate_keys()
|
|
68
|
+
|
|
69
|
+
# print("RSA Key Generation")
|
|
70
|
+
# print(" Public Key (e, n) :", public_key)
|
|
71
|
+
# print(" Private Key (d, n) :", private_key)
|
|
72
|
+
# print()
|
|
73
|
+
|
|
74
|
+
# message = "Hello World"
|
|
75
|
+
# print("Original Message :", message)
|
|
76
|
+
|
|
77
|
+
# # Encrypt
|
|
78
|
+
# encrypted = encrypt(message, public_key)
|
|
79
|
+
# print("Encrypted :", encrypted)
|
|
80
|
+
|
|
81
|
+
# # Decrypt
|
|
82
|
+
# decrypted = decrypt(encrypted, private_key)
|
|
83
|
+
# print("Decrypted Message :", decrypted)
|
|
84
|
+
|
|
85
|
+
from Crypto.PublicKey import RSA
|
|
86
|
+
from Crypto.Cipher import PKCS1_OAEP
|
|
87
|
+
|
|
88
|
+
# Generate keys
|
|
89
|
+
key = RSA.generate(2048)
|
|
90
|
+
public_key = key.publickey()
|
|
91
|
+
|
|
92
|
+
# Encrypt
|
|
93
|
+
message = "Hello RSA"
|
|
94
|
+
cipher = PKCS1_OAEP.new(public_key)
|
|
95
|
+
encrypted = cipher.encrypt(message.encode())
|
|
96
|
+
|
|
97
|
+
print("Encrypted:", encrypted)
|
|
98
|
+
|
|
99
|
+
# Decrypt
|
|
100
|
+
cipher_dec = PKCS1_OAEP.new(key)
|
|
101
|
+
decrypted = cipher_dec.decrypt(encrypted)
|
|
102
|
+
|
|
103
|
+
print("Decrypted:", decrypted.decode())
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Q4. Create a simple blockchain using Proof of Work (PoW)
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import hashlib
|
|
6
|
+
import time
|
|
7
|
+
|
|
8
|
+
class Block:
|
|
9
|
+
def __init__(self, index, data, previous_hash):
|
|
10
|
+
self.index = index
|
|
11
|
+
self.timestamp = time.time()
|
|
12
|
+
self.data = data
|
|
13
|
+
self.previous_hash = previous_hash
|
|
14
|
+
self.nonce = 0
|
|
15
|
+
self.hash = self.proof_of_work()
|
|
16
|
+
|
|
17
|
+
def compute_hash(self):
|
|
18
|
+
block_string = f"{self.index}{self.timestamp}{self.data}{self.previous_hash}{self.nonce}"
|
|
19
|
+
return hashlib.sha256(block_string.encode()).hexdigest()
|
|
20
|
+
|
|
21
|
+
def proof_of_work(self, difficulty=4):
|
|
22
|
+
# Keep hashing until hash starts with required number of zeros
|
|
23
|
+
target = "0" * difficulty
|
|
24
|
+
while True:
|
|
25
|
+
self.hash = self.compute_hash()
|
|
26
|
+
if self.hash.startswith(target):
|
|
27
|
+
return self.hash
|
|
28
|
+
self.nonce += 1
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
class Blockchain:
|
|
32
|
+
def __init__(self):
|
|
33
|
+
self.chain = []
|
|
34
|
+
self.create_genesis_block()
|
|
35
|
+
|
|
36
|
+
def create_genesis_block(self):
|
|
37
|
+
genesis_block = Block(0, "Genesis Block", "0")
|
|
38
|
+
self.chain.append(genesis_block)
|
|
39
|
+
|
|
40
|
+
def get_last_block(self):
|
|
41
|
+
return self.chain[-1]
|
|
42
|
+
|
|
43
|
+
def add_block(self, data):
|
|
44
|
+
last_block = self.get_last_block()
|
|
45
|
+
new_block = Block(len(self.chain), data, last_block.hash)
|
|
46
|
+
self.chain.append(new_block)
|
|
47
|
+
|
|
48
|
+
def display_chain(self):
|
|
49
|
+
for block in self.chain:
|
|
50
|
+
print(f"\nBlock Index : {block.index}")
|
|
51
|
+
print(f"Timestamp : {block.timestamp}")
|
|
52
|
+
print(f"Data : {block.data}")
|
|
53
|
+
print(f"Nonce : {block.nonce}")
|
|
54
|
+
print(f"Previous Hash : {block.previous_hash}")
|
|
55
|
+
print(f"Hash : {block.hash}")
|
|
56
|
+
print("-" * 64)
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
# ── Main ──────────────────────────────────────────────────────
|
|
60
|
+
blockchain = Blockchain()
|
|
61
|
+
|
|
62
|
+
blockchain.add_block("Transaction: Alice pays Bob 10 BTC")
|
|
63
|
+
blockchain.add_block("Transaction: Bob pays Carol 5 BTC")
|
|
64
|
+
blockchain.add_block("Transaction: Carol pays Dave 2 BTC")
|
|
65
|
+
|
|
66
|
+
print("=" * 64)
|
|
67
|
+
print(" Simple Blockchain with Proof of Work (PoW)")
|
|
68
|
+
print("=" * 64)
|
|
69
|
+
blockchain.display_chain()
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Q5. Demonstrate sending of a digitally signed document
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import hashlib
|
|
6
|
+
|
|
7
|
+
# ── RSA helper functions (from scratch) ───────────────────────
|
|
8
|
+
|
|
9
|
+
def gcd(a, b):
|
|
10
|
+
while b:
|
|
11
|
+
a, b = b, a % b
|
|
12
|
+
return a
|
|
13
|
+
|
|
14
|
+
def mod_inverse(e, phi):
|
|
15
|
+
original_phi = phi
|
|
16
|
+
x0, x1 = 0, 1
|
|
17
|
+
if phi == 1:
|
|
18
|
+
return 0
|
|
19
|
+
while e > 1:
|
|
20
|
+
q = e // phi
|
|
21
|
+
phi, e = e % phi, phi
|
|
22
|
+
x0, x1 = x1 - q * x0, x0
|
|
23
|
+
if x1 < 0:
|
|
24
|
+
x1 += original_phi
|
|
25
|
+
return x1
|
|
26
|
+
|
|
27
|
+
def generate_rsa_keys():
|
|
28
|
+
p, q = 61, 53
|
|
29
|
+
n = p * q
|
|
30
|
+
phi = (p - 1) * (q - 1)
|
|
31
|
+
e = 17
|
|
32
|
+
d = mod_inverse(e, phi)
|
|
33
|
+
return (e, n), (d, n) # public_key, private_key
|
|
34
|
+
|
|
35
|
+
# ── Digital Signature functions ───────────────────────────────
|
|
36
|
+
|
|
37
|
+
def hash_document(document):
|
|
38
|
+
"""Compute SHA-256 digest of the document and return as integer."""
|
|
39
|
+
digest_hex = hashlib.sha256(document.encode()).hexdigest()
|
|
40
|
+
# Use only first 8 hex chars (32-bit int) to keep within RSA key space
|
|
41
|
+
return int(digest_hex[:8], 16)
|
|
42
|
+
|
|
43
|
+
def sign_document(document, private_key):
|
|
44
|
+
"""Sender signs the document hash using private key."""
|
|
45
|
+
d, n = private_key
|
|
46
|
+
doc_hash = hash_document(document)
|
|
47
|
+
doc_hash_mod = doc_hash % n # ensure hash fits within key space
|
|
48
|
+
signature = pow(doc_hash_mod, d, n) # signature = hash^d mod n
|
|
49
|
+
return signature
|
|
50
|
+
|
|
51
|
+
def verify_signature(document, signature, public_key):
|
|
52
|
+
"""Receiver verifies the document using the sender's public key."""
|
|
53
|
+
e, n = public_key
|
|
54
|
+
doc_hash = hash_document(document)
|
|
55
|
+
doc_hash_mod = doc_hash % n
|
|
56
|
+
# Decrypt signature using public key
|
|
57
|
+
decrypted_hash = pow(signature, e, n)
|
|
58
|
+
return decrypted_hash == doc_hash_mod
|
|
59
|
+
|
|
60
|
+
# ── Main ──────────────────────────────────────────────────────
|
|
61
|
+
|
|
62
|
+
public_key, private_key = generate_rsa_keys()
|
|
63
|
+
|
|
64
|
+
document = "This is a digitally signed document sent from Alice to Bob."
|
|
65
|
+
|
|
66
|
+
print("=" * 60)
|
|
67
|
+
print(" Digitally Signed Document Demo")
|
|
68
|
+
print("=" * 60)
|
|
69
|
+
print()
|
|
70
|
+
print("[ SENDER - Alice ]")
|
|
71
|
+
print(f" Document : {document}")
|
|
72
|
+
print(f" Public Key : {public_key}")
|
|
73
|
+
print(f" Private Key : {private_key}")
|
|
74
|
+
|
|
75
|
+
# Alice signs the document
|
|
76
|
+
signature = sign_document(document, private_key)
|
|
77
|
+
print(f" Signature : {signature}")
|
|
78
|
+
print()
|
|
79
|
+
print(" Alice sends the document + signature to Bob.")
|
|
80
|
+
|
|
81
|
+
print()
|
|
82
|
+
print("[ RECEIVER - Bob ]")
|
|
83
|
+
print(f" Document : {document}")
|
|
84
|
+
print(f" Signature : {signature}")
|
|
85
|
+
|
|
86
|
+
# Bob verifies using Alice's public key
|
|
87
|
+
is_valid = verify_signature(document, signature, public_key)
|
|
88
|
+
|
|
89
|
+
if is_valid:
|
|
90
|
+
print(" Verification : SUCCESS - Document is authentic and untampered.")
|
|
91
|
+
else:
|
|
92
|
+
print(" Verification : FAILED - Document may be tampered!")
|
|
93
|
+
|
|
94
|
+
# ── Demonstrate tampering ─────────────────────────────────────
|
|
95
|
+
print()
|
|
96
|
+
print("[ TAMPERING DEMO ]")
|
|
97
|
+
tampered_document = "This is a TAMPERED document."
|
|
98
|
+
print(f" Tampered Doc : {tampered_document}")
|
|
99
|
+
is_valid_tampered = verify_signature(tampered_document, signature, public_key)
|
|
100
|
+
|
|
101
|
+
if is_valid_tampered:
|
|
102
|
+
print(" Verification : SUCCESS")
|
|
103
|
+
else:
|
|
104
|
+
print(" Verification : FAILED - Tampering detected! Signature is invalid.")
|