PIVX Core  5.6.99
P2P Digital Currency
blocksignature.cpp
Go to the documentation of this file.
1 // Copyright (c) 2017-2021 The PIVX Core developers
2 // Distributed under the MIT software license, see the accompanying
3 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
4 
5 #include "blocksignature.h"
6 
7 #include "script/standard.h"
8 #include "zpiv/zpivmodule.h"
9 
10 static bool GetKeyIDFromUTXO(const CTxOut& utxo, CKeyID& keyIDRet)
11 {
12  std::vector<valtype> vSolutions;
13  txnouttype whichType;
14  if (utxo.scriptPubKey.empty() || !Solver(utxo.scriptPubKey, whichType, vSolutions))
15  return false;
16  if (whichType == TX_PUBKEY) {
17  keyIDRet = CPubKey(vSolutions[0]).GetID();
18  return true;
19  }
20  if (whichType == TX_PUBKEYHASH || whichType == TX_COLDSTAKE) {
21  keyIDRet = CKeyID(uint160(vSolutions[0]));
22  return true;
23  }
24  if (whichType == TX_EXCHANGEADDR) {
25  keyIDRet = CExchangeKeyID(uint160(vSolutions[0]));
26  return true;
27  }
28  return false;
29 }
30 
31 bool SignBlockWithKey(CBlock& block, const CKey& key)
32 {
33  if (!key.Sign(block.GetHash(), block.vchBlockSig))
34  return error("%s: failed to sign block hash with key", __func__);
35 
36  return true;
37 }
38 
39 bool SignBlock(CBlock& block, const CKeyStore& keystore)
40 {
41  CKeyID keyID;
42  if (!GetKeyIDFromUTXO(block.vtx[1]->vout[1], keyID)) {
43  return error("%s: failed to find key for PoS", __func__);
44  }
45 
46  CKey key;
47  if (!keystore.GetKey(keyID, key))
48  return error("%s: failed to get key from keystore", __func__);
49 
50  return SignBlockWithKey(block, key);
51 }
52 
53 bool CheckBlockSignature(const CBlock& block)
54 {
55  if (block.IsProofOfWork())
56  return block.vchBlockSig.empty();
57 
58  if (block.vchBlockSig.empty())
59  return error("%s: vchBlockSig is empty!", __func__);
60 
65  CPubKey pubkey;
66  bool fzPIVStake = block.vtx[1]->vin[0].IsZerocoinSpend();
67  if (fzPIVStake) {
69  pubkey = spend.getPubKey();
70  } else {
71  txnouttype whichType;
72  std::vector<valtype> vSolutions;
73  const CTxOut& txout = block.vtx[1]->vout[1];
74  if (!Solver(txout.scriptPubKey, whichType, vSolutions))
75  return false;
76 
77  if (whichType == TX_PUBKEY) {
78  valtype& vchPubKey = vSolutions[0];
79  pubkey = CPubKey(vchPubKey);
80  } else if (whichType == TX_PUBKEYHASH) {
81  const CTxIn& txin = block.vtx[1]->vin[0];
82  // Check if the scriptSig is for a p2pk or a p2pkh
83  if (txin.scriptSig.size() == 73) { // Sig size + DER signature size.
84  // If the input is for a p2pk and the output is a p2pkh.
85  // We don't have the pubkey to verify the block sig anywhere in this block.
86  // p2pk scriptsig only contains the signature and p2pkh scriptpubkey only contain the hash.
87  return false;
88  } else {
89  unsigned int start = 1 + (unsigned int) *txin.scriptSig.begin(); // skip sig
90  if (start >= txin.scriptSig.size() - 1) return false;
91  pubkey = CPubKey(txin.scriptSig.begin()+start+1, txin.scriptSig.end());
92  }
93  } else if (whichType == TX_COLDSTAKE) {
94  // pick the public key from the P2CS input
95  const CTxIn& txin = block.vtx[1]->vin[0];
96  unsigned int start = 1 + (unsigned int) *txin.scriptSig.begin(); // skip sig
97  if (start >= txin.scriptSig.size() - 1) return false;
98  start += 1 + (int) *(txin.scriptSig.begin()+start); // skip flag
99  if (start >= txin.scriptSig.size() - 1) return false;
100  pubkey = CPubKey(txin.scriptSig.begin()+start+1, txin.scriptSig.end());
101  }
102  }
103 
104  if (!pubkey.IsValid())
105  return error("%s: invalid pubkey %s", __func__, HexStr(pubkey));
106 
107  return pubkey.Verify(block.GetHash(), block.vchBlockSig);
108 }
bool SignBlock(CBlock &block, const CKeyStore &keystore)
bool CheckBlockSignature(const CBlock &block)
bool SignBlockWithKey(CBlock &block, const CKey &key)
uint256 GetHash() const
Definition: block.cpp:15
Definition: block.h:80
std::vector< CTransactionRef > vtx
Definition: block.h:83
std::vector< unsigned char > vchBlockSig
Definition: block.h:86
bool IsProofOfWork() const
Definition: block.h:139
A reference to a CKey: the Hash160 of its serialized public key, special case for exchange key.
Definition: pubkey.h:30
An encapsulated private key.
Definition: key.h:30
bool Sign(const uint256 &hash, std::vector< unsigned char > &vchSig, uint32_t test_case=0) const
Create a DER-serialized signature.
Definition: key.cpp:200
A reference to a CKey: the Hash160 of its serialized public key.
Definition: pubkey.h:21
A virtual base class for key stores.
Definition: keystore.h:23
virtual bool GetKey(const CKeyID &address, CKey &keyOut) const =0
An encapsulated public key.
Definition: pubkey.h:44
CKeyID GetID() const
Get the KeyID of this public key (hash of its serialization)
Definition: pubkey.h:167
bool IsValid() const
Definition: pubkey.h:183
bool Verify(const uint256 &hash, const std::vector< unsigned char > &vchSig) const
Verify a DER signature (~72 bytes).
Definition: pubkey.cpp:169
An input of a transaction.
Definition: transaction.h:94
CScript scriptSig
Definition: transaction.h:97
An output of a transaction.
Definition: transaction.h:137
CScript scriptPubKey
Definition: transaction.h:140
The complete proof needed to spend a zerocoin.
Definition: CoinSpend.h:79
CPubKey getPubKey() const
Definition: CoinSpend.h:94
bool empty() const
Definition: prevector.h:281
size_type size() const
Definition: prevector.h:277
iterator begin()
Definition: prevector.h:285
iterator end()
Definition: prevector.h:287
160-bit opaque blob.
Definition: uint256.h:127
std::vector< unsigned char > valtype
Definition: interpreter.cpp:17
libzerocoin::CoinSpend TxInToZerocoinSpend(const CTxIn &txin)
Definition: zpivmodule.cpp:191
bool Solver(const CScript &scriptPubKey, txnouttype &typeRet, std::vector< std::vector< unsigned char > > &vSolutionsRet)
Parse a scriptPubKey and identify script type for standard scripts.
Definition: standard.cpp:90
txnouttype
Definition: standard.h:46
@ TX_PUBKEYHASH
Definition: standard.h:50
@ TX_PUBKEY
Definition: standard.h:49
@ TX_COLDSTAKE
Definition: standard.h:54
@ TX_EXCHANGEADDR
Definition: standard.h:55
bool error(const char *fmt, const Args &... args)
Definition: system.h:77
std::string HexStr(const Span< const uint8_t > s)
Convert a span of bytes to a lower-case hexadecimal string.