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:
29
    """
30
    Removes an item from the stack.
31
32
    Parameters
33
    ----------
34
    evm :
35
        The current EVM frame.
36
37
    """
38
    # STACK
39
    stack.pop(evm.stack)
40
41
    # GAS
42
    charge_gas(evm, GasCosts.OPCODE_POP)
43
44
    # OPERATION
45
    pass
46
47
    # PROGRAM COUNTER
48
    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:
52
    """
53
    Pushes an N-byte immediate onto the stack. Push zero if num_bytes is zero.
54
55
    Parameters
56
    ----------
57
    evm :
58
        The current EVM frame.
59
60
    num_bytes :
61
        The number of immediate bytes to be read from the code and pushed to
62
        the stack. Push zero if num_bytes is zero.
63
64
    """
65
    # STACK
66
    pass
67
68
    # GAS
69
    if num_bytes == 0:
70
        charge_gas(evm, GasCosts.OPCODE_PUSH0)
71
    else:
72
        charge_gas(evm, GasCosts.OPCODE_PUSH)
73
74
    # OPERATION
75
    data_to_push = U256.from_be_bytes(
76
        buffer_read(evm.code, U256(evm.pc + Uint(1)), U256(num_bytes))
77
    )
78
    stack.push(evm.stack, data_to_push)
79
80
    # PROGRAM COUNTER
81
    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:
85
    """
86
    Duplicates the Nth stack item (from top of the stack) to the top of stack.
87
88
    Parameters
89
    ----------
90
    evm :
91
        The current EVM frame.
92
93
    item_number :
94
        The stack item number (0-indexed from top of stack) to be duplicated
95
        to the top of stack.
96
97
    """
98
    # STACK
99
    pass
100
101
    # GAS
102
    charge_gas(evm, GasCosts.OPCODE_DUP)
103
    if item_number >= len(evm.stack):
104
        raise StackUnderflowError
105
    data_to_duplicate = evm.stack[len(evm.stack) - 1 - item_number]
106
    stack.push(evm.stack, data_to_duplicate)
107
108
    # PROGRAM COUNTER
109
    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:
113
    """
114
    Swaps the top and the `item_number` element of the stack, where
115
    the top of the stack is position zero.
116
117
    If `item_number` is zero, this function does nothing (which should not be
118
    possible, since there is no `SWAP0` instruction).
119
120
    Parameters
121
    ----------
122
    evm :
123
        The current EVM frame.
124
125
    item_number :
126
        The stack item number (0-indexed from top of stack) to be swapped
127
        with the top of stack element.
128
129
    """
130
    # STACK
131
    pass
132
133
    # GAS
134
    charge_gas(evm, GasCosts.OPCODE_SWAP)
135
    if item_number >= len(evm.stack):
136
        raise StackUnderflowError
137
    evm.stack[-1], evm.stack[-1 - item_number] = (
138
        evm.stack[-1 - item_number],
139
        evm.stack[-1],
140
    )
141
142
    # PROGRAM COUNTER
143
    evm.pc += Uint(1)

push0

146
push0 = partial(push_n, num_bytes=0)

push1

147
push1 = partial(push_n, num_bytes=1)

push2

148
push2 = partial(push_n, num_bytes=2)

push3

149
push3 = partial(push_n, num_bytes=3)

push4

150
push4 = partial(push_n, num_bytes=4)

push5

151
push5 = partial(push_n, num_bytes=5)

push6

152
push6 = partial(push_n, num_bytes=6)

push7

153
push7 = partial(push_n, num_bytes=7)

push8

154
push8 = partial(push_n, num_bytes=8)

push9

155
push9 = partial(push_n, num_bytes=9)

push10

156
push10 = partial(push_n, num_bytes=10)

push11

157
push11 = partial(push_n, num_bytes=11)

push12

158
push12 = partial(push_n, num_bytes=12)

push13

159
push13 = partial(push_n, num_bytes=13)

push14

160
push14 = partial(push_n, num_bytes=14)

push15

161
push15 = partial(push_n, num_bytes=15)

push16

162
push16 = partial(push_n, num_bytes=16)

push17

163
push17 = partial(push_n, num_bytes=17)

push18

164
push18 = partial(push_n, num_bytes=18)

push19

165
push19 = partial(push_n, num_bytes=19)

push20

166
push20 = partial(push_n, num_bytes=20)

push21

167
push21 = partial(push_n, num_bytes=21)

push22

168
push22 = partial(push_n, num_bytes=22)

push23

169
push23 = partial(push_n, num_bytes=23)

push24

170
push24 = partial(push_n, num_bytes=24)

push25

171
push25 = partial(push_n, num_bytes=25)

push26

172
push26 = partial(push_n, num_bytes=26)

push27

173
push27 = partial(push_n, num_bytes=27)

push28

174
push28 = partial(push_n, num_bytes=28)

push29

175
push29 = partial(push_n, num_bytes=29)

push30

176
push30 = partial(push_n, num_bytes=30)

push31

177
push31 = partial(push_n, num_bytes=31)

push32

178
push32 = partial(push_n, num_bytes=32)

dup1

180
dup1 = partial(dup_n, item_number=0)

dup2

181
dup2 = partial(dup_n, item_number=1)

dup3

182
dup3 = partial(dup_n, item_number=2)

dup4

183
dup4 = partial(dup_n, item_number=3)

dup5

184
dup5 = partial(dup_n, item_number=4)

dup6

185
dup6 = partial(dup_n, item_number=5)

dup7

186
dup7 = partial(dup_n, item_number=6)

dup8

187
dup8 = partial(dup_n, item_number=7)

dup9

188
dup9 = partial(dup_n, item_number=8)

dup10

189
dup10 = partial(dup_n, item_number=9)

dup11

190
dup11 = partial(dup_n, item_number=10)

dup12

191
dup12 = partial(dup_n, item_number=11)

dup13

192
dup13 = partial(dup_n, item_number=12)

dup14

193
dup14 = partial(dup_n, item_number=13)

dup15

194
dup15 = partial(dup_n, item_number=14)

dup16

195
dup16 = partial(dup_n, item_number=15)

swap1

197
swap1 = partial(swap_n, item_number=1)

swap2

198
swap2 = partial(swap_n, item_number=2)

swap3

199
swap3 = partial(swap_n, item_number=3)

swap4

200
swap4 = partial(swap_n, item_number=4)

swap5

201
swap5 = partial(swap_n, item_number=5)

swap6

202
swap6 = partial(swap_n, item_number=6)

swap7

203
swap7 = partial(swap_n, item_number=7)

swap8

204
swap8 = partial(swap_n, item_number=8)

swap9

205
swap9 = partial(swap_n, item_number=9)

swap10

206
swap10 = partial(swap_n, item_number=10)

swap11

207
swap11 = partial(swap_n, item_number=11)

swap12

208
swap12 = partial(swap_n, item_number=12)

swap13

209
swap13 = partial(swap_n, item_number=13)

swap14

210
swap14 = partial(swap_n, item_number=14)

swap15

211
swap15 = partial(swap_n, item_number=15)

swap16

212
swap16 = 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:
216
    """
217
    Duplicate the Nth stack item (from top of the stack) to the top of stack.
218
    The item number is read from the immediate byte following the opcode and
219
    decoded using the EIP-8024 index shifting rules.
220
221
    Parameters
222
    ----------
223
    evm :
224
        The current EVM frame.
225
226
    """
227
    # STACK
228
    pass
229
230
    # GAS
231
    charge_gas(evm, GasCosts.OPCODE_DUPN)
232
233
    # OPERATION
234
    immediate_data = U8(
235
        buffer_read(evm.code, U256(evm.pc + Uint(1)), U256(1))[0]
236
    )
237
    item_number = decode_single(immediate_data)
238
    if int(item_number) > len(evm.stack):
239
        raise StackUnderflowError
240
    data_to_duplicate = evm.stack[-item_number]
241
    stack.push(evm.stack, data_to_duplicate)
242
243
    # PROGRAM COUNTER
244
    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:
248
    """
249
    Swap the top stack item with the Nth stack item.
250
    The value N is read from the immediate byte following the opcode and
251
    decoded using the EIP-8024 index shifting rules.
252
253
    Parameters
254
    ----------
255
    evm :
256
        The current EVM frame.
257
258
    """
259
    # STACK
260
    pass
261
262
    # GAS
263
    charge_gas(evm, GasCosts.OPCODE_SWAPN)
264
265
    # OPERATION
266
    immediate_data = U8(
267
        buffer_read(evm.code, U256(evm.pc + Uint(1)), U256(1))[0]
268
    )
269
    item_number = decode_single(immediate_data)
270
    # SWAPN with decoded value n swaps top (position 1) with position (n+1)
271
    if int(item_number) + 1 > len(evm.stack):
272
        raise StackUnderflowError
273
    # stack[-1] is top (position 1), stack[-(item_number+1)] is position (n+1)
274
    evm.stack[-1], evm.stack[-(item_number + U8(1))] = (
275
        evm.stack[-(item_number + U8(1))],
276
        evm.stack[-1],
277
    )
278
279
    # PROGRAM COUNTER
280
    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:
284
    """
285
    Exchange the Nth stack item with the Mth stack item.
286
    The values N and M are decoded from the immediate byte using the
287
    EIP-8024 index shifting rules.
288
289
    Parameters
290
    ----------
291
    evm :
292
        The current EVM frame.
293
294
    """
295
    # STACK
296
    pass
297
298
    # GAS
299
    charge_gas(evm, GasCosts.OPCODE_EXCHANGE)
300
301
    # OPERATION
302
    immediate_data = U8(
303
        buffer_read(evm.code, U256(evm.pc + Uint(1)), U256(1))[0]
304
    )
305
    n, m = decode_pair(immediate_data)
306
    # EXCHANGE swaps position (n+1) with position (m+1)
307
    depth = max(n, m) + U8(1)
308
    if int(depth) > len(evm.stack):
309
        raise StackUnderflowError
310
    evm.stack[-(n + U8(1))], evm.stack[-(m + U8(1))] = (
311
        evm.stack[-(m + U8(1))],
312
        evm.stack[-(n + U8(1))],
313
    )
314
315
    # PROGRAM COUNTER
316
    evm.pc += Uint(2)