VERIFICACIÓN INDEPENDIENTE
Verificá anclas on-chain sin confiar en nadie
No necesitás la API de ChainMemory para verificar que un estado de proyecto fue anclado en un bloque específico. Esta página muestra cómo verificar directamente contra la blockchain usando herramientas Web3 estándar.
Qué necesitás
- El hash del estado del proyecto (de la API o compartido por alguien)
- El hash de la transacción o número de bloque del ancla
- Node.js con
ethersinstalado — o cualquier librería Web3
Paso 1 — Obtener los datos del ancla
Usá el endpoint público (sin autenticación) de ChainMemory o recibilos de quien compartió la prueba:
bash
curl https://api.chainmemory.ai/v1/project/chainmemory/state/anchor
Respuesta
{
"project": "chainmemory",
"projectId": "0x77f7d980...",
"version": 8,
"state_hash": "0xa6c45d1db753b1ec96240d169b2d91fb0ce76112558b302a8822b2988aeb8212",
"anchor": {
"status": "anchored",
"onchain_anchor_id": 8,
"tx_hash": "0x95b732d20b8935a2...",
"block_number": 173831,
"contract": "0xa7A8BA51950255b3e223a6745597C67009Fe7875"
},
"verify": "ProjectStateAnchor.getStateAnchor(projectId, version)"
}
Paso 2 — Verificar on-chain con Ethers.js
Conectate directamente al RPC de ChainMemory y leé el smart contract. Sin API Key, sin cuenta, sin confianza requerida.
javascript
import { ethers } from 'ethers';
// Conectar al RPC de ChainMemory — sin API Key necesaria
const provider = new ethers.JsonRpcProvider('https://rpc.chainmemory.ai');
// Contrato ProjectStateAnchor
const CONTRACT = '0xa7A8BA51950255b3e223a6745597C67009Fe7875';
const ABI = [
'function getStateAnchor(bytes32 projectId, uint64 version) view returns (bytes32 stateHash, uint256 anchoredAt, address anchoredBy, uint256 anchorId)'
];
const contract = new ethers.Contract(CONTRACT, ABI, provider);
// El project ID es el keccak256 del nombre del proyecto
const projectId = ethers.keccak256(ethers.toUtf8Bytes('chainmemory'));
const version = 8;
// Leer directamente de la blockchain
const [stateHash, anchoredAt, anchoredBy, anchorId] = await contract.getStateAnchor(projectId, version);
console.log('Hash on-chain del estado:', stateHash);
console.log('ID de ancla:', anchorId.toString());
console.log('Anchored at:', new Date(Number(anchoredAt) * 1000).toISOString());
// Comparar con el hash que recibiste
const expectedHash = '0xa6c45d1db753b1ec96240d169b2d91fb0ce76112558b302a8822b2988aeb8212';
if (stateHash === expectedHash) {
console.log('VERIFICADO — el estado coincide con el ancla on-chain');
} else {
console.log('DISCREPANCIA — el estado fue manipulado');
}
javascript
const Web3 = require('web3');
const web3 = new Web3('https://rpc.chainmemory.ai');
const CONTRACT = '0xa7A8BA51950255b3e223a6745597C67009Fe7875';
const ABI = [{
name: 'getStateAnchor',
type: 'function',
stateMutability: 'view',
inputs: [
{ name: 'projectId', type: 'bytes32' },
{ name: 'version', type: 'uint64' }
],
outputs: [
{ name: 'stateHash', type: 'bytes32' },
{ name: 'anchoredAt', type: 'uint256' },
{ name: 'anchoredBy', type: 'address' },
{ name: 'anchorId', type: 'uint256' }
]
}];
const contract = new web3.eth.Contract(ABI, CONTRACT);
const projectId = web3.utils.keccak256('chainmemory');
const result = await contract.methods.getStateAnchor(projectId, 8).call();
console.log('Hash on-chain del estado:', result.stateHash);
console.log('ID de ancla:', result.anchorId);
Paso 3 — Verificar la transacción
También podés verificar la transacción cruda que creó el ancla:
javascript
// Leer la transacción directamente
const tx = await provider.getTransaction('0x95b732d20b8935a286869d90e60a40f5c31d350a94e27bfd7845770fe0c3e2c3');
console.log('From:', tx.from); // Debería ser un validador conocido
console.log('To:', tx.to); // Debería ser la dirección del contrato
console.log('Block:', tx.blockNumber);
// Leer el bloque para confirmar timestamp
const block = await provider.getBlock(tx.blockNumber);
console.log('Hora del bloque:', new Date(block.timestamp * 1000).toISOString());
Verificación zero-trust
Todo este proceso requiere cero interacción con los servidores de ChainMemory. Te conectás directamente al endpoint RPC de la blockchain y leés el smart contract. Incluso si la API de ChainMemory estuviera comprometida o caída, los datos on-chain siguen siendo verificables.
Alternativa con MetaMask
También podés verificar visualmente: agregá la red ChainMemory a MetaMask, navegá a la dirección del contrato en el Explorer, e inspeccioná los datos de la transacción manualmente.