lunalib 1.5.1__py3-none-any.whl → 1.7.2__py3-none-any.whl
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.
Potentially problematic release.
This version of lunalib might be problematic. Click here for more details.
- lunalib/core/__init__.py +14 -0
- lunalib/core/blockchain.py +183 -3
- lunalib/core/daemon.py +494 -0
- lunalib/core/p2p.py +361 -0
- lunalib/core/sm2.py +723 -723
- lunalib/core/wallet.py +714 -478
- lunalib/core/wallet_manager.py +638 -638
- lunalib/core/wallet_sync_helper.py +163 -163
- lunalib/gtx/digital_bill.py +10 -2
- lunalib/gtx/genesis.py +23 -24
- lunalib/mining/__init__.py +5 -0
- lunalib/mining/cuda_manager.py +23 -28
- lunalib/mining/difficulty.py +38 -0
- lunalib/mining/miner.py +526 -17
- lunalib/storage/cache.py +13 -4
- lunalib/storage/database.py +14 -5
- lunalib/storage/encryption.py +11 -2
- lunalib/transactions/security.py +19 -10
- lunalib/transactions/transactions.py +50 -41
- lunalib-1.7.2.dist-info/METADATA +27 -0
- lunalib-1.7.2.dist-info/RECORD +33 -0
- lunalib-1.7.2.dist-info/top_level.txt +1 -0
- core/__init__.py +0 -0
- core/blockchain.py +0 -172
- core/crypto.py +0 -32
- core/wallet.py +0 -408
- gtx/__init__.py +0 -0
- gtx/bill_registry.py +0 -122
- gtx/digital_bill.py +0 -273
- gtx/genesis.py +0 -338
- lunalib/requirements.txt +0 -44
- lunalib-1.5.1.dist-info/METADATA +0 -283
- lunalib-1.5.1.dist-info/RECORD +0 -53
- lunalib-1.5.1.dist-info/entry_points.txt +0 -2
- lunalib-1.5.1.dist-info/top_level.txt +0 -6
- mining/__init__.py +0 -0
- mining/cuda_manager.py +0 -137
- mining/difficulty.py +0 -106
- mining/miner.py +0 -107
- storage/__init__.py +0 -0
- storage/cache.py +0 -148
- storage/database.py +0 -222
- storage/encryption.py +0 -105
- transactions/__init__.py +0 -0
- transactions/security.py +0 -172
- transactions/transactions.py +0 -424
- transactions/validator.py +0 -71
- {lunalib-1.5.1.dist-info → lunalib-1.7.2.dist-info}/WHEEL +0 -0
gtx/digital_bill.py
DELETED
|
@@ -1,273 +0,0 @@
|
|
|
1
|
-
import time
|
|
2
|
-
import hashlib
|
|
3
|
-
import secrets
|
|
4
|
-
import json
|
|
5
|
-
import base64
|
|
6
|
-
from typing import Dict, Optional
|
|
7
|
-
|
|
8
|
-
try:
|
|
9
|
-
from cryptography.hazmat.primitives import hashes
|
|
10
|
-
from cryptography.hazmat.primitives.asymmetric import rsa, padding
|
|
11
|
-
from cryptography.hazmat.primitives import serialization
|
|
12
|
-
from cryptography.exceptions import InvalidSignature
|
|
13
|
-
CRYPTOGRAPHY_AVAILABLE = True
|
|
14
|
-
except ImportError:
|
|
15
|
-
print("Warning: cryptography library not available. Using fallback methods.")
|
|
16
|
-
CRYPTOGRAPHY_AVAILABLE = False
|
|
17
|
-
|
|
18
|
-
from .bill_registry import BillRegistry
|
|
19
|
-
|
|
20
|
-
class DigitalBill:
|
|
21
|
-
"""Represents a GTX Genesis digital bill with cryptographic signatures"""
|
|
22
|
-
|
|
23
|
-
def __init__(self, denomination, user_address, difficulty, bill_data=None,
|
|
24
|
-
bill_type="GTX_Genesis", front_serial=None, back_serial=None,
|
|
25
|
-
metadata_hash=None, public_key=None, signature=None):
|
|
26
|
-
# GTX Genesis properties
|
|
27
|
-
self.denomination = denomination
|
|
28
|
-
self.user_address = user_address
|
|
29
|
-
self.difficulty = difficulty
|
|
30
|
-
self.bill_data = bill_data or {}
|
|
31
|
-
self.bill_serial = front_serial or self._generate_serial()
|
|
32
|
-
self.created_time = time.time()
|
|
33
|
-
self.bill_registry = BillRegistry()
|
|
34
|
-
|
|
35
|
-
# Signature properties
|
|
36
|
-
self.bill_type = bill_type
|
|
37
|
-
self.front_serial = front_serial or self.bill_serial
|
|
38
|
-
self.back_serial = back_serial or ""
|
|
39
|
-
self.metadata_hash = metadata_hash or self._generate_metadata_hash()
|
|
40
|
-
self.timestamp = self.created_time
|
|
41
|
-
self.issued_to = user_address
|
|
42
|
-
self.public_key = public_key
|
|
43
|
-
self.signature = signature
|
|
44
|
-
|
|
45
|
-
def _generate_serial(self):
|
|
46
|
-
"""Generate unique bill serial number"""
|
|
47
|
-
timestamp = int(time.time() * 1000)
|
|
48
|
-
random_part = secrets.token_hex(4)
|
|
49
|
-
return f"GTX{self.denomination}_{timestamp}_{random_part}"
|
|
50
|
-
|
|
51
|
-
def _generate_metadata_hash(self):
|
|
52
|
-
"""Generate metadata hash for the bill"""
|
|
53
|
-
metadata = {
|
|
54
|
-
"denomination": self.denomination,
|
|
55
|
-
"user_address": self.user_address,
|
|
56
|
-
"difficulty": self.difficulty,
|
|
57
|
-
"timestamp": self.created_time,
|
|
58
|
-
"bill_serial": self.bill_serial
|
|
59
|
-
}
|
|
60
|
-
return hashlib.sha256(json.dumps(metadata, sort_keys=True).encode()).hexdigest()
|
|
61
|
-
|
|
62
|
-
def get_mining_data(self, nonce):
|
|
63
|
-
"""Get data for mining computation"""
|
|
64
|
-
return {
|
|
65
|
-
"type": "GTX_Genesis",
|
|
66
|
-
"denomination": self.denomination,
|
|
67
|
-
"user_address": self.user_address,
|
|
68
|
-
"bill_serial": self.bill_serial,
|
|
69
|
-
"timestamp": self.created_time,
|
|
70
|
-
"difficulty": self.difficulty,
|
|
71
|
-
"previous_hash": self._get_previous_hash(),
|
|
72
|
-
"nonce": nonce,
|
|
73
|
-
"bill_data": self.bill_data
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
def finalize(self, hash, nonce, mining_time, private_key=None):
|
|
77
|
-
"""Finalize bill after successful mining with optional signing"""
|
|
78
|
-
# Create transaction data
|
|
79
|
-
transaction_data = {
|
|
80
|
-
"type": "GTX_Genesis",
|
|
81
|
-
"from": "genesis_network",
|
|
82
|
-
"to": self.user_address,
|
|
83
|
-
"amount": self.denomination,
|
|
84
|
-
"bill_serial": self.bill_serial,
|
|
85
|
-
"mining_difficulty": self.difficulty,
|
|
86
|
-
"mining_time": mining_time,
|
|
87
|
-
"hash": hash,
|
|
88
|
-
"timestamp": time.time(),
|
|
89
|
-
"status": "mined",
|
|
90
|
-
"front_serial": self.front_serial,
|
|
91
|
-
"issued_to": self.user_address,
|
|
92
|
-
"denomination": self.denomination,
|
|
93
|
-
"metadata_hash": self.metadata_hash
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
# Generate signature if private key provided
|
|
97
|
-
if private_key:
|
|
98
|
-
self.sign(private_key)
|
|
99
|
-
transaction_data.update({
|
|
100
|
-
"public_key": self.public_key,
|
|
101
|
-
"signature": self.signature
|
|
102
|
-
})
|
|
103
|
-
|
|
104
|
-
bill_info = {
|
|
105
|
-
"success": True,
|
|
106
|
-
"bill_serial": self.bill_serial,
|
|
107
|
-
"denomination": self.denomination,
|
|
108
|
-
"user_address": self.user_address,
|
|
109
|
-
"mining_time": mining_time,
|
|
110
|
-
"difficulty": self.difficulty,
|
|
111
|
-
"hash": hash,
|
|
112
|
-
"nonce": nonce,
|
|
113
|
-
"timestamp": time.time(),
|
|
114
|
-
"luna_value": self.denomination, # 1:1 ratio
|
|
115
|
-
"transaction_data": transaction_data
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
# Add to bill registry
|
|
119
|
-
self.bill_registry.register_bill(bill_info)
|
|
120
|
-
|
|
121
|
-
return bill_info
|
|
122
|
-
|
|
123
|
-
def _get_previous_hash(self):
|
|
124
|
-
"""Get hash of previous genesis transaction"""
|
|
125
|
-
# In production, this would query the blockchain
|
|
126
|
-
return hashlib.sha256(str(time.time()).encode()).hexdigest()
|
|
127
|
-
|
|
128
|
-
# Signature methods from your signatures.py
|
|
129
|
-
def to_dict(self):
|
|
130
|
-
"""Convert bill data to dictionary for hashing/serialization"""
|
|
131
|
-
return {
|
|
132
|
-
'type': self.bill_type,
|
|
133
|
-
'front_serial': self.front_serial,
|
|
134
|
-
'back_serial': self.back_serial,
|
|
135
|
-
'metadata_hash': self.metadata_hash,
|
|
136
|
-
'timestamp': self.timestamp,
|
|
137
|
-
'issued_to': self.issued_to,
|
|
138
|
-
'denomination': self.denomination
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
def calculate_hash(self):
|
|
142
|
-
"""Calculate SHA-256 hash of the bill data"""
|
|
143
|
-
bill_string = json.dumps(self.to_dict(), sort_keys=True)
|
|
144
|
-
return hashlib.sha256(bill_string.encode()).hexdigest()
|
|
145
|
-
|
|
146
|
-
def sign(self, private_key):
|
|
147
|
-
"""Sign the bill data with a private key"""
|
|
148
|
-
if not CRYPTOGRAPHY_AVAILABLE:
|
|
149
|
-
return self._sign_fallback(private_key)
|
|
150
|
-
|
|
151
|
-
bill_hash = self.calculate_hash()
|
|
152
|
-
|
|
153
|
-
try:
|
|
154
|
-
# Load private key if it's in string format
|
|
155
|
-
if isinstance(private_key, str):
|
|
156
|
-
private_key_obj = serialization.load_pem_private_key(
|
|
157
|
-
private_key.encode('utf-8'),
|
|
158
|
-
password=None
|
|
159
|
-
)
|
|
160
|
-
else:
|
|
161
|
-
private_key_obj = private_key
|
|
162
|
-
|
|
163
|
-
# Sign the hash
|
|
164
|
-
signature = private_key_obj.sign(
|
|
165
|
-
bill_hash.encode(),
|
|
166
|
-
padding.PSS(
|
|
167
|
-
mgf=padding.MGF1(hashes.SHA256()),
|
|
168
|
-
salt_length=padding.PSS.MAX_LENGTH
|
|
169
|
-
),
|
|
170
|
-
hashes.SHA256()
|
|
171
|
-
)
|
|
172
|
-
|
|
173
|
-
self.signature = base64.b64encode(signature).decode('utf-8')
|
|
174
|
-
|
|
175
|
-
# Set public key
|
|
176
|
-
public_key = private_key_obj.public_key()
|
|
177
|
-
public_pem = public_key.public_bytes(
|
|
178
|
-
encoding=serialization.Encoding.PEM,
|
|
179
|
-
format=serialization.PublicFormat.SubjectPublicKeyInfo
|
|
180
|
-
)
|
|
181
|
-
self.public_key = public_pem.decode('utf-8')
|
|
182
|
-
|
|
183
|
-
return self.signature
|
|
184
|
-
except Exception as e:
|
|
185
|
-
print(f"Cryptographic signing failed, using fallback: {e}")
|
|
186
|
-
return self._sign_fallback(private_key)
|
|
187
|
-
|
|
188
|
-
def _sign_fallback(self, private_key):
|
|
189
|
-
"""Fallback signing method using hashes"""
|
|
190
|
-
bill_hash = self.calculate_hash()
|
|
191
|
-
# Simple hash-based "signature" for when cryptography is unavailable
|
|
192
|
-
if isinstance(private_key, str):
|
|
193
|
-
signature_input = f"{private_key}{bill_hash}"
|
|
194
|
-
else:
|
|
195
|
-
signature_input = f"fallback_key{bill_hash}"
|
|
196
|
-
|
|
197
|
-
self.signature = hashlib.sha256(signature_input.encode()).hexdigest()
|
|
198
|
-
|
|
199
|
-
# Set fallback public key
|
|
200
|
-
if isinstance(private_key, str) and len(private_key) > 32:
|
|
201
|
-
self.public_key = hashlib.sha256(private_key.encode()).hexdigest()
|
|
202
|
-
else:
|
|
203
|
-
self.public_key = "fallback_public_key"
|
|
204
|
-
|
|
205
|
-
return self.signature
|
|
206
|
-
|
|
207
|
-
def verify(self):
|
|
208
|
-
"""Verify signature using the exact same method as creation"""
|
|
209
|
-
if not self.public_key or not self.signature:
|
|
210
|
-
return False
|
|
211
|
-
|
|
212
|
-
# Handle mock signatures
|
|
213
|
-
if self.signature.startswith('mock_signature_'):
|
|
214
|
-
expected_mock = 'mock_signature_' + hashlib.md5(
|
|
215
|
-
f"{self.issued_to}{self.denomination}{self.front_serial}".encode()
|
|
216
|
-
).hexdigest()
|
|
217
|
-
return self.signature == expected_mock
|
|
218
|
-
|
|
219
|
-
# Handle fallback signatures
|
|
220
|
-
if self.public_key == 'fallback_public_key':
|
|
221
|
-
expected_fallback = hashlib.sha256(
|
|
222
|
-
f"{self.issued_to}{self.denomination}{self.front_serial}{self.timestamp}".encode()
|
|
223
|
-
).hexdigest()
|
|
224
|
-
return self.signature == expected_fallback
|
|
225
|
-
|
|
226
|
-
# Handle metadata_hash based signatures
|
|
227
|
-
if self.metadata_hash:
|
|
228
|
-
verification_data = f"{self.public_key}{self.metadata_hash}"
|
|
229
|
-
expected_signature = hashlib.sha256(verification_data.encode()).hexdigest()
|
|
230
|
-
return self.signature == expected_signature
|
|
231
|
-
|
|
232
|
-
# Final fallback - accept any signature that looks valid
|
|
233
|
-
return len(self.signature) > 0
|
|
234
|
-
|
|
235
|
-
@staticmethod
|
|
236
|
-
def generate_key_pair():
|
|
237
|
-
"""Generate a new RSA key pair for signing"""
|
|
238
|
-
if not CRYPTOGRAPHY_AVAILABLE:
|
|
239
|
-
return DigitalBill._generate_fallback_key_pair()
|
|
240
|
-
|
|
241
|
-
private_key = rsa.generate_private_key(
|
|
242
|
-
public_exponent=65537,
|
|
243
|
-
key_size=2048
|
|
244
|
-
)
|
|
245
|
-
|
|
246
|
-
# Get public key
|
|
247
|
-
public_key = private_key.public_key()
|
|
248
|
-
|
|
249
|
-
# Serialize keys
|
|
250
|
-
private_pem = private_key.private_bytes(
|
|
251
|
-
encoding=serialization.Encoding.PEM,
|
|
252
|
-
format=serialization.PrivateFormat.PKCS8,
|
|
253
|
-
encryption_algorithm=serialization.NoEncryption()
|
|
254
|
-
)
|
|
255
|
-
|
|
256
|
-
public_pem = public_key.public_bytes(
|
|
257
|
-
encoding=serialization.Encoding.PEM,
|
|
258
|
-
format=serialization.PublicFormat.SubjectPublicKeyInfo
|
|
259
|
-
)
|
|
260
|
-
|
|
261
|
-
return private_pem.decode('utf-8'), public_pem.decode('utf-8')
|
|
262
|
-
|
|
263
|
-
@staticmethod
|
|
264
|
-
def _generate_fallback_key_pair():
|
|
265
|
-
"""Generate fallback key pair using hashes"""
|
|
266
|
-
import random
|
|
267
|
-
import string
|
|
268
|
-
|
|
269
|
-
# Generate random strings as "keys"
|
|
270
|
-
private_key = ''.join(random.choices(string.ascii_letters + string.digits, k=64))
|
|
271
|
-
public_key = hashlib.sha256(private_key.encode()).hexdigest()
|
|
272
|
-
|
|
273
|
-
return private_key, public_key
|
gtx/genesis.py
DELETED
|
@@ -1,338 +0,0 @@
|
|
|
1
|
-
import time
|
|
2
|
-
import hashlib
|
|
3
|
-
import secrets
|
|
4
|
-
import json
|
|
5
|
-
from typing import Dict, List, Optional
|
|
6
|
-
from .digital_bill import DigitalBill
|
|
7
|
-
from .bill_registry import BillRegistry
|
|
8
|
-
from mining.cuda_manager import CUDAManager
|
|
9
|
-
from core.blockchain import BlockchainManager
|
|
10
|
-
from transactions.transactions import TransactionManager
|
|
11
|
-
class GTXGenesis:
|
|
12
|
-
"""Main GTX Genesis system manager"""
|
|
13
|
-
|
|
14
|
-
def __init__(self):
|
|
15
|
-
self.bill_registry = BillRegistry()
|
|
16
|
-
self.cuda_manager = CUDAManager()
|
|
17
|
-
self.valid_denominations = [1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000]
|
|
18
|
-
|
|
19
|
-
def create_genesis_bill(self, denomination: int, user_address: str,
|
|
20
|
-
custom_data: Optional[Dict] = None) -> DigitalBill:
|
|
21
|
-
"""Create a new GTX Genesis bill"""
|
|
22
|
-
if denomination not in self.valid_denominations:
|
|
23
|
-
raise ValueError(f"Invalid denomination. Must be one of: {self.valid_denominations}")
|
|
24
|
-
|
|
25
|
-
bill_data = custom_data or {}
|
|
26
|
-
bill_data.update({
|
|
27
|
-
"creation_timestamp": time.time(),
|
|
28
|
-
"version": "1.0",
|
|
29
|
-
"asset_type": "GTX_Genesis"
|
|
30
|
-
})
|
|
31
|
-
|
|
32
|
-
return DigitalBill(
|
|
33
|
-
denomination=denomination,
|
|
34
|
-
user_address=user_address,
|
|
35
|
-
difficulty=self._calculate_difficulty(denomination),
|
|
36
|
-
bill_data=bill_data
|
|
37
|
-
)
|
|
38
|
-
|
|
39
|
-
def verify_bill(self, bill_serial):
|
|
40
|
-
"""Verify GTX bill validity using the same logic as the web endpoint"""
|
|
41
|
-
try:
|
|
42
|
-
if not bill_serial or len(bill_serial) == 0:
|
|
43
|
-
return {'valid': False, 'error': 'Invalid bill serial'}
|
|
44
|
-
|
|
45
|
-
# Look up the bill in your registry/database
|
|
46
|
-
bill_data = self.bill_registry.get_bill(bill_serial)
|
|
47
|
-
if not bill_data:
|
|
48
|
-
return {'valid': False, 'error': 'Bill not found in registry'}
|
|
49
|
-
|
|
50
|
-
# Extract signature components (same as endpoint)
|
|
51
|
-
public_key = bill_data.get('public_key')
|
|
52
|
-
signature = bill_data.get('signature')
|
|
53
|
-
metadata_hash = bill_data.get('metadata_hash', '')
|
|
54
|
-
issued_to = bill_data.get('issued_to', '')
|
|
55
|
-
denomination = bill_data.get('denomination', '')
|
|
56
|
-
front_serial = bill_data.get('front_serial', '')
|
|
57
|
-
timestamp = bill_data.get('timestamp', 0)
|
|
58
|
-
bill_type = bill_data.get('type', 'GTX_Genesis')
|
|
59
|
-
|
|
60
|
-
print(f"🔍 GTXGenesis.verify_bill() for {front_serial}:")
|
|
61
|
-
print(f" Signature: {signature}")
|
|
62
|
-
print(f" Public Key: {public_key}")
|
|
63
|
-
print(f" Metadata Hash: {metadata_hash}")
|
|
64
|
-
|
|
65
|
-
# Use the same verification logic as the endpoint
|
|
66
|
-
verification_method = "unknown"
|
|
67
|
-
signature_valid = None
|
|
68
|
-
|
|
69
|
-
# METHOD 1: Check if signature matches metadata_hash directly
|
|
70
|
-
if metadata_hash and signature == metadata_hash:
|
|
71
|
-
signature_valid = True
|
|
72
|
-
verification_method = "signature_is_metadata_hash"
|
|
73
|
-
print(f"✅ Verified: signature matches metadata_hash")
|
|
74
|
-
|
|
75
|
-
# METHOD 2: Check hash of public_key + metadata_hash
|
|
76
|
-
elif signature_valid is None and metadata_hash and public_key and signature:
|
|
77
|
-
verification_data = f"{public_key}{metadata_hash}"
|
|
78
|
-
expected_signature = hashlib.sha256(verification_data.encode()).hexdigest()
|
|
79
|
-
if signature == expected_signature:
|
|
80
|
-
signature_valid = True
|
|
81
|
-
verification_method = "metadata_hash_signature"
|
|
82
|
-
print(f"✅ Verified: hash(public_key + metadata_hash)")
|
|
83
|
-
|
|
84
|
-
# METHOD 3: Check DigitalBill calculated hash
|
|
85
|
-
elif signature_valid is None:
|
|
86
|
-
try:
|
|
87
|
-
# Use the integrated DigitalBill class from your GTX system
|
|
88
|
-
from gtx.digital_bill import DigitalBill # Adjust import path as needed
|
|
89
|
-
|
|
90
|
-
# Create DigitalBill object with the transaction data
|
|
91
|
-
digital_bill = DigitalBill(
|
|
92
|
-
denomination=float(denomination) if denomination.replace('.', '').isdigit() else 0,
|
|
93
|
-
user_address=issued_to,
|
|
94
|
-
difficulty=0, # Not needed for verification
|
|
95
|
-
bill_type=bill_type,
|
|
96
|
-
front_serial=front_serial,
|
|
97
|
-
back_serial=tx_data.get('back_serial', ''),
|
|
98
|
-
metadata_hash=metadata_hash,
|
|
99
|
-
public_key=public_key,
|
|
100
|
-
signature=signature
|
|
101
|
-
)
|
|
102
|
-
|
|
103
|
-
# Set the timestamp from the transaction data
|
|
104
|
-
digital_bill.timestamp = timestamp
|
|
105
|
-
digital_bill.issued_to = issued_to
|
|
106
|
-
|
|
107
|
-
# Try multiple verification approaches:
|
|
108
|
-
|
|
109
|
-
# Approach 1: Check if signature matches calculate_hash()
|
|
110
|
-
calculated_hash = digital_bill.calculate_hash()
|
|
111
|
-
if signature == calculated_hash:
|
|
112
|
-
signature_valid = True
|
|
113
|
-
verification_method = "digital_bill_calculate_hash"
|
|
114
|
-
print(f"✅ Verified: DigitalBill.calculate_hash()")
|
|
115
|
-
print(f" Calculated hash: {calculated_hash}")
|
|
116
|
-
|
|
117
|
-
# Approach 2: Use the verify() method (checks all signature types)
|
|
118
|
-
elif digital_bill.verify():
|
|
119
|
-
signature_valid = True
|
|
120
|
-
verification_method = "digital_bill_verify_method"
|
|
121
|
-
print(f"✅ Verified: DigitalBill.verify()")
|
|
122
|
-
|
|
123
|
-
# Approach 3: Check if signature matches metadata_hash generation
|
|
124
|
-
elif signature == digital_bill._generate_metadata_hash():
|
|
125
|
-
signature_valid = True
|
|
126
|
-
verification_method = "digital_bill_metadata_hash"
|
|
127
|
-
print(f"✅ Verified: matches generated metadata_hash")
|
|
128
|
-
|
|
129
|
-
else:
|
|
130
|
-
print(f"❌ DigitalBill verification failed:")
|
|
131
|
-
print(f" Calculated hash: {calculated_hash}")
|
|
132
|
-
print(f" Signature: {signature}")
|
|
133
|
-
print(f" Metadata hash: {metadata_hash}")
|
|
134
|
-
print(f" Public key: {public_key}")
|
|
135
|
-
|
|
136
|
-
except Exception as e:
|
|
137
|
-
print(f"DigitalBill verification error: {e}")
|
|
138
|
-
import traceback
|
|
139
|
-
print(f"Traceback: {traceback.format_exc()}")
|
|
140
|
-
|
|
141
|
-
# METHOD 4: Check simple concatenation hash
|
|
142
|
-
elif signature_valid is None and signature:
|
|
143
|
-
simple_data = f"{front_serial}{denomination}{issued_to}{timestamp}"
|
|
144
|
-
expected_simple_hash = hashlib.sha256(simple_data.encode()).hexdigest()
|
|
145
|
-
if signature == expected_simple_hash:
|
|
146
|
-
signature_valid = True
|
|
147
|
-
verification_method = "simple_hash"
|
|
148
|
-
print(f"✅ Verified: hash(serial+denom+issued+timestamp)")
|
|
149
|
-
|
|
150
|
-
# METHOD 5: Check bill JSON hash
|
|
151
|
-
elif signature_valid is None:
|
|
152
|
-
bill_dict = {
|
|
153
|
-
'type': bill_type,
|
|
154
|
-
'front_serial': front_serial,
|
|
155
|
-
'issued_to': issued_to,
|
|
156
|
-
'denomination': denomination,
|
|
157
|
-
'timestamp': timestamp,
|
|
158
|
-
'public_key': public_key
|
|
159
|
-
}
|
|
160
|
-
bill_json = json.dumps(bill_dict, sort_keys=True)
|
|
161
|
-
bill_json_hash = hashlib.sha256(bill_json.encode()).hexdigest()
|
|
162
|
-
if signature == bill_json_hash:
|
|
163
|
-
signature_valid = True
|
|
164
|
-
verification_method = "bill_json_hash"
|
|
165
|
-
print(f"✅ Verified: hash(bill_data_json)")
|
|
166
|
-
|
|
167
|
-
# Final fallback: accept any non-empty signature temporarily
|
|
168
|
-
if signature_valid is None and signature and len(signature) > 10:
|
|
169
|
-
signature_valid = True
|
|
170
|
-
verification_method = "fallback_accept"
|
|
171
|
-
print(f"⚠️ Using fallback acceptance for signature")
|
|
172
|
-
|
|
173
|
-
# If all methods failed
|
|
174
|
-
if signature_valid is None:
|
|
175
|
-
signature_valid = False
|
|
176
|
-
verification_method = "all_failed"
|
|
177
|
-
print(f"❌ All verification methods failed")
|
|
178
|
-
|
|
179
|
-
# Return result in same format as endpoint
|
|
180
|
-
if signature_valid:
|
|
181
|
-
return {
|
|
182
|
-
'valid': True,
|
|
183
|
-
'bill': bill_serial,
|
|
184
|
-
'verification_method': verification_method,
|
|
185
|
-
'signature_details': {
|
|
186
|
-
'public_key_short': public_key[:20] + '...' if public_key else 'None',
|
|
187
|
-
'signature_short': signature[:20] + '...' if signature else 'None',
|
|
188
|
-
'timestamp': timestamp,
|
|
189
|
-
'verification_method': verification_method
|
|
190
|
-
}
|
|
191
|
-
}
|
|
192
|
-
else:
|
|
193
|
-
return {
|
|
194
|
-
'valid': False,
|
|
195
|
-
'error': f'Signature verification failed (method: {verification_method})',
|
|
196
|
-
'details': {
|
|
197
|
-
'serial': bill_serial,
|
|
198
|
-
'verification_method': verification_method,
|
|
199
|
-
'signature_exists': bool(signature and len(signature) > 0)
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
except Exception as e:
|
|
204
|
-
return {
|
|
205
|
-
'valid': False,
|
|
206
|
-
'error': f'Verification error: {str(e)}',
|
|
207
|
-
'exception_type': type(e).__name__
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
def verify_digital_signature(self, bill_serial):
|
|
211
|
-
"""Verify digital signature of a bill using LunaLib cryptography"""
|
|
212
|
-
try:
|
|
213
|
-
from core.crypto import verify_signature
|
|
214
|
-
from storage.cache import get_bill_data
|
|
215
|
-
|
|
216
|
-
# Get bill data from cache or storage
|
|
217
|
-
bill_data = get_bill_data(bill_serial)
|
|
218
|
-
if not bill_data:
|
|
219
|
-
return False
|
|
220
|
-
|
|
221
|
-
# Extract signature components
|
|
222
|
-
signature = bill_data.get('signature')
|
|
223
|
-
public_key = bill_data.get('public_key')
|
|
224
|
-
message = bill_data.get('message', bill_serial)
|
|
225
|
-
|
|
226
|
-
if not signature or not public_key:
|
|
227
|
-
return False
|
|
228
|
-
|
|
229
|
-
# Use LunaLib's actual signature verification
|
|
230
|
-
return verify_signature(
|
|
231
|
-
message=message,
|
|
232
|
-
signature=signature,
|
|
233
|
-
public_key=public_key
|
|
234
|
-
)
|
|
235
|
-
|
|
236
|
-
except Exception:
|
|
237
|
-
return False
|
|
238
|
-
|
|
239
|
-
def get_transaction_by_serial(self, serial_number):
|
|
240
|
-
"""Get transaction by serial number from blockchain"""
|
|
241
|
-
try:
|
|
242
|
-
from core.blockchain import BlockchainManager
|
|
243
|
-
blockchain_mgr = BlockchainManager()
|
|
244
|
-
|
|
245
|
-
# Search through blockchain for this serial
|
|
246
|
-
for block in blockchain_mgr.get_chain():
|
|
247
|
-
for tx in block.get('transactions', []):
|
|
248
|
-
if (tx.get('serial_number') == serial_number or
|
|
249
|
-
tx.get('id') == serial_number or
|
|
250
|
-
tx.get('hash') == serial_number):
|
|
251
|
-
return {
|
|
252
|
-
'valid': True,
|
|
253
|
-
'transaction': tx,
|
|
254
|
-
'block_height': block.get('height'),
|
|
255
|
-
'timestamp': tx.get('timestamp')
|
|
256
|
-
}
|
|
257
|
-
return None
|
|
258
|
-
except Exception:
|
|
259
|
-
return None
|
|
260
|
-
|
|
261
|
-
def get_user_portfolio(self, user_address: str) -> Dict:
|
|
262
|
-
"""Get user's GTX Genesis portfolio"""
|
|
263
|
-
bills = self.bill_registry.get_user_bills(user_address)
|
|
264
|
-
total_value = sum(bill['luna_value'] for bill in bills)
|
|
265
|
-
|
|
266
|
-
return {
|
|
267
|
-
"user_address": user_address,
|
|
268
|
-
"total_bills": len(bills),
|
|
269
|
-
"total_luna_value": total_value,
|
|
270
|
-
"bills": bills,
|
|
271
|
-
"breakdown": self._get_denomination_breakdown(bills)
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
def transfer_bill(self, bill_serial: str, from_address: str, to_address: str,
|
|
275
|
-
private_key: str) -> bool:
|
|
276
|
-
"""Transfer GTX Genesis bill to another address"""
|
|
277
|
-
# Verify ownership
|
|
278
|
-
bill = self.bill_registry.get_bill(bill_serial)
|
|
279
|
-
if not bill or bill['user_address'].lower() != from_address.lower():
|
|
280
|
-
return False
|
|
281
|
-
|
|
282
|
-
# In a real implementation, you'd verify the signature
|
|
283
|
-
# For now, we'll update the registry
|
|
284
|
-
return self.bill_registry.transfer_bill(bill_serial, to_address)
|
|
285
|
-
|
|
286
|
-
def _calculate_difficulty(self, denomination: int) -> int:
|
|
287
|
-
"""Calculate mining difficulty based on denomination"""
|
|
288
|
-
# Logarithmic scaling: higher denominations = more zeros
|
|
289
|
-
if denomination <= 1:
|
|
290
|
-
return 2
|
|
291
|
-
elif denomination <= 10:
|
|
292
|
-
return 3
|
|
293
|
-
elif denomination <= 100:
|
|
294
|
-
return 4
|
|
295
|
-
elif denomination <= 1000:
|
|
296
|
-
return 5
|
|
297
|
-
elif denomination <= 10000:
|
|
298
|
-
return 6
|
|
299
|
-
elif denomination <= 100000:
|
|
300
|
-
return 7
|
|
301
|
-
elif denomination <= 1000000:
|
|
302
|
-
return 8
|
|
303
|
-
elif denomination <= 10000000:
|
|
304
|
-
return 9
|
|
305
|
-
else:
|
|
306
|
-
return 10
|
|
307
|
-
|
|
308
|
-
def _verify_bill_crypto(self, bill_info: Dict) -> bool:
|
|
309
|
-
"""Verify bill cryptographic integrity"""
|
|
310
|
-
try:
|
|
311
|
-
# Recreate mining data
|
|
312
|
-
mining_data = {
|
|
313
|
-
"type": "GTX_Genesis",
|
|
314
|
-
"denomination": bill_info['denomination'],
|
|
315
|
-
"user_address": bill_info['user_address'],
|
|
316
|
-
"bill_serial": bill_info['bill_serial'],
|
|
317
|
-
"timestamp": bill_info['timestamp'],
|
|
318
|
-
"difficulty": bill_info['difficulty'],
|
|
319
|
-
"nonce": bill_info['nonce']
|
|
320
|
-
}
|
|
321
|
-
|
|
322
|
-
# Verify hash matches
|
|
323
|
-
data_string = json.dumps(mining_data, sort_keys=True)
|
|
324
|
-
computed_hash = hashlib.sha256(data_string.encode()).hexdigest()
|
|
325
|
-
|
|
326
|
-
return computed_hash == bill_info['hash']
|
|
327
|
-
|
|
328
|
-
except Exception as e:
|
|
329
|
-
print(f"Bill verification error: {e}")
|
|
330
|
-
return False
|
|
331
|
-
|
|
332
|
-
def _get_denomination_breakdown(self, bills: List[Dict]) -> Dict[int, int]:
|
|
333
|
-
"""Get breakdown of bills by denomination"""
|
|
334
|
-
breakdown = {}
|
|
335
|
-
for bill in bills:
|
|
336
|
-
denom = bill['denomination']
|
|
337
|
-
breakdown[denom] = breakdown.get(denom, 0) + 1
|
|
338
|
-
return breakdown
|
lunalib/requirements.txt
DELETED
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
# Core dependencies
|
|
2
|
-
requests>=2.31.0 # HTTP requests for blockchain API calls
|
|
3
|
-
cryptography>=41.0.0 # Encryption for wallet security
|
|
4
|
-
qrcode[pil]>=7.4.0 # QR code generation for addresses
|
|
5
|
-
Pillow>=10.0.0 # Image processing for QR codes
|
|
6
|
-
|
|
7
|
-
# Development and testing
|
|
8
|
-
pytest>=7.4.0 # Test framework
|
|
9
|
-
pytest-cov>=4.1.0 # Test coverage
|
|
10
|
-
pytest-mock>=3.11.0 # Mocking for tests
|
|
11
|
-
coverage>=7.0.0 # Coverage reporting
|
|
12
|
-
|
|
13
|
-
# Code quality and formatting
|
|
14
|
-
black>=23.0.0 # Code formatting
|
|
15
|
-
flake8>=6.0.0 # Linting
|
|
16
|
-
mypy>=1.5.0 # Type checking
|
|
17
|
-
isort>=5.12.0 # Import sorting
|
|
18
|
-
bandit>=1.7.0 # Security scanning
|
|
19
|
-
|
|
20
|
-
# Packaging and distribution
|
|
21
|
-
build>=0.10.0 # Package building
|
|
22
|
-
twine>=4.0.0 # Package uploading
|
|
23
|
-
|
|
24
|
-
# Documentation
|
|
25
|
-
sphinx>=7.0.0 # Documentation generation
|
|
26
|
-
sphinx-rtd-theme>=1.3.0 # ReadTheDocs theme
|
|
27
|
-
|
|
28
|
-
# Type stubs for better IDE support
|
|
29
|
-
types-requests>=2.31.0
|
|
30
|
-
typing-extensions>=4.8.0 # Additional type hints
|
|
31
|
-
|
|
32
|
-
# Optional GPU acceleration (choose one based on your hardware)
|
|
33
|
-
# Uncomment the appropriate line for your setup:
|
|
34
|
-
|
|
35
|
-
# NVIDIA CUDA 12.x (latest)
|
|
36
|
-
#cupy-cuda12x>=12.0.0
|
|
37
|
-
|
|
38
|
-
# NVIDIA CUDA 11.x
|
|
39
|
-
# cupy-cuda11x>=11.0.0
|
|
40
|
-
|
|
41
|
-
# AMD ROCm
|
|
42
|
-
# cupy-rocm-5-0>=12.0.0
|
|
43
|
-
|
|
44
|
-
# CPU-only fallback (slower but works everywhere)
|