input: Write a function to compose a basic blockchain system in Python. The function should define a `Block` class for each block in the blockchain and a `Blockchain` class to manage the chain. The `Blockchain` class should have methods to add new blocks and retrieve the entire chain in JSON format.
  
  
  import hashlib
  import json
  
  def compose_blockchain():
      def sha256(data):
          hash_function = hashlib.sha256()
          hash_function.update(data.encode('utf-8'))
          return hash_function.hexdigest()
  
      class Block:
          def __init__(self, index, timestamp, data, previous_hash):
              self.index = index
              self.timestamp = timestamp
              self.data = data
              self.previous_hash = previous_hash
              self.hash = sha256(f'{self.index}{self.timestamp}{self.data}{self.previous_hash}')
  
      class Blockchain:
          def __init__(self):
              self.chain = []
  
          def add_block(self, data):
              previous_hash = self.chain[-1].hash if len(self.chain) > 0 else None
              block = Block(len(self.chain), data['timestamp'], data['data'], previous_hash)
              self.chain.append(block)
  
          def get_chain(self):
              return json.dumps([b.__dict__ for b in self.chain], indent=2)
  
      return Blockchain
  
  assert json.loads(compose_blockchain().get_chain()) == []
  assert json.loads(compose_blockchain().add_block({'timestamp': '2023-01-01', 'data': 'First Block'}).get_chain())[0]['data'] == 'First Block'
  assert json.loads(compose_blockchain().add_block({'timestamp': '2023-01-02', 'data': 'Second Block'}).get_chain())[0]['data'] == 'Second Block'
  assert json.loads(compose_blockchain().add_block({'timestamp': '2023-01-03', 'data': 'Third Block'}).get_chain())[0]['data'] == 'Third Block'
  assert json.loads(compose_blockchain().add_block({'timestamp': '2023-01-04', 'data': 'Fourth Block'}).get_chain())[0]['data'] == 'Fourth Block'
  
output: 
  def compose_blockchain():
      def sha256(data):
          hash_function = hashlib.sha256()
          hash_function.update(data.encode('utf-8'))
          return hash_function.hexdigest()
  
      class Block:
          def __init__(self, index, timestamp, data, previous_hash):
              self.index = index
              self.timestamp = timestamp
              self.data = data
              self.previous_hash = previous_hash
              self.hash = sha256(f'{self.index}{self.timestamp}{self.data}{self.previous_hash}')
  
      class Blockchain:
          def __init__(self):
              self.chain = []
  
          def add_block(self, data):
              previous_hash = self.chain[-1].hash if len(self.chain) > 0 else None
              block = Block(len(self.chain), data['timestamp'], data['data'], previous_hash)
              self.chain.append(block)
              return self
  
          def get_chain(self):
              return json.dumps([b.__dict__ for b in self.chain], indent=2)
  
      return Blockchain
  