首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何用Python AlgoSDK恢复Algorand钱包?

如何用Python AlgoSDK恢复Algorand钱包?
EN

Stack Overflow用户
提问于 2021-02-07 06:59:53
回答 1查看 200关注 0票数 1

虽然官方的algosdk (Python SDK for Algorand)文档建议,只需调用以下函数(link)即可恢复钱包:

代码语言:javascript
复制
create_wallet(name, pswd, driver_name='sqlite', master_deriv_key=None)

第四个参数:

代码语言:javascript
复制
master_deriv_key (str, optional) – if recovering a wallet, include

钱包恢复在我的代码中不起作用,也会导致遇到异常。此外,官方Algorand文档还展示了如何使用上述函数恢复钱包(link):

代码语言:javascript
复制
# recover the wallet by passing mdk when creating a wallet
new_wallet = kcl.create_wallet("MyTestWallet2", "testpassword", master_deriv_key=mdk)

下面,您可以查看我的代码,这是一个非常简单的代码片段,我用Algorand SDK进行了一些测试:

代码语言:javascript
复制
from algosdk import kmd
from algosdk import mnemonic

kmd_clt = kmd.KMDClient('855d39510cce40caf11de4c941b37632d1529ec970156214528a33a0ae8473b4', 'http://127.0.0.1:6969')
if kmd_clt:
    kmd_wlt_mdk = None
    kmd_wlt_list = kmd_clt.list_wallets()
    for kmd_wlt in kmd_wlt_list:
        kmd_name = kmd_wlt['name']
        kmd_id = kmd_wlt['id']
        if kmd_name == 'wallet_name':
            kmd_wlt_hdl = kmd_clt.init_wallet_handle(kmd_id, 'wallet_password')
            if kmd_wlt_hdl:
                kmd_wlt_mdk = kmd_clt.export_master_derivation_key(kmd_wlt_hdl, 'wallet_password')
            break
    if kmd_wlt_mdk:
        kmd_wlt = kmd_clt.create_wallet('wallet_name', 'wallet_password', master_deriv_key=kmd_wlt_mdk)
        kmd_wlt_hdl = kmd_clt.init_wallet_handle(kmd_wlt['id'], 'wallet_password')
        acc_addr_list = kmd_clt.list_keys(kmd_wlt_hdl)
        for acc_addr in acc_addr_list:
            account_address = acc_addr
            print(account_address)
            account_key = kmd_clt.export_key(kmd_wlt_hdl, 'wallet_password', account_address)
            print(account_key)
            account_mnemonic = mnemonic.from_private_key(account_key)
            print(account_mnemonic)

下面,您可以查看在运行时返回的回溯和错误消息:

代码语言:javascript
复制
Traceback (most recent call last):
  File "/home/emiliano/anaconda3/lib/python3.7/site-packages/algosdk/kmd.py", line 63, in kmd_request
    resp = urlopen(req)
  File "/home/emiliano/anaconda3/lib/python3.7/urllib/request.py", line 222, in urlopen
    return opener.open(url, data, timeout)
  File "/home/emiliano/anaconda3/lib/python3.7/urllib/request.py", line 531, in open
    response = meth(req, response)
  File "/home/emiliano/anaconda3/lib/python3.7/urllib/request.py", line 641, in http_response
    'http', request, response, code, msg, hdrs)
  File "/home/emiliano/anaconda3/lib/python3.7/urllib/request.py", line 569, in error
    return self._call_chain(*args)
  File "/home/emiliano/anaconda3/lib/python3.7/urllib/request.py", line 503, in _call_chain
    result = func(*args)
  File "/home/emiliano/anaconda3/lib/python3.7/urllib/request.py", line 649, in http_error_default
    raise HTTPError(req.full_url, code, msg, hdrs, fp)
urllib.error.HTTPError: HTTP Error 400: Bad Request

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/emiliano/anaconda3/lib/python3.7/site-packages/algosdk/kmd.py", line 67, in kmd_request
    raise error.KMDHTTPError(json.loads(e)["message"])
algosdk.error.KMDHTTPError: wallet with same name already exists

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "algorand_test.py", line 49, in <module>
    kmd_wlt = kmd_clt.create_wallet('emiliano', 'emiliano', master_deriv_key=kmd_wlt_mdk)
  File "/home/emiliano/anaconda3/lib/python3.7/site-packages/algosdk/kmd.py", line 118, in create_wallet
    return self.kmd_request("POST", req, data=query)["wallet"]
  File "/home/emiliano/anaconda3/lib/python3.7/site-packages/algosdk/kmd.py", line 69, in kmd_request
    raise error.KMDHTTPError(e)
algosdk.error.KMDHTTPError: {
  "error": true,
  "message": "wallet with same name already exists"
}

似乎很清楚,create_wallet函数是这种行为的罪魁祸首,它会导致返回错误"wallet同名已存在“。Algorand SDK的内部非常简单,API是REST方法的包装器。Function create_wallet的作用很简单(link):

代码语言:javascript
复制
def create_wallet(self, name, pswd, driver_name="sqlite",
                  master_deriv_key=None):
    """
    Create a new wallet.
    Args:
        name (str): wallet name
        pswd (str): wallet password
        driver_name (str, optional): name of the driver
        master_deriv_key (str, optional): if recovering a wallet, include
    Returns:
        dict: dictionary containing wallet information
    """
    req = "/wallet"
    query = {
        "wallet_driver_name": driver_name,
        "wallet_name": name,
        "wallet_password": pswd
    }
    if master_deriv_key:
        query["master_derivation_key"] = master_deriv_key
    return self.kmd_request("POST", req, data=query)["wallet"]

我确信传入输入的主导出密钥是正确的,因为我已经在控制台使用goal命令检查过它。

以前有没有其他人遇到过这种类型的问题?

EN

回答 1

Stack Overflow用户

发布于 2021-02-08 06:54:12

总而言之,REST API的算法和文档并没有明确建议在创建POST /v1/wallet (link)时使用主导出密钥来检索钱包。相反,Python SDK的算法和文档建议可以将主导出密钥传递给create_wallet函数,然后该函数生成前面声明的HTTP POST,以恢复现有的钱包(link)。

正如我在上面的问题中所解释的那样,由于底层POST /v1/wallet出现故障,create_wallet无法恢复钱包。在@Arty的建议下,这已经被证明如下:

代码语言:javascript
复制
curl -X POST -H "X-KMD-API-Token: <kmd-token>" -H "Content-Type: application/json" -d '{"wallet_driver_name": "sqlite", "wallet_name": <wallet-name>, "wallet_password": <wallet-password>, "master_derivation_key": <master-derivation-key>}' <kmd-address-and-port>/v1/wallet

返回的

代码语言:javascript
复制
{ "error": true, "message": "wallet with same name already exists" }

我已经将这个问题通知了Algorand支持部门,目前正在等待回复。总之,为了让问题的标题更有意义,我想分享另一种可能的解决方案,即仍然依靠Python SDK来恢复钱包:

代码语言:javascript
复制
from algosdk import kmd
from algosdk import wallet
from algosdk import mnemonic

kmd_clt = kmd.KMDClient(<kmd-token>, <kmd-address-and-port>)
if kmd_clt:
    kmd_wlt_mdk = None
    kmd_wlt_list = kmd_clt.list_wallets()
    for kmd_wlt in kmd_wlt_list:
        kmd_name = kmd_wlt['name']
        kmd_id = kmd_wlt['id']
        if kmd_name == <wallet-name>:
            kmd_wlt_hdl = kmd_clt.init_wallet_handle(kmd_id, <wallet-password>)
            if kmd_wlt_hdl:
                kmd_wlt_mdk = kmd_clt.export_master_derivation_key(kmd_wlt_hdl, <wallet-password>)
            break
    if kmd_wlt_mdk:
        wlt = wallet.Wallet(<wallet-name>, <wallet-password>, kmd_clt, mdk=kmd_wlt_mdk)
        if wlt:
            acc_addr_list = wlt.list_keys()
            for acc_addr in acc_addr_list:
                account_address = acc_addr
                print(account_address)
                account_key = wlt.export_key(acc_addr)
                print(account_key)
                account_mnemonic = mnemonic.from_private_key(account_key)
                print(account_mnemonic)

我希望它能在将来对其他人有用。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66082860

复制
相关文章

相似问题

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