Airdropping on fx(hash): Tips and Tricks

By Nudoru and Abstractment

So, you have an awesome gentk on fx(hash)! Congratulations! Now you want to send copies to your supporters and fans? Here’s our quick guide on how to do it.

The end goal is to get a CSV file that we can drop into http://batch.xtz.tools and have it do the work of passing out our tokens for us. 

The CSV we’ll want to use for the batch tools site needs 3 columns: wallet IDs, fx(hash) token IDs, and quantity (1 for one per wallet). We’ve gone ahead and created this template for you to make it as easy as possible. When you click this link, it’ll require you to create a copy so that it’s your own unique copy.

Step 1 – Mint your tokens

This is the most manual and time-consuming part of the process. You need to manually mint each token that you want to airdrop. Put on a good show or some tunes to keep you occupied. Keep in mind that your transactions will fail if you try to process more than one mint within a single block. A good baseline is to wait 30 seconds between each mint or just wait for the confirmation to show on the fx(hash) page.  You can also track the Tezos blocks here if you want to move quickly. Once you’re done and they’re all signed by fx(hash), you may want to clear/refresh the metadata in your wallet so that the names and thumbnails are updated.

Step 2 – Get the token IDs

Go to your project’s page on this site: https://fxfam.xyz/YOUR_PROJECT_ID. Thanks to @zancan for creating this resource. This site uses the fx(hash) API to display a list of minted editions and the owner. We want to scrape the list of the tokens we minted from this site. 

Open up the JavaScript console and paste this script to the console.  Before hitting enter, change YOUR_fx(hash)_ID to your fx(hash) username on the fourth line of code.

let a=[]; 
document.querySelectorAll('li.token').forEach((e,i) => {
let o = e.querySelector('div.owner').innerText;
if(o === 'YOUR_fx(hash)_ID') {
let lnk = e.querySelector('div.inner a');
a.push(`${lnk.href}\n`)}}); 
console.log(a.join(''));

As an example, the project ID is 7044 in this sample below.

Voila!  Now you’ll see a list of all of the tokens you hold for this collection.  Copy and paste this list to column A on tab 2 of the Google sheet. We just need the ID number of each mint, and the google sheet will automate extracting this for you.

Note: Sometimes it doesn’t load all of the editions and you’ll need to refresh the page. Make sure that all editions have loaded before pasting the script for this step.

Step 3 – Get the list of lucky wallets

How you determine which wallets will receive an airdrop is up to you, you just need a list of them for column A of our sheet. Use tab 3 in the google sheet for these steps.

If you want to use the owners of previous projects:

  • Visit your project on https://fxcollectors.stroep.nl.  Shout out to @mknol for creating this. 
  • Enter your project ID and hit enter.  
  • Click the Owners tab. This entire page is sorted by the number of pieces in the wallet. Scroll to the very bottom of the page and you’ll find a text area of wallet addresses. This list is ordered by the number of pieces in the wallet, so if you want to airdrop to just holders of a specific number of pieces, you can compare the first on this page to determine where to cut it off.
  • Copy and paste the wallet addresses to column A of tab 3 in the Google sheet. Note: In a recent update, the number of editions is after the wallet addresses. You’ll need to manually remove this in the Google sheet.
  • You can pull wallets from multiple projects, just keep copying and pasting to the bottom of the list in the sheet.
    • If you want to remove duplicate wallets so that everyone only gets 1 airdrop, do the following: In Google sheets, select column A, then Data menu > Data cleanup > Remove duplicates.
  • How do you want to assign tokens to the wallets?  
    • Want your largest holders to get lower numbered editions?  If so, you’re done.  
    • Want everything randomized? Shuffle the list: With column A still selected, Data menu > Randomize range. Do this as many times as you want, but I usually do it 3 times for a good shuffle. 
    • Want to pick and choose which wallet gets which pieces?  Just put them in the order that you want and confirm they match on the first tab.

Step 4 – Double-check the sheet

Now, in the first tab (_final for CSV), you should have a Google sheet with 3 columns: a list of wallets, a list of your minted IDs, and a 1 beside each in column C. Make sure all of the data matches up and that columns A and C are the same lengths as column B. 

Export the list: File > Download > Comma Separated Values (.csv).  Open up your CSV to confirm you have just one tab with three columns.

Step 5 – Airdrops!

Now for some magic, thanks to the work of @pureSpider.  

  • Go to http://batch.xtz.tools and connect your wallet. 
  • Pick “fx(hash) 1.0” in the FA2 Contract drop down.
  • Upload or paste the CSV file.
  • Do a quick double-check of the data.
  • Click Send Transaction, and approve the transaction through your wallet. In a few minutes, you’ll see all of the transactions sent.

I’ve stopped writing my own JavaScript framework because …

This post should have been written back in February! But I’m bad at blogging …

Rolling my own solution was a great way to quickly get up to speed on modern JavaScript syntax and best practices. I think it’s really the best way – for me. But in the end I was never going to be confident in it enough to release or suggest anyone else use it.

I was building more apps and the realization that someone was going to come behind me and maintain these things started to hit home. I’ve been in this situation before, and long term product maintenance and support wasn’t something that I wanted to get into again.

And I was job hunting. “No, I’ve never used React/Angular but I wrote my own thing …” was going to go anywhere. So I quit cold turkey and started picking up React. I’d based a lot of my methodologies on it anyway.

So that’s where I’m at now. As an e-learning developer at Red Hat, I don’t bang out code all day, but React has been great for producing apps very quickly. I’m really happy with it.

Smart WBT Players

Just a Saturday morning thought –

Smart WBTs. I’ve always liked the idea.

A long time ago, I wrote several Flash based WBT presentation tools – content was externalized in my own XML schema, played in my nice player. These things are pretty common. Even in modern HTML5 / JavaScript land, a nice player that can present any type of content is a big efficiency. I was taking apart the Articulate Storyline 2 Player JavaScript the other day and it does the same thing. It’s fun to see how other developers tackled the problem.

But one idea I had (around 2005) was: What if the player was smart enough to not only present the content, but understand what the learner was trying to do? What if it’s a typical learner that’s mashing Next as quickly as possible to get to the test and the system noticed this (based on time per page) and prompted you to just go to the test? What if the learner sat on a question or tried 5 times and couldn’t get it right? It would notice and ask if you’d like to go back to that part of the content for a quick review?

I had it all coded up and working perfectly – but it’s hard to get business partners to buy into that when deadlines come. I couldn’t get anyone interested in the idea we just moved on without it. But I never forgot it.

I did bring the idea back with the Social Sim “engine” I built, but never completed my vision for it.

This morning I saw the Synaptic JavaScript library on GitHub. A JavaScript based neural frakin’ network. How cool would that be integrated into a WBT player? If the WBT learned how you interacted with it and altered it’s own behavior.

That would indeed be pretty cool.

The not so curious case of the “Click Next Fatigue”

As someone who annually sufferers through painful elearning courses, I thought that I’d make a list to help my punishers, who are surely ignorant of the pain they’re causing. My “click next button finger” is falling off at this point!

In a past life, I used to build courses like this. I’m sure that I’ve inflicted unmeasurable “click next fatigue” on countless employees/associates/teammates/whatever. But, I like to believe that I was aware of good user experience and always fought for what was best for the user.

So here’s my list, feel free to leave your thoughts or additions in the comments.

Some helpful guidelines for keeping the victim of an elearning course happy:

1. Golden Rule: Treat me like a responsible, honest adult
2. Let me test out
3. Never disable the back or next buttons
4. Don’t make me listen for the page to be read out loud before I can click next.
5. Don’t use sound! But if you must, make it optional.
6. Do not require me to click all of the buttons/links/etc. before I can click next.
7. If all of the content will fit on the page, put it there. Don’t force me through unnecessary interactions in the sake of “making it interactive.”
8. Don’t cover the next button I need to click on next with an oversized box from another button.
9. Be honest about how long the course will take to complete.
10. Developers: Don’t let the SMEs tell you how to build the interaction. That’s YOUR job.
11. Designers: Don’t let the SMEs write the content. That’s YOUR job.
12. Keep me entertained with novel interactions. When every course that you’ve created for the past 3 years uses the same interactions – you’re doing it wrong.
13. Make the graphics pretty. Pick stock art from at least the last decade. Why is that business executive on a Motorola flip phone (or worse!)?
14. Never copy a Microsoft UI style.
15. Never copy an Apple UI style.
16. When I miss a question, let me know what the correct answer was.
17. After you’ve shown me the correct answer, don’t make me change my answer and then resubmit the question.
18. The built-in knowledge check types in practically ALL elearning authoring tools suck. Don’t use them.
19. When you have mandatory popups on a page, don’t hide mandatory clicks in there.
20. Show my progress and let me know how much longer I’ll be stuck in here.
21. Ask for my opinion with at least one free form text field in a level 1 survey.

Clean Code

I’ve been programming for along time now. My first program was probably back in 5th or 6th grade when I had to get checked off on basic computer skills in elementary school. I think they were pretty progressive for 1989. It would have been as BASIC program on an Apple II and gone something like this:

10 PRINT "Hello!"
20 GOTO 10

I got into this seriously in 8th grade programming games in BASIC on the TRS-80s in the typing lab. Then moved though various lanauges (QuickBasic, Pascal, C++, Lingo, Javascript, ActionScript 0, 1 and 2) before landing where I currently am: an ActionScript 3 developer working with the Flash Platform.

Throughout all of this, I really just concentrated on syntax of the language and getting stuff done. But two years ago, I started using design patterns and looking beyond the code into the technique 9or craft) of coding. And in the past few weeks, I’ve really started thinking seriously about how bad I code and how want to code. In my freshman year of college, my first English assignment was a required paper titled: “My Writing Sucks and And Why.” Now I’m doing this mentally.

I picked up a copy of the excellent Clean Code by Robert C. Martin and have just started to read it. A few weeks from now, I fully intent to be a better programmer and look back on the code that I’ll write today and think: “What the hell was I thinking?!”

Note, I’d consider ActionScript 0 to be what ever the hell we were writing for frame scripts in Flash 4. That was painful.

Social sim. engine, pt. 2

So what’s first? I’ve got the requirements down, so now I need to start translating that in to code.

The most basic thing I’ll need to build is a player. I like to use a simple MVC pattern for this. It’ll need to be a very scaled down version of my Ramen player so that should be easy enough.

The player/controller will have the model load an XML file that contains the information for the characters, the structure of the sim and some settings (ui, speed, don’t know at this point). Model will do a little parsing and then the view will take over and draw the UI. After we’re all set up, the player will show the first page.

Each page will be a movie clip in the library of the player. In ramen, each page is an external SWF, but I’d like to keep this player simple. Having everything in one place will make it easier to keep a consistent UI and make it easier to edit. The content for each page will be stored in an XML file. I’ll need a class for the page that handles loading the XML and then kicking off any interaction specific interaction code. So a base template class and a few subclasses for each specific type.

Also need to come up with a schema for the XML and keep it as human readable as possible. Keeping the structure separate from the content of the questions should help a little. But as the complexity of the simulation goes up so will the mark up. I’m not quite sure how the variables and evaluations of the dynamic state will even be defined yet.

All of that will probably take me a week or so to get though. I’ll have screen shots up as I make progress.