Ethereum Transactions
Towards Metropolis
@tomusdrw
Tomasz Drwiega
Parity Technologies
<= THIS
Where do the transactions come from?
Transactions propagation
Node1 sends TX1
Node2 relays it
Transactions propagation
Node1 sends TX1
Miner includes it in a block.
Node2 relays it
Transactions propagation
Node1 sends TX1
Node2 DECIDES to relay it
Miner DECIDES to include it in a block.
Agenda
- What does the transaction look like?
- How the node decides what transactions to propagate?
- How the miner decides what transactions to mine?
- What are the changes in Metropolis?
What does the transaction need?
-
Sender?
-
Recipient?
-
Value?
Ethereum Transaction
-
Sender?
Not a part of the transaction, recovered from the signature (v, r, s) -
Recipient?
Optional, not needed for contract deployment. -
Value?
Currently yes, but not in future.
Ethereum Transaction
- Sender?
Not a part of the transaction, recovered from the signature (v, r, s) - Recipient?
Optional, not needed for contract deployment. - Value?
Currently yes, but not in future. -
Gas Price?
-
Gas (Limit)?
Ethereum Transaction
- Sender?
Not a part of the transaction, recovered from the signature (v, r, s) - Recipient?
Optional, not needed for contract deployment. - Value?
Currently yes, but not in future. -
Gas Price?
Currently yes. -
Gas (Limit)?
Yes! How much gas the transaction can use. Gas * GPrice = Fee.
Ethereum Transaction
- Sender?
Not a part of the transaction, recovered from the signature (v, r, s) - Recipient?
Optional, not needed for contract deployment. - Value?
Currently yes, but not in future. - Gas Price?
Currently yes. - Gas (Limit)?
Yes! How much gas the transaction can use. Gas * GPrice = Fee. -
Data!
Yes! Bytes to be read by contract, usually ETHABI encoded.
Ethereum Transaction
- Sender?
Not a part of the transaction, recovered from the signature (v, r, s) - Recipient?
Optional, not needed for contract deployment. - Value?
Currently yes, but not in future. - Gas Price?
Currently yes. -
Gas (Limit)?
Yes! How much gas the transaction can use. Gas * GPrice = Fee. - Data!
Yes! Bytes to be read by contract, usually ETHABI encoded. -
Nonce!
Currently yes. Why do we need it?
Ethereum Transaction
-
Defines the order of the transactions
Lower nonces need to be executed first. -
Prevents replaying the same transaction
Each nonce is valid only once. -
Nonce = number of transactions sent before
Nonce of any address is part of the State.
Transaction Nonce
Ethereum Transaction
Transaction:
nonce : u256
gas_price : u256
gas : u256
to | null : h160 (address)
value : u256
data : bytes
v : u64
r : u256
s : u256
Transactions in the network are encoded using RLP in this exact order (9 fields)
How do we decide what to propagate and mine?
Miner Strategy
Transaction:
nonce : u256
gas_price : u256
gas : u256
to | null : h160 (address)
value : u256
data : bytes
v : u64
r : u256
s : u256
A rational miner will try to maximise her's earnings.
So let's just order by fee: gas_price * gas
Note: Miner strategy is not part of the protocol!
Miner Strategy
But processing transaction takes time and it increases a chance to mine an uncle.
There is an equilibrium:
https://blog.ethereum.org/2016/10/31/uncle-rate-transaction-fee-analysis/
https://etherchain.org/statistics/gasPrice
Miner Strategy
Do you remember about nonce?
We must include transactions in order, despite the fee!
// We're ordering by "nonce height" first
Height=0:
Tx1(from=1, fee=3, nonce=0)
Tx3(from=2, fee=1, nonce=100)
Height=1:
Tx4(from=2, fee=2, nonce=101)
Tx2(from=1, fee=4, nonce=1)
Miner Strategy
The transactions may be received out of order.
What to do if we get a transaction with nonce=N+1 before none=N?
We cannot ignore them, cause they might never be propagated again.
Miner Strategy
We maintain two separate queues:
"current" and "future"
// Current
Height=0:
Tx1(from=1, fee=3, nonce=0)
Tx3(from=2, fee=1, nonce=100)
Height=1:
Tx4(from=2, fee=2, nonce=101)
Tx2(from=1, fee=4, nonce=1)
// Future
Height=3:
// awaiting tx with nonce=2
Tx5(from=1, fee=3, nonce=3)
Of course both queues should be limited.
(especially future queue)
What if one sets the gas price to 0?
Shall we have a gas price market?
Whitelisting contracts the users may invoke
(e.g. faucet contract).
Miner Strategy
We also need to validate correctness of the transaction.
- Check if the signature is correct.
- Check network ID (replay protection)
- Check if declared gas does not exceed current block gas limit.
- Check if the gas price is greater than minimal gas price (or contract is whitelisted).
Miner Strategy
What if the transaction uses more gas than declared?
- The transaction goes Out Of Gas (OOG).
- But it's still included in the blockchain, otherwise you could DDoS miners.
But we do verify minimal gas requirements:
21k + costOf(data)
Miner Strategy
We also need to check if user has enough balance.
// A has 5 ETH
Height=0:
Tx1(from=1, to=B, value=5)
Height=1:
Tx2(from=1, to=C, value=5)
But you cannot tell if the first one doesn't increase the balance without executing it!
Miner Strategy
What if someones sends two transactions with the same nonce?
// Fee is the same. Which one should we choose?
Tx1(from=A, nonce=0, gasPrice=1, gas=100) fee = 100
Tx2(from=A, nonce=0, gasPrice=2, gas=50) fee = 100
Miner Strategy
So how to "cancel" the transaction?
The transaction might become stalled and block subsequent transactions.
- Gas might exceed current block gas limit.
- Gas price might be to little.
Enough to propagate but not accepted by the miner.
Miner Strategy
So how to "cancel" the transaction?
You can *try* to replace transaction with no-op transactions and increase gas price.
Transaction:
from: A,
to: A,
value: 0,
gas: 21k,
gasPrice: ?,
Parity
-
--relay-set (cheap, strict)
-
--usd-per-tx
-
--tx-gas-limit
-
--refuse-service-transactions
Metropolis
Metropolis
Next stage of the Etherum project.
- Frontier, July 2015 ✓
- Homestead, March 2016 ✓
- Metropolis, Q2 2017
- Serenity
Metropolis
Metropolis
Currently:
nonce
gas_price
gas
to | null
value
data
v
r
s
Metropolis:
gas
to | null
data
network_id
Account Contract
# Get signature from tx data
sig_v = ~calldataload(0)
sig_r = ~calldataload(32)
sig_s = ~calldataload(64)
# Get tx arguments
tx_nonce = ~calldataload(96)
tx_to = ~calldataload(128)
tx_value = ~calldataload(160)
tx_gasprice = ~calldataload(192)
tx_data = string(~calldatasize() - 224)
~calldataload(tx_data, 224, ~calldatasize())
# Get signing hash
signing_data = string(~calldatasize() - 64)
~mstore(signing_data, tx.startgas)
~calldataload(signing_data + 32, 96, ~calldatasize() - 96)
signing_hash = sha3(signing_data:str)
# Perform usual checks
prev_nonce = ~sload(-1)
assert tx_nonce == prev_nonce + 1
assert self.balance >= tx_value + tx_gasprice * tx.startgas
assert ~ecrecover(signing_hash, sig_v, sig_r, sig_s) == <pubkey hash here>
# Update nonce
~sstore(-1, prev_nonce + 1)
# Pay for gas
~send(MINER_CONTRACT, tx_gasprice * tx.startgas)
# Make the main call
~call(msg.gas - 50000, tx_to, tx_value, tx_data, len(tx_data), 0, 0)
# Get remaining gas payments back
~call(20000, MINER_CONTRACT, 0, [msg.gas], 32, 0, 0)
Consequences
- Account can be abstracted to contract
Less stuff in the protocol - Contracts can pay for the execution
New users don't need to get initial ETH - Any replay protection (nonce)
Implemented in the contract - In-contract signature verification
Enables other signature schemes to be used instead of ECDSA - ETH becomes "just a token"
In principle miners could accept fee in any token
Challenges
Current miner strategy doesn't work at all!
Ideas:
- Pre-defined list of contracts (initially)
- On-chain whitelist?
- + Kind of "execute" the contract:
- Verify signature
- Verify gasPrice
- Verify nonce
- Verify balance
Challenges
We can also try to execute the transaction with some reasonable gas limit and check if you will get payed.
Problem: What if the state is reverted after that?
References
- Metropolis changes:
https://github.com/ethereum/pm/blob/master/All%20Core%20Devs%20Meetings/Meeting%209.md#agenda - EIP86/208 (Abstraction)
https://github.com/ethereum/EIPs/issues/86
https://github.com/ethereum/EIPs/pull/208 - EIP232 (Transaction format)
https://github.com/ethereum/EIPs/issues/232 - Dan's Intro to How Ethereum Works
https://www.youtube.com/watch?v=-SMliFtoPn8 - Mr Buterin's transaction inclusion analysis
https://blog.ethereum.org/2016/10/31/uncle-rate-transaction-fee-analysis/ - Why we shouldn't abstract economy by Mr Zamfir
https://medium.com/@Vlad_Zamfir/against-economic-abstraction-mitigating-possible-collateral-damage-ce8b939e808f
https://medium.com/@Vlad_Zamfir/against-economic-abstraction-round-2-21f5c4e77d54#.jwr377ystg
Thank You!
Questions?
@tomusdrw
Tomasz Drwiega
Ethereum Transactions
By Tomasz Drwięga
Ethereum Transactions
- 1,006