Toy Blocks

Our friends’ son is turning one year old. His parents, deep in the Silicon Valley tech world, would prefer to delay the point when screens become a major component of his entertainment. Fortunately, screens are a major component of my entertainment, and so Pinterest suggested the perfect gift: wooden blocks. But why buy, when you can
make?

I’ve hauled around a few large leftover hunks of maple from the bed I made. This one was a little over 1 3/4 inches thick. After consulting choking hazard regulations, and thinking about common children’s blocks, 1 3/4 inches seemed about right. I ripped two square-ish columns, and then sent them through the planer to square them up and smooth out the faces.

Each block is 2 5/8 inches tall: a lower, cube 1 3/4 on a side, plus a 45º “roof” half that height. Instead of cutting these columns into 2 5/8 inch segements, though, I cut them into twice that length, plus 1/8 inch (5 3/8 inches). The extra length gave me a better hold on the piece while I cut the angles on either end.

I attached a sacrificial extension to my miter gauge, to give me more support and reduce tear-out at the near side. The way I attached the extension, with a little clearance off the table, made it difficult to use my normal method of setting the angle. That is, if I set my try-square against the miter rail, the ruler of the square didn’t engage the extension. So instead I laid my framing square against the saw blade, and then set my miter so that the extension crossed the same marking on either leg – a 1-in-1 drop.

With the angle set, I lined up the first cut, and clamped a stop block in place at the other end of the piece. With that preparation, cutting all off the roof lines was a simple matter of placing the block against the stop, running it past the blade, flipping it over, and doing the same again. In no time, my floor was covered in off-cuts.

The final cut was to separate the two blocks in each segment. This was the reason for the extra 1/8 inch: that’s the kerf of my saw blade. With the mitre gauge set to 90º and a new stop block in place, I had a village assembled in no time.

My final bit of dust creation was to ease the edges and scrape off any marks with some 220-grit sandpaper. I call this one the “cathedral” formation:

With all shaping done, it was on to painting. I re-learned my lesson with my last project, and returned to taping stencils for this one. I wanted very simple patterns anyway; most often just a face or two painted, with an occasional simple geometry.

We used milk paint to keep the toxicity low. The red and green hues covered solidly mostly after just one coat. We added a second for evenness. The blue and yellow showed through a bit more, so we added a third coat to those. I think more even roughing with the sandpaper would have helped with adhesion, but I tried to go easy on the faces, since the grain figure was so nice right off the planer.

The milk paint dried with a slightly dusty texture. Wax coating is very common for milk paint projects, so I mixed up my usual beeswax and mineral oil finish. I mixed it a little stiffer than normal, which resulted in a moment when I was sure I had ruined the project.

The finish was too stiff when it cooled in its container. I heated it to make it spreadable, but as soon as it came in contact with the wood, it cooled into ugly clumps. We decided that if heating worked once, it could work again, so we put the blocks in a low oven for fifteen minutes.

It worked perfectly. The wax reflowed evenly, and a quick wipe to remove the excess is all that was needed. The wax also lightly glossed the dusty texture of the milk paint and the face of the raw wood.

The final step was to prepare some sort of container. We couldn’t drop a sixteen-piece toy in our friends’ laps without some way to organize it.

My wife designed and sewed a beautiful felt box to carry the set. We spent some time considering different options for closures, but ultimately settled on suede thongs loosely wrapping a large button. I love the simple look of it.

The gift has now been given, receiving smiles all around the room. He has already demonstrated his love for knocking down towers, so I think this toy will provide plenty of entertainment for a few years.

Project Box: Fit and Finish

The inside of this box is about 36 x 12 x 3 inches – not something that could just sit on a table for decoration. It was built for a purpose: carrying equipment. Let’s talk about how I prepared it to do that.

I wanted the items in this box to be held securely, so they wouldn’t rattle around and bump into each other. I decided to cut profiles of each piece into ribs that span the width. That process was: dry fitting, tracing profiles, roughing in with a coping saw, and then refining the fit with a file. The result was a framework custom fit to the intended contents.

box-build-fitting - 1.jpg

I also added a handle and lockable latches, to cover “held securely” from another perspective.

box-build-handle-latches - 1.jpg

With that, construction was complete. On to finishing! First, a bit of art, and your first real clue to the box’s purpose. A tip: many corporations publish a “press kit” on their website, that includes scalable versions of their logo. I found the logo I wanted, and printed a letter-paper size copy. I used a DIY carbon paper technique to transfer it to my lid: shade the back of the paper with pencil, secure it to the lid, then trace over the image with a pen.

box-build-tracing - 2.jpg

The logo is often used in yellow and blue, like the Swedish flag it represents. My wood is going to have a yellow tone to it, so I selected a dark blue paint for my work. I’m not a freehand painter, and I probably should have chosen to cut a stencil instead, but sometimes you have to experiment anyway.

box-build-logo-painted - 1.jpg

I wanted a finish that was easy to apply, and would offer a fair amount of protection. This box won’t see harsh conditions, but it will get knocked around a little, loading and unloading. I just happened to have some spray-on Minwax Helmsman, so that’s what I used. I covered the hardware with gaffers tape, so I could focus on spraying evenly, without worry about urethane seizing my hinges.

box-build-tape - 1.jpg

I propped the box on a tripod and applied two coats.

box-build-spray-finish - all.png

Once the finish dried, my only remaining task was fixing suede strips to the contact points on the supports. With those in place, my box was complete.

box-build-complete - 2.jpg

box-build-complete - 1.jpg

I’ve now used this box to carry my shotgun to the range several times, and it has worked quite well. The handle is a little narrow for the weight, and the weight is a little unbalanced, but on the whole, the box has served its purpose. It also stores well, sliding unobtrusively into a corner, efficiently using space. And, it provided a great platform for practice and experimentation with some techniques I plan to use in my next big project.

box-build-range-glamour - 1.jpg

Project Box: Planning

While I think about how to tell you about the process of fitting the internal components of this box, I’m going to talk about planning.

box-build-planning - 1.jpg

The image above is the whiteboard in my shop, as it was at the end of this project. I’ve lost some of the context about what each scribble meant, but there are three obvious diagrams: the dovetails, the hinges, and the latches and handle. None are to scale. None indicate relationships to each other. All were drawn at the moment they were needed.

It’s tempting to write about how this plan-as-you-go process is because of the nature of wood. The many ways different grain patterns can and cannot be used, and the inability to be sure of what you’ll find inside a slab, means that most projects end up needing to be adapted to fit as they progress.

But this incremental design is how all of my projects go. The basic structure of a program gets sketched and then adapted as I start to code. Presentations are outlined and then rearranged as I find each part needing a different fit in the story. Dinner plans come together on the cutting board. Road trips have a destination and, “Something like this road will probably work.”

I would make far fewer things if I designed the entire solution up-front. There is, of course, plenty of planning that happens before the first cuts are made. However, there is a point in the initial design of every project at which there are too many unknowns. My solution is often to bring the work near the point where the project is blocked without their decision. This brings clarity to the details surrounding the issue. Sometimes the details become so clear that the solution is obvious, and other times I learn that the question wasn’t even relevant.

There are two keys to this flow working. The first is enough familiarity with the domain to recognize which decisions are likely to doom a project if not addressed early. My box must have internal dimensions large enough for the things I intend to store in it. I must have yeast and two hours of lead time if I want to bake bread for dinner. Put another way, it must be possible to determine what can be left unknown.

The second key to this process is the confidence that I can solve the problems that will arise. I find this one key to my work, even if I’ve over-planned. Years of projects in many domains have taught me that I have to expect that I will make a mistake somewhere in either my plan or my execution. I’ve also learned from this experience that very few of these mistakes spell disaster.

So, a whiteboard hangs in my shop to provide a place for information to accumulate to clarify the unknowns, as needed.

Project Box: Hinges

This box was designed to be a carrying case, so the lid need to be hinged to the bottom. In keeping with the theme of cheap practice, I grabbed brass-colored, stamped hinges at the local Home Depot. Also in keeping with the theme, I watched Matt Estlea’s videos on preparing these hinges and chiseling mortises for them. The particular style of hinge I bought required a little change to the plan, but I’ll explain that in a bit. The mortising started with lines scribed for the edges of the hinge plate.

scribe lines

The first step in choping out the hinge was not cutting along these lines. Instead, it was chopping across the grain, 1/8″ to 3/16″ inside these lines.

cross chopping

With the grain sliced, it was easy to pare in from the edge, without any risk of splitting past my markings.

paring 1

A couple of rounds of chopping and pairing, and I had reached my desired depth.

depth reached

With that base defined, I could work my way back to the scribed lines carefully.

working back to lines

The hinge plate was a nice snug fit side-to-side, but this is where the style of hinge came into play. The hinge pin stuck out of either end, so I needed to cut relief for it as well.

hinge shoulders

shoulder relief

fully seated

After repeating that process seven more times, drilling, and screwing, my lid was attached.

box-build-hinges - 1

It closed quite closely. There wasn’t even enough room for some thin cork lining I was considering.

lid closed

The hinges protruded so little that the box had no trouble standing on that edge. I may add some feet at some point, just to protect them a bit anyway.

Project Box: Right in Two

Possibly even more exciting than my dovetails turning out well was the fact that, from the first dry fitting, the box was square. Corner to corner, any difference in the diagonals was less than my tape measure would read.

box-build-squareness - 1

I cut a panel groove in each side, and then cut panels just barely undersized, to allow seasonal play. That required some careful planning and router setup, to prevent the groove from showing at the end of a pin or tail. Once everything was ready, I glued the whole box shut.

box-build-paneled - 1

 

I had always wanted to try this next step. If you’ve been paying close attention to the photos, you’ve probably noticed that one of the dovetail pins was wider than the others. In fact, it was exactly 1/8″ wider, which happens to be the kerf my table saw cuts. To turn this permanently closed box into an opening box, I sawed right through the middle of that wide pin.

box-build-sawn - 1

I ran the short ends through the saw first, then each long side. See the small edge near the corner that tapers along that long side? That’s from the thin top pulling away from the bottom as the saw relieved tension behind it. The sudden edge near the corner is there because the top couldn’t do that while I was sawing the short end. There’s a matching taper on the opposite corner, where the back side did the same. About three passes with a plane brought it right down.

box-build-two-pieces - 1

Project Box: Dovetails

It’s not perfect. Looking at it, preparing to write about it, I see flaws all over. But, I’ve finally cut a dovetail I don’t consider horrible.

box-build-good-dovetail-1.jpg

For years this joint has eluded me. Always too tight off the saw, but filled with giant gaps once together. Results were no better with a router – in fact, I ruined a bit and took a nice chunk out of the jig while trying.

So what changed? Some of the expected: I have more practice, in general, and I treated myself to a few new tools. But, there are two elements that I think played roles at least as important.

Improvement number one came from Matt Estlea’s videos. My skill in following written directions is second to none. I’ve read several step-by-steps, and attempted to perform their processes faithfully. Yet somehow watching Matt do it, listening to him talk through all the things he’s thinking about as he’s thinking about them, just made some of the important steps click as I was doing it myself this time.

As just one specific example, I’ve never particularly liked sharpening. I’ve read how to do it properly. I’ve bought nice stones to do it with. My edges have turned out well when I’ve done it. But it has always felt like a major chore. Watching Matt explain the reason behind the two bevels, and then show that it really is just a few strokes on the finer stones to keep the cutting edge in good shape made it a super easy thing to do, as often as I wanted. Quick, easy sharpening meant I (almost) never wasted my energy forcing a dull chisel to do awful work.

The second major element in my improvement came from experimenting, and closer evaluation of each result. This project is a box, and thus called for four dovetails. For the first, I used my new tools, thought about what Matt had demonstrated, and was close right off the saw. After that, I fixed the joint in my usual way, but ended up sort of “meh” – not my worst, but not enough better to make me excited about doing more.

I analyzed what had gone wrong. The joint didn’t fit to start; the pins just wouldn’t go in. So, I trimmed the pins to make them fit. By the time I got them pushed through, though, there were gaps around their visible ends. There are two simple explanations for this problem: either I pared a taper into the pins (so their tips were smaller than their bases), or there was already a taper on the tails (so the holes for the pins are larger on the outside than the inside).

Either problem indicates an error in sawing. I need to fix that, but in an attempt to get a feel for my new saw, I had decided to do all of my sawing up front. I needed to find a better way to fit whatever I already had. So, what about trimming the place that won’t show instead? Bingo: shaving the inside of the tail instead of the outside of the pin produced a much tighter dovetail.

My final problem was how to move more quickly. Dovetails one and two each took an hour and a half or more. If I had sawn true, things would have been significantly quicker, but test fitting went slowly. It was hard to know where to trim. This is when I pulled another YouTube tip out of my history. Larry Potterfield perfects ill-fitting pieces all the time, by coating one piece in some sort of carbon black, fitting it to the other, and then taking them apart again to see where they touched.

Obviously I didn’t want to coat the entire end of my board in carbon, but just a few scribbles of pencil on the cheeks of the pins would never been seen. Each test fit left smudges on the tails exactly where the pieces touched, darker where they squeezed harder. This cut down the guesswork, both speeding up the process and making sure I wasn’t weakening the joint by removing wood from the wrong places.

Joint number three was the first dovetail I’ve cut that I’m actually not completely unhappy with. Dovetail four was almost as good. A little overconfidence, or a little eagerness to get onto the next part of the project, may have played a role in some small mistakes. I’ll know soon: the dovetails on this project are practice for a much bigger project on the horizon.

Ethereum Signature Verification

But there’s the trouble. To get back the address of the originating account, you have to have both the signature and the original field values. If you supply different field values, you don’t get, “This signature doesn’t match,” you get, “This transaction came from a completely different account.”

Disclaimer: The views in this article are my own, and do not necessarily represent the views of my employer.

As part of the blockchain work I’ve been doing, I’ve been examining designs of the popular existing networks. Ethereum had my attention this week, and I was digging into its transaction authentication mechanisms when I found something confusing. I think it’s easiest to demonstrate with quick example.

Say I’m running a private network, and I submit a transaction to transfer value 1000 from one account to another. I can do that like this:

> eth.getBalance("0xaf4be85b32868c5b7c121115ad8cd93e0ad4f14e")
2025000000000000
> eth.getBalance("0xfab48eb52368c8b5c7211151dac89de3a04d1fe4")
0
> var tx = {"from": "0xaf4be85b32868c5b7c121115ad8cd93e0ad4f14e", "to": "0xfab48eb52368c8b5c7211151dac89de3a04d1fe4", "value": 1000};
undefined
> eth.sendTransaction(tx);
INFO [07-06|08:56:59] Submitted transaction fullhash=0x79c78bb2da3f61ddb2b55ffc89158b4ed0aa06917aa7f3d3813693e4da6deafb recipient=0xFAb48eb52368C8b5c7211151daC89DE3A04D1Fe4
"0x79c78bb2da3f61ddb2b55ffc89158b4ed0aa06917aa7f3d3813693e4da6deafb"

Once the transaction gets mined, I can see the value has moved:

> eth.getTransactionReceipt("0x79c78bb2da3f61ddb2b55ffc89158b4ed0aa06917aa7f3d3813693e4da6deafb").blockNumber
1
> eth.getBalance("0xaf4be85b32868c5b7c121115ad8cd93e0ad4f14e")
1646999999999000 // gas*gasPrice = 378000000000000
> eth.getBalance("0xfab48eb52368c8b5c7211151dac89de3a04d1fe4")
1000

And I can see the raw transaction:

> eth.getRawTransaction("0x79c78bb2da3f61ddb2b55ffc89158b4ed0aa06917aa7f3d3813693e4da6deafb")
"0xf86980850430e2340083015f9094fab48eb52368c8b5c7211151dac89de3a04d1fe48203e880820348a0780d4ea898306e700cea578140cc4502d401c5949e7f4cab6a72c08a1a065aaba00cc22d63e2ef8acaaf1f6ead7a68de12e48a79f17d0a5ebab006fa996076ed53"

A key component of blockchains is that every transaction is signed by its issuer, and meddling with the details of the transaction will be obvious to all parties. Let’s verify that. Let’s try to resubmit that transaction, and have it transfer value 1001, which requires modifying just one bit:

//              original: 0xf86980850430e2340083015f9094fab48eb52368c8b5c7211151dac89de3a04d1fe48203e880820348a0780d4ea898306e700cea578140cc4502d401c5949e7f4cab6a72c08a1a065aaba00cc22d63e2ef8acaaf1f6ead7a68de12e48a79f17d0a5ebab006fa996076ed53
// >---modified-bit-is-out-here-------------------------------------------------------modified bit---|
> eth.sendRawTransaction("0xf86980850430e2340083015f9094fab48eb52368c8b5c7211151dac89de3a04d1fe48203e980820348a0780d4ea898306e700cea578140cc4502d401c5949e7f4cab6a72c08a1a065aaba00cc22d63e2ef8acaaf1f6ead7a68de12e48a79f17d0a5ebab006fa996076ed53")
INFO [07-06|09:14:25] Submitted transaction fullhash=0xa06d51ff57bc41d33c812f08bdb65641db7581d97bd1d524fc8d0dd448a2aa9a recipient=0xFAb48eb52368C8b5c7211151daC89DE3A04D1Fe4
"0xa06d51ff57bc41d33c812f08bdb65641db7581d97bd1d524fc8d0dd448a2aa9a"

Why did we get a receipt? Surely we should have been told that transaction was invalid. Did it just get logged as a failure?

> eth.getTransactionReceipt("0xa06d51ff57bc41d33c812f08bdb65641db7581d97bd1d524fc8d0dd448a2aa9a").blockNumber
2

No. So did value move?

> eth.getBalance("0xaf4be85b32868c5b7c121115ad8cd93e0ad4f14e")
1646999999999000
> eth.getBalance("0xfab48eb52368c8b5c7211151dac89de3a04d1fe4")
2001

Kind of. Value was deposited in the target account, but wasn’t debited from the source account. Where did it come from?

> eth.getTransactionReceipt("0xa06d51ff57bc41d33c812f08bdb65641db7581d97bd1d524fc8d0dd448a2aa9a").from
"0xf2b40cc46f06f8d28a2b021851f721592b1f78e8"
> eth.getBalance("0xf2b40cc46f06f8d28a2b021851f721592b1f78e8")
1646999999998999 // started with the same balance as 0xaf4b...

That’s not the account debited in the original transaction. So, I guess it’s true that we weren’t able to replay that transaction with modifications. But what about this other account? It didn’t sign this transaction.

This is where I had to learn the details of how transaction signing works in Ethereum. To submit a signed transaction, your client must encode a string containing: nonce, gas price, gas limit, destination address, value, contract data, and chain ID. The exact encoding is irrelevant here, but those are the components of the transaction (see this post and EIP 155 for the full details). A representation (hash) of those values is passed to an elliptic curve signing function, along with your account’s private key. That function produces what is called a “recoverable signature”. This recoverable signature is added to the end of the previous list, and the resulting string is a “signed raw transaction”.

A signed raw transaction can be submitted to any Ethereum node, without that node needing to know the private key of the account submitting the transaction. Notice that the list of fields included doesn’t include the address of the account submitting the transaction. Anyone can recover that address using the signature and the original list of signed fields.

But there’s the trouble. To get back the address of the originating account, you have to have both the signature and the original field values. If you supply different field values, you don’t get, “This signature doesn’t match,” you get, “This transaction came from a completely different account.”

This is what happened in the example above. If we recover the address using the original values and signature, we get the address we used to sign the original transaction:

$ tools/ecrecover 0xf86980850430e2340083015f9094fab48eb52368c8b5c7211151dac89de3a04d1fe48203e880820348a0780d4ea898306e700cea578140cc4502d401c5949e7f4cab6a72c08a1a065aaba00cc22d63e2ef8acaaf1f6ead7a68de12e48a79f17d0a5ebab006fa996076ed53
Recovered: af4be85b32868c5b7c121115ad8cd93e0ad4f14e

But if we recover the address using the altered values and the signature, we get the other address:

$ tools/ecrecover 0xf86980850430e2340083015f9094fab48eb52368c8b5c7211151dac89de3a04d1fe48203e980820348a0780d4ea898306e700cea578140cc4502d401c5949e7f4cab6a72c08a1a065aaba00cc22d63e2ef8acaaf1f6ead7a68de12e48a79f17d0a5ebab006fa996076ed53
Recovered: f2b40cc46f06f8d28a2b021851f721592b1f78e8

Before you run off to tweet about this, let me say: trying to produce a set of field values to make some signature point to a particular account is not within the realm of your powers. I precalculated the account address that would match, and gave it value in my genesis block for the purposes of this demonstration. If I we try again with a value two greater, we get a completely different address that has no value:

$ tools/ecrecover 0xf86980850430e2340083015f9094fab48eb52368c8b5c7211151dac89de3a04d1fe48203ea80820348a0780d4ea898306e700cea578140cc4502d401c5949e7f4cab6a72c08a1a065aaba00cc22d63e2ef8acaaf1f6ead7a68de12e48a79f17d0a5ebab006fa996076ed53
Recovered: c30d2d79cbb88531abeb585dcf4f4fcfbb4ce373
> eth.getBalance("0xc30d2d79cbb88531abeb585dcf4f4fcfbb4ce373")
0
> eth.sendRawTransaction("0xf86980850430e2340083015f9094fab48eb52368c8b5c7211151dac89de3a04d1fe48203ea80820348a0780d4ea898306e700cea578140cc4502d401c5949e7f4cab6a72c08a1a065aaba00cc22d63e2ef8acaaf1f6ead7a68de12e48a79f17d0a5ebab006fa996076ed53")
Error: insufficient funds for gas * price + value
at web3.js:3143:20
at web3.js:6347:15
at web3.js:5081:36
at :1:1

Trying to match a particular address is a process of mashing numbers hoping to accidentally hit one in 2160. Even if you just wanted to hit any in-use address, and each person alive on Earth had their own, you’d still be looking at one in 2127(=2160/233, 233 ≈ 8 billion).

So why do I care? Two reasons:

  1. Being corrected for the wrong mistake makes the protocol harder to use. The error above for the “two greater value” mismatch points a debugger toward balances, not toward signatures.
  2. Fixing this seems simple.

Number 2 is the naïve thing to say. If it’s so simple, why hasn’t it been done? It’s more likely that I just don’t understand the domain and/or design decisions made elsewhere. I’m going to trudge on with explaining anyway, and hope it leads to my education.

I think this can be fixed by including the originating address in the details that are signed. If what was signed was instead: nonce, gas price, gas limit, originating address, destination address, value, contract data, and chain ID; I think the problem would disappear entirely. We can try the same single-bit modification as last time:

# >---changes---------------------------------|-|---------added-from-address-----------|--------------------------------------------------------|---new-signature--->
$ tools/ecrecover 0xf87e80850430e2340083015f9094af4be85b32868c5b7c121115ad8cd93e0ad4f14e94fab48eb52368c8b5c7211151dac89de3a04d1fe48203e880820348a0a6ef55701d8b89007f729cbf0ff5abcabcfbf714017337c9ba3fd7d6fa9d22b1a05b2e8022f0a26f5928b7faa0aa94613328d9d6718a56cd4b951882e092467020
Recovered: af4be85b32868c5b7c121115ad8cd93e0ad4f14e
#          |-------------matches----------------^=|------------------------------------^
# >---modified-bit-is-out-here---------------------------------------------------------------------------------------------------------|
$ tools/ecrecover 0xf87e80850430e2340083015f9094af4be85b32868c5b7c121115ad8cd93e0ad4f14e94fab48eb52368c8b5c7211151dac89de3a04d1fe48203e980820348a0a6ef55701d8b89007f729cbf0ff5abcabcfbf714017337c9ba3fd7d6fa9d22b1a05b2e8022f0a26f5928b7faa0aa94613328d9d6718a56cd4b951882e092467020
Recovered: 8e80dee68fa86c07fe7753fad297a45ee0570eb0
#          |---------does not match-------------^=|------------------------------------^

But this time, we can compare the recovered address to the “from” address in the transaction. They don’t match, so we can say, “This signature doesn’t match.”

And hey, the “attack” gets harder too. It’s not as simple as just changing the from address in the transaction. If we do that, the recovered address also changes, to yet something different:

# >---changes-----------------------------------|----recovered-address-from-above------|---------------------value-is-still-modified---|
$ tools/ecrecover 0xf87e80850430e2340083015f90948e80dee68fa86c07fe7753fad297a45ee0570eb094fab48eb52368c8b5c7211151dac89de3a04d1fe48203e980820348a0a6ef55701d8b89007f729cbf0ff5abcabcfbf714017337c9ba3fd7d6fa9d22b1a05b2e8022f0a26f5928b7faa0aa94613328d9d6718a56cd4b951882e092467020
Recovered: 680d265d9d2c9654e02bd6d46b2db025058a6672
#          |---still-does-not-match-------------^=|------------------------------------^

With this scheme, to find a valid transaction, you’re forced to find a match for a specific address. So, as a side effect of improving usability, we also return to a collision probability of one in 2160.

Is it the case that EIPs 712 and 191 are attempting to address some of this situation, but not directly? It seems like “malleability” of ECDSA signatures, while perhaps slightly different than what is described above, is something that has caused trouble elsewhere.

Finally, thanks to the makers of two tools that helped me debug what was going on: Ethereumjs-tx, which includes a nice “from” recovery function, and Keythereum, which can extract a private key from a geth keystore.

Am I on track, or have I missed something? Let me know.