ethereum.forks.bpo5.vm.instructions.stackethereum.forks.amsterdam.vm.instructions.stack

Ethereum Virtual Machine (EVM) Stack Instructions.

.. contents:: Table of Contents :backlinks: none :local:

Introduction

Implementations of the EVM stack related instructions.

pop

Removes an item from the stack.

Parameters

evm : The current EVM frame.

def pop(evm: Evm) -> None:
30
    <snip>
39
    # STACK
40
    stack.pop(evm.stack)
41
42
    # GAS
43
    charge_gas(evm, GasCosts.OPCODE_POP)
44
45
    # OPERATION
46
    pass
47
48
    # PROGRAM COUNTER
49
    evm.pc += Uint(1)

push_n

Pushes an N-byte immediate onto the stack. Push zero if num_bytes is zero.

Parameters

evm : The current EVM frame.

num_bytes : The number of immediate bytes to be read from the code and pushed to the stack. Push zero if num_bytes is zero.

def push_n(evm: Evm, ​​num_bytes: int) -> None:
53
    <snip>
66
    # STACK
67
    pass
68
69
    # GAS
70
    if num_bytes == 0:
71
        charge_gas(evm, GasCosts.OPCODE_PUSH0)
72
    else:
73
        charge_gas(evm, GasCosts.OPCODE_PUSH)
74
75
    # OPERATION
76
    data_to_push = U256.from_be_bytes(
77
        buffer_read(evm.code, U256(evm.pc + Uint(1)), U256(num_bytes))
78
    )
79
    stack.push(evm.stack, data_to_push)
80
81
    # PROGRAM COUNTER
82
    evm.pc += Uint(1) + Uint(num_bytes)

dup_n

Duplicates the Nth stack item (from top of the stack) to the top of stack.

Parameters

evm : The current EVM frame.

item_number : The stack item number (0-indexed from top of stack) to be duplicated to the top of stack.

def dup_n(evm: Evm, ​​item_number: int) -> None:
86
    <snip>
99
    # STACK
100
    pass
101
102
    # GAS
103
    charge_gas(evm, GasCosts.OPCODE_DUP)
104
    if item_number >= len(evm.stack):
105
        raise StackUnderflowError
106
    data_to_duplicate = evm.stack[len(evm.stack) - 1 - item_number]
107
    stack.push(evm.stack, data_to_duplicate)
108
109
    # PROGRAM COUNTER
110
    evm.pc += Uint(1)

swap_n

Swaps the top and the item_number element of the stack, where the top of the stack is position zero.

If item_number is zero, this function does nothing (which should not be possible, since there is no SWAP0 instruction).

Parameters

evm : The current EVM frame.

item_number : The stack item number (0-indexed from top of stack) to be swapped with the top of stack element.

def swap_n(evm: Evm, ​​item_number: int) -> None:
114
    <snip>
131
    # STACK
132
    pass
133
134
    # GAS
135
    charge_gas(evm, GasCosts.OPCODE_SWAP)
136
    if item_number >= len(evm.stack):
137
        raise StackUnderflowError
138
    evm.stack[-1], evm.stack[-1 - item_number] = (
139
        evm.stack[-1 - item_number],
140
        evm.stack[-1],
141
    )
142
143
    # PROGRAM COUNTER
144
    evm.pc += Uint(1)

push0

147
push0: Callable[[Evm], None] = partial(push_n, num_bytes=0)

push1

148
push1: Callable[[Evm], None] = partial(push_n, num_bytes=1)

push2

149
push2: Callable[[Evm], None] = partial(push_n, num_bytes=2)

push3

150
push3: Callable[[Evm], None] = partial(push_n, num_bytes=3)

push4

151
push4: Callable[[Evm], None] = partial(push_n, num_bytes=4)

push5

152
push5: Callable[[Evm], None] = partial(push_n, num_bytes=5)

push6

153
push6: Callable[[Evm], None] = partial(push_n, num_bytes=6)

push7

154
push7: Callable[[Evm], None] = partial(push_n, num_bytes=7)

push8

155
push8: Callable[[Evm], None] = partial(push_n, num_bytes=8)

push9

156
push9: Callable[[Evm], None] = partial(push_n, num_bytes=9)

push10

157
push10: Callable[[Evm], None] = partial(push_n, num_bytes=10)

push11

158
push11: Callable[[Evm], None] = partial(push_n, num_bytes=11)

push12

159
push12: Callable[[Evm], None] = partial(push_n, num_bytes=12)

push13

160
push13: Callable[[Evm], None] = partial(push_n, num_bytes=13)

push14

161
push14: Callable[[Evm], None] = partial(push_n, num_bytes=14)

push15

162
push15: Callable[[Evm], None] = partial(push_n, num_bytes=15)

push16

163
push16: Callable[[Evm], None] = partial(push_n, num_bytes=16)

push17

164
push17: Callable[[Evm], None] = partial(push_n, num_bytes=17)

push18

165
push18: Callable[[Evm], None] = partial(push_n, num_bytes=18)

push19

166
push19: Callable[[Evm], None] = partial(push_n, num_bytes=19)

push20

167
push20: Callable[[Evm], None] = partial(push_n, num_bytes=20)

push21

168
push21: Callable[[Evm], None] = partial(push_n, num_bytes=21)

push22

169
push22: Callable[[Evm], None] = partial(push_n, num_bytes=22)

push23

170
push23: Callable[[Evm], None] = partial(push_n, num_bytes=23)

push24

171
push24: Callable[[Evm], None] = partial(push_n, num_bytes=24)

push25

172
push25: Callable[[Evm], None] = partial(push_n, num_bytes=25)

push26

173
push26: Callable[[Evm], None] = partial(push_n, num_bytes=26)

push27

174
push27: Callable[[Evm], None] = partial(push_n, num_bytes=27)

push28

175
push28: Callable[[Evm], None] = partial(push_n, num_bytes=28)

push29

176
push29: Callable[[Evm], None] = partial(push_n, num_bytes=29)

push30

177
push30: Callable[[Evm], None] = partial(push_n, num_bytes=30)

push31

178
push31: Callable[[Evm], None] = partial(push_n, num_bytes=31)

push32

179
push32: Callable[[Evm], None] = partial(push_n, num_bytes=32)

dup1

181
dup1: Callable[[Evm], None] = partial(dup_n, item_number=0)

dup2

182
dup2: Callable[[Evm], None] = partial(dup_n, item_number=1)

dup3

183
dup3: Callable[[Evm], None] = partial(dup_n, item_number=2)

dup4

184
dup4: Callable[[Evm], None] = partial(dup_n, item_number=3)

dup5

185
dup5: Callable[[Evm], None] = partial(dup_n, item_number=4)

dup6

186
dup6: Callable[[Evm], None] = partial(dup_n, item_number=5)

dup7

187
dup7: Callable[[Evm], None] = partial(dup_n, item_number=6)

dup8

188
dup8: Callable[[Evm], None] = partial(dup_n, item_number=7)

dup9

189
dup9: Callable[[Evm], None] = partial(dup_n, item_number=8)

dup10

190
dup10: Callable[[Evm], None] = partial(dup_n, item_number=9)

dup11

191
dup11: Callable[[Evm], None] = partial(dup_n, item_number=10)

dup12

192
dup12: Callable[[Evm], None] = partial(dup_n, item_number=11)

dup13

193
dup13: Callable[[Evm], None] = partial(dup_n, item_number=12)

dup14

194
dup14: Callable[[Evm], None] = partial(dup_n, item_number=13)

dup15

195
dup15: Callable[[Evm], None] = partial(dup_n, item_number=14)

dup16

196
dup16: Callable[[Evm], None] = partial(dup_n, item_number=15)

swap1

198
swap1: Callable[[Evm], None] = partial(swap_n, item_number=1)

swap2

199
swap2: Callable[[Evm], None] = partial(swap_n, item_number=2)

swap3

200
swap3: Callable[[Evm], None] = partial(swap_n, item_number=3)

swap4

201
swap4: Callable[[Evm], None] = partial(swap_n, item_number=4)

swap5

202
swap5: Callable[[Evm], None] = partial(swap_n, item_number=5)

swap6

203
swap6: Callable[[Evm], None] = partial(swap_n, item_number=6)

swap7

204
swap7: Callable[[Evm], None] = partial(swap_n, item_number=7)

swap8

205
swap8: Callable[[Evm], None] = partial(swap_n, item_number=8)

swap9

206
swap9: Callable[[Evm], None] = partial(swap_n, item_number=9)

swap10

207
swap10: Callable[[Evm], None] = partial(swap_n, item_number=10)

swap11

208
swap11: Callable[[Evm], None] = partial(swap_n, item_number=11)

swap12

209
swap12: Callable[[Evm], None] = partial(swap_n, item_number=12)

swap13

210
swap13: Callable[[Evm], None] = partial(swap_n, item_number=13)

swap14

211
swap14: Callable[[Evm], None] = partial(swap_n, item_number=14)

swap15

212
swap15: Callable[[Evm], None] = partial(swap_n, item_number=15)

swap16

213
swap16: Callable[[Evm], None] = partial(swap_n, item_number=16)

dupn

Duplicate the Nth stack item (from top of the stack) to the top of stack. The item number is read from the immediate byte following the opcode and decoded using the EIP-8024 index shifting rules.

Parameters

evm : The current EVM frame.

def dupn(evm: Evm) -> None:
217
    <snip>
228
    # STACK
229
    pass
230
231
    # GAS
232
    charge_gas(evm, GasCosts.OPCODE_DUPN)
233
234
    # OPERATION
235
    immediate_data = U8(
236
        buffer_read(evm.code, U256(evm.pc + Uint(1)), U256(1))[0]
237
    )
238
    item_number = decode_single(immediate_data)
239
    if int(item_number) > len(evm.stack):
240
        raise StackUnderflowError
241
    data_to_duplicate = evm.stack[-item_number]
242
    stack.push(evm.stack, data_to_duplicate)
243
244
    # PROGRAM COUNTER
245
    evm.pc += Uint(2)

swapn

Swap the top stack item with the Nth stack item. The value N is read from the immediate byte following the opcode and decoded using the EIP-8024 index shifting rules.

Parameters

evm : The current EVM frame.

def swapn(evm: Evm) -> None:
249
    <snip>
260
    # STACK
261
    pass
262
263
    # GAS
264
    charge_gas(evm, GasCosts.OPCODE_SWAPN)
265
266
    # OPERATION
267
    immediate_data = U8(
268
        buffer_read(evm.code, U256(evm.pc + Uint(1)), U256(1))[0]
269
    )
270
    item_number = decode_single(immediate_data)
271
    # SWAPN with decoded value n swaps top (position 1) with position (n+1)
272
    if int(item_number) + 1 > len(evm.stack):
273
        raise StackUnderflowError
274
    # stack[-1] is top (position 1), stack[-(item_number+1)] is position (n+1)
275
    evm.stack[-1], evm.stack[-(item_number + U8(1))] = (
276
        evm.stack[-(item_number + U8(1))],
277
        evm.stack[-1],
278
    )
279
280
    # PROGRAM COUNTER
281
    evm.pc += Uint(2)

exchange

Exchange the Nth stack item with the Mth stack item. The values N and M are decoded from the immediate byte using the EIP-8024 index shifting rules.

Parameters

evm : The current EVM frame.

def exchange(evm: Evm) -> None:
285
    <snip>
296
    # STACK
297
    pass
298
299
    # GAS
300
    charge_gas(evm, GasCosts.OPCODE_EXCHANGE)
301
302
    # OPERATION
303
    immediate_data = U8(
304
        buffer_read(evm.code, U256(evm.pc + Uint(1)), U256(1))[0]
305
    )
306
    n, m = decode_pair(immediate_data)
307
    # EXCHANGE swaps position (n+1) with position (m+1)
308
    depth = max(n, m) + U8(1)
309
    if int(depth) > len(evm.stack):
310
        raise StackUnderflowError
311
    evm.stack[-(n + U8(1))], evm.stack[-(m + U8(1))] = (
312
        evm.stack[-(m + U8(1))],
313
        evm.stack[-(n + U8(1))],
314
    )
315
316
    # PROGRAM COUNTER
317
    evm.pc += Uint(2)