Guía para principiantes de TON: cuentas, tokens y seguridad

Fondo

TON (The Open Network) es una plataforma blockchain descentralizada diseñada y desarrollada inicialmente por el equipo de Telegram. TON tiene como objetivo proporcionar una plataforma blockchain de alto rendimiento y escalable para soportar aplicaciones descentralizadas a gran escala (DApps) y contratos inteligentes.

TON es único en el sentido de que es fácil de usar, profundamente integrado con Telegram, lo que permite a la gente común utilizar fácilmente los tokens. Al mismo tiempo, es complejo, con una arquitectura distinta a la de otras cadenas de bloques, y utiliza un lenguaje de contratos inteligentes no convencional llamado FunC.

Hoy hablaremos de las características de TON y de la seguridad de los activos de los usuarios desde el punto de vista de las cuentas, los tokens y las transacciones.

Características de TON

Generación de cuentas

El método para generar una dirección de cuenta en TON es diferente al de la mayoría de blockchains; se trata de una dirección de contrato inteligente. En primer lugar, todo comienza con una clave privada. TON utiliza principalmente el algoritmo Ed25519 para generar una clave pública, con el siguiente proceso:

Existen dos formas de clave pública: una es la clave pública bruta calculada a partir de la clave privada, que tiene el aspecto siguiente:

E39ECDA0A7B0C60A7107EC43967829DBE8BC356A49B9DFC6186B3EAC74B5477D

La otra es una clave pública «embellecida», que incluye cierta información y bits de comprobación, y tiene el siguiente aspecto:

Pubjns2gp7DGCnEH7EOWeCnb6Lw1akm538YYaz6sdLVHfRB2

Si crees que con sólo obtener la clave pública podrás obtener la dirección de la cuenta como en Ethereum, estás equivocado. El mero hecho de tener la clave pública del usuario no es suficiente para calcular la dirección de la cuenta del usuario.

Como se ha mencionado, la dirección de la cuenta del usuario es una dirección de contrato inteligente, pero ¿cómo se puede desplegar un contrato inteligente sin tener una cuenta?

La secuencia correcta es calcular primero la dirección, recibir una cantidad inicial de tokens y, a continuación, desplegar el contrato. El proceso de cálculo de la dirección de la cuenta se muestra en el siguiente diagrama:

La dirección de un usuario también se presenta de varias formas. En primer lugar, está la forma bruta, que se parece a:

0:b4c1b2ede12aa76f4a44353944258bcc8f99e9c7c474711a152c78b43218e296

Luego hay un formulario fácil de usar, que tiene este aspecto:

Mainnet:

  • Rebotable: EQC0wbLt4Sqnb0pENTlEJYvMj5npx8R0cRoVLHi0MhjilkPX
  • No rebotable: UQC0wbLt4Sqnb0pENTlEJYvMj5npx8R0cRoVLHi0Mhjilh4S

Testnet:

  • Rebotable: kQC0wbLt4Sqnb0pENTlEJYvMj5npx8R0cRoVLHi0Mhjilvhd
  • No rebotable: 0QC0wbLt4Sqnb0pENTlEJYvMj5npx8R0cRoVLHi0MhjilqWY

Observando detenidamente estas direcciones, se puede ver que sólo difieren en los primeros y últimos caracteres, siendo los account_id centrales iguales.

Sin embargo, todavía no podemos ver la relación entre la clave pública y la dirección de la cuenta.

El secreto reside en el initial data del principio, que contiene la clave pública de un usuario, lo que le permite controlar el contrato del monedero. El workchainId es fácil de entender; TON no es una única cadena, sino que consta de muchos fragmentos.

Cada fragmento es una parte de toda la red, que gestiona cuentas y transacciones específicas. Para localizar y gestionar contratos inteligentes, es necesario especificar en qué shard se encuentran. ¿Cuál es la diferencia entre Bounceable y Non-bounceable?

Esto está relacionado con la forma en que funcionan los contratos inteligentes, pero sigamos profundizando.

Contrato monedero

A continuación se muestra un fragmento del código fuente de un contrato de monedero de usuario. Muestra que al recibir un mensaje del usuario, lee cuatro parámetros: stored_seqno, stored_subwallet, public_key y plugins:

wallet-v4-code.fc



() recv_external(slice in_msg) impure {

var signature = in_msg~load_bits(512);

var cs = in_msg;

var (subwallet_id, valid_until, msg_seqno) = (cs~load_uint(32), cs~load_uint(32), cs~load_uint(32));

throw_if(36, valid_until <= now());

var ds = get_data().begin_parse();

var (stored_seqno, stored_subwallet, public_key, plugins) = (ds~load_uint(32), ds~load_uint(32), ds~load_uint(256), ds~load_dict()); ;;##The Initial Data

ds.end_parse();

throw_unless(33, msg_seqno == stored_seqno);

throw_unless(34, subwallet_id == stored_subwallet);

throw_unless(35, check_signature(slice_hash(in_msg), signature, public_key));

//...

}

De hecho, cuando se despliega este contrato de monedero de usuario, requiere algunos parámetros iniciales, incluido un public_key de 256 bits. Esto garantiza que cada usuario tenga una dirección de contrato única aunque utilice el mismo código de contrato.

Cada transacción iniciada por el usuario debe ser firmada con in_msg, luego verificada por el contrato de monedero (check_signature), tras lo cual el contrato realizará operaciones en la blockchain. De ello se deduce que la clave pública de un usuario puede corresponder a numerosas direcciones de monedero.

El despliegue de diferentes contratos de monedero o el uso de diferentes datos de inicialización dará lugar a direcciones de contrato completamente diferentes.

Ficha Jetton

Un token representa un activo en la blockchain, lo que lo convierte en un elemento fundamental que debemos comprender. Jetton es la forma estándar de los tokens TON y se compone de dos contratos: Jetton-minter y Jetton-wallet.

Cuando se emite un token, se crea un contrato Jetton-minter. Esta inicialización del contrato registra información como el suministro total de tokens, el administrador, el código del monedero y otros detalles.

Cuando se distribuyen los tokens a los usuarios, el contrato Minter despliega un contrato monedero para cada usuario. Durante la inicialización del contrato, se registra el saldo del usuario, su titularidad, la dirección del contrato Minter del token, el código del monedero del usuario y otra información relevante. Cada usuario tiene un contrato individual.

Es importante tener en cuenta que el contrato creado aquí es un contrato de monedero para gestionar tokens Jetton específicos, que es diferente del contrato de monedero de la cuenta del usuario. El owner_address registrado aquí es la dirección del monedero de la cuenta del usuario.

Cuando el usuario Alice transfiere tokens al usuario Bob, la relación de invocación es la siguiente:

Alice firma la transacción a través de una aplicación fuera de la cadena y envía un comando operativo a través de su contrato de monedero. Estos comandos invocarán a su monedero de tokens para ejecutar la transferencia. Cuando el monedero electrónico de Bob recibe los tokens, lo notifica al contrato de monedero de Bob (la dirección del propietario del monedero Jetton de Bob).

Si sobra gas durante la transacción, se devolverá a la dirección correspondiente, normalmente el contrato de la cuenta de Alice.

A continuación se muestra un ejemplo de una transferencia de token Jetton analizado por el navegador Tonviewer:

Mientras que una transferencia ERC20 requiere una sola invocación de contrato, una transferencia de token Jetton requiere al menos cuatro invocaciones de contrato. Este método está diseñado para permitir la concurrencia en la cadena, mejorando la eficiencia de las transacciones.

Transacciones

Cuando se produce un determinado evento en una cuenta TON, se desencadena una transacción. El evento más común es «recibir un mensaje». Una transacción incluye los siguientes elementos

  • El mensaje entrante que activa inicialmente el contrato (con métodos de activación especiales disponibles).
  • Acciones del contrato resultantes del mensaje entrante, como la actualización del almacenamiento del contrato (opcional).
  • Mensajes salientes enviados a otros participantes (opcional).

Hay varias características clave que deben tenerse en cuenta en relación con las transacciones:

  1. Asíncrono: Las transacciones TON no se completan en una única llamada; pueden requerir el paso de mensajes a múltiples contratos inteligentes diferentes para ejecutar una serie de llamadas. Debido a los diferentes enrutamientos en las cadenas fragmentadas, TON no puede garantizar el orden de entrega de los mensajes entre varios contratos inteligentes.
  2. Tasas: La naturaleza asíncrona de las transacciones introduce un reto en la estimación de las tasas consumidas. Por ello, los monederos suelen enviar un pequeño token extra como comisión al iniciar una transacción. Si el contrato llamado tiene un buen mecanismo de gestión de comisiones, las comisiones restantes se devolverán al monedero del usuario. Los usuarios pueden notar que los tokens de su monedero disminuyen repentinamente y vuelven a aumentar al cabo de unos minutos, lo que se debe a este mecanismo.
  3. Rebota: El rebote es un mecanismo de gestión de errores en los contratos. Si el contrato llamado no existe o lanza un error, y la transacción se establece como rebotable, se devolverá un mensaje de rebote al contrato llamante. Por ejemplo, si un usuario inicia una transferencia y se produce un error durante el proceso, es necesario un mensaje de rebote para que el contrato del monedero del usuario pueda restablecer su saldo. Casi todos los mensajes internos enviados entre contratos inteligentes deben ser rebotados, lo que significa que deben tener su bit «bounce» activado.

Seguridad de los activos

TON tiene muchas funciones que pueden dar lugar a problemas de seguridad, por lo que los usuarios deben ser conscientes de algunas trampas comunes.

Ataque a la retención de tasas

Como ya se ha mencionado, los monederos a menudo necesitan enviar una pequeña comisión extra para evitar el fallo de la transacción, lo que supone una oportunidad para los atacantes. Si eres usuario de un monedero TON, es posible que te hayas encontrado con una situación en la que tu monedero recibe con frecuencia varios NFT o tokens.

En un principio, pueden parecer airdrops de fichas basura, pero al comprobar los detalles de la transacción, descubres que pueden venderse por una cantidad significativa de dinero. Sin embargo, cuando intentas iniciar una transacción, te das cuenta de que la comisión requerida es extremadamente alta (1 TON). En este punto, debes ser precavido, ya que podría tratarse de una estafa de comisiones.

Los atacantes crean un contrato de token cuidadosamente diseñado que hace que el monedero estime una tarifa de transferencia excesivamente alta, pero en realidad, sólo se retiene la tarifa y no se envía ningún mensaje de transferencia.

Phishing de primera y última cifra

El phishing de primer y último dígito no es exclusivo de TON; este ataque de phishing existe en muchas blockchains importantes. Los atacantes generan una cuenta falsa para cada dirección de usuario de la red con el mismo primer y último dígito.

Cuando un usuario inicia una transferencia, el atacante también envía una pequeña transferencia, tras la transacción del usuario, para dejar un registro en el historial de transacciones del usuario. Cuando el usuario destinatario quiere devolver los tokens, podría copiar la dirección de su historial de transacciones, que podría ser la del atacante, lo que llevaría a una transferencia a la dirección equivocada. El atacante ha explotado con precisión el comportamiento del usuario.

Comentario Phishing

Al transferir tokens en TON, los usuarios pueden añadir un comentario para anotar la transacción. Esta función se utiliza a menudo al realizar depósitos en las bolsas, que suelen exigir a los usuarios que incluyan su ID de usuario en el comentario del depósito. Sin embargo, esta función es explotada con frecuencia por actores maliciosos, que escriben información fraudulenta en los comentarios para robar los activos de los usuarios. Por ejemplo:

Los usuarios deben tener especial cuidado con el NFT «Número Anónimo de Telegram». Si un usuario activa su cuenta de Telegram con un Número Anónimo de Telegram pero no habilita la Verificación en Dos Pasos, y este NFT es phishing, el hacker puede iniciar sesión directamente en la cuenta de Telegram objetivo y proceder con el posterior robo de activos y actividades fraudulentas.

Vulnerabilidades de los contratos inteligentes

Las vulnerabilidades de seguridad en los contratos inteligentes pueden provocar la pérdida de los fondos almacenados en el contrato. Los usuarios deben elegir proyectos que se hayan sometido a auditorías exhaustivas. Los contratos inteligentes de TON se programan principalmente con el lenguaje FunC, aunque algunos utilizan el más avanzado Tact o el de nivel inferior Fift.

Todos estos lenguajes son muy originales. Los nuevos lenguajes de programación entrañan nuevos riesgos de seguridad, sobre todo para los desarrolladores, que deben practicar hábitos de codificación seguros, dominar las mejores prácticas de seguridad y someterse a rigurosas auditorías de seguridad antes de desplegarlos en el entorno de producción. Debido a limitaciones de espacio, este artículo no tratará en detalle la seguridad de los contratos.

Ataque de depósito falso

Los usuarios de monederos o bolsas deben ser conscientes de los ataques de depósitos falsos, que suelen presentarse de dos formas:

  1. Falsas fichas: Un atacante emite un token con metadatos idénticos al token objetivo. Si el programa de depósito automático no comprueba si el token procede del contrato de acuñación correcto, puede dar lugar a depósitos incorrectos.
  2. Rebota: El proceso de transferencia de TON requiere una relación de invocación entre los contratos de monedero de dos usuarios. Si el contrato de monedero del destinatario no existe y la transacción se establece como rebotable, el mensaje rebotará y los fondos originales, menos la comisión, se devolverán al remitente. Los interesados en los detalles pueden consultar nuestro artículo anterior sobre depósitos falsos.

Conclusión

Este artículo presenta algunos principios técnicos fundamentales de TON desde el punto de vista de la creación de claves y monederos, las formas de los tokens y las características de las transacciones. También explora los posibles problemas de seguridad al utilizar TON, con la esperanza de inspirar tu viaje de aprendizaje.