设为首页 加入收藏

TOP

剥开比原看代码12:比原是如何通过/create-account-receiver创建地址的?(一)
2018-10-19 15:51:04 】 浏览:157
Tags:代码 如何 通过 /create-account-receiver 创建 地址

作者:freewind

比原项目仓库:

Github地址:https://github.com/Bytom/bytom

Gitee地址:https://gitee.com/BytomBlockchain/bytom

在比原的dashboard中,我们可以为一个帐户创建地址(address),这样就可以在两个地址之间转帐了。在本文,我们将结合代码先研究一下,比原是如何创建一个地址的。

首先看看我们在dashboard中的是如何操作的。

我们可以点击左侧的"Accounts",在右边显示我的帐户信息。注意右上角有一个“Create Address”链接:  点击后,比原会为我当前选择的这个帐户生成一个地址,马上就可以使用了:  

本文我们就要研究一下这个过程是怎么实现的,分成了两个小问题:

  1. 前端是如何向后台接口发送请求的?
  2. 比原后台是如何创建地址的?

前端是如何向后台接口发送请求的?

在前一篇文章中,我们也是先从前端开始,在React组件中一步步找到了使用了接口,以前发送的数据。由于这些过程比较相似,在本文我们就简化了,直接给出找到的代码。

首先是页面中的"Create Address"对应的React组件:

https://github.com/Bytom/dashboard/blob/0cc300fd0a9cbc52940b2d5119cf05230392a75f/src/features/accounts/components/AccountShow.jsx#L12-L132

class AccountShow extends BaseShow {
  // ...
  // 2. 
  createAddress() {
    // ...
    // 3. 
    this.props.createAddress({
      account_alias: this.props.item.alias
    }).then(({data}) => {
      this.listAddress()
      this.props.showModal(<div>
        <p>{lang === 'zh' ? '拷贝这个地址以用于交易中:' : 'Copy this address to use in a transaction:'}</p>
        <CopyableBlock value={data.address} lang={lang}/>
      </div>)
    })
  }

  render() {
      // ...
      view = 
        <PageTitle
          title={title}
          actions={[
            // 1.
            <button className='btn btn-link' onClick={this.createAddress}>
              {lang === 'zh' ? '新建地址' : 'Create address'}
            </button>,
          ]}
        />
       // ...
    }
    // ...
  }
}

上面的第1处就是"Create Address"链接对应的代码,它实际上是一个Button,当点击后,会调用createAddress方法。而第2处就是这个createAddress方法,在它里面的第3处,又将调用this.props.createAddress,也就是由外部传进来的createAddress函数。同时,它还要发送一个参数account_alias,它对应就是当前帐户的alias。

继续可以找到createAddress的定义:

https://github.com/Bytom/dashboard/blob/674d3b1be8ec420d75f0ab0b792fd97e11ffe352/src/sdk/api/accounts.js#L3-L32

const accountsAPI = (client) => {
  return {
    // ...
    createAddress: (params, cb) => shared.create(client, '/create-account-receiver', params, {cb, skipArray: true}),
    // ...
  }
}

可以看到,它调用的比原接口是/create-account-receiver

然后我们就将进入比原后台。

比原后台是如何创建地址的?

在比原的代码中,我们可以找到接口/create-account-receiver对应的handler:

api/api.go#L164-L174

func (a *API) buildHandler() {
    // ...
    if a.wallet != nil {
        // ...
        m.Handle("/create-account-receiver", jsonHandler(a.createAccountReceiver))

原来是a.createAccountReceiver。我们继续进去:

api/receivers.go#L9-L32

// 1.
func (a *API) createAccountReceiver(ctx context.Context, ins struct {
    AccountID    string `json:"account_id"`
    AccountAlias string `json:"account_alias"`
}) Response {

    // 2.
    accountID := ins.AccountID
    if ins.AccountAlias != "" {
        account, err := a.wallet.AccountMgr.FindByAlias(ctx, ins.AccountAlias)
        if err != nil {
            return NewErrorResponse(err)
        }
        accountID = account.ID
    }

    // 3.
    program, err := a.wallet.AccountMgr.CreateAddress(ctx, accountID, false)
    if err != nil {
        return NewErrorResponse(err)
    }

    // 4. 
    return NewSuccessResponse(&txbuilder.Receiver{
        ControlProgram: program.ControlProgram,
        Address:        program.Address,
    })
}

方法中的代码可以分成4块,看起来还是比较清楚:

  1. 第1块的关注点主要在参数这块。可以看到,这个接口可以接收2个参数account_idaccount_alias,但是刚才的前端代码中传过来了account_alias这一个,怎么回事?
  2. 从第2块这里可以看出,如果传了account_alias这个参数,则会以它为准,用它去查找相应的account,再拿到相应的id。否则的话,才使用account_id当作account的id
  3. 第3块是为accountID相应的account创建一个地址
  4. 第4块返
首页 上一页 1 2 3 下一页 尾页 1/3/3
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇剥开比原看代码01:初始化时生成.. 下一篇剥开比原看代码09:通过dashboard..

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目