polyglot-alpha / scripts /w17-debug.py
licaomeng
deploy: main@8970ffb → HF Spaces (2026-05-27T05:19Z)
88d2f2a
"""W17-A diagnostic: dump on-chain reputation/registration state for all 6 seeder addresses.
Reads:
- REPUTATION_REGISTRY_ADDRESS / TRANSLATION_AUCTION_ADDRESS / ARC_TESTNET_USDC_ADDRESS / ARC_TESTNET_RPC from .env
- ABI from contracts/out/
For each of the 6 addresses (3 old gemini/deepseek/qwen + 3 v2 wallets derived
from HACKATHON_WALLET_PRIVATE_KEY), prints:
- getReputation(addr) — raw uint256 + scaled float
- getStats(addr) — totalBids/totalWins/qualityPasses/cumulativeFees/score
- reps(addr).lastUpdated — to distinguish "never touched" from "score reset"
- auction.registered(addr) — whether they finished registerAgent
- auction.stakes(addr) / lockedStakes(addr) — staked USDC
- reputation_registry.authorized(addr) — only relevant for owner check
- USDC.balanceOf(addr) and ETH balance
Plus derives v2 wallets from HACKATHON_WALLET_PRIVATE_KEY and confirms the
addresses match outputs/agent_wallets.json (rules out hypothesis B).
"""
from __future__ import annotations
import json
import os
import sys
from pathlib import Path
# Load .env manually (avoid pulling in app deps)
ROOT = Path(__file__).resolve().parents[1]
ENV_PATH = ROOT / ".env"
def load_env() -> None:
if not ENV_PATH.exists():
return
for raw in ENV_PATH.read_text().splitlines():
line = raw.strip()
if not line or line.startswith("#"):
continue
if "=" not in line:
continue
k, v = line.split("=", 1)
os.environ.setdefault(k.strip(), v.strip())
load_env()
sys.path.insert(0, str(ROOT))
from web3 import Web3 # noqa: E402
from eth_account import Account # noqa: E402
from polyglot_alpha.agents.wallets import derive_agent_wallet, AGENT_NAMES # noqa: E402
def load_abi(path: Path) -> list:
return json.loads(path.read_text())["abi"]
# ERC-20 minimal ABI for balanceOf
ERC20_ABI = [
{
"constant": True,
"inputs": [{"name": "owner", "type": "address"}],
"name": "balanceOf",
"outputs": [{"name": "", "type": "uint256"}],
"stateMutability": "view",
"type": "function",
},
{
"constant": True,
"inputs": [],
"name": "decimals",
"outputs": [{"name": "", "type": "uint8"}],
"stateMutability": "view",
"type": "function",
},
]
def main() -> int:
rpc = os.environ["ARC_TESTNET_RPC"]
rep_addr = os.environ["REPUTATION_REGISTRY_ADDRESS"]
auc_addr = os.environ["TRANSLATION_AUCTION_ADDRESS"]
usdc_addr = os.environ["ARC_TESTNET_USDC_ADDRESS"]
op_pk = os.environ["HACKATHON_WALLET_PRIVATE_KEY"]
print(f"RPC = {rpc}")
print(f"ReputationRegistry = {rep_addr}")
print(f"TranslationAuction = {auc_addr}")
print(f"USDC = {usdc_addr}")
w3 = Web3(Web3.HTTPProvider(rpc, request_kwargs={"timeout": 30}))
print(f"chain connected = {w3.is_connected()} chainId={w3.eth.chain_id}")
rep_abi = load_abi(ROOT / "contracts/out/ReputationRegistry.sol/ReputationRegistry.json")
auc_abi = load_abi(ROOT / "contracts/out/TranslationAuction.sol/TranslationAuction.json")
rep = w3.eth.contract(address=Web3.to_checksum_address(rep_addr), abi=rep_abi)
auc = w3.eth.contract(address=Web3.to_checksum_address(auc_addr), abi=auc_abi)
usdc = w3.eth.contract(address=Web3.to_checksum_address(usdc_addr), abi=ERC20_ABI)
# Confirm wallet derivation
print("\n=== Wallet derivation cross-check (rules out hypothesis B) ===")
derived: dict[str, str] = {}
for name in AGENT_NAMES:
w = derive_agent_wallet(op_pk, name)
derived[name] = w.address
print(f" {name:<14} -> {w.address}")
saved = json.loads((ROOT / "outputs/agent_wallets.json").read_text())
for name in AGENT_NAMES:
match = derived[name].lower() == saved[name]["address"].lower()
print(
f" {name:<14} saved={saved[name]['address']} match={match}"
)
# 6 addresses to investigate. Old gemini/deepseek/qwen addresses
# come from the original W14-CONTRACT-PREP keys (sha256(op_pk + ':gemini') etc).
# If that derivation has been retired we still want to inspect the
# historic addresses cited in the bug report.
old_addresses = {
"gemini-old": "0x396B...", # placeholder; only the v2 row is required
}
# We don't actually know the literal old hex from the env; derive what the
# PRE-v2 naming would have produced (sha256(pk + ':gemini')).
import hashlib
for legacy_name in ("gemini", "deepseek", "qwen"):
seed = hashlib.sha256(f"{op_pk}:{legacy_name}".encode()).hexdigest()
acct = Account.from_key("0x" + seed)
old_addresses[f"{legacy_name}-old"] = acct.address
targets: list[tuple[str, str]] = []
for legacy in ("gemini", "deepseek", "qwen"):
targets.append((f"{legacy}-old", old_addresses[f"{legacy}-old"]))
for name in AGENT_NAMES:
targets.append((name, derived[name]))
print("\n=== Per-address chain state ===")
print(
f"{'name':<15}{'address':<45}{'rep_raw':>22}{'rep_f':>10}"
f"{'lastUpd':>12}{'tBids':>7}{'tWins':>7}{'qPass':>7}"
f"{'cumFee':>10}{'reg':>5}{'stake':>10}{'lock':>10}"
f"{'usdc':>10}{'eth':>10}"
)
for label, addr in targets:
addr_cs = Web3.to_checksum_address(addr)
rep_raw = rep.functions.getReputation(addr_cs).call()
stats = rep.functions.getStats(addr_cs).call()
reps_struct = rep.functions.reps(addr_cs).call()
# reps struct: totalBids, totalWins, totalQualityPasses, cumulativeFeesEarned, score, lastUpdated
last_updated = reps_struct[5]
registered = auc.functions.registered(addr_cs).call()
stake = auc.functions.stakes(addr_cs).call()
try:
locked = auc.functions.lockedStakes(addr_cs).call()
except Exception:
locked = 0
usdc_bal = usdc.functions.balanceOf(addr_cs).call()
eth_bal = w3.eth.get_balance(addr_cs)
print(
f"{label:<15}{addr_cs:<45}{rep_raw:>22}{rep_raw/1e18:>10.4f}"
f"{last_updated:>12}{stats[0]:>7}{stats[1]:>7}{stats[2]:>7}"
f"{stats[3]:>10}{int(registered):>5}{stake/1e6:>10.4f}{locked/1e6:>10.4f}"
f"{usdc_bal/1e6:>10.4f}{eth_bal/1e18:>10.4f}"
)
# Owner of ReputationRegistry + authorized set
try:
owner = rep.functions.owner().call()
print(f"\nReputationRegistry.owner = {owner}")
except Exception as exc:
print(f"\nReputationRegistry.owner read failed: {exc}")
# Also dump bytecode size to confirm both contracts are deployed
rep_code = w3.eth.get_code(Web3.to_checksum_address(rep_addr))
auc_code = w3.eth.get_code(Web3.to_checksum_address(auc_addr))
print(
f"\nReputationRegistry bytecode bytes = {len(rep_code)}"
f" TranslationAuction bytecode bytes = {len(auc_code)}"
)
return 0
if __name__ == "__main__":
sys.exit(main())