RealPath:
WebPath:
2017/01/09 01:12 (JST) 更新
ウォレット >>

鍵情報

Contents

秘密鍵・公開鍵・Bitcoinアドレスの関係

秘密鍵から公開鍵が生成される。(不可逆)
公開鍵からBitcoinアドレスが生成される。(不可逆)

基本的に Bitcoin アドレスを生成する毎に秘密鍵が毎回ランダムに生成され直されると考えて良い。
ウォレットは複数のアドレスを管理するので複数の秘密鍵を保持することになる。

ウォレットのクラス構造

ウォレットは CWallet クラスにより管理される。
インスタンスは CWallet* pwalletMain; というグローバル変数として定義される。

 

クラス階層
CKeyStore … キー集合管理機能インターフェース(的なクラス)
│
△
│
CBasicKeyStore … キー集合管理機能の実装
│
△
│
CCryptoKeyStore … キー集合管理機能の実装(暗号対応)
│
△
│
CWallet

コマンドによる秘密鍵の確認: dumpprivkey

bitcoin-cli dumpprivkey コマンドにより Bitcoin アドレスに対応した秘密鍵を表示することができる(当然だがウォレットがそのアドレスに対応した秘密鍵を知っている場合に限る)。

$ bitcoin-cli getnewaddress
mkx1cG3KMMveEk4adadC58GpqJSy9ctCnj … 新しく生成した Bitcoin アドレス

$ bitcoin-cli getnewaddress
mxCxwmwooWBTmAH2C7jnKWpwmhQq1Hdi1t … 新しく生成した Bitcoin アドレス

$ bitcoin-cli dumpprivkey mkx1cG3KMMveEk4adadC58GpqJSy9ctCnj
cTXSYR2uPGLRjUKJRGvdv9mVJqBtb2WpP7oyYgeM2WfvSXJ96dA9 … 指定アドレスに対応する秘密鍵

$ bitcoin-cli dumpprivkey mxCxwmwooWBTmAH2C7jnKWpwmhQq1Hdi1t
cSdaU2BHx4jqUE8iwN4JTvUwzN5xbXxX3ep2sTaAhBWrg26an5qX … 指定アドレスに対応する秘密鍵(上記とは異なる値になる)

関連ソースコード

getnewaddress コマンド

UniValue getnewaddress(const JSONRPCRequest& request)
{
    ....

    // Generate a new key that is added to wallet
    CPubKey newKey;
    if (!pwalletMain->GetKeyFromPool(newKey))
        throw JSONRPCError(RPC_WALLET_KEYPOOL_RAN_OUT, "Error: Keypool ran out, please call keypoolrefill first");
    CKeyID keyID = newKey.GetID();

    pwalletMain->SetAddressBook(keyID, strAccount, "receive");

    return CBitcoinAddress(keyID).ToString();
}

鍵の生成・取得

bool CWallet::GetKeyFromPool(CPubKey& result)
{
    int64_t nIndex = 0;
    CKeyPool keypool;
    {
        LOCK(cs_wallet);
        ReserveKeyFromKeyPool(nIndex, keypool);
        if (nIndex == -1)
        {
            if (IsLocked()) return false;
            result = GenerateNewKey();
            return true;
        }
        KeepKey(nIndex);
        result = keypool.vchPubKey;
    }
    return true;
}
CPubKey CWallet::GenerateNewKey()
{
    AssertLockHeld(cs_wallet); // mapKeyMetadata
    bool fCompressed = CanSupportFeature(FEATURE_COMPRPUBKEY); // default to compressed public keys if we want 0.6.0 wallets

    CKey secret;

    // Create new metadata
    int64_t nCreationTime = GetTime();
    CKeyMetadata metadata(nCreationTime);

    // use HD key derivation if HD was enabled during wallet creation
    if (IsHDEnabled()) {
        DeriveNewChildKey(metadata, secret);
    } else {
        secret.MakeNewKey(fCompressed);
    }

    // Compressed public keys were introduced in version 0.6.0
    if (fCompressed)
        SetMinVersion(FEATURE_COMPRPUBKEY);

    CPubKey pubkey = secret.GetPubKey();
    assert(secret.VerifyPubKey(pubkey));

    mapKeyMetadata[pubkey.GetID()] = metadata;
    if (!nTimeFirstKey || nCreationTime < nTimeFirstKey)
        nTimeFirstKey = nCreationTime;

    if (!AddKeyPubKey(secret, pubkey))
        throw std::runtime_error(std::string(__func__) + ": AddKey failed");
    return pubkey;
}