Py-EVM es una implementación en Python de la Máquina Virtual de Ethereum (EVM), que faciliat a los desarrolladores la extensión y personalización de las operaciones fundamentales de Ethereum. Esta guía detalla el proceso para integrar códigos de operación (opcodes) personalizados en Py-EVM, permitiendo funcionalidades adaptadas a necesidades específicas.
La necesidad de códigos de operación personalizados surge en escenarios como la optimización de rendimiento para aplicaciones particulares, la implementación de lógica de negocio propietaria, la experimentación con nuevas características blockchain o la creación de una EVM personalizada. La arquitectura modular de Py-EVM simplifica significativamente este proceso.
El sistema de opcodes en Py-EVM se organiza en tres componentes principales: definición de opcodes en arcihvos específicos por bifurcación (por ejemplo, eth/vm/forks/cancun/opcodes.py), implementación de la lógica en el directorio eth/vm/logic/, y gestión de la ejecución en módulos de computación como eth/vm/computation.py. Cada bifurcación de Ethereum, como Cancún, Londres o Shanghái, mantiene su conjunto propio de opcodes.
Para crear un opcode personalizado, comienza configurando el entorno de desarrollo. Clona el repositorio de Py-EVM y navega al directorio del proyecto.
git clone https://gitcode.com/gh_mirrors/py/py-evm
cd py-evm
Implementa la lógica del opcode en un archivo apropiado. Por ejemplo, para una operación de resta, modifica o crea un archivo en eth/vm/logic/arithmetic.py:
def operacion_resta_personalizada(computacion):
"""
Opcode personalizado para resta modular.
"""
minuendo, sustraendo = computacion.stack_pop_ints(2)
resultado = (minuendo - sustraendo) % constants.UINT_256_MAX
computacion.stack_push_int(resultado)
Registra el opcode en la definición de opcodes de una bifurcación, como Cancún. En eth/vm/forks/cancun/opcodes.py, agrega la entrada correspondiente:
from eth.vm.logic.arithmetic import operacion_resta_personalizada
OPCODES_NUEVOS = {
# ... otros opcodes ...
0x81: as_opcode(
logic_fn=operacion_resta_personalizada,
mnemonic="CUSTOMSUB",
gas_cost=constants.GAS_LOW,
),
}
OPCODES_CANCUN = merge(
copy.deepcopy(OPCODES_SHANGHAI),
OPCODES_ACTUALIZADOS,
OPCODES_NUEVOS,
)
Actualiza el módulo de computación para incluir el nuevo conjunto de opcodes. En eth/vm/forks/cancun/computation.py, asegúrate de que la clase utilice el conjunto actualizado:
from .opcodes import OPCODES_CANCUN
class ComputacionCancun(ComputacionShanghai):
opcodes = OPCODES_CANCUN
Desarrolla pruebas exhaustivas para validar el opcode. Crea un archivo de prueba, como tests/core/vm/test_opcodes_personalizados.py:
def test_operacion_resta_opcode():
computacion = obtener_computacion_prueba()
computacion.stack_push_int(10)
computacion.stack_push_int(4)
computacion.execute_opcode(0x81)
assert computacion.stack_pop_int() == 6
Al desarrollar opcodes, sigue las mejores prácticas: elige una bifurcación base adecuada, selecciona un valor de opcode no utilizado (consulta listas EIP), establece un costo de gas razonable basado en opcodes similares, y documenta la lógica claramente. Los errores comunes incluyen conflictos de opcode, costos de gas inapropiados y fallos lógicos que pueden inestabilizar la EVM; pruebas rigurosas mitigan estos riesgos.