Lenguajes de contrato inteligente
Un gran aspecto de Ethereum es que los contratos inteligentes pueden programarse utilizando lenguajes relativamente fáciles para el programador. Si tienes experiencia con Python o JavaScript, puedes encontrar un lenguaje con una sintaxis familiar.
Los dos lenguajes más activos y soportados son:
- Solidity
- Vyper
Los desarrolladores más experimentados también podrían querer usar Yul, un lenguaje intermedio para la máquina virtual Ethereum, o Yul+, una extensión de Yul.
Requisitos previos
El conocimiento previo de lenguajes de programación, especialmente de JavaScript o Python, puede ayudarte a encontrar diferencias en los lenguajes de los contratos inteligentes. También recomendamos que entiendas los lenguajes de los contratos inteligentes como concepto antes de profundizar demasiado en las comparaciones de lenguajes. Más información sobre contratos inteligentes.
Solidity
- Influenciado por C++, Python y JavaScript.
- Escrito estáticamente (el tipo de variable se conoce durante el tiempo de compilación).
- Compatibilidad:
- Herencia (puedes ampliar otros contratos).
- Bibliotecas (puedes crear código reutilizable que puedes solicitar desde diferentes contratos, p. ej., como funciones estáticas en una clase estática en otros lenguajes de programación orientados a objetos).
- Tipos complejos definidos por el usuario.
Enlaces importantes
- Documentación
- Portal de lenguaje de Solidity
- Solidity by Example
- GitHub
- Sala de chat de Gitter sobre Solidity
- Hoja de trampas
- Blog de Solidity
Ejemplo de contrato
1// SPDX-License-Identifier: GPL-3.02Solidez pragmática >= 0.7. ;34contract Coin {5 // La palabra clave "public" hace variables6 // accesibles desde otros contratos7 dirección pública minter;8 mapeo (dirección => uint) saldos públicos;910 // Eventos permiten a los clientes reaccionar a cambios específicos11 // del contrato que declaras12 event Sent(address de, dirección a, cantidad de uint);1314 // El código del instructor solo se ejecuta cuando se crea el contrato15 //16 constructor() {17 minter = msg. ender;18 }1920 // Envía una cantidad de monedas recién creadas a una dirección21 // Sólo puede ser llamada por el creador del contrato22 function mint(address receiver, Cantidad de uint) public {23 require(msg. ender == minter);24 requerido (cantidad < 1e60);25 saldos[receiver] += cantidad;26 }2728 // Envía una cantidad de monedas existentes29 // desde cualquier llamada a una dirección30 función enviada(receptor de direcciones, Cantidad de uint) public {31 require(amount <= balances[msg.sender], "Saldo insuficiente". );32 saldos[msg.sender] -= monto;33 saldos[receiver] += monto;34 emisión Sent(msg. ender, receptor, monto);35 }36}37Mostrar todoCopiar
Este ejemplo debería darte una idea de cómo es la sintaxis de de un contrato Solidity. Para ver una descripción más detallada de las funciones y variables, consulta los documentos.
Vyper
- Lenguaje de programación Pythonic
- Escritura fuerte
- Código de compilador pequeño y comprensible
- Deliberadamente tiene menos características que Solidity con el objetivo de hacer que los contratos sean más seguros y más fáciles de auditar. Vyper no es compatible con:
- Modificadores
- Herencia
- Ensamblado en línea
- Sobrecarga de función
- Sobrecarga del operador
- Llamada recurrente
- Bucles de longitud infinita
- Puntos fijos binarios
Para obtener más información, lee la información básica de Vyper.
Enlaces importantes
- Documentación
- Vyper por Example
- GitHub
- Sala de chat de Gitter sobre Vyper
- Hoja de trampas
- Actualización del 8 de enero de 2020
Ejemplo
1# Subastas Abiertas23# Params de subastas4# Beneficiario recibe dinero de la oferta más alta5beneficiario: public(address)6auctionStart: public(uint256)7auctionEnd: public(uint256)89# Estado actual de subasta10highestBidder: public(address)11highestBid: public(uint256)1213# Establecer a verdadero al final, deshabilita cualquier cambio14finalizado: public(bool)1516# Mantener un seguimiento de las ofertas reembolsadas para que podamos seguir el patrón de retirada17pendingReturns: public(HashMap[address, uint256])1819# Crea una subasta simple con `_bidding_time`20# segundos de tiempo de oferta en nombre de la21# dirección beneficiaria `_beneficiary`.22@Ejemplo en Vyper2324@external25def __init__(_beneficiary: address, _bidding_time: uint256):26 self.beneficiary = _beneficiary27 self.auctionStart = block.timestamp28 self.auctionEnd = self.auctionStart + _bidding_time.29# El valor solo será reembolsado si la subasta30# no es ganada.31@external32@payable33def bid():34 # Comprobar si el periodo de oferta ha terminado.35 assert block.timestamp < self.auctionEnd36 # Comprobar si la oferta es suficientemente alta37 assert msg. alue > self.highestBid38 # Registrar el reembolso de la oferta alta anterior39 mismo. endingDevuelve[self.highestBidder] += self.highestBid40 # Seguimiento de la nueva oferta alta. ighestBidder = msg.sender41 self.highestBid = msg.value4243# Retira una oferta previamente reembolsada. El patrón de retirada se44# utiliza aquí para evitar un problema de seguridad. Si los reembolsos fueron directamente45# enviados como parte de la oferta(), un contrato de licitación malicioso podría bloquear46# esos reembolsos y así bloquear la entrada de nuevas ofertas más altas.47@external48retiro def ():49 pending_amount: uint256 = self.pendingDevuelve[msg.sender]50 mismo. endingDevuelve[msg.sender] = 051 envio(msg. ender, pending_amount)5253# Finalizar la subasta y enviar la oferta más alta54# al beneficiario.55@external56def endAuction():57 # Es una buena guía para las funciones de estructura que interactúan con58 # con otros contratos (es decir, llaman funciones o envían Ether)59 # en tres fases:60 # 1. condiciones de comprobación61 # 2. realizar acciones (condiciones potencialmente cambiantes)62 # 3. interactuando con otros contratos63 # Si estas fases se mezclan, el otro contrato podría llamar a64 # de vuelta al contrato actual y modificar el estado o causar65 # efectos (pago ether) a ser realizados varias veces.66 # Si las funciones llamadas internamente incluyen interacción con contratos externos67 #, también deben considerarse interacción con68 # contratos externos.6970 # 1. Condiciones71 # Comprueba si se ha alcanzado el fin de la subasta72 aserción block.timestamp >= self. uctionEnd73 # Comprueba si esta función ya ha sido llamada74 assert not self. ndded7576 # 2. Efectos77 self.ended = True7879 # 3. Interacción80 enviar(self.beneficiary, self.highestBid)81Mostrar todoCopiar
Este ejemplo debería darte una idea de cómo es la sintaxis de contrato de Vyper. Para ver una descripción más detallada de las funciones y variables, consulta los documentos.
Yul y Yul+
Si eres nuevo en Ethereum y aún no has hecho ninguna codificación con lenguajes de contrato inteligente, te recomendamos empezar con Solidity o Vyper. Basta con echar un vistazo a Yul o Yul+ una vez que estés familiarizado con las prácticas recomendadas de seguridad de los contratos inteligentes y los detalles de trabajar con la EVM.
Yul
- Lenguaje intermedio para Ethereum.
- Es compatible con la EVM y eWASM, un Ethereum con características de WebAssembly, y se ha diseñado para ser un denominador común útil de ambas plataformas.
- Buen objetivo para las etapas de optimización de alto nivel, que puede beneficiar a las plataformas de EVM y eWASM.
Yul+
- Una extensión de bajo nivel y alta eficiencia para Yul.
- Diseñada inicialmente para un contrato de Optimistic Rollup.
- Yul+ se puede considerar una propuesta de actualización experimental de Yul, que le añade nuevas funciones.
Enlaces importantes
Ejemplo de contrato
El siguiente ejemplo sencillo implementa una potente función. Puede compilarse mediante solc --strict-assembly --bin input.yul
. El ejemplo debe almacenarse en el archivo input.yul.
1{2 function power(base, exponent) -> result3 {4 switch exponent5 case 0 { result := 1 }6 case 1 { result := base }7 default8 {9 result := power(mul(base, base), div(exponent, 2))10 if mod(exponent, 2) { result := mul(base, result) }11 }12 }13 let res := power(calldataload(0), calldataload(32))14 mstore(0, res)15 return(0, 32)16}17Mostrar todo
Si ya tienes experiencia con contratos inteligentes, puedes encontrar una implementación ERC20 completa en Yul aquí.
¿Cómo escoger?
Como en cualquier otro lenguaje de programación, se trata principalmente de elegir la herramienta adecuada para el trabajo correcto así como para las preferencias personales.
Estas son algunas cosas que debes tener en cuenta si aún no has probado ninguno de los lenguajes:
¿Qué tiene de genial Solidity?
- Si eres un principiante, encontrarás muchos tutoriales y herramientas de aprendizaje por ahí. Obtén más información al respecto en la sección Aprender programando.
- Buenas herramientas de desarrollador disponibles.
- Solidity tiene una gran comunidad de desarrolladores, lo que significa que muy probablemente encontrarás rápidamente las respuestas a tus preguntas.
¿Qué tiene de genial Vyper?
- Es una fantástica forma de comenzar para aquellos desarrolladores de Python que deseen escribir contratos inteligentes.
- Vyper dispone de un pequeño número de funciones que lo convierten en la opción ideal para elaborar prototipos de ideas rápidamente.
- Vyper pretende ser una herramienta fácil de auditar y ofrecer el nivel máximo de legibilidad para las personas.
¿Qué tienen de genial Yul y Yul+?
- Lenguaje simple y funcional de bajo nivel.
- Te permite aproximarte mucho más a la EVM sin procesar, lo que puede ayudarte a optimizar el uso de gas de los contratos.
Comparación de lenguajes
Si deseas realizar comparaciones sobre la sintaxis básica, el ciclo de vida del contrato, las interfaces, los operadores, las estructuras de datos, las funciones, el flujo de control, etc., echa un vistazo a esta hoja de apuntes de Auditless