Module 4 - EVM
Module 4 - EVM
IPMac 2022
Contents
1. Introduction Appendix A : Implementation
- Blockchain - Source code in Geth
- World state - EVM developer utility
- Account - Solidity ABI
- Transaction
- Message Appendix B : User interface
- Decentralised database - Web3 API
- Atomicity and order - Geth, Mist, Solc, Remix, Truffle, ...
Blockchain
A transaction-based state machine
Transaction
Transaction
Block
Transaction T1
Transaction T2
Transaction T3
Transaction T1 Transaction T4
Transaction T2 Transaction T5
Transaction T3 Transaction T6
Transaction T1 Transaction T4
Transaction T2 Transaction T5
Transaction T3 Transaction T6
Transaction
Transaction
Transaction
Block b+1 Transaction
Transaction
Block b Transaction
: Transaction
Transaction
Transaction
Block 6 Transaction
Transaction
Transaction
Block 5 Transaction
Transaction
Transaction
Block 4 Transaction
Transaction
Transaction
Transaction
Transaction
Transaction
Block 3
Transaction
Transaction
Transaction
Block 2
Transaction
Transaction
Block 1
Genesis block
World state
World state
World state s t
: :
World state
: :
World state
Account 1
Account 2
Object view
:
Account n
Account
Account
World state
Account 1
Account 2
Account 3
World state
Account
: :
Account
Account state
Address nonce
balance
storage hash
EVM code
External actor
World state
Autonomous object
World state
code
Private key
Address Address
Transaction
A transaction
Block
Transaction
Transaction
Transaction
External actor
Transaction
Ethereum world
World state
Create
Contract Message
EOA EOA or CA
account
There are two practical types of transaction, contract creation and message call.
Transaction
init code
: : : :
code storage
Transaction
input data
: : : :
Transaction
nonce
gasPrice
gasLimit
160 bits address or 0 if contract creation
to
v, r, s
Message
Message
World state
Account A Account B
Message
Transaction
Message Message
EOA Account Contract
Account
account
EVM code
Transaction
Message EOA
EOA EOA
To EOA
Message
CA
code
Transaction
EOA
Message
To CA
Message
CA CA CA
code
Decentralised database
Globally shared, transactional database
World state
World state
World state
World state
World state
P2P
network
World state
World state
P2P
References : [E3],
Interface to a node
External
actor
Ethereum
world World state
Transaction
Transaction or Transaction
order (timing)
Transaction
Transaction Transaction
Transaction
Blockchain
External actor A
3rd submitted
Transaction
External actor B
1st submitted 2nd submitted
Transaction Transaction
order (timing)
??? ???
Transaction Transaction Transaction
Blockchain
sender
sender sender
Transaction B
Transaction A Transaction C
Transaction
Transaction A Transaction C
pool
Transaction B
determined
by miner
Transaction C
Transaction A ordered
Transaction B
Block
Winner
miner miner miner
fast
selected by PoW
Transaction T1 Transaction T4
Transaction T2 Transaction T5
Transaction T3 Transaction T6
EVM
(Ethereum Virtual Machine)
The Ethereum Virtual Machine is the runtime environment for smart contracts in Ethreum.
Virtual ROM
EVM code
(immutable)
Gas available
Gas
256 bits x 1024 elements byte addressing 256 bits to 256 bits
linear memory key-value store
Stack
256-bit read/write
:
operation with 16 elements
in stack top : 1024 elements
256 bits
Memory
256-bit load
:
256-bit store
or
8-bit store
8 bits
(Account) storage
Key 1 Value 1
Key2 Value 2
256-bit load/store
: :
Key n Value n
PUSH1 e0
PUSH1 02
EXP 0x60e060020a600035...
PUSH1 00
CALLDATALOAD
:
EVM Code is the bytecode that the EVM can natively execute.
EVM code
instructions
Stack Memory
random
access
Gas avail
(Account) storage
random
access
References : [E1] Ch.9, Appendix H
2. Virtual machine
Message call
Message call
World state
EOA
Contract account
Message
EVM code
Contract account
Message
EVM code
input data
arguments
CALL instruction
EVM EVM
Exception
Exception
Transaction
input data
Exception
EVM
ToDo: Refine this page
invalid
jump destination EVM code
invalid
instruction
Stack Memory
PC operations
Gas avail
Storage
out-of-gas stack underflow
World state
EOA
Gas supply
Message
Contract account
Refund
Gas
EVM code
EVM code
more
Gas
Message call
Stack Memory
PC operations
Storage
more
Gas
External
actor
Transaction
Message call
EVM EVM
return value
input data
CALLDATALOAD CALLDATACOPY
Stack Memory
EVM
Byte order
Endian for Memory
MSB LSB
Stack
MSB LSB
Stack
CALLDATALOAD or CALLDATACOPY
MSB LSB
Stack
or
Memory
Nth byte
0 1 ... 31
...
Stack
MSB LSB
Nth byte
31 ... 1 0
...
Stack
MSB LSB
Nth byte
31 ... 1 0
Stack ...
PUSH1 0x01 01
right-aligned, big endian
MSB LSB
Nth byte
31 ... 1 0
PUSH4 0x01020304 Stack ... 01 02 03 04
right-aligned, big endian
MSB LSB
Nth byte
31 ... 1 0
MSB LSB
right-aligned, big endian
Instruction set
Instruction set
* Hash
* SHA3
* Shift operation
* using MUL or DIV, SDIV
* Div operation
* without zero divisional exception
* ...
input data
CALLDATALOAD CALLDATACOPY
Stack Memory
CODECOPY
EXTCODECOPY
EVM EVM
Left shift
MSB LSB
Stack
MUL m (2^n) == m << n
Right shift
MSB LSB
Stack DIV m (2^n) == m >> n
Miscellaneous
EVM code generation
EVM code
References : [E7]
Ethereum virtual machine layer
software
[core/types/block.go]
Block header
type Header struct {
ParentHash common.Hash `json:"parentHash" gencodec:"required"`
UncleHash common.Hash `json:"sha3Uncles" gencodec:"required"`
Root of State
Coinbase common.Address `json:"miner" gencodec:"required"`
Root common.Hash `json:"stateRoot" gencodec:"required"`
TxHash common.Hash `json:"transactionsRoot" gencodec:"required"`
ReceiptHash common.Hash `json:"receiptsRoot" gencodec:"required"`
Root of Transaction
Bloom Bloom `json:"logsBloom" gencodec:"required"`
Difficulty *big.Int `json:"difficulty" gencodec:"required"`
Number *big.Int `json:"number" gencodec:"required"`
GasLimit uint64 `json:"gasLimit" gencodec:"required"`
GasUsed uint64 `json:"gasUsed" gencodec:"required"`
Time *big.Int `json:"timestamp" gencodec:"required"`
Extra []byte `json:"extraData" gencodec:"required"`
MixDigest common.Hash `json:"mixHash" gencodec:"required"`
Nonce BlockNonce `json:"nonce" gencodec:"required"`
}
References : [C1]
Transaction
(go-ethereum version 1.8)
[core/types/transaction.go]
Transaction
type txdata struct {
AccountNonce uint64 `json:"nonce" gencodec:"required"`
Price *big.Int `json:"gasPrice" gencodec:"required"`
GasLimit uint64 `json:"gas" to address
gencodec:"required"`
Recipient *common.Address `json:"to" rlp:"nil"`
// nil means contract creation
Amount *big.Int `json:"value" gencodec:"required"`
Payload []byte `json:"input" value (Wei)
gencodec:"required"`
References : [C1]
World state
(go-ethereum version 1.8)
[core/state/statedb.go]
World state
type StateDB struct {
db Database
trie Trie
Mapping for
Address to Account state
stateObjects map[common.Address]*stateObject
stateObjectsDirty map[common.Address]struct{}
dbErr error
refund uint64
preimages map[common.Hash][]byte
References : [C1]
Account object (state object)
(go-ethereum version 1.8)
[core/state/state_object.go]
dbErr error
References : [C1]
Account state, Code and Storage
(go-ethereum version 1.8)
[core/state/state_object.go]
References : [C1]
Stack and Memory
(go-ethereum version 1.8)
[core/vm/stack.go]
[core/vm/memory.go]
References : [C1]
Instruction operation (arithmetic and stack)
(go-ethereum version 1.8)
[core/vm/instruction.go]
Arithmetic operation
func opAdd(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack)
([]byte, error) {
x, y := stack.pop(), stack.pop()
stack.push(math.U256(x.Add(x, y)))
evm.interpreter.intPool.put(y)
Stack operation
func opPop(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack)
([]byte, error) {
evm.interpreter.intPool.put(stack.pop())
return nil, nil
}
References : [C1]
Instruction operation (memory and storage)
(go-ethereum version 1.8)
[core/vm/instruction.go]
Memory operation
func opMload(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack
*Stack) ([]byte, error) {
offset := stack.pop()
val := new(big.Int).SetBytes(memory.Get(offset.Int64(), 32))
stack.push(val)
evm.interpreter.intPool.put(offset)
return nil, nil
}
Storage operation
func opSload(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack
*Stack) ([]byte, error) {
loc := common.BigToHash(stack.pop())
val := evm.StateDB.GetState(contract.Address(), loc).Big()
stack.push(val)
return nil, nil
}
References : [C1]
Instruction operation (call)
(go-ethereum version 1.8)
[core/vm/instruction.go]
Flow operation
func opCall(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack)
([]byte, error) {
// Pop gas. The actual gas in in evm.callGasTemp.
evm.interpreter.intPool.put(stack.pop())
gas := evm.callGasTemp
// Pop other call parameters.
addr, value, inOffset, inSize, retOffset, retSize := stack.pop(),
stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop()
toAddr := common.BigToAddress(addr)
value = math.U256(value)
// Get the arguments from the memory.
args := memory.Get(inOffset.Int64(), inSize.Int64())
if value.Sign() != 0 {
gas += params.CallStipend
}
ret, returnGas, err := evm.Call(contract, toAddr, args, gas, value)
if err != nil {
:
References : [C1]
Gas
(go-ethereum version 1.8)
[core/vm/gas.go]
const ( Gbase
GasQuickStep uint64 = 2
GasFastestStep uint64 = 3 Gverylow
GasFastStep uint64 = 5
GasMidStep uint64 = 8
GasSlowStep uint64 = 10
GasExtStep uint64 = 20
GasReturn uint64 = 0
GasStop uint64 = 0
GasContractByte uint64 = 200
)
[core/vm/gas_table.go]
func gasSStore(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem
*Memory, memorySize uint64) (uint64, error) {
var (
y, x = stack.Back(1), stack.Back(0)
val = evm.StateDB.GetState(contract.Address(),
:
References : [C1]
Interpreter
(go-ethereum version 1.8)
[core/vm/interpreter.go]
func (in *Interpreter) Run(contract *Contract, input []byte) (ret []byte, err
error) {
// Increment the call depth which is restricted to 1024
in.evm.depth++ increment call depth
defer func() { in.evm.depth-- }()
in.returnData = nil
if len(contract.Code) == 0 {
return nil, nil
}
var (
op OpCode // current opcode create Memory
mem = NewMemory() // bound memory
stack = newstack() // local stack create Stack
:
References : [C1]
ApplyTransaction
(go-ethereum version 1.8)
[core/state_processor.go]
References : [C1]
Version of EVM instruction set
(go-ethereum version 1.8)
[core/vm/interpreter.go]
case evm.ChainConfig().IsHomestead(evm.BlockNumber):
added instruction:
cfg.JumpTable = homesteadInstructionSet
DELEGATECALL
default:
cfg.JumpTable = frontierInstructionSet
:
[core/config.go]
var (
MainnetChainConfig = &ChainConfig{
ChainId: big.NewInt(1),
HomesteadBlock: big.NewInt(1150000),
DAOForkBlock: big.NewInt(1920000),
DAOForkSupport: true,
EIP150Block: big.NewInt(2463000),
EIP150Hash: common.HexToHash("0x2086799aeebeae135c246c65021c82b4e15a2c451340993a
EIP155Block: big.NewInt(2675000),
EIP158Block: big.NewInt(2675000),
ByzantiumBlock: big.NewInt(4370000),
:
References : [C1]
Bootstrap of EVM in Geth
(go-ethereum version 1.8)
ApplyMessage [core/state_transaction.go]
TransactionDb [core/state_transaction.go]
Call [core/vm/evm.go]
run [core/vm/evm.go]
create Memory
Run [core/vm/interpreter.go] create Stack
References : [C1]
Appendix A
$ cat sample.asm
push 0x1
push 0x2
add
$ cat sample.bin
6001600201
References : [C1]
Example of evm command
(go-ethereum version 1.8)
References : [C1]
Appendix A
Solidity ABI
Solidity Application Binary Interface
Function selector
(SHA-3 hash) Arguments, ...
CALLDATALOAD
CALLDATACOPY
CALLDATALOAD
function
dispatching
JUMPI
function A
function B
EVM
Web3 API
Web3 API and client
Web3 API
Ethereum
network World state
Geth console,
Mist, MetaMask,
Ethereum
Remix, Truffle, ...
client
Web3 API
Ethereum
Ethereum Ethereum Ethereum
network node node ... node
(Geth, Parity, ...) (Geth, Parity, ...) (Geth, Parity, ...)
P2P
Geth
Ethereum console
client
Web3 API
node
Web3 I/F
Ethereum
network
Ethereum
EVM ... P2P node
(Geth, Parity, ...)
P2P
References : [C1]
Mist
Mist
Ethereum
client
private key
Web3 API
Ethereum
Ethereum
network node
(Geth, Parity, ...)
References : [C3]
Solc
Solidity source
Solc
(Solidity compiler)
EVM code
Web3 API
Ethereum
Ethereum
network node
(Geth, Parity, ...)
References : [C2]
Remix
Remix
EVM
Ethereum JavaScript Injected Web3
client VM Web3 provider
MetaMask
Web3 API
Ethereum
network
References : [C5]
Truffle
Truffle
Ethereum console
client
Web3 API
Ethereum Ethereum
network Private chain node
(Geth, Parity, ...)
P2P
References : [C6]
References
References
[E1] Ethereum Yellow Paper
ETHEREUM: A SECURE DECENTRALISED GENERALISED TRANSACTION LEDGER
https://ethereum.github.io/yellowpaper/paper.pdf
[E2] Glossary
https://github.com/ethereum/wiki/wiki/Glossary
[W4] Porosity
https://www.comae.io/reports/dc25-msuiche-Porosity-Decompiling-Ethereum-Smart-Contracts.pdf
References
[C1] Go Ethereum
https://github.com/ethereum/go-ethereum
[C4] MetaMask
https://github.com/MetaMask/metamask-extension
[C5] Remix
https://github.com/ethereum/browser-solidity
[C6] Truffle
https://github.com/trufflesuite/truffle