密钥存储测试示例

密钥存储测试示例

Bitcoin(0.06.0)中密钥存储keystore类定义如下:

/** A virtual base class for key stores */
class CKeyStore
{
protected:
    //mutable CCriticalSection cs_KeyStore;

public:
    virtual ~CKeyStore() {}

    //! Add a key to the store.
    virtual bool AddKeyPubKey(const CKey &key, const CPubKey &pubkey) =0;
    virtual bool AddKey(const CKey &key);

    //! Check whether a key corresponding to a given address is present in the store.
    virtual bool HaveKey(const CKeyID &address) const =0;
    virtual bool GetKey(const CKeyID &address, CKey& keyOut) const =0;
    virtual std::set<CKeyID> GetKeys() const =0;
    virtual bool GetPubKey(const CKeyID &address, CPubKey& vchPubKeyOut) const =0;

    //! Support for BIP 0013 : see https://github.com/bitcoin/bips/blob/master/bip-0013.mediawiki
    virtual bool AddCScript(const CScript& redeemScript) =0;
    virtual bool HaveCScript(const CScriptID &hash) const =0;
    virtual std::set<CScriptID> GetCScripts() const =0;
    virtual bool GetCScript(const CScriptID &hash, CScript& redeemScriptOut) const =0;

    //! Support for Watch-only addresses
    virtual bool AddWatchOnly(const CScript &dest) =0;
    virtual bool RemoveWatchOnly(const CScript &dest) =0;
    virtual bool HaveWatchOnly(const CScript &dest) const =0;
    virtual bool HaveWatchOnly() const =0;
};

typedef std::map<CKeyID, CKey> KeyMap;
typedef std::map<CKeyID, CPubKey> WatchKeyMap;
typedef std::map<CScriptID, CScript > ScriptMap;
typedef std::set<CScript> WatchOnlySet;

此类为虚类,添加密钥实现方法类为CBasicKeyStore:

/** Basic key store, that keeps keys in an address->secret map */
class CBasicKeyStore : public CKeyStore
{
protected:
    KeyMap mapKeys;
    WatchKeyMap mapWatchKeys;
    ScriptMap mapScripts;
    WatchOnlySet setWatchOnly;

    void ImplicitlyLearnRelatedKeyScripts(const CPubKey& pubkey);

public:
    bool AddKeyPubKey(const CKey& key, const CPubKey &pubkey) override;
    bool GetPubKey(const CKeyID &address, CPubKey& vchPubKeyOut) const override;
    bool HaveKey(const CKeyID &address) const override;
    std::set<CKeyID> GetKeys() const override;
    bool GetKey(const CKeyID &address, CKey &keyOut) const override;
    bool AddCScript(const CScript& redeemScript) override;
    bool HaveCScript(const CScriptID &hash) const override;
    std::set<CScriptID> GetCScripts() const override;
    bool GetCScript(const CScriptID &hash, CScript& redeemScriptOut) const override;

    bool AddWatchOnly(const CScript &dest) override;
    bool RemoveWatchOnly(const CScript &dest) override;
    bool HaveWatchOnly(const CScript &dest) const override;
    bool HaveWatchOnly() const override;
};

//typedef std::vector<unsigned char, secure_allocator<unsigned char> > CKeyingMaterial;
typedef std::vector<unsigned char> CKeyingMaterial;
typedef std::map<CKeyID, std::pair<CPubKey, std::vector<unsigned char> > > CryptedKeyMap;

/** Return the CKeyID of the key involved in a script (if there is a unique one). */
CKeyID GetKeyForDestination(const CKeyStore& store, const CTxDestination& dest);

密钥对添加方法为:

// 添加公钥对应的脚本
void CBasicKeyStore::ImplicitlyLearnRelatedKeyScripts(const CPubKey& pubkey)
{
    //AssertLockHeld(cs_KeyStore);
    CKeyID key_id = pubkey.GetID();
    // We must actually know about this key already.
    assert(HaveKey(key_id) || mapWatchKeys.count(key_id));
    // This adds the redeemscripts necessary to detect P2WPKH and P2SH-P2WPKH
    // outputs. Technically P2WPKH outputs don't have a redeemscript to be
    // spent. However, our current IsMine logic requires the corresponding
    // P2SH-P2WPKH redeemscript to be present in the wallet in order to accept
    // payment even to P2WPKH outputs.
    // Also note that having superfluous scripts in the keystore never hurts.
    // They're only used to guide recursion in signing and IsMine logic - if
    // a script is present but we can't do anything with it, it has no effect.
    // "Implicitly" refers to fact that scripts are derived automatically from
    // existing keys, and are present in memory, even without being explicitly
    // loaded (e.g. from a file).
    if (pubkey.IsCompressed()) {
        CScript script = GetScriptForDestination(WitnessV0KeyHash(key_id));
        // This does not use AddCScript, as it may be overridden.
        CScriptID id(script);
        mapScripts[id] = std::move(script);
    }
}

bool CBasicKeyStore::AddKeyPubKey(const CKey& key, const CPubKey &pubkey)
{
    //LOCK(cs_KeyStore);
    mapKeys[pubkey.GetID()] = key;	// 将公钥的Hash160值添加到std::map中
    ImplicitlyLearnRelatedKeyScripts(pubkey);	//将公钥对应的脚本存储
    return true;
}

测试主函数如下:

// 密钥存储测试程序
int main_keystoretest(){
	ECCVerifyHandle eccVerifyHandle ;
	ECC_Start();
	// 创建一个密钥存储 
	CBasicKeyStore keystore; 
	CKey priKey;
	CPubKey pubKey;
	// 添加一个密钥对
	priKey.Set(TestPriKey.begin(), TestPriKey.end(), true);
	pubKey.Set(TestPubKey.begin(), TestPubKey.end());
	keystore.AddKeyPubKey(priKey, pubKey);
	priKey.Set(TestPriKeyA.begin(), TestPriKeyA.end(), true);
	pubKey.Set(TestPubKeyA.begin(), TestPubKeyA.end());
	keystore.AddKeyPubKey(priKey, pubKey);
	priKey.Set(TestPriKeyB.begin(), TestPriKeyB.end(), true);
	pubKey.Set(TestPubKeyB.begin(), TestPubKeyB.end());
	keystore.AddKeyPubKey(priKey, pubKey);
	// 获取所有密钥对 
	CKey priKey1;
	CPubKey pubKey1;
	int count = 0;
	std::set<CKeyID> keys = keystore.GetKeys(); 
	for(std::set<CKeyID>::iterator it = keys.begin(); it != keys.end(); it++){
		std::cout<<"**** Key "<<count++<<std::endl;
		if(keystore.GetKey(*it, priKey1)){
			std::cout<<"Private key:";
			print_vector(priKey1.begin(), priKey1.size());
		}
		if(keystore.GetPubKey(*it, pubKey1)){
			std::cout<<"Public key:";
			print_vector(pubKey1, pubKey.size());
		}
	}

	pubKey.Set(TestPubKey.begin(), TestPubKey.end());
	CKeyID address = pubKey.GetID(); 
	// 添加脚本
	CScript script = GetScriptForDestination(Witnes0sV0KeyHash(address)); 
	CScriptID hash(script);
	// 根据脚本获取key 
	address = GetKeyForDestination(keystore, script);
	std::cout<<"**** Address: ";
	print_vector(address.begin(), address.size());
	// 添加密钥对时已添加对应得脚本,所以存储中已存在脚本 
	if(keystore.HaveCScript(hash)){
		std::cout<<"**** Have script: ";
		print_vector(hash.begin(), hash.size());
	}
	// 通过脚本哈希值获取脚本	
	if(keystore.GetCScript(hash, script)){
		std::cout<<"**** Get script: ";
		print_vector(script, script.size());
	} 
	
	// 只看脚本
	if(!keystore.HaveWatchOnly(script)){
		keystore.AddWatchOnly(script);
		if(keystore.HaveWatchOnly(script)){
			std::cout<<"**** Watch:";
			print_vector(script, script.size());
		}		
	}
	
	ECC_Stop();
	return 0;
} 

主函数输出:

===================================================================================================
Keystore
===================================================================================================
**** Key 0
Private key:9a9a6539856be209b8ea2adbd155c0919646d108515b60b7b13d6a79f1ae5174
-------------------
Public key:0340a609475afa1f9a784cad0db5d5ba7dbaab2147a5d7b9bbde4d1334a0e40a5e
-------------------
**** Key 1
Private key:3e46c724c8e9728379a9cab2ec46030563f06d7e0ace2b734b5861b8f64b6f2f
-------------------
Public key:020e80933a750e84b4c35c10bc797ca34d1c885e4e65531a7499170a1c78ffdd97
-------------------
**** Key 2
Private key:6bce49ff84094382d822178de357a435f85e8ad8fdfa39bd58aa2e5192267198
-------------------
Public key:03e3bd2f408e4415aa57c747f6550937823a8605706c358facdc6325b4a99f2161
-------------------
**** Address: 154de7cabbb5822075e92c57a27ca3ef3e8be50c
-------------------
**** Have script: c596906f342478ca56707f7bb1bda659cb3cef98
-------------------
**** Get script: 0014154de7cabbb5822075e92c57a27ca3ef3e8be50c
-------------------
**** Watch:0014154de7cabbb5822075e92c57a27ca3ef3e8be50c
-------------------

===================================================================================================

源代码:

https://github.com/babylco0/bitcoin_code_examples/tree/master/TestKey-1.1.0

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值