GOAL: A Proof-of-Stake Blockchain that can fully run its the consensus on the browser with support for different CPUs speed and tolerance to Winner-Takes-All, Nothing-At-Stake and other attacks.
NodeJS: Expected version "^16.14.0 || >=18.0.0".
Also install TypeScript if not already available:
npm install -g typescript
To build, create a new local keypair (coinbase) and start mining in a new network:
wget https://raw.githubusercontent.com/hyperhyperspace/pulsar/main/boot-pulsar.sh;
chmod +x ./boot-pulsar.sh;
sh ./boot-pulsar.sh;
To run/mine with an existing network use option --network=
or -n
and create a new local coinbase keypair wallet:
yarn start --network="butcher fire flag"
To run/mine with an existing coinbase keypair wallet use option --coinbase=
or -c
:
yarn start --coinbase="depth curious pound"
yarn test # and good to test
# 0) git
sudo yum update -y
sudo yum install git -y
# 1) nodejs
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.34.0/install.sh | bash
. ~/.nvm/nvm.sh
nvm install node
# 2) yarn
curl -o- -L https://yarnpkg.com/install.sh | bash
# 3) extras
npm install typescript -g
npm install microbundle-crl -g
# 4) start a new console
transfer(to,amount)
: only if balance(sender) >= amount
.increaseAllowance(to,amount)
.decreaseAllowance(to,amount)
.transferFrom(from,to,amount)
: only if allowance(from,sender) >= amount
.stake(amount)
: moves to staked
balance the amount
of sender
.unstake(amount)
: this transaction frees the funds after 7 days.delegateStake(to,amount)
: moves to delegatedStake
of to
the amount
of sender
.undelegateStake(to,amount)
: this transaction frees the funds after 7days.delayedTransfer(to,amount,delay)
: lock amount
until blocktime+delay
seconds happens.lockedTransfer(to,amount,hash)
: lock amount
until an unlock happens. Generates an unique txId
.unlockTransfer(txId,x,sig)
: only transfers txId.amount
locked before if H(x) == txId.hash
and if sender == txId.to
.lockTimedTransfer(to,amount,delay)
: lock amount
until blocktime+delay
seconds happens, then it expires. Generates an unique txId
.unlockTimedTransfer(txId,x,sig)
: only transfers txId.amount
locked before time blocktime+delay
and if sender == txId.to
.initMultiSig(n,[sign_1, ..., sign_n],m)
: makes sender
address to become a multisig wallet with n
signataries, and needing m
signataries to validate a transfer.multiSigTransfer(from,to,amount)
: if sender
is in the list of signataries of multisig from
then the signer is voting to execute the transfer, if #signers >= m
then the transfer gets executed.multiSigReset(from)
: for sender
in the list of signataries, the resetting of the wallet is voted, if #signers >= m
then all incomplete votings on the address from
are removed.There is a paper called Formal Barriers to Longest-Chain Proof-of-Stake Protocols describing limitations to Longest-Chain Fork-choice on Proof-of-Stake blockchains. Technically we are using something we call Average Fastest Chain as a Fork-choice, then is not exactly Nakamoto Consensus's Longest-Chain. We choose the change with the smallest average number of VDF steps per block. In the same line, this fork-choice if more difficult to attack with attacks of common types explore in bibliography (On the Instability of Bitcoin Without the Block Reward).
There is something called Speed Ratio that is part of the consensus. This ratio allows an exponential penalty on the linear difficulty that the miner face based on the random slot that the miner recieved. The exponential penalty (within certain bounds) avoids faster miners jumping from one slot to the previous one, avoiding faster miners to propose more blocks than their stake allows (in average).