Here’s a walk-through of the concept.
-
we have three shards: A B C
-
When an EE is deployed, it is exists on all shards. Same code, but a different balance and different stateroot on each shard. (Not all conceptions of “EE” are like this, sometimes the term “EE” is used to describe accounts with (code, stateroot, balance) that are deployed to a single shard).
-
for each EE, each shard maintains a balance map like this:
A: [1, 0, 0]
. -
we can visualize the global balance map for an EE as a matrix, but note that it is not maintained in whole anywhere. Rather, each shard maintains one row.
A B C
A [1, 0, 0]
B [0, 0, 0]
C [0, 0, 0]
- this is the map(s) for an EE with a starting balance = 1 ETH on shard A.
same-EE/cross-shard transfers
Same-EE/cross-shard transfers are done by updating the map on the sending shard shard[s1]
; the map on the receiving shard shard[s2]
is not updated. In code: shard[s1].balances[s1][ee] -= xfer_amount
and shard[s1].balances[s2][ee] += xfer_amount
- in a block on shard A there’s a txn that transfers 1 ETH to the same EE on shard B. Only the map stored on shard A is updated (Row A), shard B is not aware of this transfer.
A B C
A [0, 1, 0]
B [0, 0, 0]
C [0, 0, 0]
- in a block on shard B there’s a txn that transfers 1 ETH from B to C (in the same EE). only Row B is updated:
A B C
A [0, 1, 0]
B [0, -1, 1]
C [0, 0, 0]
Note that the text doesn’t mention any checks or proofs to do same-EE/cross-shard transfers, perhaps because the operation of adding -1 to the sending cell (row B, col B in the previous example) and +1 in the receiving cell (row B, col C) keeps the EE’s total balance constant. It does say that the “real balance should always remain non-negative”, but it doesn’t say how. If same-EE/cross-shard transfers are allowed without any proofs, then any particular column could become negative.
cross-EE/same-shard transfers
For cross-EE transfers, the protocol requires proof of an EE’s balance across shards (“real balance”).
To perform any transfers of ETH between EEs in a block, the shard must contain a Merkle proof from the most recent state of every shard, showing
shard[i].balances[s][x]
for every shard i to prove the total balance of the EE. … we check thatreal_balance(s, ee_1) >= xfer_amount
.
Take the map from the previous section:
A B C
A [0, 1, 0]
B [0, -1, 1]
C [0, 0, 0]
-
to calculate the “real balance” on a shard, you add up the column. The real balance on shard C is 1, A and B have 0.
-
In the
real_balance()
formula,i
corresponds to rows in the matrix ands
to a column. So real_balance(shard_s, ee_x) is a proof for columns
.
real\_balance(shard, ee) = \sum_{i=0}^{shard\_count} shard[i].balances[s][x]
- If same-EE/cross-shard transfers are allowed without any proofs, then checking
real_balance(shard_s, ee_x)
is not sufficient because any particular column might be negative. However, proof of all columns (i.e. thereal_balance()
proofs for all shards, not just shards
) could be used to show that the total EE balance is non-negative.
We thus have two versions:
-
version A: same-EE/cross-shard transfers do not require any proofs. cross-EE/same-shard transfers require proof of total EE value, i.e.
real_balance()
proofs for all shards. -
version B: same-EE/cross-shard transfers require a real_balance() proof for the sending shard. cross-EE/same-shard also require a real_balance() proof for the sending shard.
I guess the text is describing version B.
Continuing on, here’s how the balance maps would look before and after a cross-EE/same-shard transfer.
-before Txn-
AliceEE BobEE
A B C A B C
A [0, 1, 0] A [0, 0, 0]
B [0, -1, 1] B [0, 0, 0]
C [0, 0, 0] C [0, 0, 0]
Let’s send the 1 ETH we have in AliceEE on shard C, to BobEE on shard C. To perform the transfer, update two maps (AliceEE and BobEE) for the shard we’re on. In code: we check that real_balance(s, ee_1) >= xfer_amount
, then set shard[s].balances[s][ee_1] -= xfer_amount
and shard[s].balances[s][ee_2] += xfer_amount
-after Txn-
AliceEE BobEE
A B C A B C
A [0, 1, 0] A [0, 0, 0]
B [0, -1, 1] B [0, 0, 0]
C [0, 0, -1] C [0, 0, 1]