Skip to content

Instantly share code, notes, and snippets.

@mratsim
Last active June 7, 2018 19:53
Show Gist options
  • Save mratsim/a54b8e366063b0e75c122a3cf9066d91 to your computer and use it in GitHub Desktop.
Save mratsim/a54b8e366063b0e75c122a3cf9066d91 to your computer and use it in GitHub Desktop.
# Nimbus
# Copyright (c) 2018 Status Research & Development GmbH
# Licensed under either of
# * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)
# * MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)
# at your option. This file may not be copied, modified, or distributed except according to those terms.
import tables
type
# Yellow Paper Appendix H - https://ethereum.github.io/yellowpaper/paper.pdf
# Special notes from Yellow Paper:
# - Signed values are treated as two’s complement signed 256-bit integers.
# - When −2^255 is negated, there is an overflow
# - For addmod and mulmod, intermediate computations are not subject to the 2^256 modulo.
# Nimbus authors note:
# - This means that we can't naively do (Uint256 + Uint256) mod uint256,
# because the intermediate sum (or multiplication) might roll over if
# intermediate result is greater or equal 2^256
Op* {.pure.} = enum
# 0s: Stop and Arithmetic Operations
Stop = 0x00, # Halts execution.
Add = 0x01, # Addition operation.
Mul = 0x02, # Multiplication operation.
Sub = 0x03, # Subtraction operation.
Div = 0x04, # Integer division operation.
Sdiv = 0x05, # Signed integer division operation (truncated).
Mod = 0x06, # Modulo remainder operation.
Smod = 0x07, # Signed modulo remainder operation.
Addmod = 0x08, # Modulo addition operation.
Mulmod = 0x09, # Modulo multiplication operation.
Exp = 0x0A, # Exponential operation
SignExtend = 0x0B, # Extend length of two’s complement signed integer.
# 10s: Comparison & Bitwise Logic Operations
Lt = 0x10, # Less-than comparison.
Gt = 0x11, # Greater-than comparison.
Slt = 0x12, # Signed less-than comparison.
Sgt = 0x13, # Signed greater-than comparison.
Eq = 0x14, # Equality comparison.
IsZero = 0x15, # Simple not operator. (Note: real Yellow Paper description)
And = 0x16, # Bitwise AND operation.
Or = 0x17, # Bitwise OR operation.
Xor = 0x18, # Bitwise XOR operation.
Not = 0x19, # Bitwise NOT operation.
Byte = 0x1A, # Retrieve single byte from word.
# 20s: SHA3
Sha3 = 0x20, # Compute Keccak-256 hash.
# 30s: Environmental Information
Address = 0x30, # Get address of currently executing account.
Balance = 0x31, # Get balance of the given account.
Origin = 0x32, # Get execution origination address.
Caller = 0x33, # Get caller address.
CallValue = 0x34, # Get deposited value by the instruction/transaction responsible for this execution.
CallDataLoad = 0x35, # Get input data of current environment.
CallDataSize = 0x36, # Get size of input data in current environment.
CallDataCopy = 0x37, # Copy input data in current environment to memory.
CodeSize = 0x38, # Get size of code running in current environment.
CodeCopy = 0x39, # Copy code running in current environment to memory.
GasPrice = 0x3a, # Get price of gas in current environment.
ExtCodeSize = 0x3b, # Get size of an account's code
ExtCodeCopy = 0x3c, # Copy an account's code to memory.
ReturnDataSize = 0x3d, # Get size of output data from the previous call from the current environment.
ReturnDataCopy = 0x3e, # Copy output data from the previous call to memory.
# 40s: Block Information
Blockhash = 0x40, # Get the hash of one of the 256 most recent complete blocks.
Coinbase = 0x41, # Get the block's beneficiary address.
Timestamp = 0x42, # Get the block's timestamp.
Number = 0x43, # Get the block's number.
Difficulty = 0x44, # Get the block's difficulty.
GasLimit = 0x45, # Get the block's gas limit.
# 50s: Stack, Memory, Storage and Flow Operations
Pop = 0x50, # Remove item from stack.
Mload = 0x51, # Load word from memory.
Mstore = 0x52, # Save word to memory.
Mstore8 = 0x53, # Save byte to memory.
Sload = 0x54, # Load word from storage.
Sstore = 0x55, # Save word to storage.
Jump = 0x56, # Alter the program counter.
JumpI = 0x57, # Conditionally alter the program counter.
Pc = 0x58, # Get the value of the program counter prior to the increment corresponding to this instruction.
Msize = 0x59, # Get the size of active memory in bytes.
Gas = 0x5a, # Get the amount of available gas, including the corresponding reduction for the cost of this instruction.
JumpDest = 0x5b, # Mark a valid destination for jumps. This operation has no effect on machine state during execution.
# 60s & 70s: Push Operations.
Push1 = 0x60, # Place 1-byte item on stack.
Push2 = 0x61, # Place 2-byte item on stack.
Push3,
Push4,
Push5,
Push6,
Push7,
Push8,
Push9,
Push10,
Push11,
Push12,
Push13,
Push14,
Push15,
Push16,
Push17,
Push18,
Push19,
Push20,
Push21,
Push22,
Push23,
Push24,
Push25,
Push26,
Push27,
Push28,
Push29,
Push30,
Push31,
Push32 = 0x7f, # Place 32-byte (full word) item on stack.
# 80s: Duplication Operations
Dup1 = 0x80, # Duplicate 1st stack item.
Dup2 = 0x81, # Duplicate 2nd stack item.
Dup3,
Dup4,
Dup5,
Dup6,
Dup7,
Dup8,
Dup9,
Dup10,
Dup11,
Dup12,
Dup13,
Dup14,
Dup15,
Dup16 = 0x8f, # Duplicate 16th stack item.
# 90s: Exchange Operations
Swap1 = 0x90, # Exchange 1st and 2nd stack items.
Swap2 = 0x91, # Exchange 1st and 3rd stack items.
Swap3,
Swap4,
Swap5,
Swap6,
Swap7,
Swap8,
Swap9,
Swap10,
Swap11,
Swap12,
Swap13,
Swap14,
Swap15,
Swap16 = 0x9f, # Exchange 1st and 17th stack items.
# a0s: Logging Operations
Log0 = 0xa0, # Append log record with no topics.
Log1 = 0xa1, # Append log record with one topics.
Log2,
Log3,
Log4 = 0xa4, # Append log record with four topics.
# f0s: System operations
Create = 0xf0, # Create a new account with associated code.
Call = 0xf1, # Message-call into an account.
CallCode = 0xf2, # Message-call into this account with an alternative account's code.
Return = 0xf3, # Halt execution returning output data.
DelegateCall = 0xf4, # Message-call into this account with an alternative account's code, but persisting the current values for sender and value.
StaticCall = 0xfa, # Static message-call into an account.
Revert = 0xfd, # Halt execution reverting state changes but returning data and remaining gas.
Invalid = 0xfe, # Designated invalid instruction.
SelfDestruct = 0xff # Halt execution and register account for later deletion.
# Nimbus
# Copyright (c) 2018 Status Research & Development GmbH
# Licensed under either of
# * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)
# * MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)
# at your option. This file may not be copied, modified, or distributed except according to those terms.
import
strformat, strutils, tables, macros,
constants, stint, errors, logging, vm_state,
vm / [gas_meter, stack, code_stream, memory, message], db / db_chain, computation, opcode, opcode_values, utils / [header, address],
logic / [arithmetic, comparison, sha3, context, block_ops, stack_ops, duplication, swap, memory_ops, storage, flow, logging_ops, invalid, call, system_ops],
./vm_types
## Before
var OPCODE_TABLE* = initOpcodes:
# arithmetic
Op.Add: GasVeryLow add
Op.Mul: GasLow mul
Op.Sub: GasVeryLow sub
Op.Div: GasLow divide
Op.SDiv: GasLow sdiv
Op.Mod: GasLow modulo
Op.SMod: GasLow smod
Op.AddMod: GasMid addmod
Op.MulMod: GasMid mulmod
Op.Exp: GasInHandler arithmetic.exp
Op.SignExtend: GasLow signextend
# comparison
Op.Lt: GasVeryLow lt
Op.Gt: GasVeryLow gt
Op.SLt: GasVeryLow slt
Op.SGt: GasVeryLow sgt
Op.Eq: GasVeryLow eq
Op.IsZero: GasVeryLow iszero
Op.And: GasVeryLow andOp
Op.Or: GasVeryLow orOp
Op.Xor: GasVeryLow xorOp
Op.Not: GasVeryLow notOp
Op.Byte: GasVeryLow byteOp
# sha3
Op.SHA3: GasSHA3 sha3op
# context
Op.Address: GasBase context.address
Op.Balance: GasBalance balance
Op.Origin: GasBase origin
Op.Caller: GasBase caller
Op.CallValue: GasBase callValue
Op.CallDataLoad: GasVeryLow callDataLoad
Op.CallDataSize: GasBase callDataSize
Op.CallDataCopy: GasBase callDataCopy
Op.CodeSize: GasBase codesize
Op.CodeCopy: GasBase codecopy
Op.ExtCodeSize: GasExtCode extCodeSize
Op.ExtCodeCopy: GasExtCode extCodeCopy
# block
Op.Blockhash: GasBase block_ops.blockhash
Op.Coinbase: GasCoinbase coinbase
Op.Timestamp: GasBase timestamp
Op.Number: GasBase number
Op.Difficulty: GasBase difficulty
Op.GasLimit: GasBase gaslimit
# stack
Op.Pop: GasBase stack_ops.pop
1..32 Op.PushXX: GasVeryLow pushXX # XX replaced by macro
1..16 Op.DupXX: GasVeryLow dupXX
1..16 Op.SwapXX: GasVeryLow swapXX
# memory
Op.MLoad: GasVeryLow mload
Op.MStore: GasVeryLow mstore
Op.MStore8: GasVeryLow mstore8
Op.MSize: GasBase msize
# storage
Op.SLoad: GasSload sload
Op.SStore: GasInHandler sstore
# flow
Op.Jump: GasMid jump
Op.JumpI: GasMid jumpi
Op.PC: GasHigh pc
Op.Gas: GasBase flow.gas
Op.JumpDest: GasJumpDest jumpdest
Op.Stop: GasZero stop
# logging
0..4 Op.LogXX: GasInHandler logXX
# invalid
Op.Invalid: GasZero invalidOp
# system
Op.Return: GasZero returnOp
Op.SelfDestruct: GasSelfDestruct selfdestruct
# call
OPCODE_TABLE[Op.Call] = Call(kind: Op.Call)
OPCODE_TABLE[Op.CallCode] = CallCode(kind: Op.CallCode)
OPCODE_TABLE[Op.DelegateCall] = DelegateCall(kind: Op.DelegateCall)
# system
OPCODE_TABLE[Op.Create] = Create(kind: Op.Create)
##### After
const
OpLogic: Table[Op, proc(computation: var BaseComputation){.nimcall.}] = {
# 0s: Stop and Arithmetic Operations
STOP: stop, # 0
ADD: arithmetic.add, # 1
MUL: mul, # 2
SUB: sub, # 3
DIV: divide, # 4
SDIV: sdiv, # 5
MOD: modulo, # 6
SMOD: smod, # 7
ADDMOD: arithmetic.addmod, # 8
MULMOD: arithmetic.mulmod, # 9
EXP: arithmetic.exp, # 10
SIGNEXTEND: signextend, # 11
# 10s: Comparison & Bitwise Logic Operations
LT: lt, # 16
GT: gt, # 17
SLT: slt, # 18
SGT: sgt, # 19
EQ: eq, # 20
ISZERO: comparison.isZero, # 21
AND: andOp, # 22
OR: orOp, # 23
XOR: xorOp, # 24
NOT: notOp, # 25
BYTE: byteOp, # 26
# 20s: SHA3
SHA3: sha3op, # 32
# 30s: Environmental Information
ADDRESS: context.address, # 48
BALANCE: balance, # 49
ORIGIN: context.origin, # 50
CALLER: caller, # 51
CALLVALUE: callValue, # 52
CALLDATALOAD: callDataLoad, # 53
CALLDATASIZE: callDataSize, # 54
CALLDATACOPY: callDataCopy, # 55
CODESIZE: codesize, # 56
CODECOPY: codecopy, # 57
GASPRICE: gasPrice, # 58 # TODO this wasn't used previously
EXTCODESIZE: extCodeSize, # 59
EXTCODECOPY: extCodeCopy, # 60
RETURNDATASIZE: returnDataSize, # 61 # TODO this wasn't used previously
RETURNDATACOPY: returnDataCopy, # 62
# 40s: Block Information
BLOCKHASH: block_ops.blockhash, # 64
COINBASE: block_ops.coinbase, # 65
TIMESTAMP: block_ops.timestamp, # 66
NUMBER: block_ops.number, # 67
DIFFICULTY: block_ops.difficulty, # 68
GASLIMIT: block_ops.gaslimit, # 69
# 50s: Stack, Memory, Storage and Flow Operations
POP: stack_ops.pop, # 80
MLOAD: mload, # 81
MSTORE: mstore, # 82
MSTORE8: mstore8, # 83
SLOAD: sload, # 84
SSTORE: sstore, # 85
JUMP: jump, # 86
JUMPI: jumpi, # 87
PC: pc, # 88
MSIZE: msize, # 89
GAS: flow.gas, # 90
JUMPDEST: jumpDest, # 91
# 60s & 70s: Push Operations
PUSH1: push1, # 96
PUSH2: push2, # 97
PUSH3: push3, # 98
PUSH4: push4, # 99
PUSH5: push5, # 100
PUSH6: push6, # 101
PUSH7: push7, # 102
PUSH8: push8, # 103
PUSH9: push9, # 104
PUSH10: push10,
PUSH11: push11,
PUSH12: push12,
PUSH13: push13,
PUSH14: push14,
PUSH15: push15,
PUSH16: push16,
PUSH17: push17,
PUSH18: push18,
PUSH19: push19,
PUSH20: push20,
PUSH21: push21,
PUSH22: push22,
PUSH23: push23,
PUSH24: push24,
PUSH25: push25,
PUSH26: push26,
PUSH27: push27,
PUSH28: push28,
PUSH29: push29,
PUSH30: push30,
PUSH31: push31,
PUSH32: push32,
# 80s: Duplication Operations
DUP1: dup1, # 128
DUP2: dup2, # 129
DUP3: dup3, # 130
DUP4: dup4, # 131
DUP5: dup5, # 132
DUP6: dup6, # 133
DUP7: dup7, # 134
DUP8: dup8, # 135
DUP9: dup9, # 136
DUP10: dup10, # 137
DUP11: dup11, # 138
DUP12: dup12, # 139
DUP13: dup13, # 140
DUP14: dup14, # 141
DUP15: dup15, # 142
DUP16: dup16, # 143
# 90s: Exchange Operations
SWAP1: swap1, # 144
SWAP2: swap2, # 145
SWAP3: swap3, # 146
SWAP4: swap4, # 147
SWAP5: swap5, # 148
SWAP6: swap6, # 149
SWAP7: swap7, # 150
SWAP8: swap8, # 151
SWAP9: swap9, # 152
SWAP10: swap10, # 153
SWAP11: swap11, # 154
SWAP12: swap12, # 155
SWAP13: swap13, # 156
SWAP14: swap14, # 157
SWAP15: swap15, # 158
SWAP16: swap16, # 159
# a0s: Logging Operations
LOG0: log0, # 160
LOG1: log1, # 161
LOG2: log2, # 162
LOG3: log3, # 163
LOG4: log4, # 164
# f0s: System operations
# CREATE: create, # 240
# CALL: call, # 241
# CALLCODE: callCode, # 242
RETURN: returnOp, # 243
# DELEGATECALL: delegateCall, # 244
# STATICCALL: staticCall, # 250
Op.REVERT: revert, # 253
INVALID: invalidOp, # 254
SELFDESTRUCT: selfDestruct # 255
}.toTable
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment