Являются ли функции инструкций makeLog кодами операций или нет?

Следующий фрагмент кода является составной частью instructions.goфайла, в котором живут opCodesвсе наши друзья.

// make log instruction function
func makeLog(size int) executionFunc {
    return func(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
        topics := make([]common.Hash, size)
        mStart, mSize := stack.pop(), stack.pop()
        for i := 0; i < size; i++ {
            topics[i] = common.BigToHash(stack.pop())
        }

        d := memory.Get(mStart.Int64(), mSize.Int64())
        evm.StateDB.AddLog(&types.Log{
            Address: contract.Address(),
            Topics:  topics,
            Data:    d,
            // This is a non-consensus field, but assigned here because
            // core/state doesn't know the current block number.
            BlockNumber: evm.BlockNumber.Uint64(),
        })

        evm.interpreter.intPool.put(mStart, mSize)
        return nil, nil
    }
}

// make push instruction function
func makePush(size uint64, pushByteSize int) executionFunc {
    return func(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
        codeLen := len(contract.Code)

        startMin := codeLen
        if int(*pc+1) < startMin {
            startMin = int(*pc + 1)
        }

        endMin := codeLen
        if startMin+pushByteSize < endMin {
            endMin = startMin + pushByteSize
        }

        integer := evm.interpreter.intPool.get()
        stack.push(integer.SetBytes(common.RightPadBytes(contract.Code[startMin:endMin], pushByteSize)))

        *pc += size
        return nil, nil
    }
}

// make push instruction function
func makeDup(size int64) executionFunc {
    return func(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
        stack.dup(evm.interpreter.intPool, int(size))
        return nil, nil
    }
}

// make swap instruction function
func makeSwap(size int64) executionFunc {
    // switch n + 1 otherwise n would be swapped with n
    size += 1
    return func(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
        stack.swap(int(size))
        return nil, nil
    }

Вопрос в том, являются ли они make log instruction functionsсами кодами операций?

Если они есть, то почему они не называются так?

Если нет, то что они делают, живя в файле со всеми opCodes?

Ответы (1)

Не уверен, что я полностью понял ваш вопрос, но вот мои наблюдения...

Коды операций, обрабатываемые четырьмя make*перечисленными вами функциями, отличаются от других кодов операций EVM тем, что они являются частью более широких семейств кодов операций:

  • makeLog()обрабатывает коды операций LOG0черезLOG4

  • makePush()обрабатывает коды операций PUSH1черезPUSH32

  • makeDup()обрабатывает коды операций DUP1черезDUP16

  • makeSwap()обрабатывает коды операций SWAP1черезSWAP16

Это отличается от других функций в файле, каждая из которых обрабатывает только один код операции вместе со своими операндами стека.

Кроме того, LOG*коды операций особенно необычны, поскольку каждый из них использует разное количество операндов стека: LOG0потребляет 2, LOG4потребляет 6. Так что с этим тоже нужно разобраться.

В конце концов, функция, возвращаемая каждой из make*()метафункций, будет выполнять работу одного кода операции и, следовательно, находится на равных условиях с другими функциями в файле.