美文网首页
以太坊解析-(1) 公钥私钥地址字符串公钥推导

以太坊解析-(1) 公钥私钥地址字符串公钥推导

作者: 寄意兰舟_62db | 来源:发表于2020-05-28 10:01 被阅读0次

以太坊中私钥和HASH都为32位,公钥为65位其中第一位是压缩字节0x04,压缩公钥为33字节,地址是是公钥的后64位hash后取后20个字节​作为地址。签名数据为65位,R,S各32位,65位为0和1.​

生成私钥

//生成私钥
    key, err := crypto.GenerateKey()
    if err != nil {
        t.Fatalf("failed GenerateKey with %s.", err)
    }
  //带有0x的私钥
    fmt.Println("private key have 0x   \n", hexutil.Encode(crypto.FromECDSA(key)))
    //不含0x的私钥
    fmt.Println("private key no 0x \n", hex.EncodeToString(crypto.FromECDSA(key)))
private key have 0x   
 0xb1fb9a42d8478cf19bbc1cb4e75625ced1728c8de8691845f546b2ad84a7d379
private key no 0x 
 b1fb9a42d8478cf19bbc1cb4e75625ced1728c8de8691845f546b2ad84a7d379

私钥存储

//本地生成privatekey文件,保存私钥
    if err := crypto.SaveECDSA("privatekey", key); err != nil {
        log.Error(fmt.Sprintf("Failed to persist node key: %v", err))
    }
b1fb9a42d8478cf19bbc1cb4e75625ced1728c8de8691845f546b2ad84a7d379

公钥16进制打印

    fmt.Println("public key have 0x   \n", hexutil.Encode(crypto.FromECDSAPub(&key.PublicKey)))
    fmt.Println("public key no 0x \n", hex.EncodeToString(crypto.FromECDSAPub(&key.PublicKey)))
public key have 0x   
 0x0425b775a01b5df335cd71170f6a16d8b43704e68b8eb87a8e6ebfd3deafbfc1151d76bbe078002ffb7caaca06441b1c3976c3ca3b1e1fda9cf0f4591d799758e4
public key no 0x 
 0425b775a01b5df335cd71170f6a16d8b43704e68b8eb87a8e6ebfd3deafbfc1151d76bbe078002ffb7caaca06441b1c3976c3ca3b1e1fda9cf0f4591d799758e4

字符串转私钥和地址

    //由私钥字符串转换私钥和地址
    //由私钥字符串转换私钥
    acc1Key, _ := crypto.HexToECDSA("8a1f9a8f95be41cd7ccb6168179afb4504aefe388d1e14474d32c45c72ce7b7a")
    address1 := crypto.PubkeyToAddress(acc1Key.PublicKey)
    fmt.Println("address ", address1.String())

    dummyAddr := common.HexToAddress("9b2055d370f73ec7d8a03e965129118dc8f5bf83")
    fmt.Println("dummyAddr",dummyAddr.String())
address  0x703c4b2bD70c169f5717101CaeE543299Fc946C7
dummyAddr 0x9B2055d370F73eC7d8a03E965129118dC8F5bf83

字节转HASH和地址

    //字节转地址
    addr3      := common.BytesToAddress([]byte("ethereum"))
    fmt.Println("address ",addr3.String())

    //字节转hash
    hash1 := common.BytesToHash([]byte("topic1"))
    fmt.Println("hash ",hash1.String())
address  0x000000000000000000000000657468657265756D
hash  0x0000000000000000000000000000000000000000000000000000746f70696331

签名和摘要推出公钥

    var testAddrHex = "970e8128ab834e8eac17ab8e3812f010678cf791"
    var testPrivHex = "289c2857d4598e37fb9647507e47a309d6133539bf21a8b9cb6df88fd5232032"
    key1, _ := crypto.HexToECDSA(testPrivHex)
    addrtest := common.HexToAddress(testAddrHex)

    msg := crypto.Keccak256([]byte("foo"))
    sig, err := crypto.Sign(msg, key1)
    //推出公钥字节
    recoveredPub, err := crypto.Ecrecover(msg, sig)
    //字节转公钥
    pubKey, _ := crypto.UnmarshalPubkey(recoveredPub)
    recoveredAddr := crypto.PubkeyToAddress(*pubKey)

    // 摘要和签名推出公钥
    recoveredPub2, _ := crypto.SigToPub(msg, sig)
    recoveredAddr2 := crypto.PubkeyToAddress(*recoveredPub2)

    fmt.Println("addrtest ",addrtest.String())
    fmt.Println("recoveredAddr ",recoveredAddr.String())
    fmt.Println("recoveredAddr2 ",recoveredAddr2.String())
addrtest  0x970E8128AB834E8EAC17Ab8E3812F010678CF791
recoveredAddr  0x970E8128AB834E8EAC17Ab8E3812F010678CF791
recoveredAddr2  0x970E8128AB834E8EAC17Ab8E3812F010678CF791

压缩公钥

//压缩公钥为33字节
compressed := CompressPubkey(key)
// 解压缩33字节数据为公钥
DecompressPubkey

完整代码

在以太坊顶级目录新建test目录,新建file_test.go文件,拷贝代码即可运行

package test

import (
    "encoding/hex"
    "fmt"
    "github.com/ethereum/go-ethereum/common"
    "github.com/ethereum/go-ethereum/common/hexutil"
    "github.com/ethereum/go-ethereum/crypto"
    "github.com/ethereum/go-ethereum/log"
    "testing"
)

func TestGenerateKey(t *testing.T) {
    key, err := crypto.GenerateKey()
    if err != nil {
        t.Fatalf("failed GenerateKey with %s.", err)
    }

    fmt.Println("private key have 0x   \n", hexutil.Encode(crypto.FromECDSA(key)))
    fmt.Println("private key no 0x \n", hex.EncodeToString(crypto.FromECDSA(key)))

    if err := crypto.SaveECDSA("privatekey", key); err != nil {
        log.Error(fmt.Sprintf("Failed to persist node key: %v", err))
    }

    fmt.Println("public key have 0x   \n", hexutil.Encode(crypto.FromECDSAPub(&key.PublicKey)))
    fmt.Println("public key no 0x \n", hex.EncodeToString(crypto.FromECDSAPub(&key.PublicKey)))

    //由私钥字符串转换私钥
    acc1Key, _ := crypto.HexToECDSA("8a1f9a8f95be41cd7ccb6168179afb4504aefe388d1e14474d32c45c72ce7b7a")
    address1 := crypto.PubkeyToAddress(acc1Key.PublicKey)
    fmt.Println("address ", address1.String())

    dummyAddr := common.HexToAddress("9b2055d370f73ec7d8a03e965129118dc8f5bf83")
    fmt.Println("dummyAddr",dummyAddr.String())

    //字节转地址
    addr3      := common.BytesToAddress([]byte("ethereum"))
    fmt.Println("address ",addr3.String())

    //字节转hash
    hash1 := common.BytesToHash([]byte("topic1"))
    fmt.Println("hash ",hash1.String())


    var testAddrHex = "970e8128ab834e8eac17ab8e3812f010678cf791"
    var testPrivHex = "289c2857d4598e37fb9647507e47a309d6133539bf21a8b9cb6df88fd5232032"
    key1, _ := crypto.HexToECDSA(testPrivHex)
    addrtest := common.HexToAddress(testAddrHex)

    msg := crypto.Keccak256([]byte("foo"))
    sig, err := crypto.Sign(msg, key1)
    recoveredPub, err := crypto.Ecrecover(msg, sig)
    pubKey, _ := crypto.UnmarshalPubkey(recoveredPub)
    recoveredAddr := crypto.PubkeyToAddress(*pubKey)

    // should be equal to SigToPub
    recoveredPub2, _ := crypto.SigToPub(msg, sig)
    recoveredAddr2 := crypto.PubkeyToAddress(*recoveredPub2)

    fmt.Println("addrtest ",addrtest.String())
    fmt.Println("recoveredAddr ",recoveredAddr.String())
    fmt.Println("recoveredAddr2 ",recoveredAddr2.String())
}

相关文章

  • 以太坊解析-(1) 公钥私钥地址字符串公钥推导

    以太坊中私钥和HASH都为32位,公钥为65位其中第一位是压缩字节0x04,压缩公钥为33字节,地址是是公钥的后6...

  • 区块链钱包技术原理

    区块链的技术原理: 钱包助记词生成种子(Seed),种子生成私钥。私钥推导出公钥,公钥节选部分生成钱包地址。 同时...

  • 以太坊地址生成

    通过椭圆曲线算法生成钥匙对(公钥和私钥),以太坊采用的是secp256k1曲线。公钥采用uncompressed模...

  • 优一区块链知识学习笔记5

    公钥和私钥 公钥加密,私钥解密 私钥→椭圆曲线乘法→公钥→单向加密哈希函数→比特币地址(过程不可逆) 私钥:随机选...

  • RSA加密解密函数

    一、已有公钥私钥1、私钥解密 二、已有公钥私钥文件

  • ipfs-ipns公私钥签名算法

    生成公钥私钥对 公钥生成ID 私钥签名。解析函数分析 :resolver.Resolvenamesys->res...

  • 以太坊账户

    以一个账户举例: 路径: m/44'/60'/0'/0 助记词: 私钥: 公钥: 地址: 以太坊钱包使用户用来管理...

  • https+ ca证书

    非对称加密 1.公钥加密,私钥可以解密;2.私钥加密,公钥可以解密;3.公钥解密,公钥不可以解密; 伪造公钥 用户...

  • 应用程序数字签名技术

    什么是公钥和私钥 公钥加密,私钥解密私钥加密,公钥解密 苹果的数字签名

  • Freecash 多签测试

    1. 准备好3个地址及其公钥私钥 地址 n1GwLVa9VgynhKSCZksHs5RmrWuuNyhz4E公钥 ...

网友评论

      本文标题:以太坊解析-(1) 公钥私钥地址字符串公钥推导

      本文链接:https://www.haomeiwen.com/subject/nwroahtx.html