-
-
Notifications
You must be signed in to change notification settings - Fork 18
Plasma Fraud Proof Challenge
At Parsec Labs we ❤️ fraud proofs! Fraud proofs power the security of our Plasma chain and keep the validators in check. We have set up a chain on the Rinkeby testnet, but some malicious validators have submitted invalid blocks or withheld block data! 😱 Help us to invalidate the blocks and slash the validators' stakes. 💪 Participate with the following steps:
- Review blocks.
- Submit 3 different fraud proofs.
- Submit next block.
Each successful transaction will receive one of the crypto-kitties shown in the Plasma presentation.
1. Install Fraud Proof Library:
npm install parsec-lib
also check out the repository.
2. Get Rinkeby Ether:
3. Bind to contract:
0xc119429d57b4b5b46d17cc4277b35e222989d5a4
Hint: use Remix for simplicity of reading and writing to contract.
pragma solidity ^0.4.24;
contract ParsecBridge {
struct Period {
bytes32 parent; // the id of the parent node
uint32 height; // the height of last block in period
uint32 parentIndex; // the position of this node in the Parent's children list
uint8 slot;
uint32 timestamp;
uint64 reward;
bytes32[] children; // unordered list of children below this node
}
mapping(bytes32 => Period) public periods;
struct Deposit {
uint64 height;
uint16 color;
address owner;
uint256 amount;
}
mapping(uint32 => Deposit) public deposits;
uint256 public epochLength; // length of epoch in periods (32 blocks)
bytes32 public tipHash;
// return (slot.eventCounter, slot.owner, slot.stake, slot.signer, slot.tendermint, slot.activationEpoch, slot.newOwner, slot. newStake, slot.newSigner, slot.newTendermint);
function getSlot(uint256 _slotId) constant public returns (uint32, address, uint64, address, bytes32, uint32, address, uint64, address, bytes32);
function bet(uint256 _slotId, uint256 _value, address _signerAddr, bytes32 _tenderAddr, address _owner) public;
function submitPeriod(uint256 _slotId, bytes32 _prevHash, bytes32 _root, uint256 _sigs) public;
function reportDoubleSpend(bytes32[] _proof, bytes32[] _prevProof) public;
function challengeExit(bytes32[] _proof, bytes32[] _prevProof, uint256 _oIndex, uint256 _inputIndex) public;
function slashDoubleSig(uint256 _slotId, bytes32 _root1, uint8 _v1, bytes32 _r1, bytes32 _s1, bytes32 _root2, uint8 _v2, bytes32 _r2, bytes32 _s2) public;
function getTip() public constant returns (bytes32, uint256);
}
Also check the latest code.
blockHash: 0x4920616d207665727920616e6772792c20627574206974207761732066756e21
height: 0
txList: -
blockHash: 0xcd4389364d24815a27b3427da939a886585126fa99c4fc4297e33229280ad1e6
height: 1
txList: const tx1 = Tx.fromRaw('0x0211000000010000000005e69ec00000f3beac30c498d9e26865f34fcaa57dbb935b0d74');
, const tx2 = Tx.fromRaw('0x0311846e4f732fd1c80e0a6d608cb0c732cfbe5cbf0efe1397c3d9a44f24170fd2f500d5275e033eb32583b0bdb0e0ef8c8164c43066868ad01eafc4491a980c4d84506d308f7995d30a855d9e5bafc73ed6ca4a6bebcf54569d161a774e64354c0ac11b0000000005e69ec00000e10f3d125e5f4c753a6456fc37123cf17c6900f2')
blockHash: 0x7ea11ec101e7e5ed3786a4c1bec1b04f667f3c70f342094a44ec3a2cd7037274
height: 2
txList: const tx3 = Tx.fromRaw('0x0311846e4f732fd1c80e0a6d608cb0c732cfbe5cbf0efe1397c3d9a44f24170fd2f500d5275e033eb32583b0bdb0e0ef8c8164c43066868ad01eafc4491a980c4d84506d308f7995d30a855d9e5bafc73ed6ca4a6bebcf54569d161a774e64354c0ac11b0000000005e69ec00000e10f3d125e5f4c753a6456fc37123cf17c6900f2')
blockHash: 0xa380889bc821e85122f8d96ffb7d980bb86a0336f4d93888005b38a8b9fcc65a
height: 2
txList: const tx4 = Tx.fromRaw('0x0311efcb630956a7b3c52eb6cda0ee11be33936562bf60214cd67794dc812353a0a200505d7bb19f0ac44a6e4c3715755c74a467ae385750b950c7d870bc77a4aa24bd2d41ea9b733b5290d08eae142233f3e546c5010abe50b843074a961547567f101c0000000005e69ec00000e10f3d125e5f4c753a6456fc37123cf17c6900f2')
blockHash: 0xce935f92e6289b0bc532303f146c8de98e16a6986a054ce8c7f33ae19bb45edf
height: 3
CAS by slot 1 v: 27
CAS by slot 1 r: 0x683d0aa2f36723c6990a3199485e61a6be612f8283d450d7ca905675e55d25ea
CAS by slot 1 s: 0x24cf29ec1f0cc39211b8a8eb9bb73d0adfb35d40ac38f6874c26d804ddac6e6e
txList: const tx5= Tx.fromRaw('0x0211000000020000000005e69ec00000e10f3d125e5f4c753a6456fc37123cf17c6900f2')
blockHash: 0xd02867920f8c3928666d3aaa7f39515fb4e5ec945e83908920208b9f565a3121
height: 3
CAS by slot 1 v: 27
CAS by slot 1 r: 0x63fa9769b60e4e7c723f9c2e5c1134c7ba88662d6170276699bbb29875d31836
CAS by slot 1 s: 0x47390f65031f15a9738cd111daa138d0ac7bf0518fafdff2a563ae6eda533b5d
txList: const tx6= Tx.fromRaw('0x0311f1afcb6eb68a85e2cedad832798a9d402557c85199a5cd8861948a1a279ebc0200e52762194a99e0afa59337fd512979b0e575b5025929a1149b38cd50f096883d25b874d0f7d69321085ea17f789fdb245583f217f84ca14eef5a2b4b8f0e145c1b0000000005e69ec00000e10f3d125e5f4c753a6456fc37123cf17c6900f2')
Constructing a block:
let block = new Block(1);
const tx1 = Tx.fromRaw('hex data here');
const tx2 = Tx.fromRaw('hex data here');
block.addTx(tx1);
block.addTx(tx2);
Generating a proof:
const proof = block.proof(tx1);
To become a validator, you need the staking token (PSC). Check out our PSC faucet.
Once you have tokens, you can user the staking interface to auction a slot.
Use the submitPeriod(yourSlotId, previousRoot, newRoot)
function from the ABI to submit a new Block.