August 21, 2014

Andreas Antonopolous as canonical example of why you can't trust someone not in the WoT

Filed under: Uncategorized — @ 12:00 a.m.
Andreas Antonopolous as canonical example of why you can't trust someone not in the WoT

Andreas Antonopolous tweets:

The implementation of stealth addresses for Mac that I tweeted about last week turned out to be wallet-stealing malware. Crap.

One's affiliations in Bitcoin matter tremendously - the precise manner of their construction in the context of your existing image will haunt you forever. Nobody's going to hold the toes of the programmers to whom the Ripple work was farmed to the fire, but Jed McCaleb's forever the guy who tried again and again to implement derpy debt systems in a cryptocurrency fashion.

Antonopolous' polyp-like willingness to associate himself with anything that floats past him on the bottom of the BTC sea has bitten him not once, but at least twice now1.

Tweeting and retweeting feeds the noise machine; degrading the importance of taking the time to read code and evaluate things. When I discovered bit-c, I enlisted peers on -assets to review the source2 instead of blindly saying "HEY EVERYONE TRUST YOUR MONEY TO THIS THING".

Bitcoin calls for constant caution and paranoia. Caution, lest ye accidentally endorse that which robs others. Paranoia, lest the malware with which this world overflows infect they toolchain, depriving thee of those most important tokens.

I write software for all kinds of people. I don't have to like them, I don't have to think their businesses are of any quality, I simply take their money and render unto them that which they pay for. Should ethical conflicts arise, I have the freedom to walk from those contracts - and to date nobody's enlisted me to write a backdoored exchange, or any other actively malevolent software. Nor will they, for I shan't.

Nor do I endorse things beyond my web of trust - this is the path to madness. I can easily disqualify approximately 99% of the bullshit out there on the criteria of whether its authors or proprietors are in my WoT. If they're not, and I miss the boat, so be it - it's far more important on the long run to avoid the bad decisions that could wipe one out than it is to not miss the few opportunities out there.

Humans are wracked with the fear of missing out - missing Google, missing Bitcoin, missing Berkshire Hathaway…the focus on wild gains (and the refusal to attribute an adequate proportion of those gains to blind luck) precludes most people from doing the right thing, which is to minimize losses from scams, bad ideas, and outright mismanagement. Having skills and exercising them to grow one's pile of cash will (now that we have Bitcoin to protect our savings from deflation depreciation3) always trump the investor looking for return.

Beyond giving you the assurance that the people on the other end of the line are actual humans with actual reputations on the line, having and using a Web of Trust allows you to trivially filter the world of scams. Yes, you'll miss out on all of the randomly "successful" High Yield Investment Products, but at the same time, you'll spend not a watt of energy watching your HYIP holdings and trying to get out at the top.

Envy the randomly wealthy if you must, but never neglect your skills or stop working to grow your capital. Preserving your wealth without making bad investments is now possible4, if you care to denominate your wealth in BTC. Filter with the WoT5.



The first being that godawful NEOBEE scam that imploded with his reputation all over it. "I'm just a consultant!" he iterates and reiterates, in an attempt to distance himself from the scam where his reputation and influence among the derpy podcast listeners was purchased by the NEOBEE team.


#bitcoin-assets is blessed by a wealth of intelligent folks with experience in everything from botnets, malware, and machining technologies to open source PBX-ware. This is the difference between the Twitter and Reddit bitcoin groups and the -assets circlejerk: when we find new toys, we have the staff on hand to read through the source and put a few coins into them to test them without a whole raft of noobs using them and losing all of their coins in the vain pursuit of "anonymous transactions".

Bit-c, by the way, corrupted its transaction log when it crashed on me recently. YMMV. It correctly stores the private keys in plaintext, though, so if I'd had any amount of value in there I'd not be as shit out of luck as those whose Bitcoin "Core" wallets get corrupted on save.


At the hands of whoever controls the monetary supply. Thanks to readers for proofreading!


USians of necessity must invest their cash in the stock market to protect their holdings from the depredations of inflation - hence the US populace's obsession with the US stock markets and, I believe, Bitcoin stock markets. They're accustomed to "return" (which rarely is, taxes and inflation taken into account), and so slaver at the chance of return on coins. Holding coins alone will return in time - don't get greedy.


If someone's not represented in the WoT, you're going to get stupider listening to them derp about Bitcoin. They've a signal-to-noise problem and most terrifingly don't even realize it.

August 18, 2014

nothing beats reading the source - boto and s3 and multiple-arity edition

Filed under: Uncategorized — @ 12:00 a.m.
nothing beats reading the source - boto and s3 and multiple-arity edition

I'm scripting the provisioning of client clusters today. This entails standing up Amazon Relational Data Store (RDS) instances up for Datomic to stuff facts into. I'm using the Python1 boto library2 to stand up these RDS instance. When first I went to stand up this instance, I said, "dear boto: run you this command!"


conn, of course, being some wacky connection object with RDS manipulation objects hanging off of it3.

AWS responds thusly:

DB Security Groups can only be associated with VPC DB Instances using API versions 2012-01-15 through 2012-09-17.

Fine. Okay. I'm accustomed to this - I brought this on myself by leaving the wood shop and the metal fabrication studio and the high-end semiconductor probe manufacturing company for a lifestyle and beer in the office. How then is one to query the AWS API for the upped-ness status of an instance4?

The answer is to call get_all_instances 5 with an instance ID:

def get_all_dbinstances(self, instance_id=None, max_records=None,
    Retrieve all the DBInstances in your account.

    :type instance_id: str
    :param instance_id: DB Instance identifier.  If supplied, only
                        information this instance will be returned.
                        Otherwise, info about all DB Instances will
                        be returned.

    :type max_records: int
    :param max_records: The maximum number of records to be returned.
                        If more results are available, a MoreToken will
                        be returned in the response that can be used to
                        retrieve additional records.  Default is 100.

    :type marker: str
    :param marker: The marker provided by a previous request.

    :rtype: list
    :return: A list of :class:`boto.rds.dbinstance.DBInstance`
    params = {}
    if instance_id:
        params['DBInstanceIdentifier'] = instance_id
    if max_records:
        params['MaxRecords'] = max_records
    if marker:
        params['Marker'] = marker
    return self.get_list('DescribeDBInstances', params,
                         [('DBInstance', DBInstance)])

In the EC2 scripts, I explicitly iterate over all of my reservations, looking for the reservation id returned from the run_instance command. Then I just loop over that reservation until it returns an instance ID. I must be pretty dumb, because this is the best solution to the bog-standard use case of "give me a new instance and return its instance ID that I've found:

def get_current_hostname(conn, resid):
    i = 0
    wait_cycle = 3.0
    while True:
        if i * wait_cycle > 60.0:
            raise Exception('Timed out waiting for EC2 to return a hostname')
            reservations = all_reservations(conn)
            for res in reservations:
                if == resid:
                    pdn = res.instances[0].public_dns_name
                    if pdn == '':
                        i += 1
                        return pdn

Anyways the lesson of all this is that6 there is no substitute for a) an editor that browses source (thanks, Emacs! thanks, Elpy! Thanks, Mr. Schafer!), and b) reading the source. Documentation, man. It's always damn misleading7, at least in some regard.

I am derpy because all that I know of Java I learned from Clojure. Functions! That's all I know, man. I don't even write macros cuz I'm too dumb.



2.7 in case you're curious, because that's what ships with OS X, and my lifespan is finite and I'm trying to actually ship some software over here.


Clearly the authors of this lib were thinking about working on one project for one company, or maintaining this file by hand, or something else inscrutable. For the hired gun randomly poking at the AWS API for random projects of all kinds, all of this needs to be explicitly declared in the provisioning scripts somehow.

This means that there's a) Python and b) local configuration to deal with if using the CLI tools. This rules the CLI tools clean out, and means that my options for scripting up the enclusterification of client projects are a) dig up and prod the relevant endpoints myself (the problem with which is that they spit back XML (not even JSON I can parse with .jq ffs)) or b) take a dependency on some other language that parses XML in which case why not just use one of the AWS API's from the get-go?

Which brings me to a point I've been harping about lately which is that my bash scripts shell out to python and not the other way around and as far as I'm concerned this is the correct approach. Direct arguments on the topic to


I'm just some derpy lisper, so for the record, this is how I've turned the OOP insanity inside-out with referentially-transparent functions so that things make at least a modicum of sense:

def new_bucket(conn, bucketname, region):
    return conn.create_bucket(bucketname, location="us-west-1")

s3conn = boto.connect_s3(aws_access_key_id=creds['AWSAccessKeyId'],
new_bucket(s3conn, bucketname, region)

The critical difference is that my new bucket function takes in the connection as an argument and then calls the appropriate method dangling off the thing. I can't help but imagine passing this giant jangling set of keys around my scripts as this whole thing happens. But I digress.


For the love of Christ, don't use recursion in Python. This intuitive approach to programming (which has been technically solved since the eighties? seventies? Longer than I've been alive, certainly) will make Python blow up if it recurses more than a trivial number of times. Mr. van Rossum says this is because something to do with stacktraces, which doesn't make sense to my derpy lispy Java brain, as Clojure's stacktraces are entirely either incomprehensible or totally legible depending on who you ask and how long they've been hacking Clojure. In any case, the problem is above my head and beyond my pay grade, so disregard my derping on the topic.


Yes, I know that subscripting is ruining the reading experience on my blog. Thank you.


I'm just kidding. There's no lesson. Programming is a hilarious exercise in mashing one's fingers with a hammer. I blog to entertain with stories from the trenches, not to educate anyone about anything. Perhaps all the AWS in the post will raise me in some search rankings, though. Nefarity!


One last footnote, I swear: I'm clearly the most poorly engineered developer you know, because it took me three days of derping to realize that all of the clj-time joda-time objects implement (.toDate %). This was mentioned nowhere in the clj-time documentation (that I found). Maybe I should just call random methods on things at the REPL - that's what I'll do!

Digging out of one's own holes

Filed under: Uncategorized — @ 12:00 a.m.
Digging out of one's own holes

The best part of fixing one's mistakes is how much damned time one must spend thinking about what lead to the mistake in the first place. Ideally, the pain of that sort of introspection keeps one from making that mistake again in the future.

« Newer Posts