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

  • Abstraction of transaction origin and signature EIP 86
  • Putting block hashes and state roots into the state EIP 96
  • Remove medstate from receipts EIP 98
  • Uncle mining incentive fix EIP 100
  • Bigint arithmetic EIP 101
  • Cheap throw EIP 140
  • Putting block hashes and state roots into the state EIP 166

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