比特币源码分析——比特币地址生成流程

简介

本文参考密钥和地址,主要内容是分析生成比特币地址的代码流程。

获取新地址

bitcoin-cli getnewaddress

通过命令bitcoin-cli getnewaddress可以得到一个新的比特币地址,其调用流程如下:

bitcoin_cli.cpp rpcwallet.cpp wallet.cpp scriptpubkeymap.cp outputtype.cpp CallRPC() getnewaddress() GetNewDestination() GetNewDestination() GetKeyFromPool() GetDestinationForKey() EncodeDestination() bitcoin_cli.cpp rpcwallet.cpp wallet.cpp scriptpubkeymap.cp outputtype.cpp

通过上述过程可以发现,其核心是GetKeyFromPool()方法,从池中获取一对公钥。之后分别调用GetDestinationForKey(),EncodeDestination()两个方法产生新的可用的比特币地址。

bitcoin-cli keypoolrefile

通过上一节的流程我知道,每次调用bitcoin-cli getnewaddress得到的公钥实际是从一个公钥池中获取的,那如何填充这个池呢?通过分析代码我们可以知道需要调用命令bitcoin-cli keypoolrefile,下面的时序图即为调用bitcoin-cli keypoolrefile的过程。

bitcoin_cli.cpp rpcwallet.cpp wallet.cpp scriptpubkeyman.cp key.cpp random.cpp secp256k1.cpp CallRPC() keypoolrefill() TopUpKeyPool() TopUp() GenerateNewKey() MakeNewKey() GetStrongRandBytes() GetPubKey() secp256k1_ec_pubkey_create() bitcoin_cli.cpp rpcwallet.cpp wallet.cpp scriptpubkeyman.cp key.cpp random.cpp secp256k1.cpp

GenerateNewKey()即为产生新的公钥的核心方法,其中主要调用MakeNewKey产生一个随机数(该随机数即为比特币地址的密钥),然后调用GetPubKey()为产生密钥所对应的公钥。

总结

本文内容还比较粗浅,有很多代码细节没有描述。

Questions

  • Q:在分析过程中有多处可以得到一个32字节的char数组存储公钥,但将该公钥转换为数字后代入椭圆公式,发现计算结果不准确
    A: 原因为在进行数字转换时很有可能没有注意大数字在内存中存储顺序造成,注意:内存高位存储数字的高位。所以准确的转换代码应该如下所示。
    将转换后得到的十六进制直接复制,使用python进行验证。
    unsigned char * k = key.data;  // key 的类型为:secp256k1_pubkey   
    printf("$#####################  keys:\n");
    printf("x:")
    for(int i=31;i>=0;i--){        
        printf("%02X",k[i]);        
    }
    printf("\ny:");
    for(int i=63;i>=32;i--){
        printf("%02X",k[i]);
    }
    printf("\n");    

参考资料

  • 关于比特币地址格式
  • boost::variant

你可能感兴趣的:(比特币,区块链)