Solidity
將新的自定義操作碼添加到solidity
我在將新操作碼添加到solidity 時遇到問題。我正在使用 solc(在 C++ 上)和 geth(在 Go 上的乙太坊)。我想添加新的操作碼,它接受
address payable, uint256, uint256, bytes memory
並返回bytes memory
. 所以我有返回值的問題。下面的一些程式碼和平,我將跳過一些文件,以使問題更短。
- 索爾克
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/Instruction.cpp
// static std::map<Instruction, InstructionInfo> const c_instructionInfo = { Instruction::MYOPCODE, { "MYOPCODE", 0, 5, 1, true, Tier::Base } }
- 格思
- 核心/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, },
- 核心/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{0x1}) tmp := make([]byte, 1) tmp[0] = 0x98 callContext.memory.Set(outoffset + 1, 1, tmp) callContext.stack.push(uint256.NewInt().SetUint64(outoffset)) return tmp, nil }
- 智能合約
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
. 那麼,我需要做什麼才能讓我的程式碼正常工作?
我找到了一個解決方案,它看起來確實很愚蠢,但是開發人員已經提供了這個案例。你只需要
utils().returnDataToArray()
.