fix: check OP_RETURN en motor de análisis, banda BAJA forzada
This commit is contained in:
+27
-3
@@ -1024,7 +1024,7 @@
|
||||
input_reuse: 25, input_type_mixing: 14, output_type_mismatch: 8,
|
||||
round_numbers: 10, rbf: 5, peeling: 8,
|
||||
unnecessary_input: 12, dust: 8, change_detection: 10,
|
||||
wallet_fingerprint: 6, batch_payment: 45, entity_ofac: 20,
|
||||
wallet_fingerprint: 6, batch_payment: 45, entity_ofac: 20, op_return: 30,
|
||||
};
|
||||
let deductions = 0;
|
||||
|
||||
@@ -1459,7 +1459,29 @@
|
||||
});
|
||||
if (isBatch) deductions += weights.batch_payment;
|
||||
|
||||
// ── 15. Timing analysis — informativo ────────────────────────────
|
||||
// ── 15. OP_RETURN ─────────────────────────────────────────────────
|
||||
// Detecta outputs OP_RETURN (nulldata): presencia y tamaño total en bytes.
|
||||
// No muestra el contenido — lo relevante para privacidad es que hay datos
|
||||
// arbitrarios, no qué dicen. Ver v1.2.1 del changelog.
|
||||
const opReturnOuts = tx.vout.filter(v => isOpReturn(v));
|
||||
const hasOpReturn = opReturnOuts.length > 0;
|
||||
const opReturnBytes = opReturnOuts.reduce((s, v) => {
|
||||
// scriptpubkey: "6a" + longitud (1 byte) + datos. Datos = (hex.length/2) - 2
|
||||
const hex = v.scriptpubkey || "";
|
||||
return s + Math.max(0, hex.length / 2 - 2);
|
||||
}, 0);
|
||||
checks.push({
|
||||
id:"op_return", label:"Datos OP_RETURN", certainty:"CERTEZA", pass:!hasOpReturn,
|
||||
actionability: "no_corregible",
|
||||
detail: hasOpReturn
|
||||
? `${opReturnOuts.length} output${opReturnOuts.length > 1 ? "s" : ""} OP_RETURN con ${opReturnBytes} bytes de datos arbitrarios. Revela que esta transacción usa un protocolo o servicio que escribe datos en la cadena (Stamps, Ordinals, OpenTimestamps, Omni, etc.). Se informa la presencia y el tamaño, no el contenido.`
|
||||
: "No se detectan outputs OP_RETURN.",
|
||||
didactic: "Un output OP_RETURN contiene datos arbitrarios que cualquiera puede leer. Su presencia revela el uso de un protocolo concreto y puede vincular esta transacción con actividad on-chain identificable. El contenido no se muestra — para la privacidad lo relevante es que existe, no qué dice.",
|
||||
penalty: hasOpReturn ? weights.op_return : 0,
|
||||
});
|
||||
if (hasOpReturn) deductions += weights.op_return;
|
||||
|
||||
// ── 16. Timing analysis — informativo ────────────────────────────
|
||||
let timingDetail = "No hay timestamp disponible (transacción pendiente o sin confirmar).";
|
||||
if (tx.status?.block_time) {
|
||||
const date = new Date(tx.status.block_time * 1000);
|
||||
@@ -1547,7 +1569,9 @@
|
||||
|
||||
// ── Score compuesto ───────────────────────────────────────────────
|
||||
const maxPossible = Object.values(weights).reduce((a,b)=>a+b,0);
|
||||
const score = Math.max(0, Math.min(100, Math.round(100 - (deductions / maxPossible) * 100)));
|
||||
const rawScore = Math.max(0, Math.min(100, Math.round(100 - (deductions / maxPossible) * 100)));
|
||||
// OP_RETURN es incompatible con privacidad aceptable — fuerza banda BAJA como máximo.
|
||||
const score = hasOpReturn ? Math.min(rawScore, 44) : rawScore;
|
||||
|
||||
return {
|
||||
score, checks,
|
||||
|
||||
Reference in New Issue
Block a user