Synsemadocsv0.6.xENES

Operación

Synsema Network (L1)

Synsema Network es una L1 de Avalanche cuyo primer trabajo es ser un registro público de agentes: para cada agente, el hash de su programa, la dirección que lo controla, el hash de las capacidades que declara, la medida de atestación de la máquina donde corre y las raíces de Merkle de su auditoría. Comprobar un agente es leer su registro, no confiar en quien lo opera. Encima, una EVM abierta: pagos, tokens, contratos. El gas se paga con el token nativo, SYN.

La cadena no ejecuta agentes; los agentes corren en cualquier lado (tu máquina, un servidor, la plataforma, un TEE) y usan la cadena con los builtins EVM de Blockchain.

Hoy es una devnet, en devnet.synsema.io: el estado se puede reiniciar y el SYN ahí no tiene valor. Todo lo de esta página corre contra ella.

Chain id7960 (0x1f18)
Token nativoSYN, 18 decimales
RPChttps://devnet.synsema.io/<token>/rpc
Registro de agentes0x9124Ac7F5Ff9bA48aed29c78198b59a1Ba6732eF
Exploradordevnet.synsema.io/explorer
EVMhasta Cancun (compilá con evm_version = "cancun")

Acceso: un token, una clave, algo de SYN§

El RPC pide un token en la ruta. Sacá uno — sin registro, 10 por dirección IP por hora, 600 pedidos por minuto cada uno:

curl -s -X POST https://devnet.synsema.io/token

La respuesta trae el token, la URL del RPC y la línea para tu .env. Después, una clave propia — cualquier 32 bytes aleatorios — y su dirección:

openssl rand -hex 32
# .env, next to your programs (Synsema reads it and never prints a secret)
L1_RPC=https://devnet.synsema.io/<token>/rpc
MY_KEY=<the 64 hex characters>
-- address.syn
require secret("MY_KEY")
print(eth_address(secret("MY_KEY")))

El grifo manda 100 SYN a una dirección, una vez por hora por dirección:

curl -s -X POST https://devnet.synsema.io/<token>/faucet \
  -H 'content-type: application/json' -d '{"address": "0x…"}'

Una billetera (MetaMask, Rabby) toma los mismos valores: URL del RPC con tu token, chain id 7960, símbolo SYN. La portada tiene un botón que hace los tres pasos y agrega la red a tu billetera.

Registrar un agente§

agent.syn es el programa que se registra (cualquier programa Synsema). Cada valor que mueve plata está escrito: nada se firma con un valor por defecto que no viste.

-- register.syn: synsema run register.syn
require env("L1_RPC")
require secret("MY_KEY")
require sign("MY_KEY")
require net("devnet.synsema.io")
require file.read("agent.syn")

let url be env("L1_RPC")
let registry be "0x9124Ac7F5Ff9bA48aed29c78198b59a1Ba6732eF"
let k be secret("MY_KEY")
let me be eth_address(k)

-- the record: program, capabilities, environment, agent card
let program_hash be sha256(read_file("agent.syn"))
let caps_hash be sha256(canonical_json(["net"]))
let measurement be int_to_bytes(0, 32)
let uri be "https://example.org/.well-known/agent-card.json"
let data be abi_encode("register(bytes32,bytes32,bytes32,string)", [program_hash, caps_hash, measurement, uri])

-- build, sign, send, wait
let fees be eth_fee_history(url)
let tx be tx_eip1559({"chain_id": 7960, "nonce": eth_nonce(url, me), "to": registry, "value": 0,
    "gas": eth_estimate_gas(url, {"from": me, "to": registry, "data": data}) * 2,
    "max_fee": fees["base_fee"] * 2 + fees["priority"], "max_priority": fees["priority"], "data": data})
let hash be eth_send_raw(url, tx_eip1559_raw(tx, secp256k1_sign(tx["digest"], k)))
let receipt be eth_wait_receipt(url, hash, 1, 60)
assert(receipt != nothing and receipt["status"] == 1, "the registration did not go through")

let n be abi_decode("uint256", eth_call(url, {"to": registry, "data": abi_encode("count()", [])}))[0]
print(`registered as agent {n - 1}, tx {hash}`)

Qué va en cada campo:

CampoValor
programHashsha256 del programa: el .syn, o el módulo WASM que lo embebe, o cualquier artefacto de un agente escrito en otro lenguaje
capsHashsha256(canonical_json(<las líneas require>)) — el techo de lo que el agente puede hacer. 0x00…00 si el agente no declara nada
measurementLa medida de atestación del enclave donde corre (Atestación); cero sin TEE
agentURIDonde el agente se describe (su Agent Card, Identidad de agentes). La cadena no lo comprueba

El explorador marca cada agente con lo que declara y lo que prueba: capacidades declaradas / no declaradas, atestado / no atestado.

Leer el registro§

Leer no necesita clave ni SYN:

require env("L1_RPC")
require net("devnet.synsema.io")

let url be env("L1_RPC")
let registry be "0x9124Ac7F5Ff9bA48aed29c78198b59a1Ba6732eF"
task call(sig, args)
    give eth_call(url, {"to": registry, "data": abi_encode(sig, args)})

let n be abi_decode("uint256", call("count()", []))[0]
print(`{n} agents on chain {eth_chain_id(url)}`)
let a be abi_decode("(address,bytes32,bytes32,bytes32,string,uint64)", call("get(uint256)", [0]))
print(`agent 0: controller {a[0]}, card {a[4]}`)

Sin token, la API JSON del explorador responde lo mismo: GET /api/agents, /api/agent/<id>, /api/tx/<hash>, /api/address/<0x…>, /api/blocks, /api/tokens, descriptas en /openapi.json.

Verificar un pago sin confiar en nadie§

Un 200 de una app no prueba un pago. Lo prueba el recibo en la cadena. Este programa responde "¿este hash pagó exactamente este monto a esta dirección, y es final?":

-- paid.syn: synsema run paid.syn -- <hash> <payee>
require env("L1_RPC")
require net("devnet.synsema.io")

task hex_int(s)
    let h be slice(s, 2)
    when length(h) % 2 == 1
        set h to "0" + h
    give bytes_to_int(bytes(h, "hex"))

task paid(hash, payee, amount_wei)
    let r be eth_receipt(env("L1_RPC"), hash)
    when r == nothing or r["status"] != 1
        give false
    let t be eth_rpc(env("L1_RPC"), "eth_getTransactionByHash", [hash])
    give lower(t["to"]) == lower(payee) and hex_int(t["value"]) == amount_wei

print(paid(args()[0], args()[1], 100 * 1000000000000000000))

En Avalanche un bloque aceptado es final — no hay reorganizaciones —, así que "incluida" significa "no se puede deshacer". Para personas, la página de verificación del explorador hace lo mismo y tiene un botón que le pregunta directamente al nodo y compara.

El contrato AgentRegistry§

FunciónQuién
register(bytes32 programHash, bytes32 capsHash, bytes32 measurement, string agentURI) → uint256 idcualquiera
anchor(uint256 id, uint64 seq, bytes32 root)el controlador; seq tiene que ser el último + 1 (sin huecos, sin reescrituras)
count() → uint256, get(uint256 id), programHashOf(uint256 id)lectura
lastSeq(uint256 id), lastRoot(uint256 id)lectura

Eventos: Registered(uint256 indexed id, address indexed owner, bytes32 programHash, string agentURI) y Anchored(uint256 indexed id, uint64 seq, bytes32 root).

Tokens y contratos§

Cualquiera con SYN puede desplegar contratos; el explorador encuentra los tokens ERC-20 por sus eventos Transfer. Un programa Synsema todavía no puede crear un contrato (tx_eip1559 exige to): desplegá con Foundry y llamalo desde Synsema.

forge create --broadcast --rpc-url "$L1_RPC" --private-key "$MY_KEY" src/MyToken.sol:MyToken

Trampas§

puede superar dos veces la base. Usá max_fee = base_fee 2 + priority; con base_fee 2 solo, tx_eip1559 rechaza (max_priority is greater than max_fee).

missing trie node. La historia está completa en el explorador.

los montos en wei con aritmética entera (100 * 1000000000000000000), no desde un texto parseado.