This is a tracking issue for the RingCT Staking project. I'm thinking of it in terms of the following breakdown, with parts of it sharing some similarities to either or both of Zerocoin staking and regular RingCT transactions:
Staking Weight
Zerocoin staking power is based on the denomination "value" of the zerocoin, with a small reductions in power at each level above the first: a 100-coin has a weight of 90, a 1000-coin has a weight of 800, and a 10000-coin has a weight of 7000.
RingCT UTXOs have unknown values; to properly apply weights with minimal loss of privacy we have to make brackets similar to Zerocoin denominations. Previous work on this settled on using powers of 16 (in sats). I'll add some reductions in power to mimic the Zerocoin weights; we want to ensure that having 16 in a particular bracket will outweigh 1 in the next bracket (not counting dust).
bracket
min
weight factor
weight
1
0.00000017
2
0.00000257
3
0.00004097
4
0.00065537
5
0.01048577
6
0.16777217
7
2.68435457
100%
8
42.94967297
95%
40.8021893215
9
687.19476737
91%
625.3472383067
10
10,995.11627777
71%
7,806.5325572167
11
175,921.86044417
50%
87,960.930222085
12
2,814,749.76710657
30%
844,424.930131971
13
45,035,996.27370497
10%
4,503,599.627370497
The first three scale factors were chosen to closely match the equivalent values in zerocoin, the latter three were arbitrary extensions.
[x] Staking brackets
[x] Staking weight reduction
Transaction Creation
Blocks with Proof of Stake have two transactions: the coinbase transaction (generic), and the stake transaction. For zerocoin, the stake transaction takes one zerocoin as input, and mints one zerocoin of the same value plus the value of the coinbase split into 10s.
RingCT anon inputs are hidden amongst other anon UTXOs. RingCT sends generally output two UTXOs with a random split of the value, plus a RangeProof. However, change returned to oneself is usually a single output. In all cases, the value is hidden.
Design decision: RingCT staking transactions will return 3 outputs: one will be the same value as the original input, the other two will split the reward.
Much of my work so far has been refactoring the staking and RingCT code to allow for a smoother implementation reusing these components.
[x] RingCT stake transaction input handling
[x] RingCT stake transaction outputs handling (in progress)
[x] RingCT stake transaction rangeproof(s)
[x] stake input is at least a certain amount (namely, the bracket minimum). (I may need help on this.)
[x] regular rangeproof(s)
[x] RingCT stake transaction other transaction-as-a-whole/finalization stuff
[x] CreateCoinStake interface from miner
Validation
Once a transaction is constructed, the wallet must verify it and the block. This step runs the same code whether having generated the transaction before broadcasting it or having received it. Zerocoin stakes mainly need to compare the block hash to the zerocoin denomination weight. RingCT transactions need to verify proofs. Other generic checks such as inputs being unspent and values adding up will still apply.
This is a tracking issue for the RingCT Staking project. I'm thinking of it in terms of the following breakdown, with parts of it sharing some similarities to either or both of Zerocoin staking and regular RingCT transactions:
Staking Weight
Zerocoin staking power is based on the denomination "value" of the zerocoin, with a small reductions in power at each level above the first: a 100-coin has a weight of 90, a 1000-coin has a weight of 800, and a 10000-coin has a weight of 7000.
RingCT UTXOs have unknown values; to properly apply weights with minimal loss of privacy we have to make brackets similar to Zerocoin denominations. Previous work on this settled on using powers of 16 (in sats). I'll add some reductions in power to mimic the Zerocoin weights; we want to ensure that having 16 in a particular bracket will outweigh 1 in the next bracket (not counting dust).
The first three scale factors were chosen to closely match the equivalent values in zerocoin, the latter three were arbitrary extensions.
Transaction Creation
Blocks with Proof of Stake have two transactions: the coinbase transaction (generic), and the stake transaction. For zerocoin, the stake transaction takes one zerocoin as input, and mints one zerocoin of the same value plus the value of the coinbase split into 10s.
RingCT anon inputs are hidden amongst other anon UTXOs. RingCT sends generally output two UTXOs with a random split of the value, plus a RangeProof. However, change returned to oneself is usually a single output. In all cases, the value is hidden.
Design decision: RingCT staking transactions will return 3 outputs: one will be the same value as the original input, the other two will split the reward.
Much of my work so far has been refactoring the staking and RingCT code to allow for a smoother implementation reusing these components.
Validation
Once a transaction is constructed, the wallet must verify it and the block. This step runs the same code whether having generated the transaction before broadcasting it or having received it. Zerocoin stakes mainly need to compare the block hash to the zerocoin denomination weight. RingCT transactions need to verify proofs. Other generic checks such as inputs being unspent and values adding up will still apply.
Other staking parameters
Low-priority choosing of arbitrary numbers like what block height to start from, utxo required maturity, etc.
UTXO management
Not considering these as part of this tracking item, but we will likely want to have more user control over the UTXOs, such as: