Как запустить локальную виртуальную машину из golang?

Я собираюсь запустить виртуальную машину Эфириума из кода, передать ей скомпилированный код смарт-контракта.

Но я не знаю, как это сделать.

Это мой код: пакет main

import (
    "context"

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

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

}

Чтобы создать экземпляр виртуальной машины

vm := vm.NewEVM()

Мне нужно передать такие параметры, как:

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

Где взять эти параметры?

Рассматривали ли вы использовать утилиту «evm» от geth ( github.com/ethereum/go-ethereum )? Это упоминается в README.md. После установки этой утилиты вы можете запустить свой код с помощью следующей команды:evm --code 60ff60ff --debug
Да, я знаю об этом, но я просто хотел бы сделать то же самое из кода. Нигде не могу найти как это сделать.
Ах хорошо. Я думаю, что лучшее место, где можно получить некоторое представление об этих структурах данных, — это сама кодовая база go ethereum. В частности, я предлагаю вам взглянуть на файл core/vm/evm.goЗдесь вы можете найти определение контекста структуры и понять, что нужно.

Ответы (1)

1) Контекст создается таким образом:

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

Определение функции находится в 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) Вы получаете StateDB следующим образом:

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
}

Где blockchainнаходится core.Blockchainобъект и blockявляется types.Blockобъектом

3) ChainConfigсоздается в 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) вм конфиг создается так:

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

Очевидно, вам придется импортировать все эти модули. Ваше importзаявление будет примерно таким:

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"
}

Каталог дистрибутива cmd/evmEthereum gethсодержит пример кода, который вам понадобится для запуска произвольной сборки EVM.