The Grammar · Contracts Talking to Contracts · Week 8 · Checkpoint 17
Where the Lives Address
Checkpoint sixteen left `_implementation()` as a declaration with no body. Two files close it: sixty two lines that fill the hole with one call, and a library that keeps the answer at a number nobody counts up to. Read them and you can find any proxy's real contract in one slot.
14 steps~30 min3 nodes for your map
01 · The hole from last time
Checkpoint sixteen ended on an abstract function. `Proxy` knew how to hand a call on, but not where to hand it, because `_implementation()` was a declaration with no body at all: a name, a return type, and a semicolon where the braces should have been.
Line 15 inherits from that contract, and lines 48 to 50 are the body it was short of. Everything else in these two files is arranging for line 49 to have an answer.
02 · One call, and the hole is filled
Line 48 carries four words you have already met: `internal`, `view`, `virtual`, `override`. The body under it is one line long. It does not work the address out, it asks for it, from the library imported on line 7.
So the question moves one file sideways rather than being answered here. Before you follow it, settle what the last of those four words is doing, because the function it refers to was unusual.
Line 48 is marked `override`. Read against checkpoint sixteen, what does that word settle?
03 · The address arrives once, at construction
Line 34 takes the implementation address and a `bytes memory`, a pair you read together in checkpoint fifteen. Lines 35 to 37 refuse a construction that hands over no data, unless a contract below overrides the question asked on line 59.
Line 38 is where the address goes in. The same library line 49 reads from is handed it here, once, while the proxy is being built. Read through one library, written through the same one, and never touched directly in this file.
04 · Why not an ordinary variable
An `address public implementation;` would hold this perfectly well, and it is what you would reach for first. Lines 11 to 13 say why this file does not. The implementation's own code runs inside this contract's storage, and the implementation has variables of its own.
Those variables take the numbered places, counting from zero, in the order they are declared. So this address is deliberately put somewhere that counting will never reach, and the place is written down in a public document rather than picked per project.
05 · The library the proxy leans on
This is the file the proxy named on its line 7. Line 15 opens a library, which you read in checkpoint fourteen: no storage of its own, nothing deployed, functions carried around inside whoever uses them. Line 7 here imports the `Address` library you went through line by line last week.
Line 8 is the new one. `StorageSlot` is where the actual reaching into storage happens, and this file is the readable wrapper over it. The same arrangement `Address` had with `LowLevelCall`.
06 · A number that names a place
Line 21 is a `bytes32 internal constant`: thirty two bytes fixed when the contract is compiled and never written again. `constant` you met in Act two. What is new is what the number is for. Function first: a number that names one place in this contract's storage. The name: a slot.
Line 18 says where the number came from. Take `keccak256` of the text `eip1967.proxy.implementation`, subtract one, and write the result down. The code holds the answer rather than the sum, because hashing a fixed string gives a fixed number, and line 21 is that number.
07 · Reading the value at that place
Line 46 is what the proxy called. It takes nothing, returns an `address`, and is `view`, so it writes nothing and only looks. Line 47 hands the constant to `StorageSlot.getAddressSlot` and reads `.value` off whatever comes back.
Under that `.value` is an `assembly` block, the word from checkpoint sixteen. Function first: fetch the thirty two bytes sitting at exactly this slot number. The name: `sload`. Assigning to `.value` is the same move in reverse, and its name is `sstore`.
08 · The write, and what it asks first
Line 53 is `private`, so nothing outside this library reaches it. Line 54 asks the question you met in `Address`: how many bytes of code are deployed at this address. If the count is zero, line 55 refuses, and the error carries the address that was wrong.
Line 57 is the assignment, and it is line 47 written backwards. The same constant, the same `getAddressSlot`, `.value` on the left instead of the right. One slot, read in one line and written in one other.
09 · Checked, written, announced
Lines 67 to 76 are the function the proxy's constructor called on its line 38. It sets the implementation, announces it, and then either runs a delegate call with the data it was handed or checks that no wei came along for nothing.
Between them, three of the lines now on this board do everything these two files do with the address. Tap each one and read what it is for.
10 · What happens after the write
Lines 61 to 65 promise two things: a setup call when the data is not empty, and a refusal of `msg.value` when it is. Line 71 is that fork. Line 72 hands the data to the new implementation through `Address.functionDelegateCall`, the variant that library told you would need a checkpoint of its own.
It runs in this contract's storage, which is the point of the whole arrangement: the implementation sets its own variables at the numbered places while the address that found it sits where it does. Line 74 is the other branch, and it only looks at a number.
11 · A second slot, arranged the same way
Line 83 is a second constant, made the same way out of a different string, and lines 92 to 94 read it exactly as line 47 read the first. Below this window a third does the same for a beacon. Three names, three hashes, three places, and not one of them is a numbered slot.
Lines 88 to 90 are the part worth keeping. They tell a reader to fetch the value straight out of storage, and then print the slot number in full, so that nobody reading has to hash a string to find it.
12 · The comment is addressed to you
Lines 44 to 46 are written for somebody who has a proxy address and nothing else. They name a JSON-RPC call that reads one slot of one contract, and then print the slot number in full, the same thirty two bytes as line 21 of the library.
So the whole of this checkpoint fits inside one request. Hand that call the proxy's address and that number, and what comes back is the address line 49 will give the next call to, with no source and no explorer in between.
13 · What the slot tells you
Line 46 takes nothing and hands back an address, and line 47 is the whole of how it gets one. There is no other line in either file that answers `_implementation()`, so whatever sits at that slot is what the next call will be run against.
Which leaves one honest question about what you are holding when the answer comes back. Line 47 reads. Line 57 writes. They are one line each, and they happen in different transactions.
14 · One address, one number, one read
Two files. One fills in an abstract function with a single call and keeps nothing itself. The other keeps the answer at a number made by hashing a string, checks there is code before writing it, announces the change, and reads it back in one line.
Given any proxy of this shape, you now know exactly which place to read to find the contract that holds the logic. That is one request wide, and it is the most concretely useful thing this act has handed you.
BANK_DBowner: the bank
you2,400
what the app is actually showing you
BANK_DBowner: the bank ✍
you2,400their pen
you hold a claim. they hold the pen.
your digital life
BANK · you2,400the bank ✍
INSTAGRAM · you2.1M followersMeta ✍
STEAM · you134 gamesValve ✍
AIRLINE · you58,200 milesthe airline ✍
four tables. zero pens that are yours.
BANK_DBowner: the bank ✍
you2,400
DENIED ✗
try both pens
PLATFORM_DBowner: the platform ✍
her · 8 years2,000,000 followers
one automated decision away
your row stands on all three
FTX_DBowner: FTX ✍
you5 BTC
the row stayed. the backing did not.
CARD_DBowner: your bank ✍
TV you never bought−1,100
fraud reversal+1,100 ✓
someone holds the pen, so someone can fix it
?_DBowner: nobody
youstill yours?
can a table exist that nobody owns?
?_DBowner: ̶n̶o̶b̶o̶d̶y̶
you100
no owner, no pen, no trust?
keeper 1
you100
keeper 2
you100
keeper 3
you100
keeper 4
you100
keeper 5
you100
no THE copy, only copies.
keeper 2
you100
keeper 3
you100
keeper 4
you100
keeper 5
you100
your copy
you100
five copies. one of them is yours.
one attacker, ten thousand faces.
writing costs watts. faking voters buys nothing.
proof of work, burn energy to vote.
rewrite one line, break every lock after it.
the price buys trustlessness. the office already has trust.