向 Solidity 添加新的自定义操作码

问题描述 投票:0回答:2

我在向 Solidity 添加新操作码时遇到问题。我正在使用 solc(在 C++ 上)和 geth(在 Go 上是以太坊)。我想添加新的操作码,它需要

address payable, uint256, uint256, bytes memory
并返回
bytes memory
。所以我对返回值有问题。

下面的一些代码,我将跳过一些文件,以使问题更短。

  1. 索尔克
  • libsolidity/codegen/ExpressionCompiler.cpp
// ExpressionCompiler::visit(FunctionCall const& _functionCall)
case FunctionType::Kind::MyOpcode:
{
    acceptAndConvert(*arguments[0], *function.parameterTypes()[0], true);
    acceptAndConvert(*arguments[1], *function.parameterTypes()[1], true);
    acceptAndConvert(*arguments[2], *function.parameterTypes()[2], true);
    arguments[3]->accept(*this);
    utils().fetchFreeMemoryPointer();
    utils().packedEncode(
        {arguments[3]->annotation().type},
        {TypeProvider::array(DataLocation::Memory, true)}
    );
    utils().toSizeAfterFreeMemoryPointer();

    m_context << Instruction::MYOPCODE;
}
  • libsolidity/analysis/GlobalContext.cpp
// inline vector<shared_ptr<MagicVariableDeclaration const>> constructMagicVariables()
magicVarDecl("myopcode", TypeProvider::function(strings{"address payable", "uint256", "uint256", "bytes memory"}, strings{"bytes memory"}, FunctionType::Kind::MyOpcode, false, StateMutability::Payable)),
  • libevmasm/指令.cpp
// static std::map<Instruction, InstructionInfo> const c_instructionInfo =
{ Instruction::MYOPCODE,       { "MYOPCODE",          0, 5, 1, true, Tier::Base } }
  1. 盖斯
  • core/vm/jump_table.go
// func newFrontierInstructionSet() JumpTable {
CALLACTOR: {
    execute:    opMyOpCode,
    dynamicGas: gasCallActor,
    minStack:   minStack(5, 1),
    maxStack:   maxStack(5, 1),
    memorySize: memoryReturn,
    writes:     true,
    returns:    true,
},
  • core/vm/instructions.go
func opMyOpcode(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
    inoffset, insize := callContext.stack.pop(), callContext.stack.pop()
    params := callContext.memory.GetPtr(int64(inoffset.Uint64()), int64(insize.Uint64()))

    secondValue := callContext.stack.pop()

    firstValue := callContext.stack.pop()

    addr := callContext.stack.pop()

    // ... Do smth with input ...

    outoffset := inoffset.Uint64() + insize.Uint64()

    callContext.memory.Set(outoffset, 1, []byte{0x2})
    tmp := make([]byte, 1)
    tmp[0] = 0x98
    callContext.memory.Set(outoffset + 1, 1, tmp)

    callContext.stack.push(uint256.NewInt().SetUint64(outoffset))

    return tmp, nil
}
  1. 智能合约
pragma solidity >=0.6.0; // SPDX-License-Identifier: GPL-3
contract test {
    event ReturnValue(address payable _from, bytes data);
    function f() public returns(bytes memory){
        address payable addr1 = payable(msg.sender);
        bytes memory params = new bytes(2);
        params[0] = 0x21;
        params[1] = 0x22;
        bytes memory result = myopcode(addr1, 0x11, 0x12, params);
        emit ReturnValue(addr1, result);
        return result;
    }
}

当我运行该代码时,我得到

invalid jump destination
。那么,我需要做什么才能让我的代码正常工作?

ethereum solidity opcode
2个回答
0
投票

我找到了一个解决方案,它看起来确实很愚蠢,但开发人员已经提供了这个案例。您所需要的只是

utils().returnDataToArray()


-1
投票

我目前也在使用我的自定义操作码修改 EVM。

您介意聊聊讨论一下吗?

© www.soinside.com 2019 - 2024. All rights reserved.