Custom Bitshares airdrop spotlight #001: Asset holder airdrop

in #bitshares5 months ago

Custom airdrop #001 - Asset holders!

Recently the Bitshares Airdrop tool introduced support for custom airdrops, enabling users to craft airdrops from input JSON.

So, rather than having to calculate an airdrop based on the ticket selection process, or limiting scope of the airdrop recipients to just the ticket holders we can craft airdrops based on anything.

So let's get started with an interesting script: Asset holder airdrops!

The following example script fetches the top 10000 BTS (1.3.0) asset holders on the Bitshares blockchain:

const fs = require('fs');

const assetId = '1.3.0'; // Replace with your asset id
const limit = 100; // Max limit on the asset holders API
const totalHolders = 10000; // How many holders you want to fetch
const outputFile = './fetchedData/assetHolders.json';

const getAssetHolders = async (start) => {
  const url = `${assetId}&start=${start}&limit=${limit}`;
  const response = await fetch(url);
  return response.json();

const getAllAssetHolders = async () => {
  const allHolders = [];
  for (let i = 0; i < totalHolders / limit; i++) {
    console.log(`Fetching ${i * limit} to ${(i + 1) * limit}`);
    let assetHolders;
    try {
      assetHolders = await getAssetHolders(i * limit);
    } catch (error) {
  return allHolders;

const writeToFile = (data) => {
  console.log(`Writing to ${outputFile}`);
  fs.writeFileSync(outputFile, JSON.stringify(data));

const main = async () => {
  const allHolders = await getAllAssetHolders();


Once this script is completed, we will have the top 10,000 token holders for BTS (1.3.0) asset on the Bitshares blockchain.

This data has the format: [{"name":"accountName","account_id":"1.2.x","amount":"1234567"}, ...]

To convert this data to the required airdrop format we run the following script:

const fs = require('fs');
const assetHolders = require('./fetchedData/assetHolders.json');

 * Convert the token's blockchain representation into a human readable quantity
 * @param {Float} satoshis
 * @param {Number} precision
 * @returns {Number}
function humanReadableFloat(satoshis, precision) {
  return parseFloat((satoshis / 10 ** precision).toFixed(precision));

const output = => ({
  id: holder.account_id,
  qty: 1,
  value: humanReadableFloat(holder.amount, 5)

fs.writeFileSync('./airdrops/processedAssetHolders.json', JSON.stringify(output));

We now have the airdrop data in the format:

        "id": "1.2.x",
        "name": "accountName",
        "qty": 1,
        "value": 1234

So, with this processedAssetHolders.json file, we can create a custom airdrop:

And finally, the airdrop card prompting you to broadcast the airdrop transaction onto the Bitshares blockchain via the BEET multiwallet:


With the current settings, 10000 users in an airdrop takes up approx 65.75% of the max transaction size, so you could create an airdrop including approx 13000 top asset holders, not just the top 10000.

For the life-time members the fee is less than $20 to airdrop onto 9981 users, not bad!

Here's a preview of the airdrop prompt for a 3000 user testnet airdrop performed the other day, so you get an idea of what the next step is before broadcast to the blockchain:


These developments were brought to you by the NFTEA Gallery.
Consider collecting an NFTEA NFT to support continued Bitshares developments.

Don't have a Bitshares account? Make one today!

Coin Marketplace

STEEM 0.27
TRX 0.11
JST 0.034
BTC 44000.81
ETH 2354.21
USDT 1.00
SBD 5.27