@asalvatore/microchain
v1.4.10
Published
Microchain is a #Javascript lib for creating small #blockchain for content and ownership hosting on Node JS & Web client. Project in progress.
Downloads
54
Maintainers
Readme
Microchain 💴 (alpha)
Microchain is a blockchain Lib specially designed to run in browser & Node JS environnement, used to propel forum, allowing file posting in transactions and making theses files expirable to manage the size of the blockchain. The next coming feature will be the administration of the blockchain (content moderation, money making, forcing difficulty, etc.) with a list of public keys known as Founders, hosted in the genesis block.
There is no dependence to any other blockchain infrastructure. You create your very own blockchain with few lines of javascript.
:warning: It's still work in progress, please don't use it for production
Links
- Github: https://github.com/salvatoreparis/microchain
- Documentation: http://microchain.salvatore.paris
Installation
npm i @asalvatore/microchain
Basics
Create and add a block to the chain instance
import { Blockchain, Wallet, Block } from "@asalvatore/microchain";
// initialize a wallet
// with no option, it generate it self a public and private key
const walletSato = new Wallet();
// Get the instance of the chain. Also pass the config of it, with fees and if TX content are fungible or not.
const chain = Blockchain.init({
// Pass the genesis block param has options
// It's the config of your blockchain!
// If you change it, the ancients mined block wont be accepted
GENESIS_BLOCK: {
publisher: walletSato.publicKey,
},
});
// Create and sign a transaction
const transaction1 = walletSato.createTransaction({
sender: walletSato.publicKey,
content: "https://pbs.twimg.com/media/EwxqyQdXMAAlqIb?format=jpg&name=medium",
});
const block1 = new Block({
height: chain.lastBlock.height + 1,
publisher: walletSato.publicKey,
prevHash: chain.lastBlock.hash,
transactions: JSON.stringify([transaction1]),
});
// Sign the block with the miner wallet
block1.sign(walletSato);
// Launch the mining process
block1.mine();
// After mining we add the block to the chain
chain.addBlock(block1);
// We log to see if all was added to the chain
chain.logChain();
// Get all the UTXO information
// ownershipPool: for each publickey what id is owned as what ratio
// moneyPool: for each publickey what amount of money is owned
chain.getBank().log();
To listen events on the chain you can use blockAdded.
chain.on("blockAdded", () => {
let data = JSON.stringify(chain.chain);
fs.writeFileSync("chain.json", data);
});
Create expirable content
Expirable content is a content hosted in a transaction. Blocks need to host it till the expiration date. In the following exeample you add TX_CONTENT_EXPIRATION_HOURS , which is the expiration limit for content to the config (24h by default), and add your data to the transaction content propretie. Example in tests/testExpirable.js.
- MONEY_BY_BLOCK is the amount of money you get by a mined block.
- MONEY_BY_KO is the amount of money you need by Ko to post content in transactions (note than there's also properties to manage the miningfees).
- TX_CONTENT_MAX_SIZE_KO the max size of a transaction content in Ko, default is 250 Ko.
- BLOCK_MAX_SIZE_KO the max size of a block in Ko, default is 300 Ko.
import { Blockchain, Wallet, Block } from "@asalvatore/microchain";
import fs from "fs";
import { img2 } from "./assets/img2.js";
let blocks = null;
// try to read if file
if (fs.existsSync("chainExpirable.json")) {
const rawdata = fs.readFileSync("chainExpirable.json");
if (rawdata) blocks = JSON.parse(rawdata);
}
// Init the wallet using existing public & private keys
const walletSato = new Wallet(
"04820be6a65e928d52e92b8bfe7827de7a09d3afa1356ef81f6f8528b44ba84393d32b44e4590fa9ca6b9576a6d7f2f0467af33d8f68f83e1359a8e4981f4ed5f6",
"b6d7cf41b14a972dc3b294ea9ec0c763886e7cb9699214192f2479791ec845e8"
);
const chain = Blockchain.init(
// It's the config of your blockchain!
// If you change it, the ancients mined block wont be accepted
{
// The hash method use to hash block and transactions
BLOCK_HASH_METHOD: "MD5",
// The maximum difficulty to hash a block (number of 0 at the start of the block)
BLOCK_MAX_DIFFICULTY: 5,
// When the content of block expire to liberate size in the chain?
TX_CONTENT_EXPIRATION_HOURS: 12,
// Money you earn by block
MONEY_BY_BLOCK: 15,
// Money you need to use by KO of content KO
MONEY_BY_KO: 1.2,
GENESIS_BLOCK: {
// Public key of the publisher of the genesis
publisher: walletSato.publicKey,
},
},
blocks
);
const transaction1 = walletSato.createTransaction({
sender: walletSato.publicKey,
content: img2,
});
transaction1.sign(walletSato);
//Return if there is enought money for this transaction for this transaction
chain.enoughtMoneyFrom(transaction1, walletSato.publicKey);
chain.getBank().log();
const block = new Block({
height:
chain.lastBlock && (chain.lastBlock.height || chain.lastBlock.height === 0)
? chain.lastBlock.height + 1
: 0,
publisher: walletSato.publicKey,
transactions: JSON.stringify([transaction1]),
prevHash: chain.lastBlock && chain.lastBlock.hash ? chain.lastBlock.hash : "",
});
// Don't forget to sign the block with your wallet!
block.sign(walletSato);
// Launch the mining, it couls take a while!
block.mine();
// also don't forget to add the block to the chain!
chain.addBlock(block);
Change log
V 1.4.4 + 1.4.10
- More methods on the Bank : getAllOwnershipsForToken(block1.hash) and getOwnershipsForSender(walletSato.publicKey) + bug fix
- Took off some loggin error in the Blockchain object
- Avoid Double ownership in the bank ???
V 1.4.2 + 1.4.3
- Corrected bug on lastBlock & longuestBlockchain and also took off the logs ^^
- Added a setLogger method on blockchain to activate the logging, to avoid slowing down the chain calculations
- Changed the lastBlock method to be sure to have the top block and not the last block.
V 1.3.0
- Added the getBank() method in Blockchain to ownership and money pools, as the Class Bank
- Added iterationMax optional param, to Block.mine( numMaxIteration) method, adding a maximum iteration to the mining loop, to avoid freeze web UI. See tests/testMining.js
V 1.2.2 (fix)
- Added the index.js at the root of the module (really sorry because previous were not working -_-)
- Added lotta thing to the .gitignore
- changed the read-me because .logChain() is now .logBlockchain()
V 1.1.1 (fix)
- Take off the non-fungible content in config. Not bahaving properly.
- use the addBlock method for the genesis block
V 1.1.0
- Added expirable content in transaction.
- added a channel property in transaction propertie, for crypted conversation when content is crypted.
- added the config's Hash to all block mined.
- added the GENESIS_BLOCK to config. It's the properties you want in the geneseis block
V 1.0.11
- Added an number of average of the last n blocks to calculate the difficulty, but the result isn't very convincing. You can use it with the BLOCK_HASH_RATE_AVERAGE property of the Config class. It's 1 by default.
- Added the "blockAdded" event emitters on the chain instance.
- The chain constructor can know take an existing list of block as second parameter.
- Difficulty is now a comparison between block height-1 and block height-BLOCK_HASH_RATE_AVERAGE-1. It's to keep the diffiiculty constant during mining.
- Renamed the class Chain to Blockchain, because chain.chain is not pretty.
- Checking block validity before adding them to the chain, especialy difficulty, timestamp and height coherence.
V 1.0.10
- Property BLOCK_HASH_METHOD added to the Config class, you can pass "SHA256" or "MD5"
- Added difficulty management. use this script to test an Hash rate of 2 minutes.
npm run testDifficulty
To Do
- Send instruction(s) form the founders of the chain to administrate it.
- re-initiate the UTXOPool with the longuest chain after each block add.
- manage block and transaction announce with webRTC?
Author
I am Alexandre Salvatore & you can contact me on Twitter https://twitter.com/salvator_io
Or by mail at [email protected]