Openssl實現生成比特幣地址的base58編碼
阿新 • • 發佈:2019-02-08
比特幣協議中比特幣地址的生成演算法如下:
比特幣地址(Bitcoin Address)是ECDSA公鑰(public key)的雜湊,它是這樣計算出來的:
Version = 1 個位元組 0 ; 在測試網路上, 這個值是 1 個位元組 111
Key hash = Version 與 RIPEMD-160(SHA-256(public key)) 相接
Checksum = SHA-256(SHA-256(Key hash))的前4個位元組
Bitcoin Address = Base58Encode(Key hash 與 Checksum 相接)
下面介紹使用openssl庫實現base58編碼:
#include <stdlib.h>
#include <iostream>
#include <string>
#include <openssl/bn.h>
#include "ecdsa_test.h"
using namespace std;
#define DOMAIN_CHECK(c) ('0'<=(c)&&(c)<='9'||'a'<=(c)&&(c)<='f'||'A'<=(c)&&(c)<='F')
#define BASE58TABLE "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"
std::string base58encode(const std::string & hexstring)
{
std::string result = "";
BN_CTX * bnctx = BN_CTX_new();
BIGNUM * bn = BN_new();
BIGNUM * bn0= BN_new();
BIGNUM * bn58=BN_new();
BIGNUM * dv = BN_new();
BIGNUM * rem= BN_new();
BN_hex2bn(&bn, hexstring.c_str());
//printf("bn:%s\n", BN_bn2dec(bn));
BN_hex2bn(&bn58, "3a");//58
BN_hex2bn(&bn0,"0");
while(BN_cmp(bn, bn0)>0){
BN_div(dv, rem, bn, bn58, bnctx);
BN_copy(bn, dv);
//printf("dv: %s\n", BN_bn2dec(dv));
//printf("rem:%s\n", BN_bn2dec(rem));
char base58char = BASE58TABLE[BN_get_word(rem)];
result += base58char;
}
std::string::iterator pbegin = result.begin();
std::string::iterator pend = result.end();
while(pbegin < pend) {
char c = *pbegin;
*(pbegin++) = *(--pend);
*pend = c;
}
return result;
}
int main() {
std::string hex_string = "00010966776006953D5567439E5E39F86A0D273BEED61967F6";
cout << base58encode(hex_string).c_str() << endl;
return 0;
}