dashboard创建密钥时前端的数据怎么传到后端

免费建站   2024年05月10日 23:39  

这篇文章主要介绍“dashboard创建密钥时前端的数据怎么传到后端”,在日常操作中,相信很多人在dashboard创建密钥时前端的数据怎么传到后端问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”dashboard创建密钥时前端的数据怎么传到后端”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

我们创建一个密钥和相应的帐户,就是下面这张图所对应的:

当我们点击了"Register"按钮以后,我们在前端页面上填写的参数,到底是如何一步步的传到比原的后端的。

跟之前一样,我们将对这个问题进行细分,然后各个击破:

前端:当我们填完表单,点了提交以后,比原在前端是如何发送数据的?

:比原的后端是如何接收到数据的?

前端:当我们填完表单,点了提交以后,数据会发送到后端的哪个接口?

当我们点击了"Register"按钮,在前端页面中,一定会在某个地方触发一个向比原节点webapi接口发出请求的操作。究竟是访问的哪个web api?提交的数据又是什么样的呢?让我们先从前端代码中寻找一下。

注意,比原的前端代码位于另一个项目仓库bytom/dashboard中。为了能与我们在本系列文章中使用的比原v1.0.1的代码相匹配,我找到了dashboard中的v1.0.0的代码,并且提交到了一个单独的项目中:freewind/bytom--v1.0.0。注意该项目代码未做任何修改,其master分支对应于官方代码仓库的v1.0.0分支。之所以要弄一个单独的出来,这是因为我们在文章中,每次引用一段代码的时候,都会给出相应的github上的链接,方便读者跳过去查看全貌,使用一个独立项目,会让这个过程更简便一些。

由于比原的前端页面是使用React为主的,所以我猜想在代码中,也该会有一个名为Register的组件,或者某个表单中有一个名为Register的按钮。经过搜索,我们幸运的发现了Register.jsx 这个组件文件,它正好是我们需要的。

经过高度简化后的代码如下:

src/features/app/components/Register/Register.jsx#L9-L148

classRegisterextendsReact.Component{//...//4.submitWithErrors(data){returnnewPromise((resolve,reject)=>{//5.this.props.registerKey(data).catch((err)=>reject({_error:err.message}))})}//...render(){//...return(//...//3.<formclassName={styles.form}onSubmit={handleSubmit(this.submitWithErrors)}>//1.<TextFieldtitle={lang==='zh'?'账户别名':'AccountAlias'}placeholder={lang==='zh'?'请输入账户别名...':'Pleaseentertheaccountalias...'}fieldProps={accountAlias}/><TextFieldtitle={lang==='zh'?'密钥别名':'KeyAlias'}placeholder={lang==='zh'?'请输入密钥别名...':'Pleaseenterthekeyalias...'}fieldProps={keyAlias}/><TextFieldtitle={lang==='zh'?'密钥密码':'KeyPassword'}placeholder={lang==='zh'?'请输入密钥密码...':'Pleaseenterthekeypassword...'}fieldProps={password}type='password'/><TextFieldtitle={lang==='zh'?'重复输入密钥密码':'Repeatyourkeypassword'}placeholder={lang==='zh'?'请重复输入密钥密码...':'Pleaserepeatthekeypassword...'}fieldProps={repeatPassword}type='password'/>//2.<buttontype='submit'className='btnbtn-primary'disabled={submitting}>{lang==='zh'?'注册':'Register'}</button>//....</form>//...)}}

上面的代码,共有5个地方需要注意,被我用数字标示出来了。注意这5个数字并不是从上到下标注,而是按照我们关注的顺序来的:

表单上的各个输入框,就是我们填写别名和密码的地方。这里需要关注的是每个TextField的fieldProps属性,它对应我们提交到后台的数据的name

就是那个“Register”按钮了。需要注意的是,它的type是submit,也就是说,点击它以后,将会触发所在form的onSubmit方法

回到了form的开头。注意它的onSubmit里面,调用的是handleSubmit(this.submitWithErrors)。其中的handleSubmit是从该表单所使用的第三方redux-form中传入的,用来处理表单提交,我们在这里不关注它,只需要知道我们需要把自己的处理函数this.submitWithErrors传给它。而在后者中,我们将会调用比原节点提供的web api

第3步中的this.submitWithErrors最终将走到这里定义的submitWithErrors函数

submitWithErrors将会发起一个异步请求,最终调用由外部传进来的registerKey函数

从这里我们还看不到调用的是哪个api,所以我们必须继续去寻找registerKey。很快就在同文件中找到了registerKey:

src/features/app/components/Register/Register.jsx#L176-L180

(dispatch)=>({registerKey:(token)=>dispatch(actions.core.registerKey(token)),//...})

它又将会调用actions.core.registerKey这个函数:

src/features/core/actions.js#L44-L87

constregisterKey=(data)=>{return(dispatch)=>{//...//1.1constkeyData={'alias':data.keyAlias,'password':data.password}//1.2returnchainClient().mockHsm.keys.create(keyData).then((resp)=>{//...//2.1constaccountData={'root_xpubs':[resp.data.xpub],'quorum':1,'alias':data.accountAlias}//2.2dispatch({type:'CREATE_REGISTER_KEY',data})//2.3chainClient().accounts.create(accountData).then((resp)=>{//...//2.4if(resp.status==='success'){dispatch({type:'CREATE_REGISTER_ACCOUNT',resp})}})//...})//...}}

可以看到,在这个函数中,做的事情还是很多的。而且并不是我一开始预料的调用一次后台接口就行了,而是调用了两次(分别是创建密钥和创建帐户)。下面进行分析:

1.1是为了让后台创建密钥而需要准备的参数,一个是alias,一个是password,它们都是用户填写的

1.2是调用后台用于创建密钥的接口,把keyData传过去,并且拿到返回的resp后,进行后续的处理

2.1是为了让后台创建帐户而需要准备的参数,分别是root_xpubs, quorum和alias,其中root_xpubs是创建密钥后返回的公钥,quorum目前不知道(TODO),alias是用户填写的帐户别名

2.2这一句没有作用(经过官方确认了),因为我在代码中没有找到处理CREATE_REGISTER_KEY的代码。可以看这个issue#28

2.3调用后台创建帐户,把accountData传过去,可以拿到返回的resp

2.4调用成功后,再使用redux的dispatch函数分发一个CREATE_REGISTER_ACCOUNT信息。不过这个信息好像也没有太大用处。

关于CREATE_REGISTER_ACCOUNT,我在代码中找到了两处相关:

src/features/core/reducers.js#L229-L234

constaccountInit=(state=false,action)=>{if(action.type=='CREATE_REGISTER_ACCOUNT'){returntrue}returnstate}

src/features/app/reducers.js#L10-L115

exportconstflashMessages=(state={},action)=>{switch(action.type){//...case'CREATE_REGISTER_ACCOUNT':{returnnewSuccess(state,'CREATE_REGISTER_ACCOUNT')}//...}}

第一个看起来没什么用,第二个应该是用来在操作完成后,显示相关的错误信息。

那就让我们把关注点放在1.2和2.3这两个后台调用的地方吧。

chainClient().mockHsm.keys.create(keyData)对应的是:

src/sdk/api/mockHsmKeys.js#L3-L31

constmockHsmKeysAPI=(client)=>{return{create:(params,cb)=>{letbody=Object.assign({},params)consturi=body.xprv?'/import-private-key':'/create-key'returnshared.tryCallback(client.request(uri,body).then(data=>data),cb)},//...}}

可以看到在create方法中,如果找不到body.xprv(就是本文对应的情况),则会调用后台的/create-key接口。经过一长串的跟踪,我们终于找到了一个。

chainClient().accounts.create(accountData)对应的是:

src/sdk/api/accounts.js#L3-L30

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

很快我们在这边,也找到了创建帐户时调用的接口为/create-account

前端这边,我们终于分析完了。下一步,将进入比原的节点(也就是后端)。

后端:比原的后端是如何接收到数据的?

如果我们对前一篇文章还有印象的话,会记得比原在启动之后,会在Node.initAndstartApiServer方法中启动web api对应的http服务,并且在API.buildHandler()方法中会配置很多的功能点,其中一定会有我们这里调用的接口。

让我们看看API.buildHandler方法:

api/api.go#L164-L244

func(a*API)buildHandler(){walletEnable:=falsem:=http.NewServeMux()ifa.wallet!=nil{walletEnable=true//...m.Handle("/create-account",jsonHandler(a.createAccount))//...m.Handle("/create-key",jsonHandler(a.pseudohsmCreateKey))//...

很快,我们就发现了:

/create-account: 对应a.createAccount

/create-key: 对应a.pseudohsmCreateKey

让我们先看一下a.pseudohsmCreateKey:

api/hsm.go#L23-L32

func(a*API)pseudohsmCreateKey(ctxcontext.Context,instruct{Aliasstring`json:"alias"`Passwordstring`json:"password"`})Response{//...}

可以看到,pseudohsmCreateKey的第二个参数,是一个struct,它有两个字段,分别是Alias和Password,这正好和前面从前端传过来的参数keyData对应。那么这个参数的值是怎么由提交的JSON数据转换过来的呢?上次我们说到,主要是由a.pseudohsmCreateKey外面套着的那个jsonHandler进行的,它会处理与http协议相关的操作,以及把JSON数据转换成这里需要的Go类型的参数,pseudohsmCreateKey就可以直接用了。

由于在这个小问题中,我们问题的边界是比原后台是如何拿到数据的,所以我们到这里就可以停止对这个方法的分析了。它具体是怎么创建密钥的,这在以后的文章中将详细讨论。

再看a.createAccount:

api/accounts.go#L15-L30

//POST/create-accountfunc(a*API)createAccount(ctxcontext.Context,insstruct{RootXPubs[]chainkd.XPub`json:"root_xpubs"`Quorumint`json:"quorum"`Aliasstring`json:"alias"`})Response{//...}

与前面一样,这个方法的参数RootXPubs、Quorum和Alias也是由前端提交,并且由jsonHandler自动转换好的。

到此,关于“dashboard创建密钥时前端的数据怎么传到后端”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注网站,小编会继续努力为大家带来更多实用的文章!

域名注册
购买VPS主机

您或许对下面这些文章有兴趣:                    本月吐槽辛苦排行榜

看贴要回贴有N种理由!看帖不回贴的后果你懂得的!


评论内容 (*必填):
(Ctrl + Enter提交)   

部落快速搜索栏

各类专题梳理

网站导航栏

X
返回顶部