首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用cosmos sdk生成hd钱包密钥和地址给定的种子短语?

如何使用cosmos sdk生成hd钱包密钥和地址给定的种子短语?
EN

Stack Overflow用户
提问于 2022-02-04 05:11:59
回答 1查看 2.4K关注 0票数 2

我正在尝试使用cosmos sdk生成hd钱包私钥、公钥和无地址。下面是python中的等效实现,它生成键,按预期地址,但是当试图使用cosmos sdk在golang中生成时,它不会生成相同的键。对于python实现的等效golang版本的任何输入都是非常感谢的。谢谢。

Python

代码语言:javascript
复制
seed = Mnemonic.to_seed("blast about old claw current first paste risk involve victory edit current", passphrase="")
print("Seed: ", seed.hex())
purpose = 44
coinType = 118
account = 0
change = 0

hdwallet = HDWallet()
hdwallet.from_seed(seed=seed.hex())

for addressIndex in range(1):
    hdwallet.clean_derivation()
    hdwallet.from_index(purpose, hardened=True)
    hdwallet.from_index(coinType, hardened=True)
    hdwallet.from_index(account, hardened=True)
    hdwallet.from_index(change)
    hdwallet.from_index(addressIndex, hardened=True)

    print("---")
    print("Derivation Path: ", hdwallet.path())
    print("Private Key: ", hdwallet.private_key())
    print("Public Key: ", hdwallet.public_key())

    readdr_bytes = b"\x04" + bytearray.fromhex(hdwallet.public_key())
    readdr_bytes5 = bech32.convertbits(readdr_bytes, 8, 5)
    wallet_addr = bech32.bech32_encode("atom", readdr_bytes5)
    print("Wallet Address: ", wallet_addr)

输出

派生路径: m/44'/118'/0'/0/0‘私钥: 69668f2378b43009b16b5c6eb5e405d9224ca2a326a65a17919e567105fa4e5a公钥: 03de79435cbc8a799efc24cdce7d3b180fb014d5f19949fb8d61de3f21b9f6c1f8钱包地址: atom1qspau72rtj7g57v7lsjvmnna8vvqlvq56hcejj0m34sau0eph8mvr7qgl9avu GoLang

代码语言:javascript
复制
import (
    "github.com/tendermint/tendermint/crypto/secp256k1"
    "github.com/cosmos/cosmos-sdk/crypto/hd"
    "github.com/cosmos/go-bip39"
    "github.com/decred/dcrd/bech32"
 )

path := hd.BIP44Params{
    Purpose:      44,
    CoinType:     118,
    Account:      0,
    Change:       false,
    AddressIndex: 0,
}

seed := bip39.NewSeed("blast about old claw current first paste risk involve victory edit current","")

master, ch := hd.ComputeMastersFromSeed(seed)
priv, err := hd.DerivePrivateKeyForPath(master, ch, path.String())
if err != nil {
    log.Fatal(err)
}
var privKey = secp256k1.GenPrivKeySecp256k1(priv)
pubKey := privKey.PubKey()
fmt.Println(hex.EncodeToString(pubKey.Bytes()))

decodeString, _ := hex.DecodeString(fmt.Sprintf("04%x", pubKey.Bytes()))

// Convert test data to base32:
conv, err := bech32.ConvertBits(decodeString, 8, 5, true)
if err != nil {
    fmt.Println("Error:", err)
}
encoded, err := bech32.Encode("atom", conv)
if err != nil {
    fmt.Println("Error:", err)
}

// Show the encoded data.
fmt.Println("Atom address:", encoded)

输出

派生路径: m/44'/1022'/0'/0/0‘私钥: 84925813eac8c1dc39f170e93b3bebe0bf961ac9c46507e858ce178a1a715c26公钥: 0204a0bad86cafed2daf1b4080a3e908afcf524e2a9c24e20817920c478d537cc1钱包地址: atom1qsp3yaurlt463pl6pekgae4yudlcwk2dhxt93cxz5d5ymw3j8xmngaqef5j7p

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-02-12 23:05:08

这两项守则的结果因以下两个问题而有所不同:

在Go代码中,私钥被错误地导出:

在Python代码中,使用路径m/44'/118'/0'/0/0',如hdwallet.path()的输出所示。相反,在Go代码中使用的是路径m/44'/118'/0'/0/0,如path.String()的输出所示。

要在Go代码中使用Python代码的路径,可以直接指定路径。为此,这一行:

:= hd.DerivePrivateKeyForPath(主,ch,path.String())

必须由以下各项取代:

:= hd.DerivePrivateKeyForPath(主,ch,“m/44‘/118’/0‘/0’”)

并且可以删除path变量。

通过这一更改,Go代码提供了与Python代码相同的私钥.

  • 在Go代码中,私钥被错误导入。因此,公钥被错误地确定。要解决这个问题,行:

var privKey = secp256k1.GenPrivKeySecp256k1(priv)

必须由以下各项取代:

var privKey = secp256k1.PrivKey(priv)

通过此更改,Go代码提供与Python代码相同的公钥。。

Go代码的其余部分在功能上等同于Python代码,因此Go代码产生与Python代码相同的地址。

完整的Go代码是:

代码语言:javascript
复制
package main

import (
    "encoding/hex"
    "fmt"
    "log"

    "github.com/cosmos/cosmos-sdk/crypto/hd"
    "github.com/cosmos/go-bip39"
    "github.com/decred/dcrd/bech32"
    "github.com/tendermint/tendermint/crypto/secp256k1"
)

func main() {

    seed := bip39.NewSeed("blast about old claw current first paste risk involve victory edit current", "")
    fmt.Println("Seed: ", hex.EncodeToString(seed)) // Seed:  dd5ffa7088c0fa4c665085bca7096a61e42ba92e7243a8ad7fbc6975a4aeea1845c6b668ebacd024fd2ca215c6cd510be7a9815528016af3a5e6f47d1cca30dd

    master, ch := hd.ComputeMastersFromSeed(seed)
    path := "m/44'/118'/0'/0/0'"
    priv, err := hd.DerivePrivateKeyForPath(master, ch, path)
    if err != nil {
        log.Fatal(err)
    }
    fmt.Println("Derivation Path: ", path)                 // Derivation Path:  m/44'/118'/0'/0/0'
    fmt.Println("Private Key: ", hex.EncodeToString(priv)) // Private Key:  69668f2378b43009b16b5c6eb5e405d9224ca2a326a65a17919e567105fa4e5a

    var privKey = secp256k1.PrivKey(priv)
    pubKey := privKey.PubKey()
    fmt.Println("Public Key: ", hex.EncodeToString(pubKey.Bytes())) // Public Key:  03de79435cbc8a799efc24cdce7d3b180fb014d5f19949fb8d61de3f21b9f6c1f8

    decodeString, err := hex.DecodeString(fmt.Sprintf("04%x", pubKey.Bytes()))
    if err != nil {
        log.Fatal(err)
    }

    // Convert test data to base32:
    conv, err := bech32.ConvertBits(decodeString, 8, 5, true)
    if err != nil {
        fmt.Println("Error:", err)
    }
    encoded, err := bech32.Encode("atom", conv)
    if err != nil {
        fmt.Println("Error:", err)
    }

    // Show the encoded data.
    fmt.Println("Wallet Address:", encoded) // Wallet Address: atom1qspau72rtj7g57v7lsjvmnna8vvqlvq56hcejj0m34sau0eph8mvr7qgl9avu
}
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70981681

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档