0.0.4 • Published 8 years ago

reduxu-chain v0.0.4

Weekly downloads
1
License
MIT
Repository
-
Last release
8 years ago

reduxu-chain

yeah, I am yet another blockchain implementation in javascript.

See example on https://codesandbox.io/s/34wm9xq8m5

Simple state container like implementation of the blockchain driven flowtype checked, this is in an super early stage and can fail...

Key concepts of reduxu-chain

  • A tiny redux like implementation of the blockchain.
  • Typed with flowtypes, styled by prettier.
  • Allows minning the block or build some kind of smart contract.
  • A consensus algorithm, simple proof-of-work or proof-of-stake implementation using nonce
  • Built by rollup, it should work on web and node, but tried it for react-native

Table of Contents

Installation

Using yarn:

$ yarn add reduxu-chain

Dependencies

  • mitt an awesome tiny library to broadcast a block notification through a middleware
  • crypto-js is here to generate sha256 hash for each block

Usage

import rootReducer from "./rootReducer";

import {
	createStore,
	eventEmitterMiddleware,
	applyMiddleware,
	Block,
} from "reduxu-chain";

export default class ReduxuStore {
	constructor() {
		this.store = createStore(rootReducer);		
		applyMiddleware(this.store, eventEmitterMiddleware);		
	}

	addBlock(block) {
		return this.store.addBlock(block);
	}
	mineBlock(block) {
		return this.store.mineBlock(block);
	}
	getLastBlock() {
		return this.store.getLastBlock();
	}
	addTransaction() {
		// add transaction or define any smart contract
		const tx = {
			timestamp: new Date().getTime() / 1000,
		};
		this.store.dispatch({
			type: "ADD_TRANSACTION",
			tx,
		});
	}

	// Add a block into the local BlockChain
	mineChain(data) {

		// this one is the last as of now but might not be after minning
		const lastBlock = this.store.getLastBlock();
		const block = new Block({
			previousBlock: lastBlock,
			data,
		});

		// consensus algorithm
		return mineBlock(this.store, block).then(() => {
			// resolved the nonce, hash is valid, let's see if others resolved first	
			return store.addBlock(block).then((blockchain) => {
				// cool
				console.log("minning it");
			})
		});
	}
}
class MyComponent extends React.Component {
	addTransaction() {
		this.store1.addTransaction();
		this.setState({
			block1: {
				blockInfo: this.store1.getLastBlock(),
				transactions: this.store1.getLastBlock().data.length.toString(),
			},
		});
	}
	render() {
		return (
			<Card>
				<CardContent>
					<Title>Store 1 Local Block Info</Title>
					<Caption>
						{this.state.block1.transactions} open transactions
					</Caption>
					<Paragraph>{JSON.stringify(this.state.block1.blockInfo)}</Paragraph>
				</CardContent>
			</Card>
		);
	}
}

Simple middleware to handle side effects using eventEmitterMiddleware ( or build yours )

let emitter = new mitt();
export default function eventEmitterMiddleware(MyStore: Store) {
	emitter.on("blocks_received", (action: Action) => {
		// update my local blockchain difficulty and blocks
		// the entire blockchain or just the lasts blocks to amend
		MyStore.replaceChain(action.newBlocks, action.difficulty);
	});
	return function(dispatch: *) {
		return function eventEmitterDispatch(action: Action) {

			if (action.type === "@Blockchain/NEW_BLOCK") {
				// fire an event when accepted a new block
				emitter.emit('blocks_received', action);
			}
			dispatch(action);
		};
	};
}

Definitions

The block

// @flow

interface IBlock {
	hash: string;
	// define your state, any kind of transaction state can be here
	+data: State;
	// serialized data, this might go through p2p, but I am not trackling that as of now
	_data: string;
	// optional props
	previousBlock?: IBlock;
	// integrity to the chain is validated in block each time.
	previousHash: string;
	// privates
	// timestamp to create the hash
	+timestamp: number;
	// validates the block after minning
	nonce: number;
}

Action creators

// @flow

export type BlockchainAction =
	| {
			// action dispatched when the store is created, and it is not handled by the middlewares 
			type: "@Blockchain/INIT",
		}
	| {
			// action dispatched when new block is added to the local chain
			type: "@Blockchain/NEW_BLOCK",
			newBlock: IBlock,
			difficulty: number,
		};

The blockchain

// @flow

interface IBlockChain {
	// the entire blockchain
	chain: Array<IBlock>;
	// amount of zeros before the hash, increments the nonce till get it right, this brings security to the transaction and it is kind of useless :)
	difficulty: number;
	// works along with getLastBlock() if this chain is last one, you did it.
	// emmits
	addBlock: (newBlock: IBlock) => Promise<*>;
	getLastBlock: () => IBlock; // returns a block that might not be the last one :(
	// replacing the local chain and trying to emit your change
	replaceChain: (newBlocks: Array<IBlock>, difficulty: number) => void;
	// minning a just a block
	mineBlock: (newBlock: IBlock) => Promise<*>;
}

Related projects

Awesome inspiring projects I looked into!!!

Contribute

Thanks for taking the time to contribute!

Credits

This project was originally forked and inspired from blockchain-redux and the awesome work of Swizec Teller 👍

TODO

  • Allows implementing a P2P communication through a redux applyMiddleware(somethingMiddlewareP2PLike)
  • Allows designing your reducers to develop a transaction handler or your smart contract and data: State should be serialized.

License

MIT License