Verification
The verification process is done in the following three steps:
- Retrieve an integrity proof
- Verify the integrity proof
- Validate in blockchain
Those steps can be implemented, using our SDKs, both individually or together.
The verification process takes as input a set of Records that you are willing to validate and an optional blockchain network where the validation will be made. If the blockchain network is not set, the SDKs will select Ethereum by default if available.
The output of the process will be a timestamp which is the earliest transaction in the selected blockchain network where all the records are included.
One-step verification
In order to verify one or more records in one step, our SDKs provide the function verifyRecords. This function will take care of managing the 3 steps by itself.
Here are code example of how to implement this function:
- Typescript
- Python
- Java
- PHP
- Golang
import { Bloock, IntegrityClient, Network, RecordClient } from '@bloock/sdk';
try {
// we set the API key and create a client
Bloock.setApiKey(process.env['API_KEY']);
const integrityClient = new IntegrityClient();
const recordClient = new RecordClient();
const record = await recordClient.fromString('Hello world').build();
const records = [record];
const receipts = await integrityClient.sendRecords(records);
const _anchor = await integrityClient.waitAnchor(receipts[0].anchor);
// we can optionally specify a network (if not set, default is Ethereum Mainnet)
const timestamp = await integrityClient.verifyRecords(
records,
Network.ETHEREUM_MAINNET
);
console.log(timestamp);
} catch (e) {
console.log(e);
}
import os
import bloock
from bloock import Network
from bloock.client.integrity import IntegrityClient
from bloock.client.record import RecordClient
# we set the API key and create a client
bloock.api_key = os.environ["API_KEY"]
record_client = RecordClient()
integrity_client = IntegrityClient()
record = record_client.from_string("Hello world").build()
records = [record]
send_receipts = integrity_client.send_records(records)
anchor = integrity_client.wait_anchor(send_receipts[0].anchor, timeout=60000)
# we can optionally specify a network (if not set, default is Ethereum Mainnet)
timestamp = integrity_client.verify_records(records, Network.ETHEREUM_MAINNET)
print(timestamp)
import com.bloock.sdk.Bloock;
import com.bloock.sdk.client.IntegrityClient;
import com.bloock.sdk.client.RecordClient;
import com.bloock.sdk.entity.integrity.Anchor;
import com.bloock.sdk.entity.integrity.Network;
import com.bloock.sdk.entity.integrity.RecordReceipt;
import com.bloock.sdk.entity.record.Record;
import java.util.ArrayList;
import java.util.List;
public class VerifyRecords {
public static void main(String[] args) throws Exception {
try {
// we set the API key and create a client
Bloock.apiKey = System.getenv("API_KEY");
RecordClient recordClient = new RecordClient();
IntegrityClient integrityClient = new IntegrityClient();
ArrayList<Record> records = new ArrayList<>();
Record record = recordClient.fromString("Hello world").build();
records.add(record);
List<RecordReceipt> receipts = integrityClient.sendRecords(records);
Anchor anchor = integrityClient.waitAnchor(receipts.get(0).getAnchor(), 120000);
// we can optionally specify a network (if not set, default is Ethereum Mainnet)
long timestamp = integrityClient.verifyRecords(records, Network.ETHEREUM_MAINNET);
System.out.println(timestamp);
} catch (Exception e) {
System.out.println(e);
}
}
}
<?php
require "./vendor/autoload.php";
use Bloock\Bloock;
use Bloock\Client\IntegrityClient;
use Bloock\Client\RecordClient;
use Bloock\Entity\Integrity\Network;
Bloock::$apiKey = getenv("API_KEY") ?: "";
$integrityClient = new IntegrityClient();
$recordClient = new RecordClient();
$record = $recordClient->fromString("Hello world")->build();
$records = [$record];
$sendReceipts = $integrityClient->sendRecords($records);
$anchor = $integrityClient->waitAnchor($sendReceipts[0]->getAnchor());
$timestamp = $integrityClient->verifyRecords($records, Network::ETHEREUM_MAINNET);
package main
import (
"log"
"os"
bloock "github.com/bloock/bloock-sdk-go/v2"
"github.com/bloock/bloock-sdk-go/v2/client"
"github.com/bloock/bloock-sdk-go/v2/entity/integrity"
"github.com/bloock/bloock-sdk-go/v2/entity/record"
)
func main() {
bloock.ApiKey = os.Getenv("API_KEY")
recordClient := client.NewRecordClient()
integrityClient := client.NewIntegrityClient()
var records []record.Record
record, _ := recordClient.FromString("Hello world").Build()
// if err != nil { ... }
records = append(records, record)
receipt, _ := integrityClient.SendRecords(records)
// if err != nil { ... }
_, _ = integrityClient.WaitAnchor(receipt[0].Anchor, integrity.NewAnchorParams())
// if err != nil { ... }
network := integrity.NewNetworkParams()
// we can specify the network we verify against or leave the default
network.Network = integrity.ListOfNetworks().EthereumMainnet
// we then verify the records and we will recive a timestamp
// greater than 0 if the verification was successful
timestamp, _ := integrityClient.VerifyRecords(records, network)
// if err != nil { ... }
log.Println(timestamp)
}
Detailed verification
Retrieve an integrity proof
An integrity proof is a set of data computed by BLOOCK based on one (or more) Records that can later be verified independently to mathematically assure that those Records were included in an anchor in the past.
Once an Integrity proof is computed it's valid over time. You can store it internally and use it for later verification to ensure full independence from our service from this point.
You will not be able to verify a Record that is not fully processed and transacted to Blockchain. See Synchronization for information about how to manage it.
Our SDKs allow to easily retrieve this integrity proof. Here are some code examples of how to implement it:
- Typescript
- Python
- Java
- PHP
- Golang
import { IntegrityClient, Record } from '@bloock/sdk';
const integrityClient = new IntegrityClient();
const records: Record[] = [
/* records */
];
const _proof = await integrityClient.getProof(records);
from typing import List
from bloock.client.integrity import IntegrityClient
from bloock.entity.record.record import Record
if __name__ == "__main__":
integrity_client = IntegrityClient()
records: List[Record] = [
# records
]
proof = integrity_client.get_proof(records)
import com.bloock.sdk.client.IntegrityClient;
import com.bloock.sdk.entity.integrity.Proof;
import com.bloock.sdk.entity.record.Record;
import java.util.List;
public class GetProof {
public static void main(String[] args) throws Exception {
List<Record> records = List.of(/* records */);
IntegrityClient integrityClient = new IntegrityClient();
Proof proof = integrityClient.getProof(records);
}
}
<?php
require "./vendor/autoload.php";
use Bloock\Client\IntegrityClient;
$integrityClient = new IntegrityClient();
$records = array(/* some records */);
$proof = $integrityClient->getProof($records);
package main
import (
"log"
"github.com/bloock/bloock-sdk-go/v2/client"
"github.com/bloock/bloock-sdk-go/v2/entity/record"
)
func main() {
records := []record.Record{ /* some records */ }
// we give GetProof an array with the hashes of the records
integrityClient := client.NewIntegrityClient()
proof, _ := integrityClient.GetProof(records)
log.Printf("proof: %+v", proof)
}
Verify the integrity proof
The next step in the verification process is to verify the integrity proof retrieved in the previous step. This is made by locally computing the result of the proof, which is the value (root) that, at some point of time, got transacted into blockchain.
For more detail about this process, you can see the Protocol section.
All this process is managed by our SDKs and can be implemented as follows:
- Typescript
- Python
- Java
- PHP
- Golang
import { IntegrityClient, Proof } from '@bloock/sdk';
const integrityClient = new IntegrityClient();
let proof: Proof;
const _root = await integrityClient.verifyProof(proof);
from typing import List
from bloock.client.integrity import IntegrityClient
from bloock.entity.record.record import Record
if __name__ == "__main__":
integrity_client = IntegrityClient()
records: List[Record] = [
# records
]
# a proof
proof = integrity_client.get_proof(records)
root = integrity_client.verify_proof(proof)
import com.bloock.sdk.client.IntegrityClient;
import com.bloock.sdk.entity.integrity.Proof;
public class VerifyProof {
public static void main(String[] args) throws Exception {
IntegrityClient integrityClient = new IntegrityClient();
// Proof obtained previously
Proof proof = null;
String root = integrityClient.verifyProof(proof);
}
}
<?php
require "./vendor/autoload.php";
use Bloock\Client\IntegrityClient;
$integrityClient = new IntegrityClient();
$records = array(/* some records */);
$proof = $integrityClient->getProof($records);
$root = $integrityClient->verifyProof($proof);
package main
import (
"github.com/bloock/bloock-sdk-go/v2/client"
"github.com/bloock/bloock-sdk-go/v2/entity/integrity"
)
func main() {
integrityClient := client.NewIntegrityClient()
var proof integrity.Proof
_, _ = integrityClient.VerifyProof(proof)
// if err != nil { ... }
}
Validate in blockchain
The last step of the verification process is to check if the output of the Verify integrity proof step is actually in the selected blockchain network.
This is made by querying the obtained root on the BLOOCK's Smart Contract deployed on each network available. The result of this query is a timestamp (specifically the block time) when this root was transacted into the network.
Here's some code examples of how to implement this using our SDKs:
- Typescript
- Python
- Java
- PHP
- Golang
import { IntegrityClient, Network } from '@bloock/sdk';
const integrityClient = new IntegrityClient();
const root = 'root';
const _timestamp = await integrityClient.validateRoot(
root,
Network.ETHEREUM_MAINNET
);
from bloock.client.integrity import IntegrityClient
from bloock.entity.integrity.network import Network
if __name__ == "__main__":
integrity_client = IntegrityClient()
root = "root"
timestamp = integrity_client.validate_root(root, Network.ETHEREUM_MAINNET)
import com.bloock.sdk.client.IntegrityClient;
import com.bloock.sdk.entity.integrity.Network;
public class VerifyRoot {
public static void main(String[] args) throws Exception {
IntegrityClient integrityClient = new IntegrityClient();
String root = "root";
long timestamp = integrityClient.validateRoot(root, Network.ETHEREUM_MAINNET);
}
}
<?php
require "./vendor/autoload.php";
use Bloock\Client\IntegrityClient;
use Bloock\Entity\Integrity\Network;
$integrityClient = new IntegrityClient();
$root = "root";
$proof = $integrityClient->validateRoot($root, Network::ETHEREUM_MAINNET);
package main
import (
"log"
"github.com/bloock/bloock-sdk-go/v2/client"
"github.com/bloock/bloock-sdk-go/v2/entity/integrity"
)
func main() {
integrityClient := client.NewIntegrityClient()
network := integrity.NewNetworkParams()
// we can specify the network we verify against or leave the default
network.Network = integrity.ListOfNetworks().EthereumMainnet
// previously retrieved root
var root string
timestamp, _ := integrityClient.ValidateRoot(root, network)
// if err != nil { ... }
log.Println(timestamp)
}