In Peershare we need to allow large shareholders to secure the network while having their private keys in cold storage.
Peercoin also needs this feature so we should use a common solution for that.
So in this message I present my solution and compare it to others in the hope consensus for a final solution can be reached.
Idea
The main idea is the use a new kind of address very similar to multi-signature addresses.
These new addresses would be composed of 2 public keys:
- a minting key that is only allowed to mint
- a spending key that is only allowed to move the coins to another address
We could call these addresses “cold minting addresses”.
They will start with a lowercase “p” like multisig addresses.
Any coin sent to a “cold minting address” will only be spendable if you have the spending private key.
And to mint with these coins you only need the minting private key in your wallet.
(In both cases you also need the cold minting address in your wallet, but you can recreate it very easily)
If your minting private key is stolen, the only thing the thief can do is to mint on your behalf. This is not good for the security of the network but it is nothing compared to loosing the coins.
Other solutions
d5000 listed other proposed solutions here: http://www.peercointalk.org/index.php?topic=2467.msg22366#msg22366
Here is a quick comparison:
Sunny King’s cold locked transactions (https://bitcointalk.org/index.php?topic=194054.0):
Idea: You send coins to another address with a special “cold lock” transaction. This other address is only allowed to mint and to unlock the coins back to the original address.
Pro:
- may imply less changes in the code than my solution
Con: - you must cold lock any new coin you receive, so you must bring back your cold storage private key each time you want to cold lock coins and it costs you the transaction fee
- you must not loose the minting private key, otherwise you can’t unlock the coins
- we need a new special UI to lock and unlock coins (my proposal also requires a new UI, but it’s only used at setup time)
NXT leased forging (http://wiki.nxtcrypto.org/wiki/Glossary/fr#Leased_Forging)
Idea: you make a special transaction to say this other address is allowed to mint your coins on your behalf for a given duration. Very similar to cold locked tx but limited in time.
Pro:
- the duration?
Con: - the purpose is explicitly to let someone else mint, it looks dangerous from the network security perspective
- you must lease again when you receive new coins or when the leases expires. You must use your cold storage private key each time you do that.
- the account receiving the lease can do whatever he wants with the reward (though we can implement that differently)
ppcman’s Mint-by-proxy (http://www.peercointalk.org/index.php?topic=2467.msg20540#msg20540):
Idea: unless I misunderstood something, it works exactly like cold locked minting (with a different terminology) except there’s a high fee to lock and unlock (0.05 PPC)
So the same pro and con apply plus:
Pro:
- the fee? “These fees will be destroyed and be put back into the network, which can increase the coin supply for better rewards than 1%”
Con: - the fee?
- from the description it looks more complex to implement than cold locked minting, but I’m not sure how they differ exactly.
d5000 (http://www.peercointalk.org/index.php?topic=2467.msg21919#msg21919):
Idea: you send a signed message to other nodes to transfer the coin age from an address to another one. The message is stored in the blockchain.
Pro
- you don’t need to move the coins and loose coin age to enable cold locked minting on an address
- “the transaction system itself would not have to be modified”. That’s right but it requires so many other changes I’m not sure this is globally positive.
Con: - we must implement a new message type (but maybe we can use special transactions instead and reuse many existing code)
- we must keep a new big record to know what coin age was transferred to what address. It looks error prone and not lightweight client friendly (although peercoin is already not very lightweight client friendly)
- it looks very complex to implement
- “there must be a mechanism to avoid that someone tries to PoS mint with both addresses”
- you must have the private key nearby each time you want to transfer coin age
bitbadger (http://www.peercointalk.org/index.php?topic=2580.0)
Actually this proposal has nothing to do with cold storage minting. Although the idea of not loosing coin age when coins are sent is interesting.
jutarul (https://bitcointalk.org/index.php?topic=115608.0):
Idea: we generate CoinStake signatures in advance and use them when we find a block
Con:
- must be done again after a block has been found
- actually impractical because you can’t sign the blocks
Also Chronos suggested we allow the minting key to spend the reward, to dissuade people from sharing their minting key or being too loose on security. I’m not sure about that.
The discussion was here: http://www.peercointalk.org/index.php?topic=2467.msg21197#msg21197
Implementation details
We add a new script opcode OP_COINSTAKE that pushes 1 if we’re in a coinstake transaction and 0 otherwise. It’s easy to do because we have access to the transaction when the script is run.
We allow a new standard script that authorizes one key if the transaction is a CoinStake, and the other one in all other situations.
The script could look like this:
OP_DUP
OP_HASH160
OP_COINSTAKE
OP_IF
mintingAddress.GetHash160()
OP_ELSE
spendingAddress.GetHash160()
OP_ENDIF
OP_EQUALVERIFY
OP_CHECKSIG
When a CoinStake transaction is generated, if the kernel is a cold minting address and we know the minting private key then we sign the transaction with this key.
Right now when you find a PoS block you can send the reward and the coins to another address. We must prevent that when a cold minting address is used: the coins and the reward must be sent to the cold minting address. We must also force the output value to be exactly the sum of the inputs + the reward (currently the protocol allows a lower value).
We make the block signature and validation also work when the kernel is a minting address (right now it only supports pay-to-pubkey outputs).
In the GUI we add a new button “New cold minting address” in the “Receive coin” tab. It opens a form asking for the minting address, the spending address and an optional label.
In the RPC server we add a new command “addcoldmintingaddress []”.
We add a new “Minting only balance” in the overview page that displays the amount of coins you cannot spend but you can mint with. This amount should not appear in the balance.
During the CoinStake creation we change the coin selection process to also select the outputs with which we can only mint.
Pull request: https://github.com/peercoin/peercoin/pull/78
Specific commit : https://github.com/peercoin/peercoin/commit/8df4a0360f3917e042cc0185dc39ed894c9f4148
Edit: Added the last 2 elements in the implementation details.
Edit 2: Added requirement for the minting output value to be exactly the sum of the inputs + the reward.
Edit 3 : Added link to the proposed implementation