示例#1
0
        public override void Execute()
        {
            // Obtain our offsets and sizes for the copy.
            BigInteger memoryOffset = Stack.Pop();
            BigInteger dataOffset   = Stack.Pop();
            BigInteger dataSize     = Stack.Pop();

            // This is considered a copy operation, so we charge for the size of the data.
            GasState.Deduct(GasDefinitions.GetMemoryCopyCost(Version, dataSize));

            // Read our data from the code segment (if our offset is wrong or we hit the end of the array, the rest should be zeroes).
            byte[] data   = new byte[(int)dataSize];
            int    length = data.Length;

            if (dataOffset > EVM.Code.Length)
            {
                dataOffset = 0;
                length     = 0;
            }
            else if (dataOffset + length > EVM.Code.Length)
            {
                length = EVM.Code.Length - (int)dataOffset;
            }

            // Copy to the memory location.
            EVM.Code.Slice((int)dataOffset, length).CopyTo(data);

            // Write the data to our given memory offset.
            Memory.Write((long)memoryOffset, data);
        }
        public override void Execute()
        {
            // Obtain our offsets and sizes for the copy.
            BigInteger memoryOffset = Stack.Pop();
            BigInteger dataOffset   = Stack.Pop();
            BigInteger dataSize     = Stack.Pop();

            // This is considered a copy operation, so we charge for the size of the data.
            GasState.Deduct(GasDefinitions.GetMemoryCopyCost(Version, dataSize));

            // If we aren't copying anything, we can stop.
            if (dataOffset + dataSize == 0)
            {
                return;
            }

            // Check we have a return result, and check it's bounds.
            if (ExecutionState.LastCallResult?.ReturnData == null)
            {
                throw new EVMException($"{Opcode.ToString()} tried to copy return data from last call, but no last return data exists.");
            }
            else if (dataOffset + dataSize > (ExecutionState.LastCallResult?.ReturnData.Length ?? 0))
            {
                throw new EVMException($"{Opcode.ToString()} tried to copy return data past the end.");
            }
            else
            {
                // Otherwise we write our data we wish to copy to memory.
                Memory.Write((long)memoryOffset, ExecutionState.LastCallResult.ReturnData.Slice((int)dataOffset, (int)(dataSize)).ToArray());
            }
        }