Méthode GET/verify /merkle /{identifier}
Récupérer la preuve d'appartenance d'un article au lot ancré sur Base, avec sa feuille, sa preuve de voisinage et la racine inscrite sur la chaîne. Point d'entrée public.
Sur cette page
Vous récupérez la preuve qu'un article faisait partie d'un lot dont l'empreinte a été inscrite sur la chaîne Base. En quittant cette page, vous saurez demander cette preuve à partir de n'importe quel identifiant d'article, la recalculer vous-même sans nous faire confiance, et distinguer un article qui n'est pas ancré d'un échec de vérification.
Adresse complète :
GET https://api.sealtrust.io/v1/verify/merkle/{identifier}Le même point d'entrée répond aussi sans le préfixe /v1, à
https://api.sealtrust.io/verify/merkle/{identifier}. Les deux adresses
appellent le même code. Utilisez la forme /v1 pour une nouvelle intégration.
#Autorisation
Aucune, point d'entrée public. Vous n'envoyez ni clef d'API, ni session, ni en-tête d'origine. La réponse est la même pour tout le monde.
#Plafond d'appels
30 appels par tranche de 60 secondes, comptés par adresse réseau appelante.
Ce compteur est commun aux chemins qui commencent par /verify/, comme
/verify/batch ou /verify/scan-log. Les appels que vous adressez à l'un
d'eux entament donc le budget des autres. Le point d'entrée /verify_any
possède son propre budget, distinct de celui-ci.
Le préfixe /v1 ne crée pas un second budget : /v1/verify/merkle/1042 et
/verify/merkle/1042 remplissent le même compteur.
Chaque réponse acceptée porte trois en-têtes.
| En-tête | Contenu |
|---|---|
X-RateLimit-Limit | le plafond appliqué sur la fenêtre, ici 30 |
X-RateLimit-Remaining | ce qu'il vous reste dans la fenêtre en cours |
X-RateLimit-Reset | l'horodatage de fin de la fenêtre, en secondes |
Un refus renvoie 429, avec ces trois en-têtes et Retry-After. Sur ce point
d'entrée, Retry-After vaut la durée de la fenêtre, soit 60 secondes.
#Paramètres de chemin et de requête
| Nom | Type | Obligatoire | Description |
|---|---|---|---|
identifier | string | oui | L'article dont vous voulez la preuve. Quatre formes sont acceptées, voir ci-dessous. |
Ce point d'entrée n'a aucun paramètre de requête.
identifier accepte quatre formes, essayées dans cet ordre.
| Forme | Aspect | Provenance |
|---|---|---|
| Empreinte d'étiquette | 0x suivi de 64 caractères hexadécimaux | l'empreinte de l'identifiant de la puce NFC |
| Identifiant de jeton | un nombre écrit en décimal | l'identifiant de l'article sur la chaîne |
| Numéro de série imprimé | 12 caractères | ce que porte le QR code sur le produit, dans l'adresse /p/{serial} |
| Numéro de certificat | tel que le certificat le porte | le certificat d'authenticité de l'article |
Vous écrivez le numéro de série dans la casse que vous voulez. Nous ramenons
les caractères qui se ressemblent à une forme unique avant de chercher, donc un
I ou un L saisi à la main retrouve le 1, et un O retrouve le 0.
#En-têtes
Aucun en-tête n'est requis.
#Corps de la requête
Aucun. Cette requête n'a pas de corps.
#Requête d'exemple
Preuve d'appartenance de l'article dont l'identifiant de jeton est 1042.
curl -i https://api.sealtrust.io/v1/verify/merkle/1042const reponse = await fetch("https://api.sealtrust.io/v1/verify/merkle/1042");
if (reponse.status === 404) {
console.log("Cet article ne fait pas partie d'un lot ancré.");
} else if (reponse.ok) {
const preuve = await reponse.json();
console.log(preuve.merkle_root);
console.log(preuve.leaf, preuve.leaf_index);
console.log(preuve.proof);
console.log(preuve.basescan_url);
} else {
console.log(reponse.status, await reponse.json());
}import requests
response = requests.get(
"https://api.sealtrust.io/v1/verify/merkle/1042",
timeout=30,
)
if response.status_code == 404:
print("Cet article ne fait pas partie d'un lot ancré.")
elif response.ok:
preuve = response.json()
print(preuve["merkle_root"])
print(preuve["leaf"], preuve["leaf_index"])
print(preuve["proof"])
print(preuve["basescan_url"])
else:
print(response.status_code, response.json())#Réponse d'exemple
Code HTTP 200OK
Code HTTP 200.
{
"anchor_batch_id": 118,
"merkle_root": "0x1111111111111111111111111111111111111111111111111111111111111111",
"leaf": "0x2222222222222222222222222222222222222222222222222222222222222222",
"leaf_index": 3,
"proof": [
"0x3333333333333333333333333333333333333333333333333333333333333333",
"0x4444444444444444444444444444444444444444444444444444444444444444"
],
"anchor_tx_hash": "0x5555555555555555555555555555555555555555555555555555555555555555",
"basescan_url": "https://basescan.org/tx/0x5555555555555555555555555555555555555555555555555555555555555555",
"contract_address": "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
"network": "Base",
"token_id": "1042",
"verified": true,
"lifecycle_status": "mined",
"withdrawn": false,
"leaf_set": "frozen"
}La réponse compte quatorze champs et rien d'autre.
| Champ | Type | Description |
|---|---|---|
anchor_batch_id | integer | Le numéro sous lequel la racine du lot est inscrite dans le contrat. C'est le premier argument à passer au contrat si vous refaites la vérification sur la chaîne. |
merkle_root | string | La racine inscrite sur la chaîne, 0x suivi de 64 caractères hexadécimaux. C'est la valeur de référence. |
leaf | string | L'empreinte de cet article dans l'arbre, 0x suivi de 64 caractères hexadécimaux. |
leaf_index | integer | La position de cette empreinte dans la liste des empreintes du lot. Le comptage démarre à 0. |
proof | string[] | Les empreintes voisines à combiner avec leaf, de bas en haut, pour retrouver merkle_root. La liste est vide quand le lot ne contient qu'un article. |
anchor_tx_hash | string | La transaction Base qui porte l'inscription de la racine. |
basescan_url | string | Le lien direct vers cette transaction sur l'explorateur public de Base. |
contract_address | string ou null | L'adresse du contrat qui détient la racine ancrée. C'est l'adresse à interroger si vous refaites la vérification sur la chaîne. Le modèle de réponse autorise null, prévoyez ce cas dans votre code. |
network | string | Toujours Base. Le réseau de niveau 2 dont l'identifiant de chaîne est 8453. |
token_id | string ou null | L'identifiant de l'article sur la chaîne, écrit en décimal dans une chaîne de caractères. C'est le deuxième argument à passer au contrat. |
verified | boolean ou null | Le résultat de la vérification que nous avons faite pour vous sur la chaîne. Trois valeurs possibles, true, false et null, voir ci-dessous. |
lifecycle_status | string ou null | L'état de l'article aujourd'hui. Sur ce point d'entrée, vous lisez draft, minting, mined, written, burn_submitted, stolen ou revoked. Les états burned, superseded et archived n'apparaissent jamais ici, voir l'encadré plus bas. |
withdrawn | boolean | Sur ce point d'entrée, toujours false, voir l'encadré plus bas. Le champ passe à true quand lifecycle_status vaut superseded ou archived, les deux états qui sortent un article du catalogue de la marque. |
leaf_set | string | frozen ou recomputed. D'où vient l'arbre qui a servi à produire la preuve, voir ci-dessous. |
La réponse porte aussi l'en-tête Cache-Control: no-store, max-age=0. Une
racine inscrite ne change plus, donc la preuve d'un article donné reste la même
d'un appel à l'autre. Vous pouvez donc la conserver de votre côté. Rien dans la
réponse n'autorise un cache partagé à la garder pour vous.
#Recalculer la racine vous-même
C'est la raison d'être de ce point d'entrée. Vous n'avez pas à nous croire sur parole.
Vous partez de leaf. Pour chaque élément de proof, dans l'ordre, vous
mettez les deux valeurs de 32 octets côte à côte, la plus petite des deux
d'abord, puis vous appliquez keccak256 à la concaténation. Le résultat devient
la nouvelle valeur de travail. Après le dernier élément de proof, vous devez
obtenir exactement merkle_root.
C'est la convention de vérification d'OpenZeppelin. Les voisins sont triés à
chaque étage, donc la preuve n'a pas besoin d'indiquer un sens. Un lot d'un
seul article rend une liste proof vide : la feuille est alors la racine.
Il vous reste à vérifier que merkle_root est bien la valeur inscrite sur la
chaîne. Ouvrez basescan_url pour lire la transaction d'inscription, ou
appelez la fonction de lecture verifyAnchored(batchId, tokenId, proof) du
contrat à l'adresse contract_address, avec anchor_batch_id, token_id et
proof.
#Ce que veut dire verified
verified est le résultat de cette même lecture sur la chaîne, faite par nos
soins au moment de la réponse. Il prend trois valeurs, traitez-les
différemment.
true veut dire que le contrat a confirmé la preuve.
false veut dire que le contrat a répondu et a refusé la preuve. N'affichez
pas l'article comme vérifié dans ce cas. Signalez-le à la marque.
null veut dire que la lecture sur la chaîne n'a pas abouti, soit parce que le
nœud interrogé n'a pas répondu, soit parce que le contrat a rejeté l'appel. Un
null ne remet pas la preuve en cause : leaf, proof et merkle_root
restent vérifiables par vos propres moyens.
#Ce que veut dire leaf_set
frozen veut dire que la preuve a été produite à partir de la liste
d'empreintes enregistrée au moment même de l'inscription sur la chaîne. C'est
la valeur qui fait autorité.
recomputed veut dire que le lot a été ancré avant que nous n'enregistrions
cette liste, et que l'arbre a donc été reconstruit à partir des articles
actuels du lot. Une modification du lot survenue depuis l'ancrage peut le faire
diverger de la racine inscrite.
#Erreurs
Le corps d'une réponse d'erreur porte un champ detail.
| Code | Condition | Que faire |
|---|---|---|
| 404 | Aucun article ne correspond à cet identifiant, sous aucune des quatre formes acceptées. detail vaut Product not found. | Vérifiez l'identifiant. Un article détruit sur la chaîne, remplacé par une version ultérieure ou archivé ne se résout plus et donne cette même réponse. |
| 404 | L'article est connu, mais il n'a pas encore d'identifiant sur la chaîne, ou il n'appartient à aucun lot. detail vaut No Merkle anchor for this product. | Ne traitez pas cette réponse comme un échec. Cet article n'est pas ancré. |
| 404 | L'article appartient à un lot, mais ce lot n'a jamais été inscrit sur la chaîne. detail vaut No Merkle anchor for this product. | Ne traitez pas cette réponse comme un échec. L'ancrage d'un lot est une opération que SealTrust déclenche à la main, et la plupart des lots n'y passent pas. |
| 404 | Le lot est bien ancré, mais cet article n'a pas d'empreinte dans l'arbre ancré. detail vaut Product is not part of the anchored Merkle tree. | Aucune preuve ne peut être produite pour cet article. Contactez la marque si vous l'attendiez dans le lot. |
| 409 | Le lot a changé depuis son inscription sur la chaîne. La racine recalculée ne correspond plus à la racine inscrite. detail vaut Merkle anchor is stale for this batch — re-anchoring required. | Nous refusons de servir une preuve qui échouerait sur la chaîne. Signalez-le à la marque : le lot doit être ancré de nouveau. |
| 429 | Le plafond de 30 appels par 60 secondes est atteint pour votre adresse réseau. detail vaut Rate limit exceeded: 30 requests per 60s. | Attendez le nombre de secondes indiqué par Retry-After, puis réessayez. Mettez la réponse en cache de votre côté, la preuve d'un article ne change pas. |
| 500 | Une erreur inattendue s'est produite pendant le traitement de votre appel. detail vaut Internal Server Error. La réponse porte un en-tête X-Request-Id. | Réessayez. Si l'erreur persiste, contactez le support en indiquant la valeur de X-Request-Id. |
#Voir aussi
GET /passport/{identifier}/proof, rassembler les preuves publiques du passeport d'un article.GET /p/{serial}, traduire le numéro de série imprimé en adresse de page consommateur.- Confiance et preuves, ce que chaque preuve établit et comment un tiers refait la vérification.
Cette page vous a-t-elle été utile ?
Votre réponse ouvre un courriel pré-rempli dans votre messagerie, à destination de contact@sealtrust.io. Vous le relisez avant de l'envoyer.