-
Notifications
You must be signed in to change notification settings - Fork 32
Description
SPV workflow for verifying a payment with NiPoPoW
Created from ergo-lib #495
Using NiPoPoW described in KMZ17
Goal
Prove that a payment (ERG and/or tokens) was made on the blockchain.
EDIT: For a recent payment it would be faster to use UTXO proof described in #502
Step 1. Prove that a tx with a given id in a block with a given id exists in the blockchain.
Step 1.1. Prove that a block with a given id exists in the blockchain.
-
1.1.1. Ask proofs from known nodes via
/nipopow/proof/{m}/{k}/{headerId}. -
1.1.2. Feed all received proofs into
NipopowVerifier.process(). -
1.1.3. Check that
verifier.bestProof.suffixHead.idis our block id;
Step 1.2. Prove that a tx with a given id exists in the blockchain.
-
1.2.1. Ask any node for
MerkleProofvia/blocks/{headerId}/proofFor/{txId}; -
1.2.2. Confirm the tx id is in the block with
merkleProof.valid(header.transactionsRoot);
See Step 1.1 in ergo-lib example workflow
Step 2. Check the box with the payment
Step 2.1 Get the whole tx for tx id from Step 1
It can either be provided along with the tx id in Step 1 or fetched from the node. It is verified by serializing the tx and calculating its id and then comparing it to the tx id confirmed in Step 1.2.
Step 2.2. Confirm the payment is in this tx
Find the output box protected with a certain script (e.g certain PK) and check that its value and/or tokens are as expected.
Implement the missing parts in appkit:
- REST API calls support mentioned above;
- move
NipopowProof,NipopowVerifier, and all dependent types from node code into a lib(ergo-wallet?)Extract NiPoPoW verifier into a separate library for SPV workflow in appkit ergo#1965 - expose
NipopowProof,NipopowVerifier,MerkleProofwith mentioned above properties/methods in appkit public API.
EDIT: Actually, I'm pretty sure that the above NiPoPoW-related types would better be in a dedicated ergo-nipopow lib since they are not directly related to wallet features. However, the bigger challenge will be the dependent more low-level types like Header, etc. Seems like they should be moved to their own separate lib (ergo-core/ergo-chain-types?).