diff --git a/requirements.txt b/requirements.txt
index 145df061d3a4c6fa1c9cb843d1b39244403a12bf..0fadd5f310bf76e3db271b6a48a68a90397caef7 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,4 +1,5 @@
-duniterpy>=0.20.dev0
 git+https://github.com/Insoleet/quamash.git@master
 asynctest
-networkx
\ No newline at end of file
+networkx
+git+https://github.com/hynek/attrs.git@master
+git+https://github.com/duniter/duniter-python-api.git@master
diff --git a/src/sakia/data/entities/__init__.py b/src/sakia/data/entities/__init__.py
index 73cc2df312598e04f93841a05d05e00d473d6248..a6ebca41552f7d64cd933e4c2f6a1e874dbb8c75 100644
--- a/src/sakia/data/entities/__init__.py
+++ b/src/sakia/data/entities/__init__.py
@@ -1 +1,2 @@
-from .identity import Identity
\ No newline at end of file
+from .identity import Identity
+from .community import Community
diff --git a/src/sakia/data/entities/blockchain.py b/src/sakia/data/entities/blockchain.py
new file mode 100644
index 0000000000000000000000000000000000000000..62e5b495947f0c6cb627a272cd2a2d32c2b94533
--- /dev/null
+++ b/src/sakia/data/entities/blockchain.py
@@ -0,0 +1,14 @@
+import attr
+from duniterpy.documents import block_uid, BlockUID
+
+
+@attr.s()
+class Blockchain:
+    current_buid = attr.ib(convert=block_uid, default=BlockUID.empty())
+    nb_members = attr.ib(convert=int, default=0, cmp=False)
+    current_mass = attr.ib(convert=int, default=0, cmp=False)
+    median_time = attr.ib(convert=int, default=0, cmp=False)
+    last_ud = attr.ib(convert=int, default=0, cmp=False)
+    last_ud_base = attr.ib(convert=int, default=0, cmp=False)
+    previous_mass = attr.ib(convert=int, default=0, cmp=False)
+    currency = attr.ib(convert=str, default="", cmp=False)
diff --git a/src/sakia/data/entities/community.py b/src/sakia/data/entities/community.py
new file mode 100644
index 0000000000000000000000000000000000000000..2e483c091e0286046873def1bb908a573c12b56a
--- /dev/null
+++ b/src/sakia/data/entities/community.py
@@ -0,0 +1,42 @@
+import attr
+
+
+@attr.s()
+class Community:
+    # The decimal percent growth of the UD every [dt] period
+    c = attr.ib(convert=float, default=0, cmp=False)
+    # Time period between two UD in seconds
+    dt = attr.ib(convert=int, default=0, cmp=False)
+    # UD(0), i.e. initial Universal Dividend
+    ud0 = attr.ib(convert=int, default=0, cmp=False)
+    # Minimum delay between 2 certifications of a same issuer, in seconds. Must be positive or zero
+    sig_period = attr.ib(convert=int, default=0, cmp=False)
+    # Maximum quantity of active certifications made by member
+    sig_stock = attr.ib(convert=int, default=0, cmp=False)
+    # Maximum delay in seconds a certification can wait before being expired for non-writing
+    sig_window = attr.ib(convert=int, default=0, cmp=False)
+    # Maximum age of a active signature (in seconds)
+    sig_validity = attr.ib(convert=int, default=0, cmp=False)
+    # Minimum quantity of signatures to be part of the WoT
+    sig_qty = attr.ib(convert=int, default=0, cmp=False)
+    # Minimum decimal percent of sentries to reach to match the distance rule
+    xpercent = attr.ib(convert=float, default=0, cmp=False)
+    # Maximum age of an active membership( in seconds)
+    ms_validity = attr.ib(convert=int, default=0, cmp=False)
+    # Maximum distance between each WoT member and a newcomer
+    step_max = attr.ib(convert=int, default=0, cmp=False)
+    # Number of blocks used for calculating median time
+    median_time_blocks = attr.ib(convert=int, default=0, cmp=False)
+    # The average time for writing 1 block (wished time) in seconds
+    avg_gen_time = attr.ib(convert=int, default=0, cmp=False)
+    # The number of blocks required to evaluate again PoWMin value
+    dt_diff_eval = attr.ib(convert=int, default=0, cmp=False)
+    # The number of previous blocks to check for personalized difficulty
+    blocks_rot = attr.ib(convert=int, default=0, cmp=False)
+    # The decimal percent of previous issuers to reach for personalized difficulty
+    percent_rot = attr.ib(convert=float, default=0, cmp=False)
+    # Currency name
+    currency = attr.ib(convert=str, default="", cmp=False)
+
+
+
diff --git a/src/sakia/data/processors/communities.py b/src/sakia/data/processors/communities.py
new file mode 100644
index 0000000000000000000000000000000000000000..b9ad62a4e09e8bff3f4f7d4d2f9187dc139a656f
--- /dev/null
+++ b/src/sakia/data/processors/communities.py
@@ -0,0 +1,16 @@
+import attr
+
+
+@attr.s
+class CommunityProcessor:
+    _repo = attr.ib()  # :type sakia.data.repositories.CommunitiesRepo
+
+    async def get_from_currency(self, currency):
+        """
+        Get the community of a currency
+
+        :param currency:
+        :rtype: sakia.data.entities.Community
+        """
+        return self._repo.get_one(currency=currency)
+
diff --git a/src/sakia/data/repositories/__init__.py b/src/sakia/data/repositories/__init__.py
index ea239c6ee545babb52adb06d72d9432e9f7194d3..eca82cc1959936da34fffaf56cbd9fd921a89ee6 100644
--- a/src/sakia/data/repositories/__init__.py
+++ b/src/sakia/data/repositories/__init__.py
@@ -1,2 +1,3 @@
 from .identities import IdentitiesRepo
-from .meta import MetaDatabase
\ No newline at end of file
+from .communities import CommunitiesRepo
+from .meta import MetaDatabase
diff --git a/src/sakia/data/repositories/communities.py b/src/sakia/data/repositories/communities.py
new file mode 100644
index 0000000000000000000000000000000000000000..d2f21a1b73676c07be21d563da0374172ad1122b
--- /dev/null
+++ b/src/sakia/data/repositories/communities.py
@@ -0,0 +1,102 @@
+import attr
+
+from ..entities import Community
+
+
+@attr.s(frozen=True)
+class CommunitiesRepo:
+    """The repository for Communities entities.
+    """
+    _conn = attr.ib()  # :type sqlite3.Connection
+    _primary_keys = (Community.currency,)
+
+    def insert(self, community):
+        """
+        Commit a community to the database
+        :param sakia.data.entities.Community community: the community to commit
+        """
+        with self._conn:
+            community_tuple = attr.astuple(community)
+            values = ",".join(['?'] * len(community_tuple))
+            self._conn.execute("INSERT INTO communities VALUES ({0})".format(values), community_tuple)
+
+    def update(self, community):
+        """
+        Update an existing community in the database
+        :param sakia.data.entities.Community community: the community to update
+        """
+        with self._conn:
+            updated_fields = attr.astuple(community, filter=attr.filters.exclude(*CommunitiesRepo._primary_keys))
+            where_fields = attr.astuple(community, filter=attr.filters.include(*CommunitiesRepo._primary_keys))
+            self._conn.execute("""UPDATE communities SET
+                              c=?,
+                              dt=?,
+                              ud0=?,
+                              sig_period=?,
+                              sig_stock=?,
+                              sig_window=?,
+                              sig_validity=?,
+                              sig_qty=?,
+                              xpercent=?,
+                              ms_validity=?,
+                              step_max=?,
+                              median_time_blocks=?,
+                              avg_gen_time=?,
+                              dt_diff_eval=?,
+                              blocks_rot=?,
+                              percent_rot=?
+                               WHERE
+                              currency=?""",
+                               updated_fields + where_fields)
+
+    def get_one(self, **search):
+        """
+        Get an existing community in the database
+        :param dict search: the criterions of the lookup
+        :rtype: sakia.data.entities.Community
+        """
+        with self._conn:
+            filters = []
+            values = []
+            for k, v in search.items():
+                filters.append("{k}=?".format(k=k))
+                values.append(v)
+
+            request = "SELECT * FROM communities WHERE {filters}".format(filters=" AND ".join(filters))
+
+            c = self._conn.execute(request, tuple(values))
+            data = c.fetchone()
+            if data:
+                return Community(*data)
+
+    def get_all(self, **search):
+        """
+        Get all existing community in the database corresponding to the search
+        :param dict search: the criterions of the lookup
+        :rtype: sakia.data.entities.Community
+        """
+        with self._conn:
+            filters = []
+            values = []
+            for k, v in search.items():
+                operator = "LIKE" if k == "currency" else "="
+                value = "%{value}%".format(value=v) if k == "currency" else v
+                filters.append("{key} {operator} ?".format(key=k, operator=operator))
+                values.append(value)
+
+            request = "SELECT * FROM communities WHERE {filters}".format(filters=" AND ".join(filters))
+
+            c = self._conn.execute(request, tuple(values))
+            datas = c.fetchall()
+            if datas:
+                return [Community(*data) for data in datas]
+        return []
+
+    def drop(self, community):
+        """
+        Drop an existing community from the database
+        :param sakia.data.entities.Community community: the community to update
+        """
+        with self._conn:
+            where_fields = attr.astuple(community, filter=attr.filters.include(*CommunitiesRepo._primary_keys))
+            self._conn.execute("DELETE FROM communities WHERE currency=?", where_fields)
diff --git a/src/sakia/data/repositories/identities.py b/src/sakia/data/repositories/identities.py
index af15b132748ae6122648db5cbadf9662632a489a..d4ed89ba6df12661813342556e32fa294c6dea96 100644
--- a/src/sakia/data/repositories/identities.py
+++ b/src/sakia/data/repositories/identities.py
@@ -1,4 +1,5 @@
 import attr
+
 from ..entities import Identity
 
 
@@ -16,9 +17,8 @@ class IdentitiesRepo:
         """
         with self._conn:
             identity_tuple = attr.astuple(identity)
-            values = ",".join(['?']*len(identity_tuple))
-            self._conn.execute("INSERT INTO identities "
-                               "VALUES ({0})".format(values), identity_tuple)
+            values = ",".join(['?'] * len(identity_tuple))
+            self._conn.execute("INSERT INTO identities VALUES ({0})".format(values), identity_tuple)
 
     def update(self, identity):
         """
@@ -28,20 +28,20 @@ class IdentitiesRepo:
         with self._conn:
             updated_fields = attr.astuple(identity, filter=attr.filters.exclude(*IdentitiesRepo._primary_keys))
             where_fields = attr.astuple(identity, filter=attr.filters.include(*IdentitiesRepo._primary_keys))
-            self._conn.execute("UPDATE identities SET "
-                              "signature=?, "
-                              "ts=?,"
-                              "written=?,"
-                              "revoked=?,"
-                              "member=?,"
-                              "ms_buid=?,"
-                              "ms_timestamp=?"
-                              "WHERE "
-                              "currency=? AND "
-                              "pubkey=? AND "
-                              "uid=? AND "
-                              "blockstamp=?", updated_fields + where_fields
-                              )
+            self._conn.execute("""UPDATE identities SET
+                                  signature=?,
+                                  ts=?,
+                                  written=?,
+                                  revoked=?,
+                                  member=?,
+                                  ms_buid=?,
+                                  ms_timestamp=?
+                                  WHERE
+                                  currency=? AND
+                                  pubkey=? AND
+                                  uid=? AND
+                                  blockstamp=?""", updated_fields + where_fields
+                               )
 
     def get_one(self, **search):
         """
@@ -56,8 +56,7 @@ class IdentitiesRepo:
                 filters.append("{k}=?".format(k=k))
                 values.append(v)
 
-            request = "SELECT * FROM identities WHERE "
-            request += " AND ".join(filters)
+            request = "SELECT * FROM identities WHERE {filters}".format(filters=" AND ".join(filters))
 
             c = self._conn.execute(request, tuple(values))
             data = c.fetchone()
@@ -77,8 +76,7 @@ class IdentitiesRepo:
                 filters.append("{k}=?".format(k=k))
                 values.append(v)
 
-            request = "SELECT * FROM identities WHERE "
-            request += " AND ".join(filters)
+            request = "SELECT * FROM identities WHERE {filters}".format(filters=" AND ".join(filters))
 
             c = self._conn.execute(request, tuple(values))
             datas = c.fetchall()
@@ -93,8 +91,8 @@ class IdentitiesRepo:
         """
         with self._conn:
             where_fields = attr.astuple(identity, filter=attr.filters.include(*IdentitiesRepo._primary_keys))
-            self._conn.execute("DELETE FROM identities WHERE "
-                               "currency=? AND "
-                               "pubkey=? AND "
-                               "uid=? AND "
-                               "blockstamp=?", where_fields)
+            self._conn.execute("""DELETE FROM identities WHERE
+                               currency=? AND
+                               pubkey=? AND
+                               uid=? AND
+                               blockstamp=?""", where_fields)
diff --git a/src/sakia/data/repositories/meta.py b/src/sakia/data/repositories/meta.py
index 6e2707d67ec32147d6e5123da16fae7f0291f247..319a03fcb303cced285f0eba4f319bbe050cb0ed 100644
--- a/src/sakia/data/repositories/meta.py
+++ b/src/sakia/data/repositories/meta.py
@@ -1,4 +1,5 @@
 import attr
+import os
 
 
 @attr.s(frozen=True)
@@ -13,11 +14,11 @@ class MetaDatabase:
         Prepares the database if the table is missing
         """
         with self._conn:
-            self._conn.execute("create table if not exists meta("
-                               "id integer not null,"
-                               "version integer not null,"
-                               "primary key (id)"
-                               ")"
+            self._conn.execute("""CREATE TABLE IF NOT EXISTS meta(
+                               id INTEGER NOT NULL,
+                               version INTEGER NOT NULL,
+                               PRIMARY KEY (id)
+                               )"""
                                )
 
     @property
@@ -42,22 +43,9 @@ class MetaDatabase:
         Init all the tables
         :return:
         """
+        sql_file = open(os.path.join(os.path.dirname(__file__), 'meta.sql'), 'r')
         with self._conn:
-            self._conn.execute("create table if not exists identities("
-                               "currency varchar(30), "
-                               "pubkey varchar(50),"
-                               "uid varchar(255),"
-                               "blockstamp varchar(100),"
-                               "signature varchar(100),"
-                               "ts int,"
-                               "written boolean,"
-                               "revoked boolean,"
-                               "member boolean,"
-                               "ms_buid varchar(100),"
-                               "ms_timestamp int,"
-                               "PRIMARY KEY (currency, pubkey, uid, blockstamp)"
-                               ")"
-                               )
+            self._conn.executescript(sql_file.read())
 
     def version(self):
         with self._conn:
@@ -68,4 +56,3 @@ class MetaDatabase:
             else:
                 self._conn.execute("INSERT INTO meta VALUES (1, 0)")
                 return 0
-
diff --git a/src/sakia/data/repositories/meta.sql b/src/sakia/data/repositories/meta.sql
new file mode 100644
index 0000000000000000000000000000000000000000..91f047aca1e81af80dcb137bc3377231464a4c0d
--- /dev/null
+++ b/src/sakia/data/repositories/meta.sql
@@ -0,0 +1,37 @@
+-- IDENTITY TABLE
+CREATE TABLE IF NOT EXISTS identities(
+                               currency VARCHAR(30),
+                               pubkey VARCHAR(50),
+                               uid VARCHAR(255),
+                               blockstamp VARCHAR(100),
+                               signature VARCHAR(100),
+                               ts INT,
+                               written BOOLEAN,
+                               revoked BOOLEAN,
+                               member BOOLEAN,
+                               ms_buid VARCHAR(100),
+                               ms_timestamp INT,
+                               PRIMARY KEY (currency, pubkey, uid, blockstamp)
+                               );
+
+-- COMMUNITY TABLE
+CREATE TABLE IF NOT EXISTS communities(
+                               c FLOAT(1,6),
+                               dt INT,
+                               ud0 INT,
+                               sig_period INT,
+                               sig_stock INT,
+                               sig_window INT,
+                               sig_validity INT,
+                               sig_qty INT,
+                               xpercent FLOAT(1,6),
+                               ms_validity INT,
+                               step_max INT,
+                               median_time_blocks INT,
+                               avg_gen_time INT,
+                               dt_diff_eval INT,
+                               blocks_rot INT,
+                               percent_rot FLOAT(1,6),
+                               currency VARCHAR(30),
+                               PRIMARY KEY (currency)
+                               );
diff --git a/src/sakia/tests/unit/data/test_communities_repo.py b/src/sakia/tests/unit/data/test_communities_repo.py
new file mode 100644
index 0000000000000000000000000000000000000000..5a0d72f3b93c751b5b06ed3b865aa1c3ac39227d
--- /dev/null
+++ b/src/sakia/tests/unit/data/test_communities_repo.py
@@ -0,0 +1,132 @@
+import sqlite3
+import unittest
+
+from duniterpy.documents import BlockUID
+
+from sakia.data.entities import Community
+from sakia.data.repositories import CommunitiesRepo, MetaDatabase
+
+
+class TestIdentitiesRepo(unittest.TestCase):
+    def setUp(self):
+        sqlite3.register_adapter(BlockUID, str)
+        sqlite3.register_adapter(bool, int)
+        sqlite3.register_converter("BOOLEAN", lambda v: bool(int(v)))
+        self.con = sqlite3.connect(":memory:", detect_types=sqlite3.PARSE_DECLTYPES)
+
+    def tearDown(self):
+        self.con.close()
+
+    def test_add_get_drop_community(self):
+        meta_repo = MetaDatabase(self.con)
+        meta_repo.prepare()
+        meta_repo.upgrade_database()
+        communities_repo = CommunitiesRepo(self.con)
+        communities_repo.insert(Community(
+            0.1,
+            86400,
+            100000,
+            10800,
+            40,
+            2629800,
+            31557600,
+            1,
+            0.9,
+            604800,
+            5,
+            12,
+            300,
+            25,
+            10,
+            0.66,
+            "testcurrency"
+        ))
+        community = communities_repo.get_one(currency="testcurrency")
+        self.assertEqual(community.currency, "testcurrency")
+        self.assertEqual(community.c, 0.1)
+        self.assertEqual(community.dt, 86400)
+
+        communities_repo.drop(community)
+        community = communities_repo.get_one(currency="testcurrency")
+        self.assertIsNone(community)
+
+    def test_add_get_multiple_community(self):
+        meta_repo = MetaDatabase(self.con)
+        meta_repo.prepare()
+        meta_repo.upgrade_database()
+        communities_repo = CommunitiesRepo(self.con)
+        communities_repo.insert(Community(
+            0.1,
+            86400,
+            100000,
+            10800,
+            40,
+            2629800,
+            31557600,
+            1,
+            0.9,
+            604800,
+            5,
+            12,
+            300,
+            25,
+            10,
+            0.66,
+            "testcurrency"
+        )
+        )
+        communities_repo.insert(Community(
+            0.1,
+            86400 * 365,
+            100000,
+            10800,
+            40,
+            2629800,
+            31557600,
+            1,
+            0.9,
+            604800,
+            5,
+            12,
+            300,
+            25,
+            10,
+            0.66,
+            "testcurrency2"
+        )
+        )
+        communities = communities_repo.get_all(currency="testcurrency")
+        self.assertIn("testcurrency", [i.currency for i in communities])
+        self.assertIn("testcurrency2", [i.currency for i in communities])
+        self.assertIn(86400, [i.dt for i in communities])
+        self.assertIn(86400 * 365, [i.dt for i in communities])
+
+    def test_add_update_community(self):
+        meta_repo = MetaDatabase(self.con)
+        meta_repo.prepare()
+        meta_repo.upgrade_database()
+        communities_repo = CommunitiesRepo(self.con)
+        community = Community(
+            0.1,
+            86400,
+            100000,
+            10800,
+            40,
+            2629800,
+            31557600,
+            1,
+            0.9,
+            604800,
+            5,
+            12,
+            300,
+            25,
+            10,
+            0.66,
+            "testcurrency"
+        )
+        communities_repo.insert(community)
+        community.c = 0.0922
+        communities_repo.update(community)
+        community2 = communities_repo.get_one(currency="testcurrency")
+        self.assertEquals(0.0922, community2.c)