Angel \”Java\” Lopez on Blog

May 30, 2016

Building A Blockchain (11)

Previous Post

I refactored the blockchain implementation in my personal JavaScript/NodeJS project:

https://github.com/ajlopez/SimpleBlockchain

In the previous post I showed some tests I wrote using TDD (Test-Driven Development) workflow. Now, I want to show the current implementation, that is an evolution from the past week one.

The implementation is at:

https://github.com/ajlopez/SimpleBlockchain/blob/master/lib/blockchains.js

There is a JavaScript “class”, implemented as a function:

function Blockchain(block) {
    var self = this;
    var blocks = [block];
    var blockstore = stores.blockstore();
    blockstore.save(block);
    
    this.bestBlock = function () { return blocks[blocks.length - 1]; }

In my new implementation, I’m using a block store. This object was able to save a block, and retrieve a block by hash, or retrieve the blocks with same number. But now, I added the retrieve by parent hash: that is, given a block hash, blockstore can retrieve all its know children. Given such functionality, the blockchain implementation evolved to use that feature. In this way, I don’t need to have a tree of blocks: given a block, I can retrieve all the tree of its descendants, from the blockstore.

Notice that the state of the blockchain has a naive implementation: only a JavaScript array, where the index coincides with the block number, starting with genesis block having 0 as number. My plan is to refactor this implementation, to support thousands or millions of blocks, using a block store based on disk. But now, using this naive implementation, I could explore the behavior of the node application.

The exposed method to add a block is:

this.add = function (block) {
    if (blockstore.hasBlockHash(block.hash))
        return;
        
    blockstore.save(block);
    
    if (getUnknownAncestor(block) != null)
        return;
    
    tryAdd(block);
}

If the block is know, then it implies it was already processed, then return.

If not, the block is saved in the in-memory store, and the first unknown ancestor hash is calculated. Maybe, the store has not ALL the ancestor chain up to genesis block. In this case, I cannot process the block.

If the block has a chain of ancestor that connects it to the genesis block, then I try to add the block to the blockchain:

function tryAdd(block) {
    if (isBestBlockChild(block))
        blocks.push(block);
    else if (isBetterBestBlock(block))
        tryFork(block);
        
    tryChildren(block);
}

It it is a direct child of the best block, it is added to the block (remember, a naive implementation, a simple array). If not, but it is a better block (it has a higher number), a fork to the block is performed. In any case, the children of the block are processed: maybe, the new block is the missing link to new candidate chains based on previously known blocks that were disconnected from genesis until the arrival of the new block.

These are the predicates I wrote:

function isBestBlockChild(block) {
    var bblock = self.bestBlock();
    
    return bblock.hash === block.parentHash && bblock.number === block.number - 1;
}

function isBetterBestBlock(block) {
    var bblock = self.bestBlock();
    
    return bblock.number < block.number;
}

This is the process of the children:

function tryChildren(block) {
    var children = blockstore.getChildren(block.hash);

    for (var n in children)
        tryAdd(children[n]);
}

Note: again, it is a naive implementation, that implies a recursion using tryAdd, that calls tryChildren. I could refactor to avoid recursion, a pending task.

Given a block, this function calculates the upward chain to its first ancestor included in the current blockchain, and then change the blockchain to have that chain:

function tryFork(block) {
    var newbranch = [block];
    var parentHash = block.parentHash;
    
    while (parentHash && blockstore.hasBlockHash(parentHash)) {
        var parent = blockstore.getByHash(parentHash);
        
        if (parent.hash === blocks[parent.number].hash)
            return switchToFork(newbranch);
            
        newbranch.push(parent);
        
        parentHash = parent.parentHash;
    }
}

The find of the first unknow ancestor of a block:

function getUnknownAncestor(block) {
    var parentHash = block.parentHash;

    while (parentHash && blockstore.hasBlockHash(parentHash)) {
        var parent = blockstore.getByHash(parentHash);
        
        if (parent.hash === blocks[parent.number].hash)
            return null;
        
        parentHash = parent.parentHash;
    }
    
    return parentHash;
}

The change of the blockchain to a new fork:

function switchToFork(newbranch) {
    for (var n = newbranch.length; n-- > 0😉 {
        var block = newbranch[n];
        blocks[block.number] = block;
    }
}

All the test passed. As I mentioned, my plan is to improve the implementation. But, as usual in my TDD workflow, I prefer to give baby steps, make it works, and only then, make it right and make it fast. I had good experiences using this way of writing code, obtaining simple and solid implementations, having all the test to help me to change any internal implementation, without pain.

Encouraged by this result, I also started to refactor my blockchain implementation in my personal C# project, too:

https://github.com/ajlopez/BlockchainSharp

I started to use a block store with GetByParentHash into my BlockChain code:

https://github.com/ajlopez/BlockchainSharp/blob/master/Src/BlockchainSharp/Core/BlockChain.cs

I wrote about my previous implementation in this post.

Stay tuned!

Angel “Java” Lopez

@ajlopez

May 27, 2016

ReactJS: Links And Resources (6)

Filed under: JavaScript, Links, React, Web Development — ajlopez @ 9:14 am

Previous Post

Going cross-platform with React
http://talks.artificial.io/cross-platform-react/#/

Sharing Code between React Web and Native Apps
http://jkaufman.io/react-web-native-codesharing/

Preact by developit
http://developit.github.io/preact/

ReactJS best practices for 2016
https://blog.risingstack.com/react-js-best-practices-for-2016

The State Of Meteor Part 2: What Happens Next – Discover Meteor
https://www.discovermeteor.com/blog/the-state-of-meteor-part-2-what-happens-next/

Flipboard/react-canvas
https://github.com/flipboard/react-canvas

Relay 101: Building A Hacker News Client
https://medium.com/@clayallsopp/relay-101-building-a-hacker-news-client-bb8b2bdc76e6#.qf6r8ij5x

Functional Geekery Episode 40 – David Nolen
https://www.functionalgeekery.com/episode-40-david-nolen/

The Case for React.js and ClojureScript
http://murilopereira.com/the-case-for-reactjs-and-clojurescript/#/

React Components, Elements, and Instances | React
https://facebook.github.io/react/blog/2015/12/18/react-components-elements-and-instances.html

How we unit test React components using expect-jsx
https://blog.algolia.com/how-we-unit-test-react-components-using-expect-jsx/

My Links
https://delicious.com/ajlopez/reactjs

Stay tuned!

Angel “Java” Lopez
http://www.ajlopez.com
http://twitter.com/ajlopez

May 23, 2016

Building A Blockchain (10)

Previous Post
Next Post

This week, I added more logic to my personal blockchain project in JavaScript:

https://github.com/ajlopez/SimpleBlockchain

I started to implement the blockchain logic using TDD (Test-Driven Development) workflow. A first test creating the blockchain object using a genesis block:

var blockchains = require('../lib/blockchains');
var blocks = require('../lib/blocks');

exports['create blockchain'] = function (test) {
    var genesis = blocks.block();
    var bc = blockchains.blockchain(genesis);
    
    test.ok(bc);
    test.equal(typeof bc, 'object');
    test.equal(bc.bestBlock(), genesis);
};

Then, I wrote a test exercising to add a new block:

exports['add block'] = function (test) {
    var genesis = blocks.block();
    var block = blocks.block(genesis);
    var bc = blockchains.blockchain(genesis);
    
    bc.add(block);
    
    test.equal(bc.bestBlock(), block);
};

The rejection of a block of the same height than the best block in blockchain:

exports['add block same height'] = function (test) {
    var genesis = blocks.block();
    var block = blocks.block(genesis);
    var block2 = blocks.block(genesis);
    
    var bc = blockchains.blockchain(genesis);
    
    bc.add(block);
    bc.add(block2);
    
    test.equal(bc.bestBlock(), block);
};

The adding of a block that is a child of the best block, and the rejection of a block that is not the descendant of the best block:

exports['add block with next height'] = function (test) {
    var genesis = blocks.block();
    var block = blocks.block(genesis);
    var block2 = blocks.block(block);
    
    var bc = blockchains.blockchain(genesis);
    
    bc.add(block);
    bc.add(block2);
    
    test.equal(bc.bestBlock(), block2);
};

exports['add block next height but another parent block'] = function (test) {
    var genesis = blocks.block();
    var block = blocks.block(genesis);
    var block2 = blocks.block(genesis);
    var block3 = blocks.block(block2);
    
    var bc = blockchains.blockchain(genesis);
    
    bc.add(block);
    bc.add(block3);
    
    test.equal(bc.bestBlock(), block);
};

These tests were written one by one, and each test was followed by the simplest implementation that pass the test. This is the spirit of TDD: baby steps, simple implementation, explicit description of expected behavior.

Next post: implementing account states, immutable states, and node communication.

Stay tuned!

Angel “Java” Lopez

http://www.ajlopez.com

http://twitter.com/ajlopez

May 22, 2016

Improvement Proposal to Blockchain Mining

Filed under: Bitcoin, Blockchain, Ethereum — ajlopez @ 2:29 pm

Recently, I read the post 25-second irreversible confirmations for instant payments by @sdlerner. He mentioned:

Bitcoin forwards a block by packing the block header with all the transactions contained in the block. This strategy, while being the most easy to analyze, is known to perform badly, both regarding block propagation latency and bandwidth usage. Since the transactions on a block are generally already known to the network, there is no benefit in transmitting them again.

The transactions included in the block could be replaced by a list of hashes. The receiving node could reconstruct the full block having the hashes of the known transactions, and reclaiming the unknown ones. The alternative is sending only the block header:

…Still another improvement is to forward the block header before even checking the transactions, and only checking the block PoW and height at forward time.Still another improvement is to forward the block header before even checking the transactions, and only checking the block PoW and height at forward time. This allows the header to spread over the network in less than a second. Nodes can then start mining an empty block on top of the header even if the transactions are still missing, during a fixed interval. After that interval, they resume mining in whatever block they were mining before.

(emphasis is mine) I’m not an expert on mining and network efficiency, but I could propose an improvement to this alternative, in Ethereum (where there are accounts). Instead of propagate only the block header, the miner could send an additional account predicate, P(acc), with the following property:

– P(acc) is true for every account involved in a transaction of the received block

An “account involved in a transaction” is the receiver account or the sender account. We must consider the receiver account because in Ethereum a receiver account could be a contract, and its appearance in a transaction implies that its state will be changed by the block execution. In a “only transfer” transaction, only the sending account can be considered “involved”. The key point: the receiver node (the node that receives the new block header and account predicate) CANNOT be sure about the state of the involved accounts. So, it cannot use them in new block.

But every account that not satisfies the predicate can be used in any transaction, to be included in a new block.

The improvement proposal is: instead of “start mining an empty block”, the receiver node can start mining on a new block with any pending transactions whose account DOES NOT satisfies the received predicate. Those account does not have their states affected by the still unknown transactions included in the block that has the just received block header. Then, they can be used in any new block. They states are the same after the incoming block execution than after its processing.

How to send such predicates? One option is to have a Bloom filter. Again, I’m not an expert on Bloom filters. but I can imagine a list of bits. As a concrete example, I could use 16 bits. If an account, included in a transaction of the new block, has a public key that ends with hexadecimal 0, the first bit is on. If an involved account public key ends with hexadecimal A, the eleventh bit is on. In this way, they can be false positives applying the filter, but every involved account satifies the predicate, and the receiver node never includes an invalid transaction in the next block to mine.

The length of this bit field could be optimized according to the mean number of transactions per block. If the number of transactions per block is around 16, then the length of bits could be 32, to have a great chance of having pending transactions in the receiver node that are candidated to be included in the new block to mine.

It can be this proposal adapted to Bitcoin and related mining process? I’m think it cannot. A bloom filter of transactions can be send, but then, the receiving block is not sure about what pending transactions are candidates to be mined, in an easy way. I think that a list of transactions hashes could be more effective than a Bloom filter.

I’m not sure if this proposal has any concrete benefits, but I feel it is an interesting path to explore.

Note: I’m part of development team of @RSKsmart where @sdlerner is the Chief Scientific Officer.

Stay tuned!

Angel “Java” Lopez
http://www.ajlopez.com
http://twitter.com/ajlopez

May 19, 2016

ReactJS: Links And Resources (5)

Filed under: JavaScript, Links, React, Web Development — ajlopez @ 9:50 am

Previous Post
Next Post

JavaScript’s History and How it Led To ReactJS – The New Stack
http://thenewstack.io/javascripts-history-and-how-it-led-to-reactjs/

Comprehensive Beginner’s Guide To ReactJS – AntJanus
http://antjanus.com/blog/web-development-tutorials/front-end-development/comprehensive-beginners-guide-to-reactjs/

React Base Fiddle (JSX) – JSFiddle
https://jsfiddle.net/reactjs/69z2wepo/

ReactJS – Building Web Apps w/JavaScript
https://www.reddit.com/r/reactjs/

React.js in Real Life at Codecademy
http://www.infoq.com/articles/reactjs-codecademy

Learning React.js: Getting Started and Concepts | Scotch
https://scotch.io/tutorials/learning-react-getting-started-and-concepts

React.js cheatsheet
http://ricostacruz.com/cheatsheets/react.html

React integration for ASP.NET MVC | ReactJS.NET
http://reactjs.net/

React.js – A guide for Rails developers
https://www.airpair.com/reactjs/posts/reactjs-a-guide-for-rails-developers

ReactJS For Stupid People
http://blog.andrewray.me/reactjs-for-stupid-people/

React
https://github.com/reactjs

Mancy NodeJs Repl
http://www.mancy-re.pl/

GraphQL Introduction | React
https://facebook.github.io/react/blog/2015/05/01/graphql-introduction.html

Simon Tucker: quasar.meteor.com — video chat with webRTC + react/flux – September Devshop SF – YouTube
https://www.youtube.com/watch?v=C0S_QCb6HSM&feature=em-subs_digest

blog.brng.us
http://blog.brng.us/2015-08-17-wiring-refluxt-and-react-to-phoenix-websockets.html

Best tips and practices from React.js experts | Toptal
http://www.toptal.com/react/tips-and-practices

React and Flux… and a little Redux
http://likethemammal.github.io/reacttalk/

Creating Isomorphic Apps with Node.js, React, and Express
http://www.sitepoint.com/creating-isomorphic-apps-node-js-react-express/

Learn React, Flux, and Flow: Part I – YouTube
https://www.youtube.com/watch?v=Pd6Ub7Ju2RM

How does ReactJS Native compare with Titanium? – Quora
http://www.quora.com/How-does-ReactJS-Native-compare-with-Titanium

My Links
https://delicious.com/ajlopez/reactjs

Stay tuned!

Angel “Java” Lopez
http://www.ajlopez.com
http://twitter.com/ajlopez

May 16, 2016

Building A Blockchain (9)

Filed under: Bitcoin, Blockchain, Ethereum, JavaScript, NodeJs, Open Source Projects — ajlopez @ 10:32 am

Previous Post
Next Post

You already know my personal blockchain project in C#:

https://github.com/ajlopez/BlockchainSharp

This week I started another implementation, using JavaScript/NodeJS:

https://github.com/ajlopez/SimpleBlockchain

It is interesting to compare a typed language implementation with another without types.

The base concepts are: blocks, transactions, a blockchain, etc. I’m writing the code using TDD (Test-Driven Development) workflow, as usual. The idea is to implement those base entities, and then, write a node program that can communicate with other nodes in the network, exchanging transactions and new mined blocks. My intention is to use JSON messages, instead of byte streams. But the format could be an decision to change. By now, I have some simple behavior implemented, covered by the corresponding tests.

These are my initial block tests:

exports['create genesis block'] = function (test) {
    var block = blocks.block();
    
    test.ok(block);
    test.equal(typeof block, 'object');
    test.equal(block.number, 0);
    test.ok(isHash(block.hash));
    test.ok(isHash(block.parentHash));
    test.equal(block.parentHash, '0x000....000000');
}

exports['create child block'] = function (test) {
    var genesis = blocks.block();
    var block = blocks.block(genesis);
    
    test.ok(block);
    test.equal(typeof block, 'object');
    test.equal(block.number, 1);
    test.ok(isHash(block.hash));
    test.ok(isHash(block.parentHash));
    test.equal(block.parentHash, genesis.hash);
}

exports['create child block with initial data'] = function (test) {
    var genesis = blocks.block();
    var block = blocks.block({ extra: 'hello' }, genesis);
    
    test.ok(block);
    test.equal(typeof block, 'object');
    test.equal(block.number, 1);
    test.ok(isHash(block.hash));
    test.ok(isHash(block.parentHash));
    test.equal(block.parentHash, genesis.hash);
    test.equal(block.extra, 'hello');
}

I wrote these tests one by one, and after each test, I implemented the code that makes the test pass. In this way, I wrote the simplest solution that satisfies the expected behavior. And I can refactor the implementations to a more powerful one without unnoticed breaking changes: every behavior is backed up by a test.

After the base entities, I need some auxiliary entities that allow the efficient process of blocks and transactions. One of this helper entities is a block store: where to save and retrieve blocks using hash, parent hash or number. By now, I have an in memory implementation. Some tests:

exports['create store'] = function (test) {
    var store = stores.blockstore();
    
    test.ok(store);
    test.equal(typeof store, 'object');
};

exports['retrieve unknown block by hash'] = function (test) {
    var store = stores.blockstore();
    
    var block = store.getByHash(utils.hash());
    
    test.equal(block, null);
};

exports['save block and retrieve it by hash'] = function (test) {
    var store = stores.blockstore();
    var hash = utils.hash();
    var block = { hash: hash };
    
    store.save(block);
    
    var result = store.getByHash(hash);
    
    test.ok(result);
    test.equal(result.hash, hash);
};

I will work on both projects: C# project needs some network code, and JavaScript project needs a blockchain implementation. I want to explore an alternative implementation for the blockchain growth. One nice thing about JavaScript implementation is that I don’t need to worry about multithreading issues. I can wrote code that changes the blockchain structure without having to check concurrent access.

Stay tuned!

Angel “Java” Lopez

http://www.ajlopez.com

http://twitter.com/ajlopez

May 12, 2016

Blockchain: Links And Resources (3)

Filed under: Bitcoin, Blockchain, FinTech, Links — ajlopez @ 10:16 am

Previous Post

Blockchain in insurance
https://www.insly.com/en/blog/the-evolving-focus-of-the-blockchain-in-insurance

Security, blockchain & funding: 10 fintech wishes every CIO wants for 2016 – Computer Business Review
http://www.cbronline.com/news/verticals/finance/security-blockchain-funding-10-fintech-wishes-every-cio-wants-for-2016-4758274

Meet Our Team: Candace, Tori, & Kevin | Blockchain Blog
https://blog.blockchain.com/2015/12/21/meet-our-team-candace-tori-kevin/

Technology: Banks seek the key to blockchain – FT.com
http://www.ft.com/intl/cms/s/2/eb1f8256-7b4b-11e5-a1fe-567b37f80b64.html#axzz3vEU23zMT

With 2016 set to be another great year for innovation, what should the industry be preparing for? – bobsguide.com
http://www.bobsguide.com/guide/news/2015/Dec/22/with-2016-set-to-be-another-great-year-for-innovation-what-should-the-industry-be-preparing-for.html

What’s the future of blockchain?
https://agenda.weforum.org/2015/12/whats-the-future-of-blockchain/

Blockchain visualisation
http://dailyblockchain.github.io/

Top 10 Southeast Asian Blockchain, Bitcoin Startups | Fintech Singapore
http://fintechnews.sg/1151/blockchain/top-10-southeast-asian-blockchain-bitcoin-startups/

insight
https://insight.is/

BitcoinJS Project – BitcoinJS
http://bitcoinjs.org/

blockchain-wallet
https://www.npmjs.com/package/blockchain-wallet

blockchain
https://www.npmjs.com/package/blockchain

Block.io: Bitcoin API and More
https://block.io/api/nodejs

Top Banks Will Spend $400M on Blockchain Technology by 2019 – CoinSpeaker
http://coinspeaker.com/2015/12/19/bank-of-america-files-patent-on-blockchain-sentry/

13 Plus Blockchain Startups from the US | Let’s Talk Payments
http://letstalkpayments.com/top-us-blockchain-startups/

My Links
http://delicious.com/ajlopez/blockchain

Stay tuned!

Angel “Java” Lopez
http://www.ajlopez.com
http://twitter.com/ajlopez

May 9, 2016

Building A Blockchain (8)

Previous Post
Next Post

In previous post, I wrote about the virtual machine I’m implementing in my personal blockchain project, in C#, using TDD (Test-Driven Development) workflow:

https://github.com/ajlopez/SimpleBlockchain

I added a simple bytecode compiler, in order to simplify some tests. The class is not needed for production code, but it is included in the core project:

public class BytecodeCompiler
{
    private IList<byte> bytes = new List<byte>();

    public void Stop()
    {
        this.Compile(Bytecodes.Stop);
    }

    public void Add()
    {
        this.Compile(Bytecodes.Add);
    }

    public void Subtract()
    {
        this.Compile(Bytecodes.Subtract);
    }
    
    // more methods
    
    public byte[] ToBytes()
    {
        return this.bytes.ToArray();
    }
}

It collects a series of bytecodes, with optional arguments. There is a method to return a byte array with the compiled program. A sample test:

[TestMethod]
public void LessThan()
{
    BytecodeCompiler compiler = new BytecodeCompiler();

    compiler.Push(2);
    compiler.Push(2);
    compiler.LessThan();
    compiler.Push(0);
    compiler.Push(1);
    compiler.LessThan();
    compiler.Push(1);
    compiler.Push(0);
    compiler.LessThan();

    Machine machine = new Machine();

    machine.Execute(compiler.ToBytes());

    var stack = machine.Stack;

    Assert.IsNotNull(stack);
    Assert.AreEqual(3, stack.Size);
    Assert.AreEqual(DataWord.Zero, stack.ElementAt(2));
    Assert.AreEqual(DataWord.Zero, stack.ElementAt(1));
    Assert.AreEqual(DataWord.One, stack.ElementAt(0));
}

I also wrote a simple line compiler, named SimpleCompiler. Now, I can use it in my machine tests:

[TestMethod]
public void IsZeroUsingSimpleCompiler()
{
    string program = "push 2\n" +
        "iszero\n" +
        "push 0\n" +
        "iszero";

    SimpleCompiler compiler = new SimpleCompiler(program);

    Machine machine = new Machine();

    machine.Execute(compiler.Compile());

    var stack = machine.Stack;

    Assert.IsNotNull(stack);
    Assert.AreEqual(2, stack.Size);
    Assert.AreEqual(DataWord.Zero, stack.ElementAt(1));
    Assert.AreEqual(DataWord.One, stack.ElementAt(0));
}

These are auxiliary classes, but they simplify the writing of new tests. It is part of my simplification strategy: after some initial and long tests, try to simplify the writing of the newer ones.

In the next post, a surprise: a new blockchain project, but using NodeJS, JavaScript.

Stay tuned!

Angel “Java” Lopez

http://www.ajlopez.com

http://twitter.com/ajlopez

May 8, 2016

New Month’s Resolutions: May 2016

Filed under: C Sharp, JavaScript, NodeJs, Open Source Projects, Wang Tiles — ajlopez @ 5:27 pm

Time to write my new month’s resolutions, and review the previous month’s ones:

– Improve WangTiles [complete] see repo
– Improve BlockchainSharp [complete] see repo
– Start Blockchain in JavaScript [complete] see repo
– Work on EthSharp [pending]
– Improve SimpleGA [pending]
– Improve AjGenesisNode-Express [pending]
– Work on CrysJS [pending]
– Work on CrysSharp [pending]

Additionally, I worked on:

– Improve SimpleForth [complete] see repo
– Start WangTilesJS [complete] see repo

My new month’s resolutions are:

– Improve WangTiles
– Improve WangTilesJS
– Improve CrysSharp
– Improve BlockchainSharp
– Improve SimpleBlockchain
– Prepare and give a Bitcoin related talk

Stay tuned!

Angel “Java” Lopez
http://www.ajlopez.com
http://twitter.com/ajlopez

May 5, 2016

Redis: Links, News And Resources (9)

Filed under: Links, NoSQL, Redis — ajlopez @ 9:36 am

Previous Post

ASP.NET WebApi – Use Redis as CacheManager – CodeProject
http://www.codeproject.com/Tips/825904/ASP-NET-WebApi-Use-Redis-as-CacheManager

ASP.NET WebAPI – Basic Redis – CodeProject
http://www.codeproject.com/Tips/825903/ASP-NET-WebAPI-Basic-Redis

Slava:redis-livedata package | Atmosphere
https://atmospherejs.com/slava/redis-livedata

Slava:miniredis package | Atmosphere
https://atmospherejs.com/slava/miniredis

Redis developers meeting 2014
http://devmeeting2014.redis.io/

ryantanner/websocketchat-redis
https://github.com/ryantanner/websocketchat-redis

Cache
http://azure.microsoft.com/en-us/services/cache/

Queues and databases – Antirez weblog
http://antirez.com/news/78

etaty/rediscala
https://github.com/etaty/rediscala

danielstjules/redislock
https://github.com/danielstjules/redislock?utm_source=nodeweekly&utm_medium=email

hummingbird-me/hummingbird
https://github.com/hummingbird-me/hummingbird

justinfreitag/node-redis-client
https://github.com/justinfreitag/node-redis-client

Sketching & Scaling: Everyday HyperLogLog | Official Kiip Blog
http://blog.kiip.me/engineering/sketching-scaling-everyday-hyperloglog/

Scaling SQL with Redis – David Cramer’s Blog
http://cramer.io/2014/05/12/scaling-sql-with-redis/

My Links
http://delicious.com/ajlopez/redis

Stay tuned!

Angel “Java” Lopez
http://www.ajlopez.com
http://twitter.com/ajlopez

Older Posts »

The Shocking Blue Green Theme. Create a free website or blog at WordPress.com.

Follow

Get every new post delivered to your Inbox.

Join 73 other followers