天天看點

用 Python 實作區塊鍊公私鑰關系

作者:Boblee,人工智能碩士畢業,擅長及愛好python,基于python研究人工智能、群體智能、區塊鍊等技術,并使用python開發前後端、爬蟲等。

1、私鑰、公鑰、位址之間的關系

私鑰、公鑰:橢圓曲線加密算法生成,但是無法通過公鑰倒推得到私鑰。公鑰的作用是在和對方交易時,使用自己的私鑰加密資訊,然後對方使用自己的公鑰解密獲得原始資訊,這個過程俗稱簽名。

位址:由于公鑰太長,在交易中不友善使用,就對公鑰哈希進行SHA256、RIPEMD160、Base58算法加密生成位址。

用 Python 實作區塊鍊公私鑰關系

2、公私鑰加密流程

私鑰簽名過程:簽名即是使用私鑰将message加密,然後将原資訊和加密後的資訊發送出去的過程。

用 Python 實作區塊鍊公私鑰關系

公鑰驗簽過程:收到對方發送的資訊和私鑰簽名後的資訊,使用對方的公鑰機密簽名後的資訊,并和原資訊進行比對,一緻則未篡改,反之。

用 Python 實作區塊鍊公私鑰關系

3、Python實作(以太坊)

生成公私鑰

以太坊可以基于密碼生成公私鑰。

from eth_account import Account
from eth_utils.hexadecimal import encode_hex
from eth_account.messages import encode_defunct
import json
def get_key(key):
    """
    擷取公鑰私鑰
    :return: 傳回公鑰、私鑰
    """
    ac1 = Account.create(key)
    return encode_hex(ac1.key),ac1.address
           

複制

生成的結果:

密鑰是:

123

私鑰是:

0xbd26862c106b7985319b72a08b34ffe2827affb1a7c8f17962456a6f7c5a8246

公鑰是:

0x1761Ae9C3F60124338aEF74C5C322fB23C1AF8b2

私鑰簽名

當有一筆交易時,可以使用私鑰針對交易簽名,是以私鑰要儲存好。

def message_sign(text, prv_key):
    """
    基于私鑰擷取簽名
    :param text: 待簽名的文本
    :param prv_key: 私鑰
    :return: 簽名
    """
    try:
        message = encode_defunct(text=text)
        result = Account.sign_message(message, prv_key)
        result = str(result)
        result = result[result.find("'signature':"):result.find(')})')]
        return result[result.find("('") + 2:].replace("'", '')
    except:
        return '私鑰格式不對'
           

複制

結果是:

原文是:

qwe

私鑰是:

0xbd26862c106b7985319b72a08b34ffe2827affb1a7c8f17962456a6f7c5a8246

簽名是:

0x86b90940723e1667df873cfdcfc9ca52f045c29bb5ca700ad85f889a99c5bca43c3a5adc1d25f1b10b3314647424918426439178c0f17034cd8302d8305070131b

公鑰驗簽

當礦工打包時,可以使用公鑰進行驗證簽名。

def verifity(text, signature, address):
    """
    驗證簽名
    :param text: 原文本
    :param signature: 簽名
    :param address: 公鑰
    :return: 驗證結果
    """
    try:
        message = encode_defunct(text=text)
        address_new = Account.recover_message(message, signature=signature)
        if address == address_new:
            return '驗證一緻'
        else:
            return '驗證失敗'
    except:
        return '格式錯誤'
           

複制

原文是:

qwe

公鑰是:

0x1761Ae9C3F60124338aEF74C5C322fB23C1AF8b2

簽名是:

0x86b90940723e1667df873cfdcfc9ca52f045c29bb5ca700ad85f889a99c5bca43c3a5adc1d25f1b10b3314647424918426439178c0f17034cd8302d8305070131b

結果是:驗證一緻

私鑰推導公鑰

根據1中的關系私鑰是可以推出公鑰。

def recover_address(prv_key):
    """
    基于私鑰推出位址
    :param prv_key: 私鑰
    :return: 位址
    """
    try:
        acct = Account.from_key(prv_key)
        return acct.address
    except:
        return '格式錯誤'
           

複制

結果是:

私鑰是:

0xbd26862c106b7985319b72a08b34ffe2827affb1a7c8f17962456a6f7c5a8246

結果是:

0x1761Ae9C3F60124338aEF74C5C322fB23C1AF8b2

4、結語

本文使用的是基于python的以太坊包eth_account,安裝隻需

pip install eth_account

,該庫還有其它功能比如基于交易hash推導位址,公鑰加密等。