diff --git a/src/address.js b/src/address.js
index 4b29a1f..1b419a6 100644
--- a/src/address.js
+++ b/src/address.js
@@ -1,4 +1,3 @@
-var assert = require('assert')
 var base58check = require('bs58check')
 var typeForce = require('typeforce')
 var networks = require('./networks')
@@ -13,50 +12,55 @@ function findScriptTypeByVersion (version) {
   }
 }
 
-function Address (hash, version) {
-  typeForce('Buffer', hash)
-
-  assert.strictEqual(hash.length, 20, 'Invalid hash length')
-  assert.strictEqual(version & 0xff, version, 'Invalid version byte')
-
-  this.hash = hash
-  this.version = version
-}
-
-Address.fromBase58Check = function (string) {
+function fromBase58Check (string) {
   var payload = base58check.decode(string)
+  if (payload.length !== 21) throw new TypeError('Invalid address length')
+
   var version = payload.readUInt8(0)
   var hash = payload.slice(1)
 
-  return new Address(hash, version)
+  return { hash: hash, version: version }
 }
 
-Address.fromOutputScript = function (script, network) {
+function fromOutputScript (script, network) {
   network = network || networks.bitcoin
 
-  if (scripts.isPubKeyHashOutput(script)) return new Address(script.chunks[2], network.pubKeyHash)
-  if (scripts.isScriptHashOutput(script)) return new Address(script.chunks[1], network.scriptHash)
+  if (scripts.isPubKeyHashOutput(script)) return toBase58Check(script.chunks[2], network.pubKeyHash)
+  if (scripts.isScriptHashOutput(script)) return toBase58Check(script.chunks[1], network.scriptHash)
 
   throw new Error(script.toASM() + ' has no matching Address')
 }
 
-Address.prototype.toBase58Check = function () {
+function toBase58Check (hash, version) {
+  typeForce('Buffer', hash)
+
+  if (hash.length !== 20) throw new TypeError('Invalid hash length')
+  if (version & ~0xff) throw new TypeError('Invalid version byte')
+
   var payload = new Buffer(21)
-  payload.writeUInt8(this.version, 0)
-  this.hash.copy(payload, 1)
+  payload.writeUInt8(version, 0)
+  hash.copy(payload, 1)
 
   return base58check.encode(payload)
 }
 
-Address.prototype.toOutputScript = function () {
-  var scriptType = findScriptTypeByVersion(this.version)
+function toOutputScript (address) {
+  var payload = base58check.decode(address)
+  if (payload.length !== 21) throw new TypeError('Invalid hash length')
 
-  if (scriptType === 'pubkeyhash') return scripts.pubKeyHashOutput(this.hash)
-  if (scriptType === 'scripthash') return scripts.scriptHashOutput(this.hash)
+  var version = payload.readUInt8(0)
+  var hash = payload.slice(1)
+  var scriptType = findScriptTypeByVersion(version)
 
-  throw new Error(this.toString() + ' has no matching Script')
+  if (scriptType === 'pubkeyhash') return scripts.pubKeyHashOutput(hash)
+  if (scriptType === 'scripthash') return scripts.scriptHashOutput(hash)
+
+  throw new Error(address + ' has no matching Script')
 }
 
-Address.prototype.toString = Address.prototype.toBase58Check
-
-module.exports = Address
+module.exports = {
+  fromBase58Check: fromBase58Check,
+  fromOutputScript: fromOutputScript,
+  toBase58Check: toBase58Check,
+  toOutputScript: toOutputScript
+}
diff --git a/src/ecpair.js b/src/ecpair.js
index a8042c6..c629835 100644
--- a/src/ecpair.js
+++ b/src/ecpair.js
@@ -1,5 +1,5 @@
 var assert = require('assert')
-var base58check = require('bs58check')
+var bs58check = require('bs58check')
 var bcrypto = require('./crypto')
 var ecdsa = require('./ecdsa')
 var ecurve = require('ecurve')
@@ -7,7 +7,6 @@ var networks = require('./networks')
 var randomBytes = require('randombytes')
 var typeForce = require('typeforce')
 
-var Address = require('./address')
 var BigInteger = require('bigi')
 
 function findNetworkByWIFVersion (version) {
@@ -69,7 +68,7 @@ ECPair.fromPublicKeyBuffer = function (buffer, network) {
 }
 
 ECPair.fromWIF = function (string) {
-  var payload = base58check.decode(string)
+  var payload = bs58check.decode(string)
   var version = payload.readUInt8(0)
   var compressed
 
@@ -125,13 +124,18 @@ ECPair.prototype.toWIF = function () {
     buffer.writeUInt8(0x01, 33)
   }
 
-  return base58check.encode(buffer)
+  return bs58check.encode(buffer)
 }
 
 ECPair.prototype.getAddress = function () {
   var pubKey = this.getPublicKeyBuffer()
+  var pubKeyHash = bcrypto.hash160(pubKey)
 
-  return new Address(bcrypto.hash160(pubKey), this.network.pubKeyHash)
+  var payload = new Buffer(21)
+  payload.writeUInt8(this.network.pubKeyHash, 0)
+  pubKeyHash.copy(payload, 1)
+
+  return bs58check.encode(payload)
 }
 
 ECPair.prototype.getPublicKeyBuffer = function () {
diff --git a/src/message.js b/src/message.js
index f3791fe..b2c584c 100644
--- a/src/message.js
+++ b/src/message.js
@@ -47,7 +47,7 @@ function verify (address, signature, message, network) {
     network: network
   })
 
-  return keyPair.getAddress().toString() === address.toString()
+  return keyPair.getAddress() === address
 }
 
 module.exports = {
diff --git a/src/transaction_builder.js b/src/transaction_builder.js
index 7ddb6a6..186c93d 100644
--- a/src/transaction_builder.js
+++ b/src/transaction_builder.js
@@ -1,4 +1,5 @@
 var assert = require('assert')
+var bcrypto = require('./crypto')
 var bufferutils = require('./bufferutils')
 var ops = require('./opcodes')
 var scripts = require('./scripts')
@@ -36,7 +37,7 @@ function extractInput (txIn) {
       hashType = parsed.hashType
       pubKeys = scriptSig.chunks.slice(1)
       signatures = [parsed.signature]
-      prevOutScript = ECPair.fromPublicKeyBuffer(pubKeys[0]).getAddress().toOutputScript()
+      prevOutScript = Address.toOutputScript(ECPair.fromPublicKeyBuffer(pubKeys[0]).getAddress())
 
       break
     }
@@ -187,12 +188,7 @@ TransactionBuilder.prototype.addOutput = function (scriptPubKey, value) {
 
   // Attempt to get a valid address if it's a base58 address string
   if (typeof scriptPubKey === 'string') {
-    scriptPubKey = Address.fromBase58Check(scriptPubKey)
-  }
-
-  // Attempt to get a valid script if it's an Address object
-  if (scriptPubKey instanceof Address) {
-    scriptPubKey = scriptPubKey.toOutputScript()
+    scriptPubKey = Address.toOutputScript(scriptPubKey)
   }
 
   return this.tx.addOutput(scriptPubKey, value)
@@ -330,7 +326,7 @@ TransactionBuilder.prototype.sign = function (index, keyPair, redeemScript, hash
 
         case 'pubkeyhash': {
           var pkh1 = redeemScript.chunks[2]
-          var pkh2 = keyPair.getAddress().hash
+          var pkh2 = bcrypto.hash160(keyPair.getPublicKeyBuffer())
 
           assert.deepEqual(pkh1, pkh2, 'privateKey cannot sign for this input')
           pubKeys = [kpPubKey]
@@ -362,7 +358,7 @@ TransactionBuilder.prototype.sign = function (index, keyPair, redeemScript, hash
 
       // we know nothin' Jon Snow, assume pubKeyHash
       } else {
-        input.prevOutScript = keyPair.getAddress().toOutputScript()
+        input.prevOutScript = Address.toOutputScript(keyPair.getAddress())
         input.prevOutType = 'pubkeyhash'
         input.pubKeys = [kpPubKey]
         input.scriptType = input.prevOutType
diff --git a/test/address.js b/test/address.js
index 5259fdc..666832c 100644
--- a/test/address.js
+++ b/test/address.js
@@ -9,25 +9,13 @@ var Script = require('../src/script')
 var fixtures = require('./fixtures/address.json')
 
 describe('Address', function () {
-  describe('Constructor', function () {
-    it('does not mutate the input', function () {
-      fixtures.valid.forEach(function (f) {
-        var hash = new Buffer(f.hash, 'hex')
-        var addr = new Address(hash, f.version)
-
-        assert.strictEqual(addr.version, f.version)
-        assert.strictEqual(addr.hash.toString('hex'), f.hash)
-      })
-    })
-  })
-
   describe('fromBase58Check', function () {
     fixtures.valid.forEach(function (f) {
-      it('imports ' + f.script + ' (' + f.network + ') correctly', function () {
-        var addr = Address.fromBase58Check(f.base58check)
+      it('decodes ' + f.base58check, function () {
+        var decode = Address.fromBase58Check(f.base58check)
 
-        assert.strictEqual(addr.version, f.version)
-        assert.strictEqual(addr.hash.toString('hex'), f.hash)
+        assert.strictEqual(decode.version, f.version)
+        assert.strictEqual(decode.hash.toString('hex'), f.hash)
       })
     })
 
@@ -42,12 +30,11 @@ describe('Address', function () {
 
   describe('fromOutputScript', function () {
     fixtures.valid.forEach(function (f) {
-      it('imports ' + f.script + ' (' + f.network + ') correctly', function () {
+      it('parses ' + f.script + ' (' + f.network + ')', function () {
         var script = Script.fromASM(f.script)
-        var addr = Address.fromOutputScript(script, networks[f.network])
+        var address = Address.fromOutputScript(script, networks[f.network])
 
-        assert.strictEqual(addr.version, f.version)
-        assert.strictEqual(addr.hash.toString('hex'), f.hash)
+        assert.strictEqual(address, f.base58check)
       })
     })
 
@@ -64,20 +51,18 @@ describe('Address', function () {
 
   describe('toBase58Check', function () {
     fixtures.valid.forEach(function (f) {
-      it('exports ' + f.script + ' (' + f.network + ') correctly', function () {
-        var addr = Address.fromBase58Check(f.base58check)
-        var result = addr.toBase58Check()
+      it('formats ' + f.hash + ' (' + f.network + ')', function () {
+        var address = Address.toBase58Check(new Buffer(f.hash, 'hex'), f.version)
 
-        assert.strictEqual(result, f.base58check)
+        assert.strictEqual(address, f.base58check)
       })
     })
   })
 
   describe('toOutputScript', function () {
     fixtures.valid.forEach(function (f) {
-      it('imports ' + f.script + ' (' + f.network + ') correctly', function () {
-        var addr = Address.fromBase58Check(f.base58check)
-        var script = addr.toOutputScript()
+      it('exports ' + f.script + '(' + f.network + ')', function () {
+        var script = Address.toOutputScript(f.base58check)
 
         assert.strictEqual(script.toASM(), f.script)
       })
@@ -85,10 +70,8 @@ describe('Address', function () {
 
     fixtures.invalid.toOutputScript.forEach(function (f) {
       it('throws when ' + f.description, function () {
-        var addr = new Address(new Buffer(f.hash, 'hex'), f.version)
-
         assert.throws(function () {
-          addr.toOutputScript()
+          Address.toOutputScript(f.address)
         }, new RegExp(f.description))
       })
     })
diff --git a/test/bitcoin.core.js b/test/bitcoin.core.js
index a2d5b52..2c058b5 100644
--- a/test/bitcoin.core.js
+++ b/test/bitcoin.core.js
@@ -47,15 +47,15 @@ describe('Bitcoin-core', function () {
   })
 
   // base58_keys_valid
-  describe('Address.formBase58Check', function () {
+  describe('Address.toBase58Check', function () {
     var typeMap = {
       'pubkey': 'pubKeyHash',
       'script': 'scriptHash'
     }
 
     base58_keys_valid.forEach(function (f) {
-      var string = f[0]
-      var hex = f[1]
+      var expected = f[0]
+      var hash = new Buffer(f[1], 'hex')
       var params = f[2]
       var network = networks.bitcoin
 
@@ -64,11 +64,10 @@ describe('Bitcoin-core', function () {
         network = networks.testnet
       }
 
-      it('can import ' + string, function () {
-        var address = Address.fromBase58Check(string)
+      var version = network[typeMap[params.addrType]]
 
-        assert.strictEqual(address.hash.toString('hex'), hex)
-        assert.strictEqual(address.version, network[typeMap[params.addrType]])
+      it('can export ' + expected, function () {
+        assert.strictEqual(Address.toBase58Check(hash, version), expected)
       })
     })
   })
@@ -90,7 +89,7 @@ describe('Bitcoin-core', function () {
           var address = Address.fromBase58Check(string)
 
           assert.notEqual(allowedNetworks.indexOf(address.version), -1, 'Invalid network')
-        }, /Invalid (checksum|hash length|network)/)
+        }, /Invalid (checksum|address length|network)/)
       })
     })
   })
diff --git a/test/ecpair.js b/test/ecpair.js
index 5137c52..4408ca1 100644
--- a/test/ecpair.js
+++ b/test/ecpair.js
@@ -171,7 +171,7 @@ describe('ECPair', function () {
       it('returns ' + f.address + ' for ' + f.WIF, function () {
         var keyPair = ECPair.fromWIF(f.WIF)
 
-        assert.strictEqual(keyPair.getAddress().toString(), f.address)
+        assert.strictEqual(keyPair.getAddress(), f.address)
       })
     })
   })
diff --git a/test/fixtures/address.json b/test/fixtures/address.json
index fff8d9a..02c36a1 100644
--- a/test/fixtures/address.json
+++ b/test/fixtures/address.json
@@ -34,12 +34,12 @@
       {
         "description": "hash too short",
         "base58check": "7SeEnXWPaCCALbVrTnszCVGfRU8cGfx",
-        "exception": "Invalid hash length"
+        "exception": "Invalid address length"
       },
       {
         "description": "hash too long",
         "base58check": "j9ywUkWg2fTQrouxxh5rSZhRvrjMkEUfuiKe",
-        "exception": "Invalid hash length"
+        "exception": "Invalid address length"
       }
     ],
     "fromOutputScript": [
@@ -59,8 +59,7 @@
     "toOutputScript": [
       {
         "description": "24kPZCmVgzfkpGdXExy56234MRHrsqQxNWE has no matching Script",
-        "hash": "751e76e8199196d454941c45d1b3a323f1433bd6",
-        "version": 153
+        "address": "24kPZCmVgzfkpGdXExy56234MRHrsqQxNWE"
       }
     ]
   }
diff --git a/test/integration/advanced.js b/test/integration/advanced.js
index 81998c4..23629a7 100644
--- a/test/integration/advanced.js
+++ b/test/integration/advanced.js
@@ -29,7 +29,7 @@ describe('bitcoinjs-lib (advanced)', function () {
     var keyPair = bitcoin.ECPair.makeRandom({
       network: bitcoin.networks.testnet
     })
-    var address = keyPair.getAddress().toString()
+    var address = keyPair.getAddress()
 
     faucetWithdraw(address, 2e4, function (err) {
       if (err) return done(err)
diff --git a/test/integration/basic.js b/test/integration/basic.js
index 4c90dcd..981ffb6 100644
--- a/test/integration/basic.js
+++ b/test/integration/basic.js
@@ -11,7 +11,7 @@ describe('bitcoinjs-lib (basic)', function () {
 
     // generate random keyPair
     var keyPair = bitcoin.ECPair.makeRandom({ rng: rng })
-    var address = keyPair.getAddress().toString()
+    var address = keyPair.getAddress()
 
     assert.strictEqual(address, '1F5VhMHukdnUES9kfXqzPzMeF1GPHKiF64')
   })
@@ -21,7 +21,7 @@ describe('bitcoinjs-lib (basic)', function () {
     var d = bigi.fromBuffer(hash)
 
     var keyPair = new bitcoin.ECPair(d)
-    var address = keyPair.getAddress().toString()
+    var address = keyPair.getAddress()
 
     assert.strictEqual(address, '1C7zdTfnkzmr13HfA2vNm5SJYRK6nEKyq8')
   })
@@ -34,7 +34,7 @@ describe('bitcoinjs-lib (basic)', function () {
 
     var keyPair = bitcoin.ECPair.makeRandom({ network: litecoin, rng: rng })
     var wif = keyPair.toWIF()
-    var address = keyPair.getAddress().toString()
+    var address = keyPair.getAddress()
 
     assert.strictEqual(address, 'LZJSxZbjqJ2XVEquqfqHg1RQTDdfST5PTn')
     assert.strictEqual(wif, 'T7A4PUSgTDHecBxW1ZiYFrDNRih2o7M8Gf9xpoCgudPF9gDiNvuS')
@@ -42,7 +42,7 @@ describe('bitcoinjs-lib (basic)', function () {
 
   it('can import an address via WIF', function () {
     var keyPair = bitcoin.ECPair.fromWIF('Kxr9tQED9H44gCmp6HAdmemAzU3n84H3dGkuWTKvE23JgHMW8gct')
-    var address = keyPair.getAddress().toString()
+    var address = keyPair.getAddress()
 
     assert.strictEqual(address, '19AAjaTUbRjQCMuVczepkoPswiZRhjtg31')
   })
diff --git a/test/integration/crypto.js b/test/integration/crypto.js
index 3d8f365..f70047e 100644
--- a/test/integration/crypto.js
+++ b/test/integration/crypto.js
@@ -35,7 +35,7 @@ describe('bitcoinjs-lib (crypto)', function () {
     assert.deepEqual(QprimeR.getEncoded(), QprimeS.getEncoded())
 
     // derived shared-secret address
-    var address = new bitcoin.ECPair(null, QprimeS).getAddress().toString()
+    var address = new bitcoin.ECPair(null, QprimeS).getAddress()
 
     assert.strictEqual(address, '1EwCNJNZM5q58YPPTnjR1H5BvYRNeyZi47')
   })
diff --git a/test/integration/multisig.js b/test/integration/multisig.js
index 15d5a73..7de1aa0 100644
--- a/test/integration/multisig.js
+++ b/test/integration/multisig.js
@@ -58,7 +58,7 @@ describe('bitcoinjs-lib (multisig)', function () {
         // make a random destination address
         var targetAddress = bitcoin.ECPair.makeRandom({
           network: bitcoin.networks.testnet
-        }).getAddress().toString()
+        }).getAddress()
 
         var txb = new bitcoin.TransactionBuilder()
         txb.addInput(unspent.txId, unspent.vout)
diff --git a/test/message.js b/test/message.js
index b478a66..fb116b0 100644
--- a/test/message.js
+++ b/test/message.js
@@ -4,7 +4,6 @@ var assert = require('assert')
 var message = require('../src/message')
 var networks = require('../src/networks')
 
-var Address = require('../src/address')
 var BigInteger = require('bigi')
 var ECPair = require('../src/ecpair')
 
@@ -23,14 +22,6 @@ describe('message', function () {
   })
 
   describe('verify', function () {
-    it('accepts an Address object', function () {
-      var f = fixtures.valid.verify[0]
-      var network = networks[f.network]
-
-      var address = Address.fromBase58Check(f.address)
-      assert(message.verify(address, f.signature, f.message, network))
-    })
-
     fixtures.valid.verify.forEach(function (f) {
       it('verifies a valid signature for "' + f.message + '" (' + f.network + ')', function () {
         var network = networks[f.network]
diff --git a/test/scripts.js b/test/scripts.js
index 4e0f644..f89c44a 100644
--- a/test/scripts.js
+++ b/test/scripts.js
@@ -1,10 +1,10 @@
 /* global describe, it */
 
 var assert = require('assert')
+var bcrypto = require('../src/crypto')
 var ops = require('../src/opcodes')
 var scripts = require('../src/scripts')
 
-var ECPair = require('../src/ecpair')
 var Script = require('../src/script')
 
 var fixtures = require('./fixtures/scripts.json')
@@ -177,10 +177,10 @@ describe('Scripts', function () {
       if (f.type !== 'pubkeyhash') return
 
       var pubKey = new Buffer(f.pubKey, 'hex')
-      var address = ECPair.fromPublicKeyBuffer(pubKey).getAddress()
+      var pubKeyHash = bcrypto.hash160(pubKey)
 
       it('returns ' + f.scriptPubKey, function () {
-        var scriptPubKey = scripts.pubKeyHashOutput(address.hash)
+        var scriptPubKey = scripts.pubKeyHashOutput(pubKeyHash)
         assert.strictEqual(scriptPubKey.toASM(), f.scriptPubKey)
       })
     })
diff --git a/test/transaction_builder.js b/test/transaction_builder.js
index ccb3ae0..09dcb9a 100644
--- a/test/transaction_builder.js
+++ b/test/transaction_builder.js
@@ -65,13 +65,13 @@ describe('TransactionBuilder', function () {
     txb = new TransactionBuilder()
 
     prevTx = new Transaction()
-    prevTx.addOutput(Address.fromBase58Check('1BgGZ9tcN4rm9KBzDn7KprQz87SZ26SAMH').toOutputScript(), 0)
-    prevTx.addOutput(Address.fromBase58Check('1cMh228HTCiwS8ZsaakH8A8wze1JR5ZsP').toOutputScript(), 1)
+    prevTx.addOutput(Address.toOutputScript('1BgGZ9tcN4rm9KBzDn7KprQz87SZ26SAMH'), 0)
+    prevTx.addOutput(Address.toOutputScript('1cMh228HTCiwS8ZsaakH8A8wze1JR5ZsP'), 1)
     prevTxHash = prevTx.getHash()
 
     keyPair = new ECPair(BigInteger.ONE)
     privAddress = keyPair.getAddress()
-    privScript = privAddress.toOutputScript()
+    privScript = Address.toOutputScript(privAddress)
   })
 
   describe('addInput', function () {
@@ -125,15 +125,6 @@ describe('TransactionBuilder', function () {
 
   describe('addOutput', function () {
     it('accepts an address string and value', function () {
-      var vout = txb.addOutput(privAddress.toBase58Check(), 1000)
-      assert.strictEqual(vout, 0)
-
-      var txout = txb.tx.outs[0]
-      assert.deepEqual(txout.script, privScript)
-      assert.strictEqual(txout.value, 1000)
-    })
-
-    it('accepts an Address object and value', function () {
       var vout = txb.addOutput(privAddress, 1000)
       assert.strictEqual(vout, 0)