¿Cómo ejecutar una máquina virtual local desde golang?

Voy a ejecutar la máquina ethereum virtual desde el código, le pasaré un código de contrato inteligente compilado.

Pero no sé cómo hacerlo.

Es mi código: paquete principal

import (
    "context"

    "github.com/ethereum/go-ethereum/core/vm"
)

func main() {
    var code string = "6060604052600a8060106000396000f360606040526008565b00"
    vm := vm.NewEVM(context.Background())

}

Para crear una instancia de una máquina virtual

vm := vm.NuevoEVM()

Tengo que pasar parámetros como:

- ctx Context 
- statedb StateDB
- chainConfig *params.ChainConfig
- vmConfig Config

¿Dónde obtener estos parámetros?

¿Consideró usar la utilidad "evm" de geth ( github.com/ethereum/go-ethereum )? Se menciona en el README.md. Una vez que instale esta utilidad, puede ejecutar su código con el siguiente comando:evm --code 60ff60ff --debug
Sí, lo sé, pero me gustaría hacer lo mismo con el código. No encuentro por ningún lado como hacerlo.
Está bien. Creo que el mejor lugar para obtener una idea de estas estructuras de datos es la propia base de código de go ethereum. En particular, le sugiero que eche un vistazo al archivo core/vm/evm.goAquí puede encontrar la definición del contexto de la estructura y comprender lo que se necesita.

Respuestas (1)

1) El contexto se crea de esta manera:

context := NewEVMContext(msg, header, bc, author)

La definición de la función se encuentra en core/evm.go:

// NewEVMContext creates a new context for use in the EVM.
func NewEVMContext(msg Message, header *types.Header, chain ChainContext, author *common.Address) vm.Context {

2) Obtienes StateDB así:

statedb, err := blockchain.StateAt(block.Root())
if err != nil {
    log.Error("Can't get StateAt() , probably I am not running on a full node","block_num",block.Number().Uint64())
    return  err
}

Donde blockchaines core.Blockchainobjeto y blockes un types.Blockobjeto

3) ChainConfigse crea en params/config.go

MainnetChainConfig = &ChainConfig{
    ChainId:        big.NewInt(1),
    HomesteadBlock: big.NewInt(1150000),
    DAOForkBlock:   big.NewInt(1920000),
    DAOForkSupport: true,
    EIP150Block:    big.NewInt(2463000),
    EIP150Hash:     common.HexToHash("0x2086799aeebeae135c246c65021c82b4e15a2c451340993aacfd2751886514f0"),
    EIP155Block:    big.NewInt(2675000),
    EIP158Block:    big.NewInt(2675000),
    ByzantiumBlock: big.NewInt(4370000),

    Ethash: new(EthashConfig),
}

4) la configuración de vm se crea así:

    vm_cfg:=&vm.Config{
        Debug: false,
        EnableJit: false,
        ForceJit: false,
    }

Obviamente, tienes que importar todos estos módulos. Su importdeclaración será algo como esto:

import(
    "github.com/ethereum/go-ethereum/common"
    "github.com/ethereum/go-ethereum/consensus/misc"
    "github.com/ethereum/go-ethereum/core"
    "github.com/ethereum/go-ethereum/core/state"
    "github.com/ethereum/go-ethereum/core/types"
    "github.com/ethereum/go-ethereum/core/vm"
    "github.com/ethereum/go-ethereum/eth"
    "github.com/ethereum/go-ethereum/log"
    "github.com/ethereum/go-ethereum/params"
    "github.com/ethereum/go-ethereum/cmd/utils"
}

El cmd/evmdirectorio de gethdistribución de Ethereum contiene un código de ejemplo que necesita para ejecutar un ensamblado EVM arbitrario.