Lenguajes de contrato inteligente
Última edición: @danielpg2106(opens in a new tab), 17 de junio de 2024
Un gran aspecto de Ethereum es que los contratos inteligentes pueden programarse utilizando lenguajes relativamente fáciles para el programador. Si tiene experiencia con Python u otro lenguaje entre llaves(opens in a new tab), puede buscar 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.
Si es curioso y le gustaría ayudar a testear nuevos lenguajes que aún se encuentran bajo gran desarrollo, puede experimentar con Fe, un lenguaje emergente de contratos inteligentes que aún está en sus inicios.
Requisitos previos
El conocimiento previo de lenguajes de programación, especialmente de JavaScript o Python, puede ayudarlo a entender las diferencias en los lenguajes de los contratos inteligentes. También recomendamos que entienda los lenguajes de los contratos inteligentes como concepto antes de profundizar en las comparaciones de lenguajes. Consulte esta Introducción a los contratos inteligentes.
Solidity
- Lenguaje orientado a objeto de alto nivel para implementar contratos inteligentes.
- Lenguaje de llaves más influenciado por C++.
- Escrito estáticamente (el tipo de una variable se conoce en el momento de compilación).
- Admite:
- Herencia (puede extende otros contratos).
- Bibliotecas (puede crear código reutilizable que puede invocar de diferentes contratos, 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(opens in a new tab)
- Portal de lenguaje de Solidity(opens in a new tab)
- Solidity by Example(opens in a new tab)
- GitHub(opens in a new tab)
- Sala de chat de Solidity (Glitter)(opens in a new tab) enlazada con la Sala de chat de Solidity (Matrix)(opens in a new tab)
- Hoja de trampas(opens in a new tab)
- Blog de Solidity(opens in a new tab)
- Twitter de Solidity(opens in a new tab)
Ejemplo de contrato
1// SPDX-License-Identifier: GPL-3.02pragma solidity >= 0.7.0;34contract Coin {5 // The keyword "public" makes variables6 // accessible from other contracts7 address public minter;8 mapping (address => uint) public balances;910 // Events allow clients to react to specific11 // contract changes you declare12 event Sent(address from, address to, uint amount);1314 // Constructor code is only run when the contract15 // is created16 constructor() {17 minter = msg.sender;18 }1920 // Sends an amount of newly created coins to an address21 // Can only be called by the contract creator22 function mint(address receiver, uint amount) public {23 require(msg.sender == minter);24 require(amount < 1e60);25 balances[receiver] += amount;26 }2728 // Sends an amount of existing coins29 // from any caller to an address30 function send(address receiver, uint amount) public {31 require(amount <= balances[msg.sender], "Insufficient balance.");32 balances[msg.sender] -= amount;33 balances[receiver] += amount;34 emit Sent(msg.sender, receiver, amount);35 }36}Mostrar todoCopiar
Este ejemplo debería darle una idea de cómo es la sintaxis de un contrato Solidity. Para ver una descripción más detallada de las funciones y variables, consulte los documentos(opens in a new tab).
Vyper
- Lenguaje de programación Pythonic
- Escritura fuerte
- Código de compilador pequeño y comprensible
- Generación eficiente de bytecode
- Deliberadamente tiene menos funciones que Solidity con el objetivo de hacer que los contratos sean más seguros y más fáciles de auditar. Vyper no admite:
- Modificadores
- Herencia
- Ensamblado en línea
- Sobrecarga de funciones
- Sobrecarga de operadores
- Llamadas recurrentes
- Bucles de longitud infinita
- Puntos fijos binarios
Para obtener más información, lea los fundamentos de Vyper(opens in a new tab).
Enlaces importantes
- Documentación(opens in a new tab)
- Vyper por Example(opens in a new tab)
- Más Vyper by Example(opens in a new tab)
- GitHub(opens in a new tab)
- Chat de Discord de la comunidad de Vyper(opens in a new tab)
- Hoja de trampas(opens in a new tab)
- Marcos para desarrollo de contratos inteligentes y herramientas para Vyper
- VyperPunk: aprenda a asegurar y hackear contratos inteligentes de Vyper(opens in a new tab)
- VyperExamples: ejemplos de vulnerabilidades en Vyper(opens in a new tab)
- Vyper Hub para desarrollo(opens in a new tab)
- Ejemplos de grandes éxitos de contratos inteligentes de Vyper(opens in a new tab)
- Increíbles recursos seleccionados de Vyper(opens in a new tab)
Ejemplo
1# Open Auction23# Auction params4# Beneficiary receives money from the highest bidder5beneficiary: public(address)6auctionStart: public(uint256)7auctionEnd: public(uint256)89# Current state of auction10highestBidder: public(address)11highestBid: public(uint256)1213# Set to true at the end, disallows any change14ended: public(bool)1516# Keep track of refunded bids so we can follow the withdraw pattern17pendingReturns: public(HashMap[address, uint256])1819# Create a simple auction with `_bidding_time`20# seconds bidding time on behalf of the21# beneficiary address `_beneficiary`.22@external23def __init__(_beneficiary: address, _bidding_time: uint256):24 self.beneficiary = _beneficiary25 self.auctionStart = block.timestamp26 self.auctionEnd = self.auctionStart + _bidding_time2728# Bid on the auction with the value sent29# together with this transaction.30# El valor solo será reembolsado si la subasta31# no es ganada.32@external33@payable34def bid():35 # Comprobar si el periodo de oferta ha terminado.36 assert block.timestamp < self.auctionEnd37 # Check if bid is high enough38 assert msg.value > self.highestBid39 # Track the refund for the previous high bidder40 self.pendingReturns[self.highestBidder] += self.highestBid41 # Track new high bid42 self.highestBidder = msg.sender43 self.highestBid = msg.value4445# Withdraw a previously refunded bid. El patrón de retirada se46# utiliza aquí para evitar un problema de seguridad. Si los reembolsos fueron directamente47# enviados como parte de la oferta(), un contrato de licitación malicioso podría bloquear48# esos reembolsos y así bloquear la entrada de nuevas ofertas más altas.49@external50def withdraw():51 pending_amount: uint256 = self.pendingReturns[msg.sender]52 self.pendingReturns[msg.sender] = 053 send(msg.sender, pending_amount)5455# Finalizar la subasta y enviar la oferta más alta56# al beneficiario.57@external58def endAuction():59 # It is a good guideline to structure functions that interact60 # with other contracts (i.e. they call functions or send ether)61 # into three phases:62 # 1. condiciones de comprobación63 # 2. realizar acciones (condiciones potencialmente cambiantes)64 # 3. interactuando con otros contratos65 # Si estas fases se mezclan, el otro contrato podría llamar a66 # de vuelta al contrato actual y modificar el estado o causar67 # efectos (pago ether) a ser realizados varias veces.68 # Si las funciones llamadas internamente incluyen interacción con contratos externos69 # también deben considerarse interacción con70 # contratos externos.7172 # 1. Condiciones73 # Comprueba si se ha alcanzado el fin de la subasta74 assert block.timestamp >= self.auctionEnd75 # Comprueba si esta función ya ha sido llamada76 assert not self.ended7778 # 2. Efectos79 self.ended = True8081 # 3. Interacción82 send(self.beneficiary, self.highestBid)Mostrar todoCopiar
Este ejemplo debería darle una idea de cómo es la sintaxis de contratos de Vyper. Para ver una descripción más detallada de las funciones y variables, consulte los documentos(opens in a new tab).
Yul y Yul+
Si es nuevo en Ethereum y aún no ha hecho ninguna codificación con lenguajes de contrato inteligente, le recomendamos empezar con Solidity o Vyper. Solo póngase con Yul o Yul+ una vez que esté 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 EVM y Ewasm(opens in a new tab), un WebAssembly parecido a Ethereum, y está diseñado para ser un denominador común utilizable 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ñado inicialmente para ser un contrato de rollup optimista.
- Yul+ se puede considerar una propuesta de actualización experimental de Yul, que le añade nuevas funciones.
Enlaces importantes
- Documentacíon de Yul(opens in a new tab)
- Documentación de Yul+(opens in a new tab)
- Campo de juego de Yul+(opens in a new tab)
- Post de introducción a Yul+(opens in a new tab)
Ejemplo de contrato
El siguiente ejemplo sencillo implementa una power function. 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}Mostrar todo
Si ya tiene experiencia con contratos inteligentes, puede encontrar una implementación ERC20 completa en Yul aquí(opens in a new tab).
Fe
- Lenguaje escrito estáticamente para la Máquina Virtual de Ethereum (EVM).
- Inspirado en Python y Rust.
- Pretende ser fácil de aprender, incluso para desarrolladores que son nuevos en el ecosistema de Ethereum.
- El desarrollo de Fe se encuentra aún en sus inicios; el lenguaje tuvo su lanzamiento alpha en enero de 2021.
Enlaces importantes
- GitHub(opens in a new tab)
- Anuncio de Fe(opens in a new tab)
- Hoja de ruta de Fe 2021(opens in a new tab)
- Chat sobre Fe de Discord(opens in a new tab)
- Twitter de Fe(opens in a new tab)
Ejemplo de contrato
El siguiente es un contrato simple implementado en Fe.
1type BookMsg = bytes[100]23contract GuestBook:4 pub guest_book: map<address, BookMsg>56 event Signed:7 book_msg: BookMsg89 pub def sign(book_msg: BookMsg):10 self.guest_book[msg.sender] = book_msg1112 emit Signed(book_msg=book_msg)1314 pub def get_msg(addr: address) -> BookMsg:15 return self.guest_book[addr].to_mem()16Mostrar todo
¿Cómo escoger?
Como sucede con cualquier otro lenguaje de programación, se trata principalmente de elegir la herramienta adecuada para el trabajo correcto, así como las preferencias personales.
Estas son algunas cosas que debe tener en cuenta si aún no ha probado ninguno de los lenguajes:
¿Qué tiene de genial Solidity?
- Si es principiante, encontrará muchos tutoriales y herramientas de aprendizaje por ahí. Obtenga 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á rápidamente las respuestas a sus 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 una menor cantidad 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.
- Le permite aproximarse mucho más a la EVM sin procesar, lo que puede ayudarlo a optimizar el uso de gas en los contratos.
Comparación de lenguajes
Si desea obtener comparaciones sobre la sintaxis básica, el ciclo de vida de los contratos, las interfaces, los operadores, las estructuras de datos, las funciones, el flujo de control, etc., eche un vistazo a esta hoja de apuntes de Auditless(opens in a new tab).