Generando tu precompilado
En esta secci贸n, repasaremos el proceso para generar autom谩ticamente el c贸digo de plantilla que puedes configurar seg煤n corresponda para tu precompilado estatal.
Primero, debemos crear la interfaz Solidity que queremos que nuestro precompilado implemente. Esta ser谩
la interfaz de HelloWorld. Tendr谩 dos funciones simples, sayHello()
y setGreeting()
. Estas
dos funciones demostrar谩n la obtenci贸n y configuraci贸n, respectivamente, de un valor almacenado en el
espacio de estado del precompilado.
La funci贸n sayHello()
es una funci贸n view
, lo que significa que no modifica el estado del precompilado
y devuelve un resultado de tipo cadena. La funci贸n setGreeting()
es una funci贸n cambiadora de estado, lo que significa que
modifica el estado del precompilado. La interfaz HelloWorld
hereda la interfaz IAllowList
para usar la funcionalidad de lista de permitidos.
Para este tutorial, estaremos trabajando en una nueva rama en el repositorio Subnet-EVM/Precompile-EVM.
- Subnet-EVM
- Precompile-EVM
cd $GOPATH/src/github.com/ava-labs/subnet-evm
Luego cambia a una nueva rama:
git checkout -b hello-world-stateful-precompile
Comenzaremos en este directorio ./contracts/
:
cd contracts/
Crea un nuevo archivo llamado IHelloWorld.sol
y copia y pega el siguiente c贸digo:
// (c) 2022-2023, Ava Labs, Inc. Todos los derechos reservados.
// Consulta el archivo LICENSE para conocer los t茅rminos de licencia.
// SPDX-License-Identifier: MIT
pragma solidity >=0.8.0;
import "./IAllowList.sol";
interface IHelloWorld is IAllowList {
// sayHello devuelve la cadena de saludo almacenada
function sayHello() external view returns (string calldata result);
// setGreeting almacena la cadena de saludo
function setGreeting(string calldata response) external;
}
隆Ahora tenemos una interfaz que nuestro precompilado puede implementar! Creemos un ABI de nuestra interfaz Solidity.
En el mismo directorio, ejecutemos:
solc --abi ./contracts/interfaces/IHelloWorld.sol -o ./abis
cd $GOPATH/src/github.com/ava-labs/precompile-evm
Luego cambia a una nueva rama:
git checkout -b hello-world-stateful-precompile
Comenzaremos en este directorio ./contracts/
:
cd contracts/
Para interfaces de Precompile-EVM y otros contratos en Subnet-EVM,
se puede acceder a trav茅s del paquete @avalabs/subnet-evm-contracts
.
Esto ya se ha agregado al archivo package.json
.
Puedes instalarlo ejecutando npm install
.
Para importar la interfaz IAllowList
, puedes usar la siguiente declaraci贸n de importaci贸n:
import "@avalabs/subnet-evm-contracts/contracts/interfaces/IAllowList.sol";
El archivo completo se ve as铆:
// SPDX-License-Identifier: MIT
pragma solidity >=0.8.0;
import "@avalabs/subnet-evm-contracts/contracts/interfaces/IAllowList.sol";
interface IHelloWorld is IAllowList {
// sayHello devuelve la cadena de saludo almacenada
function sayHello() external view returns (string calldata result);
// setGreeting almacena la cadena de saludo
function setGreeting(string calldata response) external;
}
隆Ahora tenemos una interfaz que nuestro precompilado puede implementar! Creemos un ABI de nuestra interfaz Solidity.
En Precompile-EVM importamos contratos del paquete @avalabs/subnet-evm-contracts
.
Para generar el ABI en Precompile-EVM, necesitamos incluir la carpeta node_modules
para encontrar
los contratos importados con las siguientes banderas:
--abi
- Especificaci贸n ABI de los contratos.
--base-path path
- Usa la ruta dada como la ra铆z del 谩rbol de origen en lugar de la ra铆z del sistema de archivos.
--include-path path
- Hace que un directorio fuente adicional est茅 disponible para la devoluci贸n de llamada de importaci贸n predeterminada. Usa esta opci贸n si quieres importar contratos cuya ubicaci贸n no est谩 fija en relaci贸n con tu 谩rbol de origen principal; por ejemplo, bibliotecas de terceros instaladas usando un administrador de paquetes. Se puede usar varias veces. Solo se puede usar si la ruta base tiene un valor no vac铆o.
--output-dir path
- Si se proporciona, crea un archivo por componente de salida y contrato/archivo en el directorio especificado.
--overwrite
- Sobrescribe los archivos existentes (se usa junto con
--output-dir
).
- Sobrescribe los archivos existentes (se usa junto con
solc --abi ./contracts/interfaces/IHelloWorld.sol -o ./abis --base-path . --include-path ./node_modules
Esto genera el c贸digo ABI en ./abis/IHelloWorld.abi
.
[
{
"inputs": [
{ "internalType": "address", "name": "addr", "type": "address" }
],
"name": "leerAllowList",
"outputs": [
{ "internalType": "uint256", "name": "rol", "type": "uint256" }
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "decirHola",
"outputs": [
{ "internalType": "string", "name": "resultado", "type": "string" }
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "addr", "type": "address" }
],
"name": "setAdmin",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "addr", "type": "address" }
],
"name": "setEnabled",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{ "internalType": "string", "name": "response", "type": "string" }
],
"name": "setGreeting",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "addr", "type": "address" }
],
"name": "setNone",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
}
]
Como puedes ver, el ABI tambi茅n contiene las funciones de la interfaz IAllowList
. Esto se debe a que la interfaz IHelloWorld
hereda de la interfaz IAllowList
.
Nota: El ABI debe tener salidas con nombres para poder generar la plantilla de precompilaci贸n.
Ahora que tenemos un ABI con el que la herramienta de generaci贸n de precompilaciones puede interactuar, podemos ejecutar el siguiente comando para generar nuestros archivos de precompilaci贸n de HelloWorld.
隆Volviendo a la ra铆z del repositorio, ejecutemos el script de ayuda PrecompileGen:
cd ..
Tanto Subnet-EVM como Precompile-EVM tienen el mismo script generate_precompile.sh
. El de Precompile-EVM
instala el script de Subnet-EVM y lo ejecuta.
$ ./scripts/generate_precompile.sh --help
Usando la rama: precompile-tutorial
NOMBRE:
precompilegen - herramienta de generaci贸n de precompilaciones de subnet-evm
USO:
main [opciones globales] comando [opciones del comando] [argumentos...]
VERSI脫N:
1.10.26-estable
COMANDOS:
help, h Muestra una lista de comandos o ayuda para un comando
OPCIONES GLOBALES:
--abi valor
Ruta al archivo JSON del ABI del contrato a generar, - para STDIN
--out valor
Carpeta de salida para los archivos de precompilaci贸n generados, - para STDOUT (predeterminado =
./precompile/contracts/{pkg}). Los archivos de prueba no se generar谩n si se usa STDOUT
--pkg valor
Nombre del paquete Go para generar la precompilaci贸n (predeterminado = {type})
--type valor
Nombre de la estructura para la precompilaci贸n (predeterminado = {nombre del archivo abi})
MISCEL脕NEO
--help, -h (predeterminado: false)
mostrar ayuda
--version, -v (predeterminado: false)
imprimir la versi贸n
DERECHOS DE AUTOR:
Derechos de autor 2013-2022 Los autores de go-ethereum
隆Ahora generemos los archivos de plantilla de precompilaci贸n!
- Subnet-EVM
- Precompile-EVM
En Subnet-EVM, las implementaciones de precompilaci贸n residen en el directorio ./precompile/contracts
. Generemos nuestra plantilla de precompilaci贸n
en el directorio ./precompile/contracts/helloworld
, donde helloworld
es el nombre del
paquete Go en el que queremos generar la precompilaci贸n.
./scripts/generate_precompile.sh --abi ./contracts/abis/IHelloWorld.abi --type HelloWorld --pkg helloworld
Para Precompile-EVM, no necesitamos colocar los archivos en una estructura de directorios profunda. Simplemente podemos generar la
plantilla de precompilaci贸n en su propio directorio a trav茅s de la bandera --out ./helloworld
.
./scripts/generate_precompile.sh --abi ./contracts/abis/IHelloWorld.abi --type HelloWorld --pkg helloworld --out ./helloworld
Esto genera archivos de plantilla de precompilaci贸n contract.go
, contract.abi
, config.go
, module.go
y README.md
. El archivo README.md
explica pautas generales para el desarrollo de precompilaciones.
Debes leer cuidadosamente este archivo antes de modificar la plantilla de precompilaci贸n.
Hay algunos cambios que deben hacerse en el archivo generado. Cada 谩rea que requiere que agregues tu c贸digo est谩 marcada con CUSTOM CODE para que sea f谩cil de encontrar y modificar.
Adem谩s, hay otros archivos que necesitas editar para activar tu precompilaci贸n.
Estas 谩reas est谩n resaltadas con comentarios que dicen "ADD YOUR PRECOMPILE HERE".
Para hacer pruebas, echa un vistazo a otras pruebas de precompilaci贸n en contract_test.go y config_test.go en otras carpetas de precompilaci贸n.
Consulta el tutorial en <https://docs.avax.network/subnets/hello-world-precompile-tutorial> para obtener m谩s informaci贸n sobre el desarrollo de precompilaciones.
Pautas generales para el desarrollo de precompilaciones:
1- Establece una clave de configuraci贸n adecuada en el archivo module.go generado. Por ejemplo: "yourPrecompileConfig".
2- Lee el comentario y establece una direcci贸n de contrato adecuada en el archivo module.go generado. Por ejemplo:
ContractAddress = common.HexToAddress("UNADIRECCIONHEXADAEQUIVOCADA")
3- Se recomienda modificar solo el c贸digo en las 谩reas resaltadas marcadas con "CUSTOM CODE STARTS HERE". Por lo general, los c贸digos personalizados solo son necesarios en esas 谩reas.
Modificar el c贸digo fuera de estas 谩reas debe hacerse con precauci贸n y con un profundo entendimiento de c贸mo estos cambios pueden afectar a la EVM.
4- Establece los costos de gas en el archivo contract.go generado.
5- Importa forzosamente tu paquete de precompilaci贸n en precompile/registry/registry.go
6- Agrega tus pruebas unitarias de configuraci贸n bajo el paquete generado config_test.go
7- Agrega tus pruebas unitarias de contrato bajo el paquete generado contract_test.go
8- Adem谩s, puedes agregar una prueba de VM completa para tu precompilaci贸n en plugin/vm/vm_test.go. Consulta las pruebas de precompilaci贸n existentes para ver ejemplos.
9- Agrega tu interfaz de Solidity y contrato de prueba al directorio contracts/contracts
10- Escribe pruebas de contrato de Solidity para tu precompilaci贸n en contracts/contracts/test/
11- Escribe contrapartes de pruebas DS-Test en TypeScript para tus pruebas de Solidity en contracts/test/
12- Crea tu g茅nesis con tu precompilaci贸n habilitada en tests/precompile/genesis/
13- Crea una prueba de extremo a extremo para tu prueba de Solidity en tests/precompile/solidity/suites.go
14- Ejecuta tus pruebas de extremo a extremo de precompilaci贸n de Solidity con './scripts/run_ginkgo.sh`
隆Sigamos estos pasos y creemos nuestra precompilaci贸n de HelloWorld!
Was this page helpful?