Bitcoin, Blockchain.info & Google Script

Posted by mwguy on Sun 13 October 2013

Hey guys I was doing some of my spreadsheet fu on Google Sheets and I came across a problem. I needed a way to bring API data into my spreadsheet for a Bitcoin address I was trying to track. In the process I came up with a Google script way to pull a basic list of outgoing transactions and the current balance into an object which you can then use to place it in any Google App and utilize it.

Basically it consists of two parts, First is an object called addrObj. addrObj takes a public address as it's constructor and will grab the transaction information about the address. The second is an object called addrtrans. The addtrans object is stored in the addrObj. It keeps track of transactions, the effect of the transaction on the parent address and my favorite part it grabs the spot price of the transaction in three different currencies. Both of these functions require a second API call and the spot price function requires an API call to bitcoincharts.com. I think the code is reasonably self explanatory so I'm going to post it here and upload a copy below for you to use.

If there's any interest I can throw up a github for this and add features to it if you'd like.

addrObj.gs

// transactions as they relate to a parent address
function addrtrans(myblockchainobj, address){
  // Transaction ID
  this.txhash = myblockchainobj["hash"];
  // Parents Hash either the sending or the recieving hash
  this.parentaddress = address;
  // Unix Time;
  this.unixtime = myblockchainobj["time"];
  // Result Initially 0;
  this.result = 0;
  // Currency Translations By default 0;
  // "Currency" , "API Endpoint", Currency per Bitcoin]
  this.conversions = [ ["usd" , "mtgoxusd", 0 ],
                       ["gbp" , "mtgoxgbp", 0 ],
                       ["euro", "mtgoxeur", 0 ] ]

}
addrtrans.prototype.updateResult = function() {
  Logger.log(this.txhash);
  Logger.log(this.parentaddress);
  var apicall = "http://blockchain.info/q/txresult/" + this.txhash + "/" + this.parentaddress;
  // should get signed int satoshis of change
  var response = UrlFetchApp.fetch(apicall);
  this.result = response;
}

addrtrans.prototype.updateConversions = function() {
  for (var i = 0; i < this.conversions.length; i++){
    try {
      var apicall = "http://api.bitcoincharts.com/v1/trades.csv?symbol=" + this.conversions[i][1] + "&start=" + this.unixtime;
      var response = UrlFetchApp.fetch(apicall, { "muteHttpExceptions" : true } );
      var spotarray = String(response).split(',',3);

      // How many dollars per btc
      var spotprice = spotarray[1];
      //  $        = $ per XBT    * XBT
      var convertedprice = spotprice * ( this.result / 100000000 );
      this.conversions[i][2] = convertedprice;
    } catch(error) {
      Browser.msgBox("Errror in Conversion. Error Text:\n" + error);
    }
  }
}

function addrObj(address) {
  // Address Hash
  this.address = address;
  Logger.log("Address: " + address);
  // Address hash160;
  this.hash = ""
  // Number of transactiosn init 0
  this.numbertransactions = 0 ;
  // Satoshis recieved initi 0
  this.totalreceived = 0;
  // Satoshis sent
  this.totalsent = 0;
  // In satoshis Init as 0
  this.balance = 0;
  // array of transactions
  this.transactions = []

}

addrObj.prototype.populate = function() {
  Logger.log(this.address);
  var apicall = "http://blockchain.info/address/" + this.address + "?format=json" ;
  var response = UrlFetchApp.fetch(apicall);
  var alladdressdata = Utilities.jsonParse(response);
  // Populate bits and pieces
  this.balance = alladdressdata["final_balance"];
  this.hash = alladdressdata["hash160"];
  this.numbertransactions = alladdressdata["n_tx"];
  this.totalrecieved = alladdressdata["total_recieved"];
  this.totalsent = alladdressdata["total_sent"];
  // Create New Transaction List
  for (var transaction in alladdressdata["txs"]){
    //Logger.log("Transaction Number " + transaction + ":" + alladdressdata["txs"][transaction]);
    this.transactions.push(new addrtrans(alladdressdata["txs"][transaction], this.address));
  }
  // Update Transactions Will take time
  // If you don't want it you should comment out this bit.
  for (var i = 0; i < this.transactions.length; i++){
    this.transactions[i].updateResult();
    this.transactions[i].updateConversions();
  }
}