Skip to content
This repository was archived by the owner on Oct 1, 2025. It is now read-only.

Commit a638b46

Browse files
committed
docs: how does it work
1 parent a936a0a commit a638b46

File tree

10 files changed

+176
-36
lines changed

10 files changed

+176
-36
lines changed

website/docs/component/oa-verify.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ verify(document, { network: "mainnet" }).then(fragments => {
9191
```
9292

9393
Let's try to understand the different results:
94-
- `isValid(fragments, ["DOCUMENT_INTEGRITY"])` returns true because the integrity of the document is not dependant on the network it has been published to.
94+
- `isValid(fragments, ["DOCUMENT_INTEGRITY"])` returns true because the integrity of the document is not dependent on the network it has been published to.
9595
- `isValid(fragments, ["DOCUMENT_STATUS"])` returns false because the document has not been published on Ethereum main network.
9696
- `isValid(fragments, ["DOCUMENT_STATUS"])` returns false because there is no [DNS-TXT record](/docs/verifiable-document/dns-proof) associated with the Ethereum main network's document store.
9797
- `isValid(fragments)` returns false because at least one of the above returns false.

website/docs/advanced/how-does-it-work.md renamed to website/docs/how-does-it-work/document-integrity.md

Lines changed: 10 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
---
2-
id: how-does-it-work
3-
title: How does it work?
4-
sidebar_label: How does it work?
2+
title: Document integrity
3+
sidebar_label: Document integrity
54
---
65

6+
OpenAttestation ensures that the content of the document has not been modified since the document has been created, with exception of data removed using the built-in [obfuscation mechanism](/docs/component/open-attestation#obfuscating-data). Let's explore how it works.
7+
78
In the tutorial, we have learnt how to [wrap a document](/docs/verifiable-document/wrapping-document) and [issue it](/docs/verifiable-document/issuing-document) into a document store. However, we didn't explain what these actions were doing and why they are necessary.
89

910
## Wrapping a document
@@ -54,32 +55,19 @@ The first step of wrapping consists of transforming all the object properties pr
5455
### The `signature` object
5556

5657
#### targetHash
58+
See [issuance status](/docs/how-does-it-work/issuance-status#merkleroot).
5759

5860
Once the `data` object has been computed we will be able to create an unique hash for the document that we will set into `targetHash`:
5961

6062
1. List each properties' path from the `data` object and associate its value. The path follows the [flatley](https://github.com/antony/flatley) path convention. For instance: `name`, `issuers.0.tokenRegistry`, etc.
6163
1. For each properties' path, compute a hash using the properties' path and value. To compute the hash we use [keccak256](https://en.wikipedia.org/wiki/SHA-3).
6264
1. Sort all the hashes from the previous step alphabetically and hash them all together: this will provide the `targetHash` of the document. To compute the `targetHash` we also use [keccak256](https://en.wikipedia.org/wiki/SHA-3).
6365

64-
> The `targetHash` of a document is an unique identifier.
65-
66-
![Compute target hash](/docs/advanced/how-does-it-work/target-hash.png)
67-
68-
Later on, during verification of the document, the same exact steps are performed again to assert that the contents of the document has not been tampered with. This works as the final targetHash will be completely different if any part of the wrapped document is different from the original.
69-
70-
The [document store](/docs/verifiable-document/document-store) is a smart contract on the Ethereum network that records the issuance and revocation status of OpenAttestation documents. It stores the hashes of wrapped documents, which are the records of the owner of the document store having issued the documents.
71-
72-
Imagine that you wrap thousands of files and had to issue the `targetHash` for each of them. It would be extremely inefficient. That's where the `merkleRoot` will come in handy.
73-
74-
#### merkleRoot
75-
76-
Once the `targetHash` of a document is computed, OpenAttestation will determine the `merkleRoot`. The `merkleRoot` value is the merkle root hash computed from the [merkle tree](https://en.wikipedia.org/wiki/Merkle_tree) using the `targetHash` of all the document wrapped together. Each `targetHash` is a leaf in the tree. After computing the merkle tree, the `merkleRoot` associated to a document will be added to it as well as the proofs (intermediate hashes) needed to ensure that the `targetHash` has been used to compute the `merkleRoot`. The proofs are added into the `proof` property.
66+
> The `targetHash` of a document is a unique identifier.
7767
78-
In the document above we can notice that the `targetHash` and the `merkelRoot` are identical and that the `proof` is empty. This is normal and happen when you wrap only one document at a time. Try to wrap at least 2 documents at the same time, and you will see a difference between `targetHash` and the `merkelRoot`, and you will see proofs appended.
68+
![Compute target hash](/docs/how-does-it-work/target-hash.png)
7969

80-
> The `merkleRoot` will always be the same for all the documents wrapped together (in a batch). It will be different for documents wrapped separately.
81-
82-
Now that our batch of documents have a common identifier and that we can prove (thanks to the merkle tree algorithm) that the `targetHash` of a document was used to create a specific `merkleRoot`, we can use the `merkleRoot` in our document store and issue it.
70+
Later on, during verification of the document, the same exact steps are performed again to assert that the contents of the document has not been tampered with. This works as the final `targetHash` will be completely different if any part of the wrapped document is different from the original.
8371

8472
#### Data Obfuscation
8573

@@ -113,9 +101,7 @@ The content of `output.json` will be:
113101
"merkleRoot": "11d456db211d68cc8a6eac5e293422dec669b54812e4975497d7099467335987"
114102
},
115103
"privacy": {
116-
"obfuscatedData": [
117-
"9d22655fcee6bf3eb10ba280cfa40e662f004a819be0b64e2fe9d0cebba6788f"
118-
]
104+
"obfuscatedData": ["9d22655fcee6bf3eb10ba280cfa40e662f004a819be0b64e2fe9d0cebba6788f"]
119105
}
120106
}
121107
```
@@ -133,19 +119,10 @@ The hash added into `privacy.obfuscatedData` is the one used when computing the
133119

134120
The only difference with the [`targetHash`](#targethash) computation is the step 3.
135121

136-
![Compute target hash with data obfuscation](/docs/advanced/how-does-it-work/target-hash-with-data-obfuscation.png)
122+
![Compute target hash with data obfuscation](/docs/how-does-it-work/target-hash-with-data-obfuscation.png)
137123

138124
With the help of data obfuscation a user can decide to selectively disclose a subset of data he wants to share.
139125

140-
### Document Store
141-
142-
As discussed above, issuance of documents can happen individually or by batch. Issuing a batch documents is by far the more efficient way.
143-
144-
When it comes to revocation both values can also be used:
145-
146-
- `targetHash` will allow for the revocation of a specific document.
147-
- `merkleRoot` will allow for the revocation of the whole batch of documents.
148-
149126
## Additional information
150127

151128
### Data Obfuscation limitations
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
---
2+
title: Introduction
3+
sidebar_label: Introduction
4+
---
5+
6+
To fully understand how OpenAttestation works, you need to dig into the different properties the framework provides to your documents:
7+
8+
- [Document integrity](/docs/how-does-it-work/document-integrity): OpenAttestation ensures that the content of the document has not been modified since the document has been created, with exception of data removed using the built-in obfuscation mechanism.
9+
- [Issuance Status](/docs/how-does-it-work/issuance-status): OpenAttestation checks that the document has been issued and that its issuance status is in good standing (for instance, that it hasn't been revoked). As of today, OpenAttestation supports two ways to issue documents: DID Signing and Ethereum Smart Contracts.
10+
- [Issuance Identity](/docs/how-does-it-work/issuance-identity): OpenAttestation checks and returns the identity of the issuer. By default, OpenAttestation uses DNS to verify the identity but DID can be used optionally. It's important to note that OpenAttestation does not endorse any issuers. It only verifies that the issuing party in the document has provided some sort of proof that it is the same party as claimed - for example, proving ownership over a domain by the ability to create a DNS record.
11+
12+
It's very important to note that, even if we split the verification, they are all complementary. For instance, if we can prove that the document has been issued, and the issuer is valid, that would make no sense if we can't prove that the document has not been tampered. That thinking works for any combination.
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
title: Issuance Identity
3+
sidebar_label: Issuance Identity
4+
---
5+
6+
TODO
Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
---
2+
title: Issuance Status
3+
sidebar_label: Issuance Status
4+
---
5+
6+
OpenAttestation checks that the document has been issued and that it's issuance status is in good standing (for instance, that it hasn't been revoked). As of today, OpenAttestation supports two ways to issue documents: DIDs and Ethereum Smart Contracts.
7+
8+
## Ethereum Smart Contracts
9+
10+
The [document store](/docs/verifiable-document/document-store) is a smart contract on the Ethereum network that records the issuance and revocation status of OpenAttestation documents. It stores the hashes of wrapped documents, which are the records of the owner of the document store having issued the documents. Before we explain the verification process in detail, we need to introduce a new concept: the `merkleRoot`.
11+
12+
Let's imagine that we need to wrap thousands of files and had to issue the `targetHash` for each of them. It would be extremely inefficient because Ethereum is slow, and we would have to pay for each transaction.
13+
14+
That's where the `merkleRoot` will come in handy.
15+
16+
### merkleRoot
17+
18+
Once the `targetHash` of a document is computed, OpenAttestation will determine the `merkleRoot`. The `merkleRoot` value is the merkle root hash computed from the [merkle tree](https://en.wikipedia.org/wiki/Merkle_tree) using the `targetHash` of all the document wrapped together. Each `targetHash` is a leaf in the tree. After computing the merkle tree, the `merkleRoot` associated to a document will be added to it as well as the proofs (intermediate hashes) needed to ensure that the `targetHash` has been used to compute the `merkleRoot`. The proofs are added into the `proof` property.
19+
20+
On a side note, when we wrap only one document at a time, the `targetHash` and the `merkelRoot` are identical and the `proof` is empty. This is completely normal. When we wrap at least 2 documents at the same time, we will notice a difference between `targetHash` and the `merkelRoot`, and proofs appended.
21+
22+
> The `merkleRoot` will always be the same for all the documents wrapped together (in a batch). It will be different for documents wrapped separately.
23+
24+
### Issuance
25+
26+
Now that our batch of documents has a common identifier and that we can prove (thanks to the merkle tree algorithm) that the `targetHash` of a document was used to create a specific `merkleRoot`, we can use the `merkleRoot` in our document store and issue it.
27+
28+
### Revocation
29+
30+
As discussed above, issuance of documents can happen individually or by batch. Issuing a batch documents is by far the more efficient way. When it comes to revocation both values can also be used:
31+
32+
- `targetHash` will allow for the revocation of a specific document.
33+
- `merkleRoot` will allow for the revocation of the whole batch of documents.
34+
35+
### Issuance process and verification
36+
37+
To issue a document, an institution or individual :
38+
39+
- [Deploys a new document store](/docs/verifiable-document/document-store) on Ethereum and get the address of the deployed contract. (this action needs to be performed only once)
40+
- Adds the address of the deployed contract into the document (before wrapping).
41+
- Wraps a document (or a batch of documents) and get a `merkleRoot`. The wrapped documents can be shared to the recipients.
42+
- Issues the `merkleRoot` by calling the `issue` function from the document store contract.
43+
44+
An OpenAttestation verifier:
45+
46+
- Checks the `merkleRoot` of the document has been issued:
47+
1. Gets back the document store contract address from the document itself.
48+
1. Ensures that the `targetHash` and the `proof` matches the `merkleRoot`.
49+
1. Checks the `merkleRoot` is in the document store provided, by calling the `isIssued` function from the deployed contract.
50+
- Checks the `merkleRoot` of the document has been issued:
51+
1. Gets back the document store contract address from the document itself.
52+
1. Checks the `targetHash` is **not** in the document store provided, by calling the `isRevoked` function from the deployed contract.
53+
1. Checks the `merkleRoot` is **not** in the document store provided, by calling the `isRevoked` function from the deployed contract.
54+
55+
## DIDs
56+
57+
Decentralized identifiers (DIDs) are a new type of identifier that enables verifiable, decentralized digital identity. DID document associated with DIDs contains a verification method, often a public key. The owner of a DID can use the private key associated and anyone can verify that the owner control the public key.
58+
59+
At the moment, OpenAttestation only supports one DID method: `ethr`.
60+
61+
### Issuance
62+
63+
DIDs [are significantly faster and incur not costs](/docs/verifiable-document/comparison). They could directly use the `targetHash` of the document (which is unique) and sign it using the private key associated. However for consistency with our initial design, we sign the `merkleRoot`.
64+
65+
The information about the signature are added to the document, into the `proof` property. That's it, the document has been issued.
66+
67+
Let's dig a bit more to understand how it works.
68+
69+
An [`ethr` DID document](https://dev.uniresolver.io/1.0/identifiers/did:ethr:0x6813Eb9362372EEF6200f3b1dbC3f819671cBA69) looks like ::
70+
71+
```json
72+
{
73+
"@context": "https://w3id.org/did/v1",
74+
"id": "did:ethr:0x6813Eb9362372EEF6200f3b1dbC3f819671cBA69",
75+
"publicKey": [
76+
{
77+
"id": "did:ethr:0x6813Eb9362372EEF6200f3b1dbC3f819671cBA69#controller",
78+
"type": "Secp256k1VerificationKey2018",
79+
"controller": "did:ethr:0x6813Eb9362372EEF6200f3b1dbC3f819671cBA69",
80+
"ethereumAddress": "0x6813eb9362372eef6200f3b1dbc3f819671cba69"
81+
}
82+
],
83+
"authentication": [
84+
{
85+
"type": "Secp256k1SignatureAuthentication2018",
86+
"publicKey": "did:ethr:0x6813Eb9362372EEF6200f3b1dbC3f819671cBA69#controller"
87+
}
88+
]
89+
}
90+
```
91+
92+
Three important information can be found:
93+
94+
- the DID identifier (here `did:ethr:0x6813Eb9362372EEF6200f3b1dbC3f819671cBA69`). It's used to identify the DID and must be added into the `issuer.id` property of the document.
95+
- The DID controller (here `did:ethr:0x6813Eb9362372EEF6200f3b1dbC3f819671cBA69#controller`). It's used to identify which public key control the DID and must be added into the `issuer.identityProof.key` property of the document. It's also worth to note that the value is equal to the DID identifier, appended with `#controller`.
96+
- The ethereum address associated to the DID controller (here `0x6813eb9362372eef6200f3b1dbc3f819671cba69`). We will use it to verify the signature.
97+
98+
> You can find an example of document using DID in our [guide](/docs/verifiable-document/did/raw-document).
99+
100+
A proof of signature looks like:
101+
102+
```json
103+
{
104+
"proof": [
105+
{
106+
"type": "OpenAttestationSignature2018",
107+
"created": "2020-10-05T09:05:35.171Z",
108+
"proofPurpose": "assertionMethod",
109+
"verificationMethod": "did:ethr:0x6813Eb9362372EEF6200f3b1dbC3f819671cBA69#controller",
110+
"signature": "0x6d0ff5c64b8230cdc471f38267495002f2c762acf7a80250599809ee32b4255377f1adcb56fb712dee66bfeb21be6b5d802f299aea1f1edca129e88e4c1742ce1c"
111+
}
112+
]
113+
}
114+
```
115+
116+
- `signature` is the signed `merkleRoot`
117+
- `verificationMethod` is the DID controller.
118+
119+
That's all the information that we need to verify that the document has been signed with the correct private key. Indeed,`ethr` DID uses [ECDSA](https://en.wikipedia.org/wiki/Elliptic_Curve_Digital_Signature_Algorithm) with [Secp256k1](https://en.bitcoin.it/wiki/Secp256k1) as parameter of the elliptic curve which provides an interesting property: when we verify a signature, using the initial value (`merkleRoot`), and the signed value (`signature`) it will recover the ethereum address associated with the private key used. We can then compare the ethereum address from the DID document, with the ethereum address returned by the verification. If it matches, the signature is valid.
120+
121+
If you want to dig more on ECDSA, you can read this guide from [Yos Riady](https://yos.io/2018/11/16/ethereum-signatures/).
122+
123+
### Revocation
124+
125+
At the moment, there are no ways to revoke documents issued using DIDs.
126+
127+
### Issuance process and verification
128+
129+
To issue a document, an institution or individual :
130+
131+
- [Creates a new ethr DID](/docs/verifiable-document/did/create) (this action needs to be performed only once) and get the private key and the public address.
132+
- Adds the DID address and controller into the document (before wrapping).
133+
- Wraps a document and get a `merkleRoot`.
134+
- Sign the `merkleRoot` using the private key. The signature must be appended into the wrapped document.
135+
- The wrapped document can be shared to the recipients.
136+
137+
An OpenAttestation verifier:
138+
139+
- Retrieves the ethereum address associated with the DID identifier and DID controller from the document.
140+
- Retrieves the ethereum used to sign the merkle root.
141+
- Makes sure both addresses match.

website/docs/verifiable-document/going-further.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ sidebar_label: Going Further
66

77
Now that you have completed the getting started guide to create your own `Verifiable Document`, here you will find list of topic that you might be interested on to discover more
88

9-
- [How it works ?](/docs/advanced/how-does-it-work)
9+
- [How does it work?](/docs/how-does-it-work/introduction)
1010
- [Configuring DNS](/docs/advanced/configuring-dns)
1111
- [Creating a Custom Renderer](/docs/advanced/custom-renderer)
1212

website/sidebars.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,11 @@
4141
"transferable-record/issuing-transferable-record",
4242
"transferable-record/going-further"
4343
],
44+
"How does it work ?": [
45+
"how-does-it-work/introduction",
46+
"how-does-it-work/document-integrity",
47+
"how-does-it-work/issuance-status"
48+
],
4449
"Components": [
4550
"component/overview",
4651
"component/open-attestation-cli",
@@ -51,7 +56,6 @@
5156
],
5257
"Advanced": [
5358
"advanced/overview",
54-
"advanced/how-does-it-work",
5559
"advanced/verification-methods",
5660
"advanced/identity-proofs",
5761
"advanced/custom-renderer",

website/static/docs/advanced/how-does-it-work/excalidraw.json renamed to website/static/docs/how-does-it-work/excalidraw.json

File renamed without changes.

website/static/docs/advanced/how-does-it-work/target-hash-with-data-obfuscation.png renamed to website/static/docs/how-does-it-work/target-hash-with-data-obfuscation.png

File renamed without changes.

website/static/docs/advanced/how-does-it-work/target-hash.png renamed to website/static/docs/how-does-it-work/target-hash.png

File renamed without changes.

0 commit comments

Comments
 (0)