二十四小时玩转myetherwallet钱包开发_第1页
二十四小时玩转myetherwallet钱包开发_第2页
二十四小时玩转myetherwallet钱包开发_第3页
二十四小时玩转myetherwallet钱包开发_第4页
二十四小时玩转myetherwallet钱包开发_第5页
已阅读5页,还剩93页未读 继续免费阅读

付费下载

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第01:私钥助记之的爱情仇nk:包账:私钥第10第11入现第12章:eOvr:总结钱包种类非常多,主流的有以太坊钱包、比特币钱包、S钱包以及其他类型的虚拟货币钱包。在咱们这次课程中是来开发使用最频繁的钱包——以太坊钱包,在后面的课程也会陆续推出比特币钱包、S钱包开发。本课程《二十四小时玩转thrt钱包开发》主要分为两大部分,第一部分(第一章~第四章):熟悉Ethrt钱包以及搞清楚以太坊钱包理论;第二部分(第五章~第十二章):编码实现以太坊钱包项目。以太坊作为一个广泛使用的开发平台,包含的数字货币资产的转移和投资必然需要使用到钱包,因此钱包是领域必需掌握的知识,另外也是交易所开发的。目前企业对钱包开发的求较大,很少有成钱包开发,因此特推出此满足企业与市场上对钱包的需求,以帮助家快速全面的掌握以太坊钱包理论与开发实践。内容包含:、文档、源码。本能学到什NodeJS调用Token智能合约安全管理和转移你的Token数字资前端开发基础:HTML、JavaScript、CSS语 大 Coding:生成账户的地址、私钥、keystore、助记 钱包账 二GameOver项目路 本次课程以MyEtherWallet网页钱包的重要功能作为开发需求,由此,项目的路线规划是 本章节介绍以太坊Mtert钱包,了解它的重要功能以及使用方法,将以此作为咱们钱包开发需求的基础。另外还讲述了tMsk钱包的总要功能,它的作用在项目开发中将作为一个不可缺少的辅助工具。MyEtherWallet钱包介三、查看账号详第一步:账四、ETH第一步:账02-MetaMask钱包介一、安装MetaMask基于MyEtherWallet钱包介 MyEtherWallet是一个轻钱包,使用起来最简单,无需在直接在网页上就可以完成所有的备份。支持连接所有测试网络和私有链网络。MyEtherWallet 点击“Network”,会看到MyEtherWallet支持连接主网、kovan、Ropston、Rinkeby与私有网络由于后面会演示如何转账,转账则需花费gas,因此选择为测试网络,这里使用v测试网络。在后面的章节搭建以太坊私有链学习后,便可使用私有网络,私钥网络选项在网络列表最底部。在导航栏点击“NewWallet”按钮,如下图。输入,注意长度不小于九位点击“DownloadKeystoreFile”点击“Continue”Keystore用“KeystoreKeystoreKeystore

查看账号详情之前,需要账号,账号的方式提供了多种。通过在上一步创建的账KeystoreKeystore第一步:账通过Keystore

、私钥”这些信息去账号,下面介绍使用Keystore文件、选择“Kystore/JSON选择的KeystoreFile文点击“Unlock”账点击“Unlock”账发送ETH之前,同样需要账号,账号的方式与查看账号详情一样第一步:账到Mist客户端获取到Account1的Keystore文件,然后拷贝到桌通过Keystore文件+Account1账号输入转账金额,如0.1选择币种,ETH输入GasLimit,使用默认的21000然后查看Account1 账号的ETH余额由 减少到了.745873497,可以现除了0.1外同样也会花费一定的Gas,另外收款地 也会增加0.1ETH 02-MetaMaskk是一个基于浏览器的以太坊钱包插件,能帮助用户方便地管理自己的以太坊数字资产。不需安装客户端,只需添加至浏览器扩展程序即可使用,非常方便,但目前只支持和efx浏览器,并且可以很方便的调试和测试以太坊的智能合约。支持所有测试网络和私有链网络,这里介绍在中使用ask。一、安装MetaMask基于 接着会显示钱包的助记词,切记,切记,切记,该助记词一定不能被泄漏(下面显示的助记词只是为了演示给大家操作,实际中我并不会使用该钱包,别想着看里面的账号有没有钱),建议记在纸上。然后界面上会让你点击该钱包的助记词,按照助记词的顺序依次点击每一个单词,如下:最后个界面,点击“VIEWACCOUNT”按钮即可,然后可看到MetaMask已经初始创建了一个账号,名称是Account1,连接在的主网,ETH余额为零。二、MetaMask主界面功能介 第三步:然后会自动打开 /vntestnet/fce网页,这里提供了两种索取的渠道。通过第式索取:点击上图中的 ETH然后在下图中输入KYXY代币合约地 确认拥有KYXY代币余额,下面的账号拥有100KYXY:博客中的文章归博主所有,,请联系作者 03-不得不说:钱包地址生成03-钱账地公私总二、go-ethereum账号地址生成过源源源结结每个账户都是由一对组成:公钥和私钥账号与公钥、私钥、地址,在以太坊中是一一对应的,而在有的中账号与公私钥对、地址公钥压缩格式是33字节,非压缩格式是65字节。即压缩格式是66式是130位长度的十六进制字符组成。以002003开头为压缩公钥。如 0xE4356E49C88C8B7AB370AF7D5C0C54F0261AAA006F6BDE09CD4745CF54E0115A钱包应用程序用于管理多个账号,在以太坊中账号与公私钥对、地址是一一对应的,公钥、私钥、地址也是一一对应的,私钥生成公钥,公钥生成地址,且不可逆,私钥是账号的且不可泄漏,地可以公开用于转账。go-ethereum项目是以太坊提供的Geth客户端,是目前使用最广泛的客户端,通过此客户端可以进行基本所有的以太坊相关操作。主要功能包括创建帐户、转账交易、部署合约、调用合约a中的eae方法就是Gth创建账号的方将生成地址打印到控制台给使用者查看。下面从该方法作为一步步解析地址的生成过程。////accountCreatecreatesanewaccountintothekeystoredefinedbytheCLIflags.funcaccountCreate(ctx*cli.Context){cfg:=gethConfig{Node://Loadconfigiffile:=ctx.GlobalString(configFileFlag.Name);file!={iferr:=loadConfig(file,&cfg);err!=nil{utils.Fatalf("%v",err)}}utils.SetNodeConfig(ctx,scryptN,scryptP,keydir,err:=iferr!=nilutils.Fatalf("Failedtoreadconfiguration:%v",}password:=getPassPhrase("YournewaccountislockedPleasegive sword.Donotforgetthispassword.",true,0,address,err:=keystore.StoreKey(keydir,password,scryptN,iferr!=nilutils.Fatalf("Failedtocreateaccount:%v",}returnnilcfgcfg:=gethConfig{Node:scryptNscryptN,scryptP,keydir,err:=passwordpassword:=getPassPhrase("YournewaccountislockedPlease sword.Donotforgetthispassword.",true,addressaddress,err:=keystore.StoreKey(keydir,password,scryptN, 方法中可以看出生成地址的关键在于调用keystore.StoreKey()方法,因 包下的keystore_passphrase.go文件中的StoreKey()方法。打开accounts/keystore/keystore_passphrase.go,查看StoreKey()////StoreKeygeneratesakey,encryptswith'auth'andstoresinthegivenfuncStoreKey(dir,authstring,scryptN,scryptPint)(common.Address,error){_,a,err:=storeNewKey(&keyStorePassphrase{dir,scryptN,scryptP,false},rand.Reader,auth)returna.Address,} 方法现在生成地址的关键实现在于storeNewKey(),它的实现是去新建公私钥,然后实例化账号对象。查看该方法发现又调用了newKey()方法,实现中又调用了 打开funcfuncstoreNewKey(kskeyStore,randio.Reader,authstring)(*Key,accounts.Account,error){key,err:=newKey(rand)iferr!=nil{returnnil,accounts.Account{},}a:=accounts.Account{Address:key.Address,URL:accounts.URL{Scheme:KeyStoreScheme,Path:ks.JoinPath(keyFileName(key.Address))}}iferr:=ks.StoreKey(a.URL.Path,key,auth);err!=returnnil,a,err}returnkey,a,}funcnewKey(randio.Reader)(*Key,error)privateKeyECDSA,err:=ecdsa.GenerateKey(crypto.S256(),rand)iferr!=nil{returnnil,}returnnewKeyFromECDSA(privateKeyECDSA),}funcnewKeyFromECDSA(privateKeyECDSA*ecdsa.PrivateKey){id:=uuid.NewRandom()key:=&Key{ PrivateKey:privateKeyECDSA,}return}keykey,err:= privateKeyECDSAprivateKeyECDSA,err:=ecdsa.GenerateKey(crypto.S256(),privyECDA是ed.PvateKy数据结构的指针,它就是私钥,公钥作为它的一个字段,在ees包中可以看到它的定义,源码位置在ptoeiego。////PublicKeyisarepresentationofanellipticcurvepublickey.typePublicKeystruct{X*big.IntY}//PrivateKeyisarepresentationofanellipticcurveprivatekey.typePrivateKeystruct{}地址地址由crypto.PubkeyToAddress()方法传入公钥privateKeyECDSA.PublicKey生成 crypto.PubkeyToAddress()生成地址的方法使用的是Keccak256算法。源码位置funcPubkeyToAddress(pecdsa.PublicKey){pubBytes:=return}结crypto/ecdsa包里的GenerateKey()方法,使用secp256k1

包里 从上面的源码分析可知,在生成地址的过程中主要使用了crypto库 椭圆曲线crypto、secp256k1 crypto、secp256k1npmicryptosecp256k1需要依赖库到项目 npmicryptosecp256k1varvarCrypto=varsecp256k1=require('secp256k1')varkeccak=require('keccak')varprivateKey=varpubKey=secp256k1.publicKeyCreate(privateKey,false).slice(1);address:问题二:私钥长度是64位、地址长度是40位,代表私钥与公钥的对应关系是对应,所以私钥1000000*60*60*24*365=3.1536e+13≈1000000*60*60*24*365=3.1536e+13≈1e+3, ≈1e+3*25,所就算你与10000个程序员合作,不停的生成私钥100年,那么可以获取到3.1536+19私钥的2e57分之一,你觉得这可能会碰到相同的私钥吗? 归博主所有,,请联系作者 面的中对以太坊钱包已经有了一定的认识,上一章也重点介绍了账号地址的生过程,在以太坊钱包中一个重点就是账户系统,在这个模块中很多初学同学不是很清楚ytoe、助记词与私钥它们之间的关系。下面来看看它们之间到底有着怎样的爱恨情仇,让大家琢磨不透。04-、私钥、keystore与助记词之间的爱恨情一、理码、私钥、keystore与助记私助记HD钱以太坊对BIP不是私钥,可以进行修改或重置。它主要用途有两个,一是转账时候的支付,二是keystore导入钱包时需要输入的,用于keystore在钱包应用程序中,创建账号时需要设定一个,这个一般要求不少于8个字符,为了安全,如 成对出现的,有了私钥,就可以通过一定的算法生成公钥,再通过公钥经过一定的算法生成地址,这一过程都是不可逆的,是如何生成的?在上一章节中有详细的说明。私钥一定要妥善保管,若被泄漏别人可以通过私钥账号转出你的该账号的数字货币。因为私钥不利于,容易,因此有了Keystore。Keystore常见于以太坊钱包,它并不是私钥,而是将私钥以加密的方式保存为一份JSON文件,这份JSON文件就是keystore,所以它就是加密后的私钥。但是Keystore必须配合钱包才能使用该账号,所以只有Keystore文件,并不能掌控账12~24目前数钱包应用程序支持导出助记词,如MetaMask等。通过助记词导入账号也数钱包要弄清楚助记词与私钥的关系,得清楚IP协议,是BitcoinImprovementProposals思是Btn的改进建议,用于提出ton的新功能或改进措施。IP协议衍生了很多的版本,主要有IP32、BIP39、IP44。BIP32是HD钱包的提案,通过来生成主私钥,然后派生海量的子私钥和地址,是一串很由于是一串很长的随机数,不利于记录,所以用算法将转化为一串12~24个的单词,方便保存记录,这就是BIP39,它扩展了HD钱包的生成算法。BIP44是在BIP32和BIP43的基础上增加多币种,层次结构非常全面,它允许处理多个币种,在的地址。开发可以为他们的项目未使用的号码。 账户,此级别为了设置独立的用户可以将所有币种放在一个的帐户中,从0开始按顺序递Change:常量0用于外部链,常量1用于链,外部链用于钱包在外部用于接收和付款。 地址索引,按顺序递增的方式从索引0开始。IP44的规则使得HD钱包非常强大,用户只需要保存一个,就能控制所有币种,所有账户的钱包,因此由BIP39生成的助记词非常重要,所以一定安全妥善保管,那么会不会被呢?如果一个HD钱包助记词是12个单词,一共有2048个单词可能性,那么随机的生成的助记词所有可能性大概是HD

,因此几乎不可能被 HierarchicalHDHierarchical

BIP是用于提出Bitcoin以太坊在EIPs/issues/84中,是否遵循BIP32和BIP44,社区里提出来很多有意思的观点,比特币是基于UTXO的,所以可以使用HD钱包(BIP32)为每个交易分配一个新地址,以保护您的隐私。然而,以太坊是基于帐户,每个帐户都有一个地址,BIP是比特币的提案,而且比特币的数据结构的设计是围绕改变地址的想法构建的,BIP的一些提案可能并不适合以太坊。以太坊的模式和比特币UTXO不同,以太坊转账不能改变地址,如果在以太坊上实现UTXO,用户还必须签名两个交易以将余额的一部分发送到一个地址,将余额的一部分发送到第二个地址-这将方式实现。另外,以太坊目前钱包采用KDF的形式,也就是常说的Keystore的形式。以太坊在EIPs/issues/85中,以太坊社区似乎也采用了BIP32的做法,提议HD路径为:m/44'/60'/0'/0/n,n是第n次生成地址。目前以太坊客户端实现了BIP32的客户端有:JaxxMetamask,Exodus,imToken,TREZOR(ETH)&DigitalBitbox二、、私钥、keystore与助记词的关 三、钱包的:私 私钥(PrivateKey)助记词(Mnemoniccode)++即。/bitcoin/bips/ :博客中的文章归博主所有,,请联系作者 本课程是以太坊钱包开发,后端使用的NodeJS搭建,客户端使用的b前端,VSod具,but16.04开发环境,nodev8.11.3,npmv5.6.0。一、前端架 这里只使用了jQuery框架简化代码,另外还有个jQueryValidate插件简化了表单验证。htmlhtml+css+javascript+jQuery 这个钱包应用程序与以坊节点进行交互,使用wb3.js库提供的jI以坊,因我们用NodeJS搭建后端服务,使用成M架构,ttp框架是a,需用到如下第库:a:富有强大功能的HTP中间件框架,使eb应用程序和A洁、表达力强、度高。koa-body:功能齐全的koabody解析器中间件。支持multipart,urlencoded和 web3.js:以太坊JavaScriptAPI 随机产生新的mnemoniccode,并可以将其转成binary的。ethereumjs-util:Ethereum的一个工具库。ethereumjs-wallet:生成和管理公私钥,下面使用其中hdkey子套件来创建HDlixu@ubuntu:~$lixu@ubuntu:~$cd s/demo/MyEtherWallet$npm然后不断回车初始化项目。然后后自动生成package.json文件,是项目包的配置文件,下面

package.json文件的最后一,,{"ethereumjs-tx":"koa":"koa-router":"koa-static":"koa-views":"web3":"^1.0.0-npmnpm 项目的文件。首先实例化oa对象,然后将oaBody、atc、iws由到件,务绑定到3000端口。letletkoa=letapp=newkoa()就是letrouter=require("./router/router")letstatic=require("koa-static")letpath=require("path")letviews=require("koa-views")letkoaBody=require("koa-app.use(async(ctx,next){console.log(`${ctx.method} await 静态文件的库到app.use(static(path.join(dirname, 模板引擎的库到中间app.use(views(path.join(dirname,"views"),{extension:"ejs", <title>创建钱包<scriptsrc="/js/lib/jquery-<script<script<linkrel="stylesheet"<%include<div前端的导航栏,使用$("#nav").load("/html/nav.html")方式载<div<div<divid="nav- 学院href="/account/new.html">新建账户href="/transaction.html">转账modulemodule.exports{getweb3:()=>letWeb3=varweb3=newWeb3(Web3.givenProvider|| returnsuccess:(data){responseData{}returnfail:(msg){responseData={}return} ).ready(function{ margin:100px50px50px}color:}color:text-decoration:}color:}margin:}color{}padding:2px10px;border:1pxsolidgray;}/*display:background-color:#0abc9c;position:fixed;top:0px;left:0px;}#navmargin:10px2px;}#navpadding:}#navpadding:10px;#nav-#nav-margin-left:}#nav-margin-right:}letletrouter=require("koa-router.get("/",async(ctx)=>awaitmodule.exports=koa的 koa-views的 koa-body的 koa-router的 web3.js的 项目源码地:博客中的文章归博主所有,,请联系作者 Coding:生成账户的地址、私钥、keystore、助记一、使用web3连接到以太坊网络(测试网、主网什么是实例化web3对连接到以太坊Kovan测试网二、获取地址、私钥、keystore、助记使用web3创建方式什么是web3是以太坊开提供的接以太坊的模块,允许您使用HTTP或IPC与本地或以RPC层。开发者利用web3连接RPC层,可以连接任何暴露了RPC接口的节点,从而与交互。web3是一个集合库,支持多种开发语言使用wbe3,其中的JavaScriptAPI叫做web3.js、另外还有web3.eth:用于与以太坊和智能合约之间的交互web3.utils:包含一些辅web3.shh:用于协议进行通信的P2P和广播web3.js开档varvarWeb3=//"Wviders.givenProvider"willbesetifinanEthereumsupportedvarweb3=newWeb3(Web3.givenProvider||'ws://some.local-or-ws://some.local-or-根据APIws://some.local-or-

是多少呢?这里需要使用 提供公开的Ethereum主网和测试网络节点,到infura.io后即可获取各个网络的地 第二步:点击上图标记的“createnewproject”按钮创建一个新项目。然后弹出如下弹框,在输入框输入项目名,如”MyEtherWallet“,然后点击“createproject”按钮创建。 varvarWeb3=varweb3=newWeb3(Web3.givenProvider||console.log("Web3:",console.log("web3:",连接到以太坊主网与Kvan测试网络一样的,只需主网节点的地址去实例化eb3即可。由于在主网上交易需要花费gas,因此基于Kvan测试网络进行开发,后续开发完成后可再切换到主网。在开发的项目源码中,我将获取eb3实例的代码封装到了myilj文件的getweb3()方法中,目。 参数 (可选):它是一个可选项,是一个随机字符串,将作为账号 string:帐户地址!signTransaction(tx[,signTransaction(tx[,

>sign:function(data){...},encrypt:function(password){...}}>§address:sign:function(data){...},encrypt:function(password){...}}使用使用APIweb3.eth.accounts.create()创建了新账户后生成了一个账户对象,在该对象中拥有address属性,即账户的地址。letaddress=account.address letprivateKey=account.privateKey获取encrypt:在账户对象中,可以发现它拥 对象方法,encrypt:letkeystore=account.encrypt(password)crypt(privateKey,参数返回值

:用于加密的Object:加密后的keystore文92ae468d01a3f362318',>version:id:'04e9bcbb-96fa-497b-94d1-14df4cd20af6',crypto:{cipherparams:{iv:'2885df2b63f7ef247d753c82fa20038a'},cipher:'aes-128-ctr',kdf:kdfparams:kdfparams:n:262144,r:p:}}在以太坊常见钱包中,只 钱包支持导出助记词,那么如何实现生成助记词呢?这就需用到HD钱包。HD钱包和BIP协议的相关概念请查看"04-、私钥、keystore与助记词之间的爱恨 ip39,cd到项目跟路径运行命令npmibip39letletbip39=//输出:rotatebossclick umexercisedunediagrambecauseonlyanyminutemonitor

web3.eth.accounts.create()方法创建账号,然后account.encrypt()方法生成keystore文件,提供对应的keystore文件与私钥给前letfs=require("fs")letpath=module.exports=//2.//2.根据账号 生成keystore文lettime=newDate()letfilePath=path.join(dirname,"../static/keystore",fs.writeFileSync(filePath,//4.await}}newAccountHtmlasync(ctx{awaitnewAccountasync(ctx{console.log("password:",//1.letnewAccountController=//获取创建钱包账户的页router.get("/account/new.html",//提交创建钱包账户的表 <title>创建钱包<scriptsrc="/js/lib/jquery-<linkrel="stylesheet"<%include<div<h1>创建一个新的账号<formmethod="POST"<inputtype="text"placeholder="请输 "<buttontype="submit">创建账号在iws文件夹下新建dloadytl文件,实现前端将创建后的账号信息提供给用户保存下来,如ye文件、私钥。<title>保存你的<scriptsrc="/js/lib/jquery-<script<script<linkrel="stylesheet"<%include<%include<div<divid="save-<h1>保存你的<aclass="button"href=downloadurl keystore文件 onclick="saveKeystoreNext()">下一步<divid="save-privatekey"style="display:<h1>保存你的私钥<%=privatekeyfunctionfunctionsaveKeystoreNext()$("#save-$("#save-}项目源 钱包账号一:私钱包账号一:私使用web3通过私钥账使用web3获取以太币余三、项目运行效 使用web3通过私钥账参数

>sign:function(data){...},encrypt:function(password){...}}参数addressStringdefaultBlock-callback-defaultBlock-callback-:返回:返回String:给定地址的当前余额,以wei>web3web3.utils.fromWei(number[,参数

finney:ether: kether: mether: gether: tether: unit-String(可选):默认为"ether"web3web3.utils.fromWei('1',>web3.utils.fromWei('1',> modulemodule.exports=transactionHtml:async(ctx)=>await}olrs文件夹下新建ajs文件,后端实现通过私钥账户,并返回以太币余额、账户地址、私钥给前端。letlet{success,fail}=require("../utils/myUtils")letweb3=require("../utils/myUtils").getweb3()//获取以太币余asyncfunctiongetAccountBalance(address)letbalance=awaitweb3.eth.getBalance(address)returnweb3.utils.fromWei(balance,"ether")}asyncfunctionsetResponseData(account){//获取letbalance=awaitgetAccountBalance(account.address)letresDatasuccess({balance,privatekey:returnresData}module.exports=unlockAccountWithPrivate:async(ctx)=>////2.通过私 账//3.将账户信ctx.body=await}letaccountController=require("../controllers/account")//router.get("/transaction.html",//通过私 账router.post("/unlock/private",<title>转账<scriptsrc="/js/lib/jquery-<script<script<linkrel="stylesheet"<%include<div<h1>发送以太币或者Token代币<div name="unlocktype"value="1"><labelfor="unlock-account-type-name="unlocktype"value="2"><labelfor="unlock-account-type-name="unlocktype"value="3"><divid="unlock-account-privatekey"style="display:<h3>请输入你的私钥<textareaid="input-privatekey" onclick="unlockAccountWithPrivatekey()">锁<divid="unlock-account-keystore"style="display:<divid="unlock-account-mnemonic"style="display:<divid="transaction-second"style="display:5.//通过私 账functionunlockAccountWithPrivatekey()status){if(res.code==0){//}}//改变 账号的方$$("input[name=unlocktype]").change(function{if(this.value==1)$("#unlock-account-$("#unlock-account-$("#unlock-account-}elseif(this.value==2)$("#unlock-account-$("#unlock-account-$("#unlock-account-}else$("#unlock-account-$("#unlock-account-$("#unlock-account-}项目源码地 钱包账号二钱包账号二:keystore+ 参数keystoreJsonV3-String:要私钥的keystorepassword-String:加密keystore文件的,一般为创建账号时的 sion:3,id:'04e9bcbb-96fa-497b-94d1-crypto:{cipherparams:{iv:'2885df2b63f7ef247d753c82fa20038a'},cipher:'aes-128-ctr',kdf:kdfparamskdfparams:n:262144,r:p:}},>address:sign:function(data){...},encrypt:function(password){...}} letfs=module.exports=unlockAccountWithKeystore:async(ctx)=>//1.获取前端传递的数据,包括keystoreletpassword=ctx.request.body.passwordletkeystore=ctx.request.files.file 缓存文件中keystore的数letkeystoreData=fs.readFileSync(keystore.path,"utf8")//3.通过keystore 账//ctx.body=await} 3.<divid="unlock-account-keystore"style="display:<h3>请选择你的keystore文件<inputtype="file"id="unlock-accoutn-<inputtype="password"id="unlock-account-4.//通过 账functionunlockAccountWithKeystore()if(filedata.length<=0){alert("请选择文件}}//文件上传通过Formdata 文件的数vardata=newdata.append("file",$("#unlock-accoutn-file")[0].files[0])varurlStr="/unlock/keystore"url:urlStr,type:"post",data:data,success:function(res,{)if(res.code==0)//}error:function(res,{}}项目源 钱包账号三:助记钱包账号三:助记依赖输三、项目运行效

ethereumjs-协议将助记词转换成,再通ethereumjs-

库生成hdethereumjs-的不同从hd钱包中获取不同的keypair,keypairethereumjs-HD钱包和BIP协议的相关概念请查看"04-、私钥、keystore与助记词之间的爱恨情仇"章节中助记npmibip39ethereumjs-walletethereumjs-npmibip39ethereumjs-walletethereumjs-bip39:随机产生新的mnemoniccode,并可以将其转成binary的seed。ethereumjs-wallethdkeyHD钱包。ethereumjs-util:Ethereum的一个工具库。代码示letletbip39=letutil=require('ethereumjs-util')//npminstallbip39ethereumjs-walletethereumjs- 验证结letmnemonic=bip39.generateMnemonic()//2.将助记词转成letseed=bip39.mnemonicToSeed(mnemonic)console.log("seed:"+util.bufferToHex(seed))//3.通过hdkey将seed生成HDlethdWallet=for(leti=0;i<10;i++)//4.生成钱包中在m/44'/60'/0'/0/i路径的letkey=hdWallet.derivePath("m/44'/60'/0'/0/"+//5.从keypair中获取console.log("私钥://6.从keypair中获取console.log("公钥://7.使用keypair中的公钥生成地letaddress=util.pubToAddress(key._hdkey._publicKey,//编码地addressutil.toChecksumAddress(address.toString('hex'))console.log("地址:"+address,"\n")}输lixu@ubuntu:~/Desktop/demo/test$nodetimevoyagesevenbelievemuscletrumpetlaterbreezepoolfiscalsibling私钥验证助记 timevoyagesevenmuscletrumpetlaterbreezepoolfiscalsiblingribbon,选择ETH 在d文件夹下新建文件,实现通过助记词与路径获取相应的私钥。需要用到三个库:bip39、theeumj-allethdy、teeumj-util。letletbip39=letutil=require('ethereumjs-util')module.exports=getPrivatekeyWithMnemonicgetPrivatekeyWithMnemonic:(mnemonic,derivePath)=>//将助记词转成letseed=//通过hdkey将seed生成lethdWallet=letkey=hdWallet.derivePath(derivePath)//return}}letletmenmonicModel=module.exports=unlockAccountWithMnemonic:async(ctx)=>//1.获取助记letmnemonic=ctx.request.body.mnemonic//2.通过助记词"m/44'/60'/0'/0/0",在实际开发工作中需枚举路径"m/44'/60'/0'/0/0"的最后一位0继续取值为0,1,2,3,4……console.log("//3.通过私 账//4.将账户信息返回给前ctx.body=await} <div<divid="unlock-account-mnemonic"style="display:<h3>请输入你的助记词<textareaid="input-mnemonic"5. //通过助记 账functionunlockAccountWithMnemonic()status){if(res.code==0){//将服务端返回的账户信息显示到页}}项目源 地 10-三、项目源码二:以太币转四、项目运行效 获取以太 100ETH,而它在主网上的ETH可能为0,也就是说其它网络上的ETH余额与o上拥有100ETH没有一点关系,他们之间的资源不会共享,当然,也就在不同网络间不能转账。但是账号在各个网络中都是可用的,账号的公钥私钥在各个网络也不会发生变化。比如您在Kvan测试网络创建的账号,在主网和R测试网络中也能向这个账号地址进行交易。在本中学习的重点是钱包开发,因此使用其中的Kva测试网络获取以太币(因为私网没有搭建,在主网交易需要花费ga),采用最后种途径:主动索取。在Kvan的操作步骤在MtaMask章节作出了详情说明,若还未获取到E请先查看该章节内容。web3.eth.sendSignedTransaction(signedTransactionDataweb3.eth.sendSignedTransaction(signedTransactionData[,signedTransactionData-signedTransactionData- -String:(可选)-

-Number:(可选,默认:待定)用于交易的gas(未使用的gas会退还)。gasPrice-Number|String|BN|BigNumber:(可选)此交易的gas价格,以wei为单位,-

---PromiEvent:promise返回"receipt"返回Object返回

返 varvarTx=require('ethereumjs-tx');varprivateKey=newvarrawTx{gasLimit:'0x2710',to: }vartx=newTx(rawTx);varserializedTx=// web3.eth.sendSignedTransaction('0x'+.on('receipt',>{blockHash:blockNumber:8858763,contractAddress:null,logs:[],root:null,status:true,transactionIndex:2}unknownError:Error:Returnederror:Invalidparams:unknownfield`gasLimit`,expectedoneof`from`,`to`,`gasPrice`,`gas`,`value`,`data`,`nonce`.须 Transactiongasistoo

字段Error:Error:Returnederror:Transactiongasistoolow.Thereisnotenoughgastocoverminimalcostofthetransaction(minimal:21004,got:0).Try dgas.web3.eth.estimateGas()方法预估交易gas用用若是转以太币,则必填字段是letlet{fromaddress,toaddress,number,privatekey}=letnonce=awaitweb3.eth.getTransactionCount(fromaddress)letgasPrice=awaitweb3.eth.getGasPrice()letbalance=awaitvarTx=require('ethereumjs-varprivateKey=newBuffer(privatekey.slice(2),varrawTx=nonce:nonce,to:toaddress,value:balance,data:'0x00'//转Token代币会用到的一个}letgas=awaitweb3.eth.estimateGas(rawTx)rawTx.gas=gas先将账号信息显示端页面再实现转账业务功能,即先实现之前注释的账号完成后调用的方法,同时取消注释(通过三种方式成功后都有调用,都需取消释)<divid="transaction-second"style="display:<divid="account-<span>账户地址<spanid="account-<span>账户余额<spanid="account-2. 成功后给functionconfigAccountInfo(data)$("#account-$("#account-balance").text(data.balance+"$("#transaction-}letlet{success,fail}=require("../utils/myUtils")letweb3=require("../utils/myUtils").getweb3()module.exports=sendTransaction:async(ctx)=>let{fromaddress,toaddress,number,privatekey}=letnonce=awaitweb3.eth.getTransactionCount(fromaddress)letgasPrice=awaitweb3.eth.getGasPrice()letbalance=awaitvarTx=require('ethereumjs-varprivateKey=newBuffer(privatekey.slice(2),varrawTx=nonce:nonce,to:toaddress,value:balance,data:'0x00'//转Token代币会用到的一个字}letgas=awaitweb3.eth.estimateGas(rawTx)rawTx.gas=gasvartx=newTx(rawTx);varserializedTx=tx.serialize();letresponseData;awaitweb3.eth.sendSignedTransaction('0x'+serializedTx.toString('hex'),function(err,data)ifif(err)responseData=}{)if(data)responseDatasuccess({"transactionHash":data.transac}elseresponseData=fail("交易失败}}//发送转账交router.post("/transaction/send",<div<div<divid="transaction-second"style="display:<divid="send-<formid="send-transaction-<span>对方地址<inputtype="text"<span>发送金额<inputtype="text"<selectid="send-transaction-token-<option<optionvalue="2"id="send-transaction-<inputname="fromaddress"<inputname="privatekey"<buttontype="submit">发送交易<divid="account-<div<span>交易<spanplate"style="display:plate-4.编辑atc文件夹下的llt.js文件,前端处理以太币转账交易的网络请求,另外需要设置提交表单时传递的dds、privty。 functionconfigAccountInfo(data)}//$("#send-transaction-required:required:"请输入对方地址required:"请输入转账数额submitHandler:{varif(tokenType==1){urlStr=}elseurlStr=}$(form).ajaxSubmit({success:function(res,{console.log(status+JSON.stringify(res))if(res.code==0){}error:function(res,{console.log(status+}}项目源 地:博客中的文章归博主所有,,请联系作者 11-深入:如何通过钱包集成第数字货币11-深入:如何通过钱包集成第数字货币以及转账实获取Token调用线上合约二、项目源码一:后端集成第数字货三、项目源码二:调用合约API本章主要内容是en代币转账交易,所以前提条件是要拥有oen代币(才能转账)。如何获取en代币?主要有以下三种方式:在本中学习的重点是钱包开发,因此使用其中的Kva测试网络获取en代币(私网没有搭建,在主网交易需要花费ga),采用第一种途径:别人给您的账号地址转账获得。其中发布Token发布Token代币、中心化交易所、EOS钱包、比特币钱包、多币种钱包的开发,请持续关注。在这里博主提供给大家转下面的KY代币(使用于Kvan测试网络),如果自己可以部署合约可跳过此步骤。需要添加学院:,然后发送账号地址,会在第一时间转KY到账号,如:0bb521853d0864397b8047b7。[{"anonymous":false,"inputs":[{"indexed":"_owner","type":"address"},{"indexed":"_spender","type":"address"},{"indexed":"_value","type":"uint256"}],"name":"Approval","type":{"anonymous":false,"inputs":[{"indexed":"_from","type":"address"},{"indexed":true,"name":"address"},{"indexed":false,"name":"uint256"}],"name":"Transfer","type":false,"inputs":[{"name":"_spender","type":"_value","type":"uint256"}],"name":"approve","outputs":[{"name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"uint256"}],"name":"transfer","outputs":[{"name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_from","type":"address"},{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transferFrom","outputs":[{"name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_name","type":"string"},{"name":"_symbol","type":"_decimals","type":"uint8"},{"name":"_totalSupply","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"constant":true,"inputs":[{"name":"address"},{"name":"_spender","type":"allowance","outputs":[{"name":"remaining","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"}],"name":"balanceOf","outputs":[{"name":"balance","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"decimals","outputs":[{"name":"","type":"uint8"}],"payable":true,"inputs":[],"name":"name","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":[{"name":"","type":"string"}],"payable":"view","type":"function"},{"constant":true,"inputs":"totalSupply","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"}]newnewweb3.eth.Contract(jsonInterface[,address][,参数 myContract.options.addressmyContract.options.address=-String

varvarmyContract=newweb3.eth.Contract([...],from: 7891',//defaultgasPrice:'20000000000'//defaultgaspriceinwei,20gweiin参数from-String-Number:为交易提供的最大gas //usingthecallback//usingthecallback'0xde0B295669a9FD93d5F28D9Ec85E40f4cb697BAe'},function(error,//usingthepromise//MULTI-ARGUMENT//contractMyContract{return(23456, }}//varMyContract=newweb3.eth.contract(abi,address);>ResultmyNumber:'23456',myString:' 0:'23456',//thesearehereasfallbacksifthenameisnotknowor1: }{{return }}//varMyContract=newweb3.eth.contract(abi,address);> //SINGLE-ARGUMENT//contractMyContractfunctionmyFunction()returns(stringTransactionexecutionError:Error:Returnederror:Transactionexecution在转账代币交易时可能会出现的错误,需设置fromunknownunknownfieldError:Returnederror:Invalidparams:unknownfield`gasLimit`,expectedoneof`from`,`to`,`gasPrice`,`gas`,`value`,`data`,`nonce`.须 Transactiongasistoo

字段Error:Error:Returnederror:Transactiongasistoolow.Thereisnotenoughgastocoverminimalcostofthetransaction(minimal:21004,got:0).Try dgas.

dataAPIdataAPI, toaddress,balance:调用该方法的参数,该方法有两个参数,第一个是转账给对方的letletdecimals=awaitmyContract.methods.decimals().call()letbalance=number*Math.pow(10,decimals)web3.utils.toWei()方法将单位进行转换。若是转代币,则必填字段是from、to、nonce、gas、dataletlet{fromaddress,toaddress,number,privatekey}=letnonce=awaitweb3.eth.getTransactionCount(fromaddress)letgasPrice=awaitweb3.eth.getGasPrice()letdecimals=awaitmyContract.methods.decimals().call()letbalance=number*Math.pow(10,decimals)if(myBalance<balance){ctx.bodyfail("余额不足")}lettokenData=awaitmyContract.methods.transfer(toaddress,varTx=require('ethereumjs-varprivateKey=newBuffer(privatekey.slice(2),varrawTx=nonce:nonce, from:fromaddress,data:tokenData//转Token}letgas=awaitweb3.eth.estimateGas(rawTx)rawTxrawTx.gas=二、项目源码一:后端集成第数字货在d文件夹下新建t文件,后端实现根据ABI与合约地址创建合约对象。注意:需要将AI与合约地址相对应,并且你的账号拥有此代币合约的余额。letletweb3=module.exports{getContract:()=>letABI=[{"anonymous":false,"inputs":[{"indexed":true,"name":"_owner","type":"address"},{"indexed":true,"name":"_spender","type":"address"},{"indexed":false,"name":"_value","type":"Approval","type":"event"},{"anonymous":false,"inputs":true,"name":"_from","type":"address"},{"indexed":"_to","type":"address"},{"indexed":false,"name":"uint256"}],"name":"Transfer","type":false,"inputs":[{"name":"_spender","type":"_value","type":"uint256"}],"name":"approve","outputs":[{"name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_value","type":"transfer","outputs":[{"name":"success","type":"bool"}],"payable":false,"inputs":[{"name":"_from","type":"address"},{"name":"_to","type":"address"},{"name":"_value","type":"transferFrom","outputs":[{"name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_name","type":"string"},{"name":"_symbol","type":"string"},{"name":"_decimals","type":"uint8"},{"name":"_totalSupply","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"constant":true,"inputs":[{"name":"address"},{"name":"_spender","type":"allowance","outputs":[{"name":"remaining","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"}],"name":"balanceOf","out

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论