Explorar o código

Initial program upload

DebenOldert %!s(int64=4) %!d(string=hai) anos
pai
achega
03e56c4d2c
Modificáronse 9 ficheiros con 261 adicións e 1 borrados
  1. 0 1
      .gitignore
  2. 0 0
      lib/__init__.py
  3. 61 0
      lib/block.py
  4. 13 0
      lib/chain.py
  5. 61 0
      lib/contract.py
  6. 2 0
      lib/rpc.py
  7. 54 0
      lib/transaction.py
  8. 68 0
      main.py
  9. 2 0
      requirements.txt

+ 0 - 1
.gitignore

@@ -14,7 +14,6 @@ dist/
 downloads/
 eggs/
 .eggs/
-lib/
 lib64/
 parts/
 sdist/

+ 0 - 0
lib/__init__.py


+ 61 - 0
lib/block.py

@@ -0,0 +1,61 @@
+import hashlib
+import json
+import time
+
+from lib.transaction import Transaction
+
+
+class Block:
+    def __init__(self, previous=None):
+        self.proof = None
+        self.previous_hash = previous.hash if previous is not None else None
+        self.transactions = []
+        self.hash_value = None
+        self.locked = False
+        self.timestamp = 0
+
+    def add_transaction(self, trans: Transaction):
+        if not self.locked:
+            trans.lock_hash_finish()
+            self.transactions.append(trans)
+            self.log(f'Transaction added: {trans.id}')
+            return True
+        return False
+
+    def lock_hash_finish(self):
+        if not self.locked:
+            self.timestamp = int(time.time())
+            self.hash()
+            self.locked = True
+            self.log('Locked')
+            return True
+        return False
+
+    def serialize(self):
+        trans_serialize = []
+
+        for transaction in self.transactions:
+            trans_serialize.append(transaction.serialize())
+
+        obj = {
+            'timestamp': self.timestamp,
+            'previous': self.previous_hash,
+            'transactions': trans_serialize
+        }
+        self.log(f'Serialized: {len(trans_serialize)} transactions')
+        return obj
+
+    def hash(self):
+        string_object = json.dumps(self.serialize(), sort_keys=True)
+        block_string = string_object.encode()
+
+        raw_hash = hashlib.sha256(block_string)
+        hex_hash = raw_hash.hexdigest()
+
+        self.hash_value = hex_hash
+        self.log(f'Hashed: {self.hash_value}')
+
+        return hex_hash
+
+    def log(self, text):
+        print(f'[ BLOCK ] {text}')

+ 13 - 0
lib/chain.py

@@ -0,0 +1,13 @@
+from lib.block import Block
+
+
+class Chain:
+    def __init__(self):
+        self.pending_transactions = []
+        self.blocks = []
+
+    def add_block(self, block: Block):
+        self.blocks.append(block)
+
+    def last_block(self):
+        return self.blocks[-1]

+ 61 - 0
lib/contract.py

@@ -0,0 +1,61 @@
+import json
+
+
+class Contract(object):
+    class Term:
+        def __init__(self):
+            self.id = None
+            self.title = None
+            self.description = None
+            self.deadline = None
+
+        def set_term(self, title: str, desc: str, deadline: int):
+            self.title = title
+            self.description = desc
+            self.deadline = deadline
+            self.log(f'Set: {self.title}')
+
+        def serialize(self):
+            obj = {
+                'id': self.id,
+                'title': self.title,
+                'description': self.description,
+                'deadline': self.deadline
+            }
+            self.log('Serialized')
+            return obj
+
+        def log(self, text):
+            print(f'[  TERM ] {text}')
+
+    def __init__(self):
+        self.id = None
+        self.client = None
+        self.contractor = None
+        self.deadline = None
+        self.description = None
+        self.title = None
+        self.price = None
+        self.people = None
+        self.initiator = None
+        self.terms = []
+
+    def add_term(self, term: Term):
+        self.log(f'Term added: {term.id} | {term.title}')
+        self.terms.append(term)
+
+    def serialize(self):
+        # TODO: Add all properties
+        term_serialize = []
+        for term in self.terms:
+            term_serialize.append(term.serialize())
+
+        obj = {
+            'id': self.id,
+            'terms': term_serialize
+        }
+        self.log(f'Serialized: {len(term_serialize)} terms')
+        return obj
+
+    def log(self, text):
+        print(f'[ CONTR ] {text}')

+ 2 - 0
lib/rpc.py

@@ -0,0 +1,2 @@
+class RPC:
+    pass

+ 54 - 0
lib/transaction.py

@@ -0,0 +1,54 @@
+import hashlib
+import json
+import time
+
+from lib.contract import Contract
+
+
+class Transaction:
+    def __init__(self):
+        self.id = None
+        self.data = None
+        self.hash_value = None
+        self.locked = False
+        self.timestamp = 0
+
+    def set_contract(self, contract: Contract):
+        if not self.locked:
+            self.data = contract.serialize()
+            self.log(f'Contract set: {contract.id} | {contract.title}')
+            return True
+        return False
+
+    def serialize(self):
+        obj = {
+            'id': self.id,
+            'timestamp': self.timestamp,
+            'data': self.data
+        }
+        self.log(f'Serialized')
+        return obj
+
+    def lock_hash_finish(self):
+        if not self.locked:
+            self.timestamp = int(time.time())
+            self.locked = True
+            self.hash()
+            self.log('Locked')
+            return True
+        return False
+
+    def hash(self):
+        string_object = json.dumps(self.data, sort_keys=True)
+        block_string = string_object.encode()
+
+        raw_hash = hashlib.sha256(block_string)
+        hex_hash = raw_hash.hexdigest()
+
+        self.hash_value = hex_hash
+        self.log(f'Hashed: {self.hash_value}')
+
+        return hex_hash
+
+    def log(self, text):
+        print(f'[ TRANS ] {text}')

+ 68 - 0
main.py

@@ -0,0 +1,68 @@
+import time
+from rpyc.utils.server import ThreadedServer
+
+from lib.chain import Chain, Block
+from lib.rpc import RPC
+from lib.transaction import Transaction
+from lib.contract import Contract
+
+if __name__ == '__main__':
+    # Initialize the chain (Creates empty chain)
+    chain = Chain()
+
+    # Initialize the genesis block
+    initial = Block()
+    initial.previous_hash = 'This is the founding block for our DSP project'
+    initial.proof = 69
+
+    # Lock block
+    initial.lock_hash_finish()
+
+    # Add the genesis block to the chain
+    chain.add_block(block=initial)
+
+    # Chain work starts from here
+
+    # Static chain interaction
+    block1 = Block()
+    block1.previous_hash = chain.last_block().hash_value
+
+    # Create a new contract
+    contract1 = Contract()
+    contract1.title = 'Digital legal handshake'
+    contract1.description = 'Hereby you declare to fulfill the following terms'
+    contract1.deadline = int(time.time())
+    contract1.price = 420
+
+    # Create a new term
+    term1 = Contract.Term()
+    term1.title = 'U gotta work'
+    term1.description = 'Finish this'
+    term1.deadline = int(time.time())
+
+    # Add term to contract1
+    contract1.add_term(term=term1)
+
+    # Bind contract to transaction
+    transaction1 = Transaction()
+    transaction1.set_contract(contract=contract1)
+
+    # Add transaction to current block
+    block1.add_transaction(trans=transaction1)
+
+    # Finish block and all its transactions
+    block1.lock_hash_finish()
+
+    block2 = Block(previous=block1)
+
+    server = ThreadedServer(RPC, port=42069)
+    server.start()
+
+
+    # Create a loop that starts to sleep for 10 seconds / mocking a 10 second block time
+    while True:
+        # Wait 10 seconds
+        time.sleep(10)
+
+# Possible TODO's:
+# * Upon adding transaction to block check if transaction is already locked

+ 2 - 0
requirements.txt

@@ -0,0 +1,2 @@
+plumbum==1.6.9
+rpyc==5.0.0