diff --git a/app/lib/blockchain/DuniterBlockchain.ts b/app/lib/blockchain/DuniterBlockchain.ts
index 93e8e963966f86035d3933b187e7ca2f04b2775d..220ef7440fa19165effe224223b8f123a3bd775c 100644
--- a/app/lib/blockchain/DuniterBlockchain.ts
+++ b/app/lib/blockchain/DuniterBlockchain.ts
@@ -305,21 +305,21 @@ export class DuniterBlockchain extends MiscIndexedBlockchain {
     }
   }
 
-  async updateMembers(block:BlockDTO, dal:any) {
+  async updateMembers(block:BlockDTO, dal:FileDAL) {
     // Joiners (come back)
     for (const inlineMS of block.joiners) {
       let ms = MembershipDTO.fromInline(inlineMS)
-      const idty = await dal.getWrittenIdtyByPubkey(ms.issuer);
+      const idty = await dal.getWrittenIdtyByPubkeyForWotbID(ms.issuer);
       dal.wotb.setEnabled(true, idty.wotb_id);
     }
     // Revoked
     for (const inlineRevocation of block.revoked) {
       let revocation = RevocationDTO.fromInline(inlineRevocation)
-      await dal.revokeIdentity(revocation.pubkey, block.number);
+      await dal.revokeIdentity(revocation.pubkey)
     }
     // Excluded
     for (const excluded of block.excluded) {
-      const idty = await dal.getWrittenIdtyByPubkey(excluded);
+      const idty = await dal.getWrittenIdtyByPubkeyForWotbID(excluded);
       dal.wotb.setEnabled(false, idty.wotb_id);
     }
   }
@@ -349,8 +349,8 @@ export class DuniterBlockchain extends MiscIndexedBlockchain {
     // Revert links
     const writtenOn = await dal.cindexDAL.getWrittenOn(blockstamp);
     for (const entry of writtenOn) {
-      const from = await dal.getWrittenIdtyByPubkey(entry.issuer);
-      const to = await dal.getWrittenIdtyByPubkey(entry.receiver);
+      const from = await dal.getWrittenIdtyByPubkeyForWotbID(entry.issuer);
+      const to = await dal.getWrittenIdtyByPubkeyForWotbID(entry.receiver);
       if (entry.op == CommonConstants.IDX_CREATE) {
         // We remove the created link
         dal.wotb.removeLink(from.wotb_id, to.wotb_id, true);
@@ -394,7 +394,7 @@ export class DuniterBlockchain extends MiscIndexedBlockchain {
       // Undo 'join' which can be either newcomers or comebackers
       // => equivalent to i_index.member = true AND i_index.op = 'UPDATE'
       if (entry.member === true && entry.op === CommonConstants.IDX_UPDATE) {
-        const idty = await dal.getWrittenIdtyByPubkey(entry.pub);
+        const idty = await dal.getWrittenIdtyByPubkeyForWotbID(entry.pub);
         dal.wotb.setEnabled(false, idty.wotb_id);
       }
     }
@@ -412,7 +412,7 @@ export class DuniterBlockchain extends MiscIndexedBlockchain {
       // Undo excluded (make them become members again in wotb)
       // => equivalent to m_index.member = false
       if (entry.member === false && entry.op === CommonConstants.IDX_UPDATE) {
-        const idty = await dal.getWrittenIdtyByPubkey(entry.pub);
+        const idty = await dal.getWrittenIdtyByPubkeyForWotbID(entry.pub);
         dal.wotb.setEnabled(true, idty.wotb_id);
       }
     }
@@ -435,7 +435,7 @@ export class DuniterBlockchain extends MiscIndexedBlockchain {
   static async removeCertificationsFromSandbox(block:BlockDTO, dal:FileDAL) {
     for (let inlineCert of block.certifications) {
       let cert = CertificationDTO.fromInline(inlineCert)
-      let idty = await dal.getWrittenIdtyByPubkey(cert.to);
+      let idty = await dal.getWrittenIdtyByPubkeyForHashing(cert.to);
       await dal.deleteCert({
         from: cert.from,
         target: IdentityDTO.getTargetHash(idty),
diff --git a/app/lib/common-libs/errors.ts b/app/lib/common-libs/errors.ts
new file mode 100644
index 0000000000000000000000000000000000000000..6286123f9cb4918ba9c1233001d4763d45ce4372
--- /dev/null
+++ b/app/lib/common-libs/errors.ts
@@ -0,0 +1,4 @@
+
+export enum DataErrors {
+  MEMBER_NOT_FOUND
+}
diff --git a/app/lib/common-libs/rawer.ts b/app/lib/common-libs/rawer.ts
index 568199c92a3a68b1db6c3666b8d0f2dd7ea2a576..9ed172071cad9d086bc01db5d13e3df19440d02b 100644
--- a/app/lib/common-libs/rawer.ts
+++ b/app/lib/common-libs/rawer.ts
@@ -31,7 +31,17 @@ export const getOfficialIdentity = (json:any, withSig = true) => {
   }
 }
 
-export const getOfficialCertification = (json:any) => {
+export const getOfficialCertification = (json:{
+  version?:number
+  currency:string
+  issuer:string
+  idty_issuer:string
+  idty_uid:string
+  idty_buid:string
+  idty_sig:string
+  buid:string
+  sig?:string
+}) => {
   let raw = getNormalHeader('Certification', json);
   raw += "IdtyIssuer: " + json.idty_issuer + '\n';
   raw += "IdtyUniqueID: " + json.idty_uid + '\n';
@@ -91,7 +101,11 @@ export const getTransaction = (json:any) => {
   return TransactionDTO.toRAW(json)
 }
 
-function getNormalHeader(doctype:string, json:any) {
+function getNormalHeader(doctype:string, json:{
+  version?:number
+  currency:string
+  issuer:string
+}) {
   let raw = "";
   raw += "Version: " + (json.version || DOCUMENTS_VERSION) + "\n";
   raw += "Type: " + doctype + "\n";
diff --git a/app/lib/dal/fileDAL.ts b/app/lib/dal/fileDAL.ts
index 04ba4af7b0ff5ffb18d7d5f7a1c1ba1ba21de1d2..e544a79e24efab4b694f00f72de2b4ebf351386b 100644
--- a/app/lib/dal/fileDAL.ts
+++ b/app/lib/dal/fileDAL.ts
@@ -18,7 +18,7 @@ import {ConfDTO} from "../dto/ConfDTO"
 import {BlockDTO} from "../dto/BlockDTO"
 import {DBHead} from "../db/DBHead"
 import {DBIdentity, IdentityDAL} from "./sqliteDAL/IdentityDAL"
-import {CindexEntry, IindexEntry, IndexEntry, SindexEntry} from "../indexer"
+import {CindexEntry, FullMindexEntry, IindexEntry, IndexEntry, SindexEntry} from "../indexer"
 import {DBPeer} from "./sqliteDAL/PeerDAL"
 import {TransactionDTO} from "../dto/TransactionDTO"
 import {CertDAL, DBCert} from "./sqliteDAL/CertDAL"
@@ -35,6 +35,9 @@ import {BIndexDAL} from "./sqliteDAL/index/BIndexDAL"
 import {MIndexDAL} from "./sqliteDAL/index/MIndexDAL"
 import {CIndexDAL} from "./sqliteDAL/index/CIndexDAL"
 import {SIndexDAL} from "./sqliteDAL/index/SIndexDAL"
+import {IIndexDAL} from "./sqliteDAL/index/IIndexDAL"
+import {DataErrors} from "../common-libs/errors"
+import {BasicRevocableIdentity, IdentityDTO} from "../dto/IdentityDTO"
 
 const fs      = require('fs')
 const path    = require('path')
@@ -72,7 +75,7 @@ export class FileDAL {
   walletDAL:WalletDAL
   bindexDAL:BIndexDAL
   mindexDAL:MIndexDAL
-  iindexDAL:any
+  iindexDAL:IIndexDAL
   sindexDAL:SIndexDAL
   cindexDAL:CIndexDAL
   newDals:{ [k:string]: Initiable }
@@ -297,36 +300,231 @@ export class FileDAL {
     return this.sindexDAL.getAvailableForPubkey(pubkey)
   }
 
-  async getIdentityByHashOrNull(hash:string): Promise<DBIdentity|null> {
-    const pending = await this.idtyDAL.getByHash(hash);
+  async getGlobalIdentityByHashForExistence(hash:string): Promise<boolean> {
+    const pending = await this.idtyDAL.getByHash(hash)
     if (!pending) {
-      return this.iindexDAL.getFromHash(hash);
+      const idty = await this.iindexDAL.getFullFromHash(hash)
+      if (!idty) {
+        return false
+      }
+    }
+    return true
+  }
+
+  async getGlobalIdentityByHashForHashingAndSig(hash:string): Promise<{ pubkey:string, uid:string, buid:string, sig:string }|null> {
+    const pending = await this.idtyDAL.getByHash(hash)
+    if (!pending) {
+      const idty = await this.iindexDAL.getFullFromHash(hash)
+      if (!idty) {
+        return null
+      }
+      return {
+        pubkey: idty.pub,
+        uid: idty.uid,
+        buid: idty.created_on,
+        sig: idty.sig
+      }
+    }
+    return pending
+  }
+
+  async getGlobalIdentityByHashForLookup(hash:string): Promise<{ pubkey:string, uid:string, buid:string, sig:string, member:boolean, wasMember:boolean }|null> {
+    const pending = await this.idtyDAL.getByHash(hash)
+    if (!pending) {
+      const idty = await this.iindexDAL.getFullFromHash(hash)
+      if (!idty) {
+        return null
+      }
+      return {
+        pubkey: idty.pub,
+        uid: idty.uid,
+        buid: idty.created_on,
+        sig: idty.sig,
+        member: idty.member,
+        wasMember: idty.wasMember
+      }
+    }
+    return pending
+  }
+
+  async getGlobalIdentityByHashForJoining(hash:string): Promise<{ pubkey:string, uid:string, buid:string, sig:string, member:boolean, wasMember:boolean, revoked:boolean }|null> {
+    const pending = await this.idtyDAL.getByHash(hash)
+    if (!pending) {
+      const idty = await this.iindexDAL.getFullFromHash(hash)
+      if (!idty) {
+        return null
+      }
+      const membership = await this.mindexDAL.getReducedMS(idty.pub) as FullMindexEntry
+      return {
+        pubkey: idty.pub,
+        uid: idty.uid,
+        buid: idty.created_on,
+        sig: idty.sig,
+        member: idty.member,
+        wasMember: idty.wasMember,
+        revoked: !!(membership.revoked_on)
+      }
+    }
+    return pending
+  }
+
+  async getGlobalIdentityByHashForIsMember(hash:string): Promise<{ pub:string, member:boolean }|null> {
+    const pending = await this.idtyDAL.getByHash(hash)
+    if (!pending) {
+      const idty = await this.iindexDAL.getFullFromHash(hash)
+      if (!idty) {
+        return null
+      }
+      return {
+        pub: idty.pub,
+        member: idty.member
+      }
+    }
+    return {
+      pub: pending.pubkey,
+      member: pending.member
+    }
+  }
+
+  async getGlobalIdentityByHashForRevocation(hash:string): Promise<{ pub:string, uid:string, created_on:string, sig:string, member:boolean, wasMember:boolean, revoked:boolean, revocation_sig:string|null, expires_on:number }|null> {
+    const pending = await this.idtyDAL.getByHash(hash)
+    if (!pending) {
+      const idty = await this.iindexDAL.getFullFromHash(hash)
+      if (!idty) {
+        return null
+      }
+      const membership = await this.mindexDAL.getReducedMS(idty.pub) as FullMindexEntry
+      return {
+        pub: idty.pub,
+        uid: idty.uid,
+        sig: idty.sig,
+        member: idty.member,
+        wasMember: idty.wasMember,
+        expires_on: membership.expires_on,
+        created_on: idty.created_on,
+        revoked: !!(membership.revoked_on),
+        revocation_sig: membership.revocation
+      }
+    }
+    return {
+      pub: pending.pubkey,
+      uid: pending.uid,
+      sig: pending.sig,
+      expires_on: pending.expires_on,
+      created_on: pending.buid,
+      member: pending.member,
+      wasMember: pending.wasMember,
+      revoked: pending.revoked,
+      revocation_sig: pending.revocation_sig
     }
-    return pending;
   }
 
   getMembers() {
     return this.iindexDAL.getMembers()
   }
 
-  async getWrittenIdtyByPubkey(pubkey:string) {
+  async getWrittenIdtyByPubkeyForHash(pubkey:string): Promise<{ hash:string }> {
+    return this.getWrittenForSureIdtyByPubkey(pubkey)
+  }
+
+  async getWrittenIdtyByPubkeyForHashing(pubkey:string): Promise<{ uid:string, created_on:string, pub:string }> {
+    return this.getWrittenForSureIdtyByPubkey(pubkey)
+  }
+
+  async getWrittenIdtyByPubkeyForWotbID(pubkey:string): Promise<{ wotb_id:number }> {
+    return this.getWrittenForSureIdtyByPubkey(pubkey)
+  }
+
+  async getWrittenIdtyByPubkeyForUidAndPubkey(pubkey:string): Promise<{ pub:string, uid:string }> {
+    return this.getWrittenForSureIdtyByPubkey(pubkey)
+  }
+
+  async getWrittenIdtyByPubkeyForIsMember(pubkey:string): Promise<{ member:boolean }|null> {
+    return this.iindexDAL.getFromPubkey(pubkey)
+  }
+
+  async getWrittenIdtyByPubkeyForUidAndIsMemberAndWasMember(pubkey:string): Promise<{ uid:string, member:boolean, wasMember:boolean }|null> {
+    return this.iindexDAL.getFromPubkey(pubkey)
+  }
+
+  async getWrittenIdtyByPubkeyOrUidForIsMemberAndPubkey(search:string): Promise<{ pub:string, member:boolean }|null> {
+    return this.iindexDAL.getFromPubkeyOrUid(search)
+  }
+
+  async getWrittenIdtyByPubkeyOrUIdForHashingAndIsMember(search:string): Promise<{ uid:string, created_on:string, pub:string, member:boolean }|null> {
+    return await this.iindexDAL.getFromPubkeyOrUid(search)
+  }
+
+  async getWrittenIdtyByPubkeyForRevocationCheck(pubkey:string): Promise<{ pub:string, uid:string, created_on:string, sig:string, revoked_on:number|null }|null> {
     const idty = await this.iindexDAL.getFromPubkey(pubkey)
     if (!idty) {
-      return null;
+      return null
+    }
+    const membership = await this.mindexDAL.getReducedMS(pubkey) as FullMindexEntry
+    return {
+      pub: idty.pub,
+      uid: idty.uid,
+      sig: idty.sig,
+      created_on: idty.created_on,
+      revoked_on: membership.revoked_on
     }
-    const membership = await this.mindexDAL.getReducedMS(pubkey)
-    idty.revoked_on = membership.revoked_on
-    return idty;
   }
 
-  async getWrittenIdtyByUID(uid:string) {
-    const idty = await this.iindexDAL.getFromUID(uid)
+  async getWrittenIdtyByPubkeyForCertificationCheck(pubkey:string): Promise<{ pub:string, uid:string, created_on:string, sig:string }|null> {
+    const idty = await this.iindexDAL.getFromPubkey(pubkey)
     if (!idty) {
-      return null;
+      return null
     }
-    const membership = await this.mindexDAL.getReducedMS(idty.pub)
-    idty.revoked_on = membership.revoked_on
-    return idty;
+    return {
+      pub: idty.pub,
+      uid: idty.uid,
+      sig: idty.sig,
+      created_on: idty.created_on,
+    }
+  }
+
+  async getWrittenIdtyByPubkeyForUidAndMemberAndCreatedOn(pubkey:string): Promise<{ uid:string, member:boolean, created_on:string }|null> {
+    const idty = await this.iindexDAL.getFromPubkey(pubkey)
+    if (!idty) {
+      return null
+    }
+    return {
+      uid: idty.uid,
+      member: idty.member,
+      created_on: idty.created_on,
+    }
+  }
+
+  private async getWrittenForSureIdtyByPubkey(pubkey:string) {
+    const idty = await this.iindexDAL.getFromPubkey(pubkey)
+    if (!idty) {
+      throw Error(DataErrors[DataErrors.MEMBER_NOT_FOUND])
+    }
+    return idty
+  }
+
+  private async getWrittenForSureIdtyByUid(pubkey:string) {
+    const idty = (await this.iindexDAL.getFullFromUID(pubkey))
+    if (!idty) {
+      throw Error(DataErrors[DataErrors.MEMBER_NOT_FOUND])
+    }
+    return idty
+  }
+
+  async getWrittenIdtyByPubkeyForExistence(uid:string) {
+    return !!(await this.iindexDAL.getFromPubkey(uid))
+  }
+
+  async getWrittenIdtyByUIDForExistence(uid:string) {
+    return !!(await this.iindexDAL.getFromUID(uid))
+  }
+
+  async getWrittenIdtyByUidForHashing(uid:string): Promise<{ uid:string, created_on:string, pub:string }> {
+    return this.getWrittenForSureIdtyByUid(uid)
+  }
+
+  async getWrittenIdtyByUIDForWotbId(uid:string): Promise<{ wotb_id:number }> {
+    return this.getWrittenForSureIdtyByUid(uid)
   }
 
   async findPeersWhoseHashIsIn(hashes:string[]) {
@@ -355,8 +553,8 @@ export class FileDAL {
     const revoking = await this.idtyDAL.getToRevoke();
     const toRevoke = [];
     for (const pending of revoking) {
-      const idty = await this.getWrittenIdtyByPubkey(pending.pubkey);
-      if (!idty.revoked_on) {
+      const idty = await this.getWrittenIdtyByPubkeyForRevocationCheck(pending.pubkey)
+      if (idty && !idty.revoked_on) {
         toRevoke.push(pending);
       }
     }
@@ -385,7 +583,7 @@ export class FileDAL {
     return await Promise.all(found.map(async (f:any) => {
       const ms = await this.mindexDAL.getReducedMS(f.pub);
       if (ms) {
-        f.revoked_on = ms.revoked_on ? parseInt(ms.revoked_on) : null;
+        f.revoked_on = ms.revoked_on ? ms.revoked_on : null;
         f.revoked = !!f.revoked_on;
         f.revocation_sig = ms.revocation || null;
       }
@@ -420,7 +618,7 @@ export class FileDAL {
     const links = await this.cindexDAL.getValidLinksFrom(pubkey);
     let matching = certs;
     await Promise.all(links.map(async (entry:any) => {
-      const idty = await this.getWrittenIdtyByPubkey(entry.receiver);
+      const idty = await this.getWrittenIdtyByPubkeyForHash(entry.receiver)
       entry.from = entry.issuer;
       entry.to = entry.receiver;
       const cbt = entry.created_on.split('-');
@@ -558,15 +756,17 @@ export class FileDAL {
   }
 
   async setRevoked(pubkey:string) {
-    const idty = await this.getWrittenIdtyByPubkey(pubkey);
-    idty.revoked = true;
-    return await this.idtyDAL.saveIdentity(idty);
+    return await this.idtyDAL.setRevoked(pubkey)
   }
 
-  setRevocating = (existing:DBIdentity, revocation_sig:string) => {
-    existing.revocation_sig = revocation_sig;
-    existing.revoked = false;
-    return this.idtyDAL.saveIdentity(existing);
+  setRevocating = (idty:BasicRevocableIdentity, revocation_sig:string) => {
+    const dbIdentity = IdentityDTO.fromBasicIdentity(idty)
+    dbIdentity.member = idty.member
+    dbIdentity.wasMember = idty.wasMember
+    dbIdentity.expires_on = idty.expires_on
+    dbIdentity.revocation_sig = revocation_sig
+    dbIdentity.revoked = false
+    return this.idtyDAL.saveIdentity(dbIdentity)
   }
 
   async getPeerOrNull(pubkey:string) {
@@ -682,8 +882,8 @@ export class FileDAL {
 
   async updateWotbLinks(cindex:CindexEntry[]) {
     for (const entry of cindex) {
-      const from = await this.getWrittenIdtyByPubkey(entry.issuer);
-      const to = await this.getWrittenIdtyByPubkey(entry.receiver);
+      const from = await this.getWrittenIdtyByPubkeyForWotbID(entry.issuer);
+      const to = await this.getWrittenIdtyByPubkeyForWotbID(entry.receiver);
       if (entry.op == CommonConstants.IDX_CREATE) {
         this.wotb.addLink(from.wotb_id, to.wotb_id);
       } else {
diff --git a/app/lib/dal/sqliteDAL/IdentityDAL.ts b/app/lib/dal/sqliteDAL/IdentityDAL.ts
index fa34f13e831086446377e865d404f60f26a3236f..af22cf43e9588faa108ab29d184cb6eb52e7c56e 100644
--- a/app/lib/dal/sqliteDAL/IdentityDAL.ts
+++ b/app/lib/dal/sqliteDAL/IdentityDAL.ts
@@ -27,7 +27,19 @@ export abstract class DBIdentity implements Cloneable {
   }
 
   certs:any[] = []
-  signed:any[] = []
+  signed: {
+    idty: {
+      pubkey: string
+      uid: string
+      buid: string
+      sig: string
+      member: string
+      wasMember: string
+    }
+    block_number: number
+    block_hash: string
+    sig: string
+  }[] = []
 
   revoked: boolean
   currentMSN: null
@@ -48,7 +60,11 @@ export abstract class DBIdentity implements Cloneable {
   expires_on: number
 
   getTargetHash() {
-    return IdentityDTO.getTargetHash(this)
+    return IdentityDTO.getTargetHash({
+      pub: this.pubkey,
+      created_on: this.buid,
+      uid: this.uid
+    })
   }
 
   json() {
@@ -72,7 +88,7 @@ export abstract class DBIdentity implements Cloneable {
         "timestamp": this.buid
       },
       "revoked": this.revoked,
-      "revoked_on": this.revoked_on,
+      "revoked_on": parseInt(String(this.revoked_on)),
       "revocation_sig": this.revocation_sig,
       "self": this.sig,
       "others": others
@@ -255,6 +271,10 @@ export class IdentityDAL extends AbstractSQLite<DBIdentity> {
     })
   }
 
+  setRevoked(pubkey: string) {
+    return this.query('UPDATE ' + this.table + ' SET revoked = ? WHERE pubkey = ?', [true, pubkey])
+  }
+
   getByHash(hash:string) {
     return this.sqlFindOne({
       hash: hash
diff --git a/app/lib/dal/sqliteDAL/index/IIndexDAL.ts b/app/lib/dal/sqliteDAL/index/IIndexDAL.ts
index c945ea994bc11b7c84a497fb51459111d58e79e3..050f21e55da9060d595929350f2c6e783b1fa328 100644
--- a/app/lib/dal/sqliteDAL/index/IIndexDAL.ts
+++ b/app/lib/dal/sqliteDAL/index/IIndexDAL.ts
@@ -13,7 +13,7 @@
 
 import {SQLiteDriver} from "../../drivers/SQLiteDriver";
 import {AbstractIndex} from "../AbstractIndex";
-import {IindexEntry, Indexer} from "../../../indexer";
+import {FullIindexEntry, IindexEntry, Indexer} from "../../../indexer";
 
 const _ = require('underscore');
 
@@ -126,15 +126,19 @@ export class IIndexDAL extends AbstractIndex<IindexEntry> {
   }
 
   getFromPubkey(pubkey:string) {
-    return this.entityOrNull('pub', pubkey)
+    return this.entityOrNull('pub', pubkey) as Promise<FullIindexEntry|null>
   }
 
-  getFromUID(uid:string) {
-    return this.entityOrNull('uid', uid)
+  getFromUID(uid:string, retrieveOnPubkey = false) {
+    return this.entityOrNull('uid', uid, retrieveOnPubkey)
   }
 
-  getFromHash(hash:string) {
-    return this.entityOrNull('hash', hash, true)
+  getFullFromUID(uid:string): Promise<FullIindexEntry|null> {
+    return this.entityOrNull('uid', uid, true) as Promise<FullIindexEntry|null>
+  }
+
+  getFullFromHash(hash:string): Promise<FullIindexEntry|null> {
+    return this.entityOrNull('hash', hash, true) as Promise<FullIindexEntry|null>
   }
 
   reducable(pub:string) {
@@ -179,4 +183,12 @@ export class IIndexDAL extends AbstractIndex<IindexEntry> {
       written_on: row.written_on
     }
   }
+
+  async getFromPubkeyOrUid(search: string) {
+    const idty = await this.getFromPubkey(search)
+    if (idty) {
+      return idty
+    }
+    return this.getFromUID(search, true) as Promise<FullIindexEntry|null>
+  }
 }
diff --git a/app/lib/dal/sqliteDAL/index/MIndexDAL.ts b/app/lib/dal/sqliteDAL/index/MIndexDAL.ts
index 2ff64db3b98dccf02f17ba0c788be2a6ca628fe0..29ab2c215e6c051fbdc1e8035aff7d064b42f148 100644
--- a/app/lib/dal/sqliteDAL/index/MIndexDAL.ts
+++ b/app/lib/dal/sqliteDAL/index/MIndexDAL.ts
@@ -13,7 +13,7 @@
 
 import {SQLiteDriver} from "../../drivers/SQLiteDriver";
 import {AbstractIndex} from "../AbstractIndex";
-import {Indexer, MindexEntry} from "../../../indexer";
+import {FullMindexEntry, Indexer, MindexEntry} from "../../../indexer";
 
 export class MIndexDAL extends AbstractIndex<MindexEntry> {
 
@@ -68,12 +68,12 @@ export class MIndexDAL extends AbstractIndex<MindexEntry> {
       'COMMIT;')
   }
 
-  async getReducedMS(pub:string) {
+  async getReducedMS(pub:string): Promise<FullMindexEntry|null> {
     const reducables = await this.reducable(pub);
     if (reducables.length) {
-      return Indexer.DUP_HELPERS.reduce(reducables);
+      return Indexer.DUP_HELPERS.reduce(reducables) as FullMindexEntry
     }
-    return null;
+    return null
   }
 
   reducable(pub:string) {
diff --git a/app/lib/dto/CertificationDTO.ts b/app/lib/dto/CertificationDTO.ts
index 45c2d2d403635dfd673e3ea25d1c9a5a66d6d788..66b76c92d9df315a8267dfece93d8cf622e3f7c5 100644
--- a/app/lib/dto/CertificationDTO.ts
+++ b/app/lib/dto/CertificationDTO.ts
@@ -63,8 +63,8 @@ export class CertificationDTO extends ShortCertificationDTO implements Cloneable
   getTargetHash() {
     return IdentityDTO.getTargetHash({
       uid: this.idty_uid,
-      buid: this.idty_buid,
-      pubkey: this.idty_issuer
+      created_on: this.idty_buid,
+      pub: this.idty_issuer
     })
   }
 
diff --git a/app/lib/dto/IdentityDTO.ts b/app/lib/dto/IdentityDTO.ts
index b1ed24d2ee40b3d646ee10bd176c4b4c9591b7d8..5671987b0c2801dd1f820cae2d821a408ec48048 100644
--- a/app/lib/dto/IdentityDTO.ts
+++ b/app/lib/dto/IdentityDTO.ts
@@ -18,16 +18,26 @@ import {DBIdentity, NewDBIdentity} from "../dal/sqliteDAL/IdentityDAL"
 const DEFAULT_DOCUMENT_VERSION = 10
 
 export interface HashableIdentity {
+  created_on: string
+  uid: string
+  pub: string
+}
+
+export interface BasicIdentity {
   buid: string
   uid: string
   pubkey: string
+  sig: string
 }
 
-export interface BasicIdentity {
+export interface BasicRevocableIdentity {
   buid: string
   uid: string
   pubkey: string
   sig: string
+  member: boolean
+  wasMember: boolean
+  expires_on: number
 }
 
 export class IdentityDTO {
@@ -85,7 +95,7 @@ export class IdentityDTO {
   }
 
   static getTargetHash(idty:HashableIdentity) {
-    return hashf(idty.uid + idty.buid + idty.pubkey)
+    return hashf(idty.uid + idty.created_on + idty.pub)
   }
 
   static fromJSONObject(obj:any) {
@@ -106,8 +116,8 @@ export class IdentityDTO {
       basic.buid,
       basic.uid,
       IdentityDTO.getTargetHash({
-        pubkey: basic.pubkey,
-        buid: basic.buid,
+        pub: basic.pubkey,
+        created_on: basic.buid,
         uid: basic.uid
       })
     )
@@ -120,8 +130,8 @@ export class IdentityDTO {
       revoc.idty_buid,
       revoc.idty_uid,
       IdentityDTO.getTargetHash({
-        pubkey: revoc.pubkey,
-        buid: revoc.idty_buid,
+        pub: revoc.pubkey,
+        created_on: revoc.idty_buid,
         uid: revoc.idty_uid
       })
     )
diff --git a/app/lib/dto/MembershipDTO.ts b/app/lib/dto/MembershipDTO.ts
index a3a564c03e34068acaf756d5ec2637a9ff41b94d..6d8ada8844142bb0f4c4467bd015b9a8b416c906 100644
--- a/app/lib/dto/MembershipDTO.ts
+++ b/app/lib/dto/MembershipDTO.ts
@@ -78,9 +78,9 @@ export class MembershipDTO implements Cloneable {
 
   getIdtyHash() {
     return IdentityDTO.getTargetHash({
-      buid: this.certts,
+      created_on: this.certts,
       uid: this.userid,
-      pubkey: this.issuer
+      pub: this.issuer
     })
   }
 
diff --git a/app/lib/indexer.ts b/app/lib/indexer.ts
index 42b8cea8882caa6a8623f4fe8070a519b4cde1ca..5cfa75f8be50ecbb074ca69fcfb07c4b66550efa 100644
--- a/app/lib/indexer.ts
+++ b/app/lib/indexer.ts
@@ -23,6 +23,7 @@ import {rawer, txunlock} from "./common-libs/index"
 import {CommonConstants} from "./common-libs/constants"
 import {MembershipDTO} from "./dto/MembershipDTO"
 import {UnlockMetadata} from "./common-libs/txunlock"
+import {FileDAL} from "./dal/fileDAL"
 
 const _               = require('underscore');
 
@@ -61,6 +62,21 @@ export interface MindexEntry extends IndexEntry {
   revocationSigOK?: boolean,
 }
 
+export interface FullMindexEntry {
+  op: string
+  pub: string
+  created_on: string
+  written_on: string
+  expires_on: number
+  expired_on: null|number
+  revokes_on: number
+  revoked_on: null|number
+  leaving: boolean
+  revocation: null|string
+  chainable_on: number
+  writtenOn: number
+}
+
 export interface IindexEntry extends IndexEntry {
   uid: string | null,
   pub: string,
@@ -79,6 +95,21 @@ export interface IindexEntry extends IndexEntry {
   hasToBeExcluded?: boolean,
 }
 
+export interface FullIindexEntry {
+  op: string
+  uid: string
+  pub: string
+  hash: string
+  sig: string
+  created_on: string
+  written_on: string
+  writtenOn: number
+  member: boolean
+  wasMember: boolean
+  kick: boolean
+  wotb_id: number
+}
+
 export interface CindexEntry extends IndexEntry {
   issuer: string,
   receiver: string,
@@ -855,12 +886,21 @@ export class Indexer {
 
     // BR_G45
     await Promise.all(cindex.map(async (ENTRY: CindexEntry) => {
-      ENTRY.sigOK = await checkCertificationIsValid(block, ENTRY, async (block:BlockDTO,pub:string,dal:any) => {
+      ENTRY.sigOK = await checkCertificationIsValid(block, ENTRY, async (block:BlockDTO,pub:string,dal:FileDAL) => {
         let localInlineIdty = block.getInlineIdentity(pub);
         if (localInlineIdty) {
           return IdentityDTO.fromInline(localInlineIdty)
         }
-        return dal.getWrittenIdtyByPubkey(pub)
+        const idty = await dal.getWrittenIdtyByPubkeyForCertificationCheck(pub)
+        if (!idty) {
+          return null
+        }
+        return {
+          pubkey: idty.pub,
+          uid: idty.uid,
+          sig: idty.sig,
+          buid: idty.created_on
+        }
       }, conf, dal);
     }))
 
@@ -1903,28 +1943,28 @@ async function getNodeIDfromPubkey(nodesCache: any, pubkey: string, dal: any) {
   let toNode = nodesCache[pubkey];
   // Eventually cache the target nodeID
   if (toNode === null || toNode === undefined) {
-    let idty = await dal.getWrittenIdtyByPubkey(pubkey);
+    let idty = await dal.getWrittenIdtyByPubkeyForWotbID(pubkey)
     toNode = idty.wotb_id;
     nodesCache[pubkey] = toNode;
   }
   return toNode;
 }
 
-async function sigCheckRevoke(entry: MindexEntry, dal: any, currency: string) {
+async function sigCheckRevoke(entry: MindexEntry, dal: FileDAL, currency: string) {
   try {
     let pubkey = entry.pub, sig = entry.revocation || "";
-    let idty = await dal.getWrittenIdtyByPubkey(pubkey);
+    let idty = await dal.getWrittenIdtyByPubkeyForRevocationCheck(pubkey);
     if (!idty) {
       throw Error("A pubkey who was never a member cannot be revoked");
     }
-    if (idty.revoked) {
+    if (idty.revoked_on) {
       throw Error("A revoked identity cannot be revoked again");
     }
     let rawRevocation = rawer.getOfficialRevocation({
       currency: currency,
-      issuer: idty.pubkey,
+      issuer: idty.pub,
       uid: idty.uid,
-      buid: idty.buid,
+      buid: idty.created_on,
       sig: idty.sig,
       revocation: ''
     });
@@ -1940,7 +1980,12 @@ async function sigCheckRevoke(entry: MindexEntry, dal: any, currency: string) {
 
 
 
-async function checkCertificationIsValid (block: BlockDTO, cert: CindexEntry, findIdtyFunc: (b:BlockDTO,to:string,dal:any)=>Promise<IdentityDTO>, conf: ConfDTO, dal: any) {
+async function checkCertificationIsValid (block: BlockDTO, cert: CindexEntry, findIdtyFunc: (b:BlockDTO,to:string,dal:FileDAL)=>Promise<{
+  pubkey:string
+  uid:string
+  buid:string
+  sig:string
+}|null>, conf: ConfDTO, dal: any) {
   if (block.number == 0 && cert.created_on != 0) {
     throw Error('Number must be 0 for root block\'s certifications');
   } else {
@@ -1955,7 +2000,7 @@ async function checkCertificationIsValid (block: BlockDTO, cert: CindexEntry, fi
           throw Error('Certification based on an unexisting block');
         }
       }
-      let idty = await findIdtyFunc(block, cert.receiver, dal)
+      const idty = await findIdtyFunc(block, cert.receiver, dal)
       let current = block.number == 0 ? null : await dal.getCurrentBlockOrNull();
       if (!idty) {
         throw Error('Identity does not exist for certified');
@@ -1967,8 +2012,8 @@ async function checkCertificationIsValid (block: BlockDTO, cert: CindexEntry, fi
         throw Error('Rejected certification: certifying its own self-certification has no meaning');
       else {
         const buid = [cert.created_on, basedBlock.hash].join('-');
-        idty.currency = conf.currency;
-        const raw = rawer.getOfficialCertification(_.extend(idty, {
+        const raw = rawer.getOfficialCertification({
+          currency: conf.currency,
           idty_issuer: idty.pubkey,
           idty_uid: idty.uid,
           idty_buid: idty.buid,
@@ -1976,7 +2021,7 @@ async function checkCertificationIsValid (block: BlockDTO, cert: CindexEntry, fi
           issuer: cert.issuer,
           buid: buid,
           sig: ''
-        }));
+        })
         const verified = verify(raw, cert.sig, cert.issuer);
         if (!verified) {
           throw constants.ERRORS.WRONG_SIGNATURE_FOR_CERT
diff --git a/app/lib/rules/global_rules.ts b/app/lib/rules/global_rules.ts
index 3bc3d5417591fea6df8b84d6e1ff7290786e6669..f4dcf07e8f618b7b16b6b7d5bdb7b3a33a9c6497 100644
--- a/app/lib/rules/global_rules.ts
+++ b/app/lib/rules/global_rules.ts
@@ -76,7 +76,7 @@ export const GLOBAL_RULES_FUNCTIONS = {
     let current = await dal.getCurrentBlockOrNull();
     for (const obj of block.identities) {
       let idty = IdentityDTO.fromInline(obj);
-      let found = await dal.getWrittenIdtyByUID(idty.uid);
+      let found = await dal.getWrittenIdtyByUIDForExistence(idty.uid)
       if (found) {
         throw Error('Identity already used');
       }
@@ -184,12 +184,16 @@ export const GLOBAL_RULES_HELPERS = {
   // Functions used in an external context too
   checkMembershipBlock: (ms:any, current:DBBlock, conf:ConfDTO, dal:FileDAL) => checkMSTarget(ms, current ? { number: current.number + 1} : { number: 0 }, conf, dal),
 
-  checkCertificationIsValid: (cert:any, current:BlockDTO, findIdtyFunc:any, conf:ConfDTO, dal:FileDAL) => {
-    return checkCertificationIsValid(current ? current : { number: 0, currency: '' }, cert, findIdtyFunc, conf, dal)
+  checkCertificationIsValidInSandbox: (cert:any, current:BlockDTO, findIdtyFunc:any, conf:ConfDTO, dal:FileDAL) => {
+    return checkCertificationShouldBeValid(current ? current : { number: 0, currency: '' }, cert, findIdtyFunc, conf, dal)
   },
 
-  checkCertificationIsValidForBlock: (cert:any, block:{ number:number, currency:string }, findIdtyFunc:(b:{ number:number, currency:string }, pubkey:string, dal:FileDAL) => Promise<any>, conf:ConfDTO, dal:FileDAL) => {
-    return checkCertificationIsValid(block, cert, findIdtyFunc, conf, dal)
+  checkCertificationIsValidForBlock: (cert:any, block:{ number:number, currency:string }, findIdtyFunc:(b:{ number:number, currency:string }, pubkey:string, dal:FileDAL) => Promise<{
+    pubkey:string
+    uid:string
+    buid:string
+    sig:string}|null>, conf:ConfDTO, dal:FileDAL) => {
+    return checkCertificationShouldBeValid(block, cert, findIdtyFunc, conf, dal)
   },
 
   isOver3Hops: async (member:any, newLinks:any, newcomers:string[], current:DBBlock, conf:ConfDTO, dal:FileDAL) => {
@@ -203,9 +207,9 @@ export const GLOBAL_RULES_HELPERS = {
     }
   },
 
-  checkExistsUserID: (uid:string, dal:FileDAL) => dal.getWrittenIdtyByUID(uid),
+  checkExistsUserID: (uid:string, dal:FileDAL) => dal.getWrittenIdtyByUIDForExistence(uid),
 
-  checkExistsPubkey: (pub:string, dal:FileDAL) => dal.getWrittenIdtyByPubkey(pub),
+  checkExistsPubkey: (pub:string, dal:FileDAL) => dal.getWrittenIdtyByPubkeyForExistence(pub),
 
   checkSingleTransaction: (
     tx:TransactionDTO,
@@ -263,7 +267,12 @@ async function checkMSTarget (ms:any, block:any, conf:ConfDTO, dal:FileDAL) {
   }
 }
 
-async function checkCertificationIsValid (block:{ number:number, currency:string }, cert:any, findIdtyFunc:(b:{ number:number, currency:string }, pubkey:string, dal:FileDAL) => Promise<any>, conf:ConfDTO, dal:FileDAL) {
+async function checkCertificationShouldBeValid (block:{ number:number, currency:string }, cert:any, findIdtyFunc:(b:{ number:number, currency:string }, pubkey:string, dal:FileDAL) => Promise<{
+  pubkey:string
+  uid:string
+  buid:string
+  sig:string
+}|null>, conf:ConfDTO, dal:FileDAL) {
   if (block.number == 0 && cert.block_number != 0) {
     throw Error('Number must be 0 for root block\'s certifications');
   } else {
@@ -277,7 +286,7 @@ async function checkCertificationIsValid (block:{ number:number, currency:string
         throw Error('Certification based on an unexisting block');
       }
       try {
-        const issuer = await dal.getWrittenIdtyByPubkey(cert.from)
+        const issuer = await dal.getWrittenIdtyByPubkeyForIsMember(cert.from)
         if (!issuer || !issuer.member) {
           throw Error('Issuer is not a member')
         }
@@ -299,8 +308,8 @@ async function checkCertificationIsValid (block:{ number:number, currency:string
       const buid = [cert.block_number, basedBlock.hash].join('-');
       if (cert.block_hash && buid != [cert.block_number, cert.block_hash].join('-'))
         throw Error('Certification based on an unexisting block buid. from ' + cert.from.substring(0,8) + ' to ' + idty.pubkey.substring(0,8));
-      idty.currency = conf.currency;
-      const raw = rawer.getOfficialCertification(_.extend(idty, {
+      const raw = rawer.getOfficialCertification({
+        currency: conf.currency,
         idty_issuer: idty.pubkey,
         idty_uid: idty.uid,
         idty_buid: idty.buid,
@@ -308,7 +317,7 @@ async function checkCertificationIsValid (block:{ number:number, currency:string
         issuer: cert.from,
         buid: buid,
         sig: ''
-      }));
+      })
       const verified = verify(raw, cert.sig, cert.from);
       if (!verified) {
         throw constants.ERRORS.WRONG_SIGNATURE_FOR_CERT
diff --git a/app/modules/bma/lib/controllers/blockchain.ts b/app/modules/bma/lib/controllers/blockchain.ts
index 7062a768afc2f1787c20fcafdc6ff4dbc2e8dc88..d38b561442a1b8df386b19117c3873209a68acf8 100644
--- a/app/modules/bma/lib/controllers/blockchain.ts
+++ b/app/modules/bma/lib/controllers/blockchain.ts
@@ -132,7 +132,7 @@ export class BlockchainBinding extends AbstractController {
   async hardship(req:any): Promise<HttpHardship> {
     let nextBlockNumber = 0;
     const search = await ParametersService.getSearchP(req);
-    const idty = await this.IdentityService.findMemberWithoutMemberships(search);
+    const idty = await this.server.dal.getWrittenIdtyByPubkeyOrUidForIsMemberAndPubkey(search);
     if (!idty) {
       throw BMAConstants.ERRORS.NO_MATCHING_IDENTITY;
     }
@@ -143,7 +143,7 @@ export class BlockchainBinding extends AbstractController {
     if (current) {
       nextBlockNumber = current ? current.number + 1 : 0;
     }
-    const difficulty = await this.server.getBcContext().getIssuerPersonalizedDifficulty(idty.pubkey);
+    const difficulty = await this.server.getBcContext().getIssuerPersonalizedDifficulty(idty.pub);
     return {
       "block": nextBlockNumber,
       "level": difficulty
@@ -156,8 +156,8 @@ export class BlockchainBinding extends AbstractController {
     const issuers = await this.server.dal.getUniqueIssuersBetween(number - 1 - current.issuersFrame, number - 1);
     const difficulties = [];
     for (const issuer of issuers) {
-      const member = await this.server.dal.getWrittenIdtyByPubkey(issuer);
-      const difficulty = await this.server.getBcContext().getIssuerPersonalizedDifficulty(member.pubkey);
+      const member = await this.server.dal.getWrittenIdtyByPubkeyForUidAndPubkey(issuer);
+      const difficulty = await this.server.getBcContext().getIssuerPersonalizedDifficulty(member.pub);
       difficulties.push({
         uid: member.uid,
         level: difficulty
diff --git a/app/modules/bma/lib/controllers/wot.ts b/app/modules/bma/lib/controllers/wot.ts
index c9c7d6048cccdc3c3c1404f219c859e802965c93..f88c06a52e92c4d17849e7dba19fe2c7fd0b5a81 100644
--- a/app/modules/bma/lib/controllers/wot.ts
+++ b/app/modules/bma/lib/controllers/wot.ts
@@ -30,9 +30,12 @@ import {
   HttpResult,
   HttpSimpleIdentity
 } from "../dtos";
+import {IdentityDTO} from "../../../../lib/dto/IdentityDTO"
+import {FullIindexEntry} from "../../../../lib/indexer"
 
 const _        = require('underscore');
 const http2raw = require('../http2raw');
+const constants = require('../../../../lib/constants');
 
 const ParametersService = require('../parameters').ParametersService
 
@@ -50,7 +53,7 @@ export class WOTBinding extends AbstractController {
       const certs: any[] = await this.server.dal.certsToTarget(idty.pubkey, idty.getTargetHash());
       const validCerts = [];
       for (const cert of certs) {
-        const member = await this.IdentityService.getWrittenByPubkey(cert.from);
+        const member = await this.server.dal.getWrittenIdtyByPubkeyForUidAndIsMemberAndWasMember(cert.from);
         if (member) {
           cert.uids = [member.uid];
           cert.isMember = member.member;
@@ -68,7 +71,7 @@ export class WOTBinding extends AbstractController {
       const validSigned = [];
       for (let j = 0; j < signed.length; j++) {
         const cert = _.clone(signed[j]);
-        cert.idty = await this.server.dal.getIdentityByHashOrNull(cert.target);
+        cert.idty = await this.server.dal.getGlobalIdentityByHashForLookup(cert.target)
         if (cert.idty) {
           validSigned.push(cert);
         } else {
@@ -112,11 +115,11 @@ export class WOTBinding extends AbstractController {
 
   async certifiersOf(req:any): Promise<HttpCertifications> {
     const search = await ParametersService.getSearchP(req);
-    const idty = await this.IdentityService.findMemberWithoutMemberships(search);
-    const certs = await this.server.dal.certsToTarget(idty.pubkey, idty.getTargetHash());
+    const idty = (await this.server.dal.getWrittenIdtyByPubkeyOrUIdForHashingAndIsMember(search)) as FullIindexEntry
+    const certs = await this.server.dal.certsToTarget(idty.pub, IdentityDTO.getTargetHash(idty))
     const theCerts:HttpCertification[] = [];
     for (const cert of certs) {
-      const certifier = await this.server.dal.getWrittenIdtyByPubkey(cert.from);
+      const certifier = await this.server.dal.getWrittenIdtyByPubkeyForUidAndMemberAndCreatedOn(cert.from);
       if (certifier) {
         let certBlock = await this.server.dal.getBlock(cert.block_number)
         theCerts.push({
@@ -128,7 +131,7 @@ export class WOTBinding extends AbstractController {
             block: certBlock.number,
             medianTime: certBlock.medianTime
           },
-          sigDate: certifier.buid,
+          sigDate: certifier.created_on,
           written: (cert.written_block !== null && cert.written_hash) ? {
             number: cert.written_block,
             hash: cert.written_hash
@@ -138,9 +141,9 @@ export class WOTBinding extends AbstractController {
       }
     }
     return {
-      pubkey: idty.pubkey,
+      pubkey: idty.pub,
       uid: idty.uid,
-      sigDate: idty.buid,
+      sigDate: idty.created_on,
       isMember: idty.member,
       certifications: theCerts
     }
@@ -206,11 +209,11 @@ export class WOTBinding extends AbstractController {
 
   async certifiedBy(req:any): Promise<HttpCertifications> {
     const search = await ParametersService.getSearchP(req);
-    const idty = await this.IdentityService.findMemberWithoutMemberships(search);
-    const certs = await this.server.dal.certsFrom(idty.pubkey);
+    const idty = (await this.server.dal.getWrittenIdtyByPubkeyOrUIdForHashingAndIsMember(search)) as FullIindexEntry
+    const certs = await this.server.dal.certsFrom(idty.pub);
     const theCerts:HttpCertification[] = [];
     for (const cert of certs) {
-      const certified = await this.server.dal.getWrittenIdtyByPubkey(cert.to);
+      const certified = await this.server.dal.getWrittenIdtyByPubkeyForUidAndMemberAndCreatedOn(cert.to);
       if (certified) {
         let certBlock = await this.server.dal.getBlock(cert.block_number)
         theCerts.push({
@@ -222,7 +225,7 @@ export class WOTBinding extends AbstractController {
             block: certBlock.number,
             medianTime: certBlock.medianTime
           },
-          sigDate: certified.buid,
+          sigDate: certified.created_on,
           written: (cert.written_block !== null && cert.written_hash) ? {
             number: cert.written_block,
             hash: cert.written_hash
@@ -232,9 +235,9 @@ export class WOTBinding extends AbstractController {
       }
     }
     return {
-      pubkey: idty.pubkey,
+      pubkey: idty.pub,
       uid: idty.uid,
-      sigDate: idty.buid,
+      sigDate: idty.created_on,
       isMember: idty.member,
       certifications: theCerts
     }
@@ -242,17 +245,17 @@ export class WOTBinding extends AbstractController {
 
   async identityOf(req:any): Promise<HttpSimpleIdentity> {
     let search = await ParametersService.getSearchP(req);
-    let idty = await this.IdentityService.findMemberWithoutMemberships(search);
+    const idty = await this.server.dal.getWrittenIdtyByPubkeyOrUIdForHashingAndIsMember(search)
     if (!idty) {
-      throw 'Identity not found';
+      throw constants.ERRORS.NO_MEMBER_MATCHING_PUB_OR_UID;
     }
     if (!idty.member) {
       throw 'Not a member';
     }
     return {
-      pubkey: idty.pubkey,
+      pubkey: idty.pub,
       uid: idty.uid,
-      sigDate: idty.buid
+      sigDate: idty.created_on
     };
   }
 
diff --git a/app/modules/crawler/lib/sync.ts b/app/modules/crawler/lib/sync.ts
index fea2026986e7394185b003a818840e40d48a8a27..2a2d6aeba0e428712165a967e3d0f1699a0188d0 100644
--- a/app/modules/crawler/lib/sync.ts
+++ b/app/modules/crawler/lib/sync.ts
@@ -283,7 +283,7 @@ export class Synchroniser extends stream.Duplex {
         }
         // Tells wether given peer is a member peer
         async isMemberPeer(thePeer: PeerDTO): Promise<boolean> {
-          let idty = await this.dal.getWrittenIdtyByPubkey(thePeer.pubkey);
+          let idty = await this.dal.getWrittenIdtyByPubkeyForIsMember(thePeer.pubkey);
           return (idty && idty.member) || false;
         }
         downloadBlocks(thePeer: PeerDTO, fromNumber: number, count?: number | undefined): Promise<BlockDTO[]> {
diff --git a/app/modules/prover/lib/blockGenerator.ts b/app/modules/prover/lib/blockGenerator.ts
index 20096a8d958e49e0a6e557186f9458f4ed28ea9e..3c6d67921060590fc4906325cb86d369955a2f4f 100644
--- a/app/modules/prover/lib/blockGenerator.ts
+++ b/app/modules/prover/lib/blockGenerator.ts
@@ -27,7 +27,6 @@ import {IdentityDTO} from "../../../lib/dto/IdentityDTO"
 import {CertificationDTO} from "../../../lib/dto/CertificationDTO"
 import {MembershipDTO} from "../../../lib/dto/MembershipDTO"
 import {BlockDTO} from "../../../lib/dto/BlockDTO"
-import {DBIdentity} from "../../../lib/dal/sqliteDAL/IdentityDAL"
 import {ConfDTO} from "../../../lib/dto/ConfDTO"
 import {FileDAL} from "../../../lib/dal/fileDAL"
 
@@ -37,6 +36,31 @@ const inquirer        = require('inquirer');
 
 const constants     = CommonConstants
 
+interface PreJoin {
+  identity: {
+    pubkey: string
+    uid: string
+    buid: string
+    sig: string
+    member: boolean
+    wasMember: boolean
+    revoked: boolean
+  }
+  key: null
+  idHash: string
+  certs: any[]
+  ms: any
+}
+
+interface LeaveData {
+  identity: {
+    member: boolean
+  } | null
+  ms: any
+  key: any
+  idHash: string
+}
+
 export class BlockGenerator {
 
   mainContext:BlockchainContext
@@ -82,13 +106,11 @@ export class BlockGenerator {
     const exclusions = await this.dal.getToBeKickedPubkeys();
     const wereExcludeds = await this.dal.getRevokedPubkeys();
     const newCertsFromWoT = await generator.findNewCertsFromWoT(current);
-    const newcomersLeavers = await this.findNewcomersAndLeavers(current, (joinersData:any) => generator.filterJoiners(joinersData));
+    const newcomers = await this.findNewcomers(current, (joinersData:any) => generator.filterJoiners(joinersData))
+    const leavers = await this.findLeavers(current)
     const transactions = await this.findTransactions(current, manualValues);
-    const joinData = newcomersLeavers[2];
-    const leaveData = newcomersLeavers[3];
-    const newCertsFromNewcomers = newcomersLeavers[4];
-    const certifiersOfNewcomers = _.uniq(_.keys(joinData).reduce((theCertifiers:any, newcomer:string) => {
-      return theCertifiers.concat(_.pluck(joinData[newcomer].certs, 'from'));
+    const certifiersOfNewcomers = _.uniq(_.keys(newcomers).reduce((theCertifiers:any, newcomer:string) => {
+      return theCertifiers.concat(_.pluck(newcomers[newcomer].certs, 'from'));
     }, []));
     const certifiers:string[] = [].concat(certifiersOfNewcomers);
     // Merges updates
@@ -102,24 +124,8 @@ export class BlockGenerator {
         return !isCertifier;
       });
     });
-    _(newCertsFromNewcomers).keys().forEach((certified:string) => {
-      newCertsFromWoT[certified] = (newCertsFromWoT[certified] || []).concat(newCertsFromNewcomers[certified]);
-    });
-    // Revocations
     // Create the block
-    return this.createBlock(current, joinData, leaveData, newCertsFromWoT, revocations, exclusions, wereExcludeds, transactions, manualValues);
-  }
-
-  private async findNewcomersAndLeavers(current:DBBlock, filteringFunc: (joinData: { [pub:string]: any }) => Promise<{ [pub:string]: any }>) {
-    const newcomers = await this.findNewcomers(current, filteringFunc);
-    const leavers = await this.findLeavers(current);
-
-    const cur = newcomers.current;
-    const newWoTMembers = newcomers.newWotMembers;
-    const finalJoinData = newcomers.finalJoinData;
-    const updates = newcomers.updates;
-
-    return [cur, newWoTMembers, finalJoinData, leavers, updates];
+    return this.createBlock(current, newcomers, leavers, newCertsFromWoT, revocations, exclusions, wereExcludeds, transactions, manualValues);
   }
 
   private async findTransactions(current:DBBlock, options:{ dontCareAboutChaining?:boolean }) {
@@ -155,12 +161,12 @@ export class BlockGenerator {
   }
 
   private async findLeavers(current:DBBlock) {
-    const leaveData: { [pub:string]: any } = {};
+    const leaveData: { [pub:string]: { identity: { member:boolean }|null, ms: any, key: any, idHash: string } } = {};
     const memberships = await this.dal.findLeavers(current && current.medianTime);
     const leavers:string[] = [];
     memberships.forEach((ms:any) => leavers.push(ms.issuer));
     for (const ms of memberships) {
-      const leave: { identity: DBIdentity|null, ms: any, key: any, idHash: string } = { identity: null, ms: ms, key: null, idHash: '' };
+      const leave: { identity: { member:boolean }|null, ms: any, key: any, idHash: string } = { identity: null, ms: ms, key: null, idHash: '' };
       leave.idHash = (hashf(ms.userid + ms.certts + ms.issuer) + "").toUpperCase();
       let block;
       if (current) {
@@ -169,20 +175,19 @@ export class BlockGenerator {
       else {
         block = {};
       }
-      const identity = await this.dal.getIdentityByHashOrNull(leave.idHash);
+      const identity = await this.dal.getGlobalIdentityByHashForIsMember(leave.idHash)
       const currentMembership = await this.dal.mindexDAL.getReducedMS(ms.issuer);
       const currentMSN = currentMembership ? parseInt(currentMembership.created_on) : -1;
       if (identity && block && currentMSN < leave.ms.number && identity.member) {
         // MS + matching cert are found
         leave.identity = identity;
-        leaveData[identity.pubkey] = leave;
+        leaveData[identity.pub] = leave;
       }
     }
     return leaveData;
   }
 
   private async findNewcomers(current:DBBlock, filteringFunc: (joinData: { [pub:string]: any }) => Promise<{ [pub:string]: any }>) {
-    const updates = {};
     const preJoinData = await this.getPreJoinData(current);
     const joinData = await filteringFunc(preJoinData);
     const members = await this.dal.getMembers();
@@ -198,12 +203,12 @@ export class BlockGenerator {
           joiners: someNewcomers,
           identities: _.filter(newcomers.map((pub:string) => joinData[pub].identity), { wasMember: false }).map((idty:any) => idty.pubkey)
         };
-        const theNewLinks = await this.computeNewLinks(nextBlockNumber, someNewcomers, joinData, updates)
+        const theNewLinks = await this.computeNewLinks(nextBlockNumber, someNewcomers, joinData)
         await this.checkWoTConstraints(nextBlock, theNewLinks, current);
       })
-      const newLinks = await this.computeNewLinks(nextBlockNumber, realNewcomers, joinData, updates);
+      const newLinks = await this.computeNewLinks(nextBlockNumber, realNewcomers, joinData)
       const newWoT = wotMembers.concat(realNewcomers);
-      const finalJoinData: { [pub:string]: any } = {};
+      const finalJoinData: { [pub:string]: PreJoin } = {};
       realNewcomers.forEach((newcomer:string) => {
         // Only keep membership of selected newcomers
         finalJoinData[newcomer] = joinData[newcomer];
@@ -217,12 +222,7 @@ export class BlockGenerator {
         });
         joinData[newcomer].certs = keptCerts;
       });
-      return {
-        current: current,
-        newWotMembers: wotMembers.concat(realNewcomers),
-        finalJoinData: finalJoinData,
-        updates: updates
-      }
+      return finalJoinData
     } catch(err) {
       this.logger.error(err);
       throw err;
@@ -272,7 +272,7 @@ export class BlockGenerator {
   }
 
   private async getPreJoinData(current:DBBlock) {
-    const preJoinData:any = {};
+    const preJoinData:{ [k:string]: PreJoin } = {}
     const memberships = await this.dal.findNewcomers(current && current.medianTime)
     const joiners:string[] = [];
     memberships.forEach((ms:any) => joiners.push(ms.issuer));
@@ -289,7 +289,7 @@ export class BlockGenerator {
           }
         }
         const idtyHash = (hashf(ms.userid + ms.certts + ms.issuer) + "").toUpperCase();
-        const join:any = await this.getSinglePreJoinData(current, idtyHash, joiners);
+        const join = await this.getSinglePreJoinData(current, idtyHash, joiners);
         join.ms = ms;
         const currentMembership = await this.dal.mindexDAL.getReducedMS(ms.issuer);
         const currentMSN = currentMembership ? parseInt(currentMembership.created_on) : -1;
@@ -307,19 +307,16 @@ export class BlockGenerator {
     return preJoinData;
   }
 
-  private async computeNewLinks(forBlock:number, theNewcomers:any, joinData:any, updates:any) {
+  private async computeNewLinks(forBlock:number, theNewcomers:any, joinData:any) {
     let newCerts = await this.computeNewCerts(forBlock, theNewcomers, joinData);
-    return this.newCertsToLinks(newCerts, updates);
+    return this.newCertsToLinks(newCerts);
   }
 
-  newCertsToLinks(newCerts:any, updates:any) {
+  newCertsToLinks(newCerts:any) {
     let newLinks:any = {};
     _.mapObject(newCerts, function(certs:any, pubkey:string) {
       newLinks[pubkey] = _.pluck(certs, 'from');
     });
-    _.mapObject(updates, function(certs:any, pubkey:string) {
-      newLinks[pubkey] = (newLinks[pubkey] || []).concat(_.pluck(certs, 'pubkey'));
-    });
     return newLinks;
   }
 
@@ -352,7 +349,7 @@ export class BlockGenerator {
   }
 
   async getSinglePreJoinData(current:DBBlock, idHash:string, joiners:string[]) {
-    const identity = await this.dal.getIdentityByHashOrNull(idHash);
+    const identity = await this.dal.getGlobalIdentityByHashForJoining(idHash)
     let foundCerts = [];
     const vHEAD_1 = await this.mainContext.getvHEAD_1();
     if (!identity) {
@@ -413,10 +410,12 @@ export class BlockGenerator {
             const isMember = await this.dal.isMember(cert.from);
             const doubleSignature = !!(~certifiers.indexOf(cert.from))
             if (isMember && !doubleSignature) {
-              const isValid = await GLOBAL_RULES_HELPERS.checkCertificationIsValidForBlock(cert, { number: current.number + 1, currency: current.currency }, async () => {
-                const idty = await this.dal.getIdentityByHashOrNull(idHash)
-                return idty
-              }, this.conf, this.dal);
+              const isValid = await GLOBAL_RULES_HELPERS.checkCertificationIsValidForBlock(
+                cert,
+                { number: current.number + 1, currency: current.currency },
+                async () => this.dal.getGlobalIdentityByHashForHashingAndSig(idHash),
+                this.conf,
+                this.dal)
               if (isValid) {
                 certifiers.push(cert.from);
                 foundCerts.push(cert);
@@ -429,15 +428,26 @@ export class BlockGenerator {
         }
       }
     }
+    const ms:any = null // TODO: refactor
     return {
       identity: identity,
       key: null,
       idHash: idHash,
-      certs: foundCerts
+      certs: foundCerts,
+      ms
     };
   }
 
-  private async createBlock(current:DBBlock, joinData:any, leaveData:any, updates:any, revocations:any, exclusions:any, wereExcluded:any, transactions:any, manualValues:any) {
+  private async createBlock(
+    current:DBBlock,
+    joinData:{ [pub:string]: PreJoin },
+    leaveData:{ [pub:string]: LeaveData },
+    updates:any,
+    revocations:any,
+    exclusions:any,
+    wereExcluded:any,
+    transactions:any,
+    manualValues:any) {
 
     if (manualValues && manualValues.excluded) {
       exclusions = manualValues.excluded;
@@ -547,7 +557,7 @@ export class BlockGenerator {
     leavers.forEach((leaver:any) => {
       const data = leaveData[leaver];
       // Join only for non-members
-      if (data.identity.member) {
+      if (data.identity && data.identity.member) {
         if (blockLen < maxLenOfBlock) {
           block.leavers.push(MembershipDTO.fromJSONObject(data.ms).inline());
           blockLen++;
@@ -709,7 +719,7 @@ class NextBlockGenerator implements BlockGeneratorInterface {
     const certs = await this.dal.certsFindNew();
     const vHEAD_1 = await this.mainContext.getvHEAD_1();
     for (const cert of certs) {
-      const targetIdty = await this.dal.getIdentityByHashOrNull(cert.target);
+      const targetIdty = await this.dal.getGlobalIdentityByHashForHashingAndSig(cert.target)
       // The identity must be known
       if (targetIdty) {
         const certSig = cert.sig;
diff --git a/app/service/IdentityService.ts b/app/service/IdentityService.ts
index 9bccc12bc93793063c77c89d852e3419eedda733..167e3291d838baf94d5ace097ecaa6b634cf7a01 100644
--- a/app/service/IdentityService.ts
+++ b/app/service/IdentityService.ts
@@ -14,7 +14,7 @@
 import {GlobalFifoPromise} from "./GlobalFifoPromise"
 import {FileDAL} from "../lib/dal/fileDAL"
 import {ConfDTO} from "../lib/dto/ConfDTO"
-import {DBIdentity, ExistingDBIdentity} from "../lib/dal/sqliteDAL/IdentityDAL"
+import {DBIdentity} from "../lib/dal/sqliteDAL/IdentityDAL"
 import {GLOBAL_RULES_FUNCTIONS, GLOBAL_RULES_HELPERS} from "../lib/rules/global_rules"
 import {BlockDTO} from "../lib/dto/BlockDTO"
 import {RevocationDTO} from "../lib/dto/RevocationDTO"
@@ -50,18 +50,17 @@ export class IdentityService extends FIFOService {
     return this.dal.searchJustIdentities(search)
   }
 
-  async findMember(search:string): Promise<{ idty: ExistingDBIdentity; memberships: { blockstamp: string; membership: string; number: number; fpr: string; written_number: number | null }[] }> {
+  async findMember(search:string) {
     let idty = null;
     if (search.match(constants.PUBLIC_KEY)) {
-      idty = await this.dal.getWrittenIdtyByPubkey(search);
+      idty = await this.dal.getWrittenIdtyByPubkeyForHashing(search);
     }
     else {
-      idty = await this.dal.getWrittenIdtyByUID(search);
+      idty = await this.dal.getWrittenIdtyByUidForHashing(search);
     }
     if (!idty) {
       throw constants.ERRORS.NO_MEMBER_MATCHING_PUB_OR_UID;
     }
-    const obj = DBIdentity.copyFromExisting(idty)
 
     let memberships: {
       blockstamp:string
@@ -71,9 +70,9 @@ export class IdentityService extends FIFOService {
       written_number:number|null
     }[] = []
 
-    if (obj) {
-      const mss = await this.dal.msDAL.getMembershipsOfIssuer(obj.pubkey);
-      const mssFromMindex = await this.dal.mindexDAL.reducable(obj.pubkey);
+    if (idty) {
+      const mss = await this.dal.msDAL.getMembershipsOfIssuer(idty.pub);
+      const mssFromMindex = await this.dal.mindexDAL.reducable(idty.pub);
       memberships = mss.map(m => {
         return {
           blockstamp: [m.blockNumber, m.blockHash].join('-'),
@@ -95,25 +94,14 @@ export class IdentityService extends FIFOService {
       }))
     }
 
-    return { idty: obj, memberships }
-  }
-
-  async findMemberWithoutMemberships(search:string) {
-    let idty = null;
-    if (search.match(constants.PUBLIC_KEY)) {
-      idty = await this.dal.getWrittenIdtyByPubkey(search)
-    }
-    else {
-      idty = await this.dal.getWrittenIdtyByUID(search)
+    return {
+      idty: {
+        pubkey: idty.pub,
+        uid: idty.uid,
+        buid: idty.created_on
+      },
+      memberships
     }
-    if (!idty) {
-      throw constants.ERRORS.NO_MEMBER_MATCHING_PUB_OR_UID;
-    }
-    return DBIdentity.copyFromExisting(idty)
-  }
-
-  getWrittenByPubkey(pubkey:string) {
-    return this.dal.getWrittenIdtyByPubkey(pubkey)
   }
 
   getPendingFromPubkey(pubkey:string) {
@@ -134,17 +122,17 @@ export class IdentityService extends FIFOService {
       if (!verified) {
         throw constants.ERRORS.SIGNATURE_DOES_NOT_MATCH;
       }
-      let existing = await this.dal.getIdentityByHashOrNull(toSave.hash);
+      let existing = await this.dal.getGlobalIdentityByHashForExistence(toSave.hash);
       if (existing) {
         throw constants.ERRORS.ALREADY_UP_TO_DATE;
       }
       else {
         // Create if not already written uid/pubkey
-        let used = await this.dal.getWrittenIdtyByPubkey(idty.pubkey);
+        let used = await GLOBAL_RULES_HELPERS.checkExistsPubkey(idty.pubkey, this.dal)
         if (used) {
           throw constants.ERRORS.PUBKEY_ALREADY_USED;
         }
-        used = await this.dal.getWrittenIdtyByUID(idty.uid);
+        used = await GLOBAL_RULES_HELPERS.checkExistsUserID(idty.uid, this.dal)
         if (used) {
           throw constants.ERRORS.UID_ALREADY_USED;
         }
@@ -183,9 +171,14 @@ export class IdentityService extends FIFOService {
     obj.currency = this.conf.currency || obj.currency;
     const cert = CertificationDTO.fromJSONObject(obj)
     const targetHash = cert.getTargetHash();
-    let possiblyNullIdty = await this.dal.getIdentityByHashOrNull(targetHash);
+    let possiblyNullIdty = await this.dal.getGlobalIdentityByHashForHashingAndSig(targetHash);
     let idtyAbsorbed = false
-    const idty: DBIdentity = possiblyNullIdty !== null ? possiblyNullIdty : await this.submitIdentity({
+    const idty:{
+      pubkey:string
+      uid:string
+      buid:string
+      sig:string
+    } = possiblyNullIdty !== null ? possiblyNullIdty : await this.submitIdentity({
       pubkey: cert.idty_issuer,
       uid: cert.idty_uid,
       buid: cert.idty_buid,
@@ -199,7 +192,7 @@ export class IdentityService extends FIFOService {
     return this.pushFIFO<CertificationDTO>(hash, async () => {
       this.logger.info('⬇ CERT %s block#%s -> %s', cert.from, cert.block_number, idty.uid);
       try {
-        await GLOBAL_RULES_HELPERS.checkCertificationIsValid(cert, potentialNext, () => Promise.resolve(idty), this.conf, this.dal);
+        await GLOBAL_RULES_HELPERS.checkCertificationIsValidInSandbox(cert, potentialNext, () => Promise.resolve(idty), this.conf, this.dal);
       } catch (e) {
         anErr = e;
       }
@@ -268,7 +261,7 @@ export class IdentityService extends FIFOService {
         if (!verified) {
           throw 'Wrong signature for revocation';
         }
-        const existing = await this.dal.getIdentityByHashOrNull(obj.hash);
+        const existing = await this.dal.getGlobalIdentityByHashForRevocation(obj.hash)
         if (existing) {
           // Modify
           if (existing.revoked) {
@@ -277,7 +270,15 @@ export class IdentityService extends FIFOService {
           else if (existing.revocation_sig) {
             throw 'Revocation already registered';
           } else {
-            await this.dal.setRevocating(existing, revoc.revocation);
+            await this.dal.setRevocating({
+              pubkey: existing.pub,
+              buid: existing.created_on,
+              sig: existing.sig,
+              uid: existing.uid,
+              expires_on: existing.expires_on,
+              member: existing.member,
+              wasMember: existing.wasMember,
+            }, revoc.revocation);
             this.logger.info('✔ REVOCATION %s %s', revoc.pubkey, revoc.idty_uid);
             return revoc
           }
diff --git a/test/integration/branches_revert_memberships.js b/test/integration/branches_revert_memberships.js
index b40919e7d0fd6555bd9121fa0fe1b80cbb0ded14..33446bee4f554b005d67518aa2b328834c612f86 100644
--- a/test/integration/branches_revert_memberships.js
+++ b/test/integration/branches_revert_memberships.js
@@ -15,9 +15,7 @@
 
 const co        = require('co');
 const should    = require('should');
-const bma       = require('../../app/modules/bma').BmaDependency.duniter.methods.bma;
 const TestUser  = require('./tools/TestUser').TestUser
-const commit    = require('./tools/commit');
 const toolbox   = require('./tools/toolbox');
 
 let s1, i1, i2, i3
diff --git a/test/integration/wotb.js b/test/integration/wotb.js
index 6c180b4a83ee20048172b8f584ff725b84a11bc0..029cc4b0b06a08d59695eb8c6985418bbad09bc1 100644
--- a/test/integration/wotb.js
+++ b/test/integration/wotb.js
@@ -132,8 +132,8 @@ describe("WOTB module", function() {
 
     it('the wotb_id should be affected to new members', function() {
       return co(function *() {
-        let icat = yield s1.dal.getWrittenIdtyByUID("cat");
-        let itoc = yield s1.dal.getWrittenIdtyByUID("toc");
+        let icat = yield s1.dal.getWrittenIdtyByUIDForWotbId("cat");
+        let itoc = yield s1.dal.getWrittenIdtyByUIDForWotbId("toc");
         icat.should.have.property('wotb_id').equal(0);
         itoc.should.have.property('wotb_id').equal(1);
         wotb.isEnabled(0).should.equal(true);
@@ -157,7 +157,7 @@ describe("WOTB module", function() {
         yield toc.cert(tic);
         yield tic.join();
         yield commit(s1)();
-        let itic = yield s1.dal.getWrittenIdtyByUID("tic");
+        let itic = yield s1.dal.getWrittenIdtyByUIDForWotbId("tic");
         itic.should.have.property('wotb_id').equal(2);
         wotb.isEnabled(2).should.equal(true);
         wotb.existsLink(1, 2).should.equal(true);