Less Than 50 Lines of Code for a Password-Protected, Online Bitcoin Wallet

Buildling a full-blown Bitcoin Wallet like Blockchain.info is a time-consuming task (surprise, surprise), but with the help of a few JavaScript-libraries and the Blockchain.info-API, it’s possible to develop a Bitcoin Wallet with just a few lines of code. There are two features:


  • Creating the Bitcoin address and encrypting the private key to receive Bitcoin.
  • Sending Bitcoin from your address to another address.

For doing the Bitcoin-related stuff, I used the “BitcoinJS”-library. It depends on some other libraries as well, but as long as you use a package manager like npm, all of them will be loaded automatically. Furthermore, the “TripleSec”-library is used for cryptographic functions.


First of all, load the libraries mentioned above.


var base58 = require('bs58');
var bitcoin = require('bitcoinjs-lib');
var ecurve = require('ecurve');
var BigInteger = require('bigi');
var Buffer = require('buffer');
var triplesec = require('triplesec');

Next, the code to generate the address and encrypt the private key with a PIN code:


function generate(pinCode) {
var keyPair = bitcoin.ECPair.makeRandom();
var address = keyPair.getAddress();

triplesec.encrypt ({
data: new triplesec.Buffer(keyPair.toWIF()),
key: new triplesec.Buffer(pinCode)
}, function (err, buff) {
if (err) {
// do something when encryption failed
} else {
var ciphertext = buff.toString('hex'); // do something with the address and the encrypted private key

}
});

Save the generated Bitcoin address and the encrypted private key. You can now use the Bitcoin address to receive transactions.


Loading the libraries is exactly the same as above. Here is the code to send the Bitcoin (actually: Satoshis) to another address:


function sendmoney(amountSatoshis, address, privatekey, pinCode, receiver) {
triplesec.decrypt ({
data: new triplesec.Buffer(privatekey, "hex"),
key: new triplesec.Buffer(pinCode)
}, function (err, buff) {
if (err) {
// ... do something when decryption failed (invalid pin code)
return;
} $.ajax({
// using Blockchain.info API to get unspent outputs
url: 'https://blockchain.info/de/unspent?cors=true&active=' + address,
type: 'GET'
}).done(function(data) { var tx = new bitcoin.TransactionBuilder()
var txfeemin = 1000; var balance = 0;
var inputCount = 0;
data.unspent_outputs.forEach(function(uo) {
tx.addInput(uo.tx_hash_big_endian, uo.tx_output_n);
balance += uo.value;
inputCount++;
});

var txfee = txfeemin;
//Estimate transaction size in bytes
var txSize = inputCount * 180 + 2 * 34 + 10 + inputCount;
//Blockchain: Minimum fee is 1.5 satoshi / Byte
if (txSize * 2 > txfeemin)
txfee = txSize * 2; tx.addOutput(receiver, amountSatoshis - txfee);
tx.addOutput(address, balance - amountSatoshis); for (var i = 0; i < inputCount; i++)
tx.sign(i, keyPair); var txHex = tx.build().toHex();

// pushing raw transaction to Blockchain.info API
$.ajax({
url: 'https://blockchain.info/pushtx?cors=true',
type: 'POST',
data: 'tx=' + txHex
}).done(function(data) { // transaction successful }).fail(function(err) {
// push transaction to Blockchain failed
}); }).fail(function(err) {
// most likely no unspent output (no balance)
});
});

Using the Blockchain.info-API this is almost a no-brainer. The only tricky part is to calculate the transaction fee (“mining fee”) so that the transaction is not declined.


The Blockchain.info formula is (currently):


So I have to estimate the transaction size (in bytes) to calculate the mining fee. The formula is:


To be on the safe side, my wallet grants 2 Satoshi per byte.


Thanks to public APIs and Open Source projects it’s pretty simple to provide Bitcoin functionality in your own applications.


Комментарии