├── 002_myWallet ├── index.js ├── package-lock.json ├── package.json └── routers │ └── index.js ├── 003_myWallet ├── controllers │ └── account.js ├── index.js ├── package-lock.json ├── package.json ├── routers │ └── index.js └── utils │ └── web3helper.js ├── 004_myWallet ├── config │ └── config.js ├── controllers │ └── account.js ├── index.js ├── package-lock.json ├── package.json ├── routers │ └── index.js ├── static │ ├── css │ │ └── bootstrap.min.css │ ├── js │ │ ├── bootstrap.min.js │ │ └── jquery-3.3.1.min.js │ └── keystore │ │ ├── UTC--2018-07-12T07:06:57.659Z--0x5c438a4430F6c06E7945084729bC72Fb94B28F05 │ │ ├── UTC--2018-07-12T07:41:06.111Z--0x31919378FD418e427D8fb021e41748d11067183E │ │ ├── UTC--2018-07-12T09:29:58.857Z--0x3b517808584D546A44C6C5C013851D6b3d952f5B │ │ ├── UTC--2018-07-12T09:30:42.943Z--0xd4e02f82b1A7144Df65E41DF2eb597Dd4DFF7359 │ │ ├── UTC--2018-07-12T09:43:12.015Z--0xC3e2d83BC37462F357cA5c7f8e5Ff7fAE99CcF56 │ │ ├── UTC--2018-07-12T09:45:15.771Z--0xd5d53E133c4e4150bAddF7Cd4Fe4078cb8e4B6b9 │ │ ├── UTC--2018-07-12T09:46:37.558Z--0x878a0Ab8201d11fdbe04e1b5cB1Af1D77a7A1294 │ │ ├── UTC--2018-07-12T09:49:25.152Z--0xa51A2dE9b643527fabaD5775Ac45Bdaed0651b02 │ │ ├── UTC--2018-07-12T09:54:18.944Z--0xe6E6e464995C14708b6B90b11d24fFf0F6b6E5DA │ │ ├── UTC--2018-07-12T09:54:47.024Z--0xF05c267F4F256ff5C7cC5078022740c26D384Ab5 │ │ ├── UTC--2018-07-13T01:23:34.519Z--0x24791a9EB7899A67E97369738EEC45bBb9b4Dc04 │ │ ├── UTC--2018-07-13T01:24:33.724Z--0x740b94aFAbDaB9eB95848079AE743e06026CbE67 │ │ ├── UTC--2018-07-13T02:22:11.919Z--0x6a3255db9A489A78fdE14F47B9c17a108784932c │ │ ├── UTC--2018-07-16T01:19:41.108Z--0x100CD4b78A67e689581AbC7c43CD7C650cE2CfFb │ │ ├── UTC--2018-07-24T16:21:07.143Z--0xf3eda43f191Ba2eA6D264c77Ed80ae251cA79e09 │ │ └── UTC--2018-07-24T16:23:04.957Z--0x1F8C49d69E5796C72f7f824f97d685aB5E91fF2A ├── utils │ ├── fileutil.js │ └── web3helper.js └── view │ └── account.html ├── 005_myWallet ├── config │ └── config.js ├── controllers │ ├── account.js │ └── transaction.js ├── index.js ├── package-lock.json ├── package.json ├── routers │ └── index.js ├── static │ ├── css │ │ └── bootstrap.min.css │ ├── js │ │ ├── bootstrap.min.js │ │ └── jquery-3.3.1.min.js │ └── keystore │ │ ├── UTC--2018-07-12T07:06:57.659Z--0x5c438a4430F6c06E7945084729bC72Fb94B28F05 │ │ ├── UTC--2018-07-12T07:41:06.111Z--0x31919378FD418e427D8fb021e41748d11067183E │ │ ├── UTC--2018-07-12T09:29:58.857Z--0x3b517808584D546A44C6C5C013851D6b3d952f5B │ │ ├── UTC--2018-07-12T09:30:42.943Z--0xd4e02f82b1A7144Df65E41DF2eb597Dd4DFF7359 │ │ ├── UTC--2018-07-12T09:43:12.015Z--0xC3e2d83BC37462F357cA5c7f8e5Ff7fAE99CcF56 │ │ ├── UTC--2018-07-12T09:45:15.771Z--0xd5d53E133c4e4150bAddF7Cd4Fe4078cb8e4B6b9 │ │ ├── UTC--2018-07-12T09:46:37.558Z--0x878a0Ab8201d11fdbe04e1b5cB1Af1D77a7A1294 │ │ ├── UTC--2018-07-12T09:49:25.152Z--0xa51A2dE9b643527fabaD5775Ac45Bdaed0651b02 │ │ ├── UTC--2018-07-12T09:54:18.944Z--0xe6E6e464995C14708b6B90b11d24fFf0F6b6E5DA │ │ ├── UTC--2018-07-12T09:54:47.024Z--0xF05c267F4F256ff5C7cC5078022740c26D384Ab5 │ │ ├── UTC--2018-07-13T01:23:34.519Z--0x24791a9EB7899A67E97369738EEC45bBb9b4Dc04 │ │ ├── UTC--2018-07-13T01:24:33.724Z--0x740b94aFAbDaB9eB95848079AE743e06026CbE67 │ │ ├── UTC--2018-07-13T02:22:11.919Z--0x6a3255db9A489A78fdE14F47B9c17a108784932c │ │ ├── UTC--2018-07-16T01:19:41.108Z--0x100CD4b78A67e689581AbC7c43CD7C650cE2CfFb │ │ ├── UTC--2018-07-24T16:21:07.143Z--0xf3eda43f191Ba2eA6D264c77Ed80ae251cA79e09 │ │ └── UTC--2018-07-24T16:23:04.957Z--0x1F8C49d69E5796C72f7f824f97d685aB5E91fF2A ├── utils │ ├── fileutil.js │ └── web3helper.js └── view │ ├── account.html │ └── transaction.html ├── 006_myWallet ├── config │ └── config.js ├── controllers │ ├── account.js │ ├── token.js │ └── transaction.js ├── index.js ├── package-lock.json ├── package.json ├── routers │ └── index.js ├── static │ ├── css │ │ └── bootstrap.min.css │ ├── js │ │ ├── bootstrap.min.js │ │ └── jquery-3.3.1.min.js │ └── keystore │ │ ├── UTC--2018-07-12T07:06:57.659Z--0x5c438a4430F6c06E7945084729bC72Fb94B28F05 │ │ ├── UTC--2018-07-12T07:41:06.111Z--0x31919378FD418e427D8fb021e41748d11067183E │ │ ├── UTC--2018-07-12T09:29:58.857Z--0x3b517808584D546A44C6C5C013851D6b3d952f5B │ │ ├── UTC--2018-07-12T09:30:42.943Z--0xd4e02f82b1A7144Df65E41DF2eb597Dd4DFF7359 │ │ ├── UTC--2018-07-12T09:43:12.015Z--0xC3e2d83BC37462F357cA5c7f8e5Ff7fAE99CcF56 │ │ ├── UTC--2018-07-12T09:45:15.771Z--0xd5d53E133c4e4150bAddF7Cd4Fe4078cb8e4B6b9 │ │ ├── UTC--2018-07-12T09:46:37.558Z--0x878a0Ab8201d11fdbe04e1b5cB1Af1D77a7A1294 │ │ ├── UTC--2018-07-12T09:49:25.152Z--0xa51A2dE9b643527fabaD5775Ac45Bdaed0651b02 │ │ ├── UTC--2018-07-12T09:54:18.944Z--0xe6E6e464995C14708b6B90b11d24fFf0F6b6E5DA │ │ ├── UTC--2018-07-12T09:54:47.024Z--0xF05c267F4F256ff5C7cC5078022740c26D384Ab5 │ │ ├── UTC--2018-07-13T01:23:34.519Z--0x24791a9EB7899A67E97369738EEC45bBb9b4Dc04 │ │ ├── UTC--2018-07-13T01:24:33.724Z--0x740b94aFAbDaB9eB95848079AE743e06026CbE67 │ │ ├── UTC--2018-07-13T02:22:11.919Z--0x6a3255db9A489A78fdE14F47B9c17a108784932c │ │ ├── UTC--2018-07-16T01:19:41.108Z--0x100CD4b78A67e689581AbC7c43CD7C650cE2CfFb │ │ ├── UTC--2018-07-24T16:21:07.143Z--0xf3eda43f191Ba2eA6D264c77Ed80ae251cA79e09 │ │ └── UTC--2018-07-24T16:23:04.957Z--0x1F8C49d69E5796C72f7f824f97d685aB5E91fF2A ├── utils │ ├── fileutil.js │ └── web3helper.js └── view │ ├── account.html │ └── transaction.html ├── 008_myWallet ├── config │ └── config.js ├── controllers │ ├── account.js │ └── transaction.js ├── index.js ├── package-lock.json ├── package.json ├── routers │ └── index.js ├── static │ ├── css │ │ └── bootstrap.min.css │ ├── js │ │ ├── bootstrap.min.js │ │ └── jquery-3.3.1.min.js │ └── keystore │ │ ├── UTC--2018-07-12T07:06:57.659Z--0x5c438a4430F6c06E7945084729bC72Fb94B28F05 │ │ ├── UTC--2018-07-12T07:41:06.111Z--0x31919378FD418e427D8fb021e41748d11067183E │ │ ├── UTC--2018-07-12T09:29:58.857Z--0x3b517808584D546A44C6C5C013851D6b3d952f5B │ │ ├── UTC--2018-07-12T09:30:42.943Z--0xd4e02f82b1A7144Df65E41DF2eb597Dd4DFF7359 │ │ ├── UTC--2018-07-12T09:43:12.015Z--0xC3e2d83BC37462F357cA5c7f8e5Ff7fAE99CcF56 │ │ ├── UTC--2018-07-12T09:45:15.771Z--0xd5d53E133c4e4150bAddF7Cd4Fe4078cb8e4B6b9 │ │ ├── UTC--2018-07-12T09:46:37.558Z--0x878a0Ab8201d11fdbe04e1b5cB1Af1D77a7A1294 │ │ ├── UTC--2018-07-12T09:49:25.152Z--0xa51A2dE9b643527fabaD5775Ac45Bdaed0651b02 │ │ ├── UTC--2018-07-12T09:54:18.944Z--0xe6E6e464995C14708b6B90b11d24fFf0F6b6E5DA │ │ ├── UTC--2018-07-12T09:54:47.024Z--0xF05c267F4F256ff5C7cC5078022740c26D384Ab5 │ │ ├── UTC--2018-07-13T01:23:34.519Z--0x24791a9EB7899A67E97369738EEC45bBb9b4Dc04 │ │ ├── UTC--2018-07-13T01:24:33.724Z--0x740b94aFAbDaB9eB95848079AE743e06026CbE67 │ │ ├── UTC--2018-07-13T02:22:11.919Z--0x6a3255db9A489A78fdE14F47B9c17a108784932c │ │ ├── UTC--2018-07-16T01:19:41.108Z--0x100CD4b78A67e689581AbC7c43CD7C650cE2CfFb │ │ ├── UTC--2018-07-24T16:21:07.143Z--0xf3eda43f191Ba2eA6D264c77Ed80ae251cA79e09 │ │ └── UTC--2018-07-24T16:23:04.957Z--0x1F8C49d69E5796C72f7f824f97d685aB5E91fF2A ├── utils │ ├── fileutil.js │ └── web3helper.js └── view │ ├── account.html │ └── transaction.html ├── README.md └── accountsWallet ├── index.js ├── package-lock.json └── package.json /002_myWallet/index.js: -------------------------------------------------------------------------------- 1 | const Koa = require('koa'); 2 | const routers = require('./routers/index') 3 | const koaBody = require('koa-body'); 4 | 5 | const app = new Koa(); 6 | // 引入 koa-body 中间件 7 | app.use(koaBody({ 8 | multipart: true 9 | })); 10 | 11 | 12 | // 初始化路由中间件 13 | app.use(routers.routes()).use(routers.allowedMethods()) 14 | app.listen(3000); 15 | console.log('server is starting at port 3000') -------------------------------------------------------------------------------- /002_myWallet/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mywallet", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "", 10 | "license": "ISC", 11 | "dependencies": { 12 | "koa": "^2.5.2", 13 | "koa-body": "^4.0.4", 14 | "koa-router": "^7.4.0", 15 | "web3": "^1.0.0-beta.34" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /002_myWallet/routers/index.js: -------------------------------------------------------------------------------- 1 | const router = require('koa-router')() 2 | 3 | router.get('/', (ctx) => { 4 | 5 | const body = ctx.request.query; 6 | 7 | ctx.body = 'Hello Router GET '+ JSON.stringify(body); 8 | }); 9 | 10 | router.post('/', (ctx) => { 11 | 12 | const body = ctx.request.body; 13 | 14 | ctx.body = 'Hello Router POST '+ JSON.stringify(body); 15 | }); 16 | module.exports = router -------------------------------------------------------------------------------- /003_myWallet/controllers/account.js: -------------------------------------------------------------------------------- 1 | const web3 = require("../utils/web3helper").getWeb3() 2 | 3 | module.exports = { 4 | async getAccountList (ctx) { 5 | console.log("version: "+ web3.version) 6 | const accountList = await web3.eth.getAccounts() 7 | console.log("accountList..."+accountList) 8 | ctx.body = accountList 9 | } 10 | } -------------------------------------------------------------------------------- /003_myWallet/index.js: -------------------------------------------------------------------------------- 1 | const Koa = require('koa'); 2 | const routers = require('./routers/index') 3 | const koaBody = require('koa-body'); 4 | 5 | const app = new Koa(); 6 | // 引入 koa-body 中间件 7 | app.use(koaBody({ 8 | multipart: true 9 | })); 10 | 11 | 12 | // 初始化路由中间件 13 | app.use(routers.routes()).use(routers.allowedMethods()) 14 | app.listen(3000); 15 | console.log('server is starting at port 3000') -------------------------------------------------------------------------------- /003_myWallet/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mywallet", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "", 10 | "license": "ISC", 11 | "dependencies": { 12 | "koa": "^2.5.2", 13 | "koa-body": "^4.0.4", 14 | "koa-router": "^7.4.0", 15 | "web3": "^1.0.0-beta.34" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /003_myWallet/routers/index.js: -------------------------------------------------------------------------------- 1 | const router = require('koa-router')() 2 | 3 | const accountController = require("../controllers/account") 4 | 5 | router.get('/', accountController.getAccountList); 6 | 7 | router.post('/', (ctx) => { 8 | 9 | const body = ctx.request.body; 10 | 11 | ctx.body = 'Hello Router POST '+ JSON.stringify(body); 12 | }); 13 | module.exports = router -------------------------------------------------------------------------------- /003_myWallet/utils/web3helper.js: -------------------------------------------------------------------------------- 1 | const Web3 = require('web3'); 2 | 3 | module.exports = { 4 | getWeb3(){ 5 | const web3 = new Web3(Web3.givenProvider || "http://localhost:8545"); 6 | return web3 7 | } 8 | } -------------------------------------------------------------------------------- /004_myWallet/config/config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | keystoreUrl : 'http://localhost:3000/keystore/' 3 | } -------------------------------------------------------------------------------- /004_myWallet/controllers/account.js: -------------------------------------------------------------------------------- 1 | const web3 = require("../utils/web3helper").getWeb3() 2 | const fileUtil = require('../utils/fileUtil') 3 | const path = require('path'); 4 | const config = require("../config/config") 5 | 6 | module.exports = { 7 | async createAccount (ctx) { 8 | let returnResult = { 9 | code: 0, 10 | msg: '成功!', 11 | data: {} 12 | } 13 | 14 | let data = ctx.request.body 15 | const pwd = data.pwd 16 | 17 | // 调用 web3 创建账户 18 | let account = await web3.eth.accounts.create(); 19 | 20 | // encrypt 返回一个JSON 对象 21 | const keystoreJson = await account.encrypt(pwd) 22 | 23 | // 将 JSON 对象转为字符串 24 | const keystoreStr = JSON.stringify(keystoreJson) 25 | 26 | // 生成随机文件存储 keystore 的字符串 27 | const randFilename = "UTC--"+new Date().toISOString()+"--"+account.address 28 | 29 | // 设置存储文件的目录 30 | const filePath =path.join(__dirname,"../static/keystore/"+randFilename) 31 | 32 | // 将 keystore 的内容写入文件中 33 | await fileUtil.writeFile(filePath,keystoreStr) 34 | 35 | // 将 用户地址、私钥、keystore 数据返回 36 | const result = {"account":account.address,"privateKey":account.privateKey,"keystore": config.keystoreUrl+randFilename} 37 | returnResult.data = result 38 | ctx.body = returnResult 39 | }, 40 | async getAccountList (ctx) { 41 | await ctx.render("account") 42 | } 43 | } -------------------------------------------------------------------------------- /004_myWallet/index.js: -------------------------------------------------------------------------------- 1 | const Koa = require('koa'); 2 | const routers = require('./routers/index') 3 | const koaBody = require('koa-body'); 4 | const views = require('koa-views') 5 | const path = require('path') 6 | const static = require('koa-static') 7 | 8 | const app = new Koa(); 9 | 10 | // 引入 koa-body 中间件 11 | app.use(koaBody({ 12 | multipart: true 13 | })); 14 | 15 | // 加载模板引擎 16 | app.use(views(path.join(__dirname, './view'), { 17 | map : {html:'ejs'} 18 | })) 19 | 20 | // 静态资源目录对于相对入口文件index.js的路径 21 | const staticPath = './static' 22 | 23 | app.use(static( 24 | path.join( __dirname, staticPath) 25 | )) 26 | 27 | 28 | // 初始化路由中间件 29 | app.use(routers.routes()).use(routers.allowedMethods()) 30 | app.listen(3000); 31 | console.log('server is starting at port 3000') -------------------------------------------------------------------------------- /004_myWallet/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mywallet", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "", 10 | "license": "ISC", 11 | "dependencies": { 12 | "ejs": "^2.6.1", 13 | "koa": "^2.5.2", 14 | "koa-body": "^4.0.4", 15 | "koa-router": "^7.4.0", 16 | "koa-static": "^5.0.0", 17 | "koa-views": "^6.1.4", 18 | "web3": "^1.0.0-beta.34" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /004_myWallet/routers/index.js: -------------------------------------------------------------------------------- 1 | const router = require('koa-router')() 2 | 3 | const accountController = require("../controllers/account") 4 | 5 | router.get('/', accountController.getAccountList); 6 | 7 | router.post('/', (ctx) => { 8 | 9 | const body = ctx.request.body; 10 | 11 | ctx.body = 'Hello Router POST '+ JSON.stringify(body); 12 | }); 13 | 14 | router.post('/account/create',accountController.createAccount) 15 | 16 | module.exports = router -------------------------------------------------------------------------------- /004_myWallet/static/js/bootstrap.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap v4.1.1 (https://getbootstrap.com/) 3 | * Copyright 2011-2018 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors) 4 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 5 | */ 6 | !function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports,require("jquery"),require("popper.js")):"function"==typeof define&&define.amd?define(["exports","jquery","popper.js"],e):e(t.bootstrap={},t.jQuery,t.Popper)}(this,function(t,e,c){"use strict";function i(t,e){for(var n=0;nthis._items.length-1||t<0))if(this._isSliding)P(this._element).one(Q.SLID,function(){return e.to(t)});else{if(n===t)return this.pause(),void this.cycle();var i=ndocument.documentElement.clientHeight;!this._isBodyOverflowing&&t&&(this._element.style.paddingLeft=this._scrollbarWidth+"px"),this._isBodyOverflowing&&!t&&(this._element.style.paddingRight=this._scrollbarWidth+"px")},t._resetAdjustments=function(){this._element.style.paddingLeft="",this._element.style.paddingRight=""},t._checkScrollbar=function(){var t=document.body.getBoundingClientRect();this._isBodyOverflowing=t.left+t.right
',trigger:"hover focus",title:"",delay:0,html:!(_e={AUTO:"auto",TOP:"top",RIGHT:"right",BOTTOM:"bottom",LEFT:"left"}),selector:!(de={animation:"boolean",template:"string",title:"(string|element|function)",trigger:"string",delay:"(number|object)",html:"boolean",selector:"(string|boolean)",placement:"(string|function)",offset:"(number|string)",container:"(string|element|boolean)",fallbackPlacement:"(string|array)",boundary:"(string|element)"}),placement:"top",offset:0,container:!1,fallbackPlacement:"flip",boundary:"scrollParent"},pe="out",ve={HIDE:"hide"+he,HIDDEN:"hidden"+he,SHOW:(me="show")+he,SHOWN:"shown"+he,INSERTED:"inserted"+he,CLICK:"click"+he,FOCUSIN:"focusin"+he,FOCUSOUT:"focusout"+he,MOUSEENTER:"mouseenter"+he,MOUSELEAVE:"mouseleave"+he},Ee="fade",ye="show",Te=".tooltip-inner",Ce=".arrow",Ie="hover",Ae="focus",De="click",be="manual",Se=function(){function i(t,e){if("undefined"==typeof c)throw new TypeError("Bootstrap tooltips require Popper.js (https://popper.js.org)");this._isEnabled=!0,this._timeout=0,this._hoverState="",this._activeTrigger={},this._popper=null,this.element=t,this.config=this._getConfig(e),this.tip=null,this._setListeners()}var t=i.prototype;return t.enable=function(){this._isEnabled=!0},t.disable=function(){this._isEnabled=!1},t.toggleEnabled=function(){this._isEnabled=!this._isEnabled},t.toggle=function(t){if(this._isEnabled)if(t){var e=this.constructor.DATA_KEY,n=oe(t.currentTarget).data(e);n||(n=new this.constructor(t.currentTarget,this._getDelegateConfig()),oe(t.currentTarget).data(e,n)),n._activeTrigger.click=!n._activeTrigger.click,n._isWithActiveTrigger()?n._enter(null,n):n._leave(null,n)}else{if(oe(this.getTipElement()).hasClass(ye))return void this._leave(null,this);this._enter(null,this)}},t.dispose=function(){clearTimeout(this._timeout),oe.removeData(this.element,this.constructor.DATA_KEY),oe(this.element).off(this.constructor.EVENT_KEY),oe(this.element).closest(".modal").off("hide.bs.modal"),this.tip&&oe(this.tip).remove(),this._isEnabled=null,this._timeout=null,this._hoverState=null,(this._activeTrigger=null)!==this._popper&&this._popper.destroy(),this._popper=null,this.element=null,this.config=null,this.tip=null},t.show=function(){var e=this;if("none"===oe(this.element).css("display"))throw new Error("Please use show on visible elements");var t=oe.Event(this.constructor.Event.SHOW);if(this.isWithContent()&&this._isEnabled){oe(this.element).trigger(t);var n=oe.contains(this.element.ownerDocument.documentElement,this.element);if(t.isDefaultPrevented()||!n)return;var i=this.getTipElement(),r=Cn.getUID(this.constructor.NAME);i.setAttribute("id",r),this.element.setAttribute("aria-describedby",r),this.setContent(),this.config.animation&&oe(i).addClass(Ee);var s="function"==typeof this.config.placement?this.config.placement.call(this,i,this.element):this.config.placement,o=this._getAttachment(s);this.addAttachmentClass(o);var a=!1===this.config.container?document.body:oe(this.config.container);oe(i).data(this.constructor.DATA_KEY,this),oe.contains(this.element.ownerDocument.documentElement,this.tip)||oe(i).appendTo(a),oe(this.element).trigger(this.constructor.Event.INSERTED),this._popper=new c(this.element,i,{placement:o,modifiers:{offset:{offset:this.config.offset},flip:{behavior:this.config.fallbackPlacement},arrow:{element:Ce},preventOverflow:{boundariesElement:this.config.boundary}},onCreate:function(t){t.originalPlacement!==t.placement&&e._handlePopperPlacementChange(t)},onUpdate:function(t){e._handlePopperPlacementChange(t)}}),oe(i).addClass(ye),"ontouchstart"in document.documentElement&&oe(document.body).children().on("mouseover",null,oe.noop);var l=function(){e.config.animation&&e._fixTransition();var t=e._hoverState;e._hoverState=null,oe(e.element).trigger(e.constructor.Event.SHOWN),t===pe&&e._leave(null,e)};if(oe(this.tip).hasClass(Ee)){var h=Cn.getTransitionDurationFromElement(this.tip);oe(this.tip).one(Cn.TRANSITION_END,l).emulateTransitionEnd(h)}else l()}},t.hide=function(t){var e=this,n=this.getTipElement(),i=oe.Event(this.constructor.Event.HIDE),r=function(){e._hoverState!==me&&n.parentNode&&n.parentNode.removeChild(n),e._cleanTipClass(),e.element.removeAttribute("aria-describedby"),oe(e.element).trigger(e.constructor.Event.HIDDEN),null!==e._popper&&e._popper.destroy(),t&&t()};if(oe(this.element).trigger(i),!i.isDefaultPrevented()){if(oe(n).removeClass(ye),"ontouchstart"in document.documentElement&&oe(document.body).children().off("mouseover",null,oe.noop),this._activeTrigger[De]=!1,this._activeTrigger[Ae]=!1,this._activeTrigger[Ie]=!1,oe(this.tip).hasClass(Ee)){var s=Cn.getTransitionDurationFromElement(n);oe(n).one(Cn.TRANSITION_END,r).emulateTransitionEnd(s)}else r();this._hoverState=""}},t.update=function(){null!==this._popper&&this._popper.scheduleUpdate()},t.isWithContent=function(){return Boolean(this.getTitle())},t.addAttachmentClass=function(t){oe(this.getTipElement()).addClass(ue+"-"+t)},t.getTipElement=function(){return this.tip=this.tip||oe(this.config.template)[0],this.tip},t.setContent=function(){var t=oe(this.getTipElement());this.setElementContent(t.find(Te),this.getTitle()),t.removeClass(Ee+" "+ye)},t.setElementContent=function(t,e){var n=this.config.html;"object"==typeof e&&(e.nodeType||e.jquery)?n?oe(e).parent().is(t)||t.empty().append(e):t.text(oe(e).text()):t[n?"html":"text"](e)},t.getTitle=function(){var t=this.element.getAttribute("data-original-title");return t||(t="function"==typeof this.config.title?this.config.title.call(this.element):this.config.title),t},t._getAttachment=function(t){return _e[t.toUpperCase()]},t._setListeners=function(){var i=this;this.config.trigger.split(" ").forEach(function(t){if("click"===t)oe(i.element).on(i.constructor.Event.CLICK,i.config.selector,function(t){return i.toggle(t)});else if(t!==be){var e=t===Ie?i.constructor.Event.MOUSEENTER:i.constructor.Event.FOCUSIN,n=t===Ie?i.constructor.Event.MOUSELEAVE:i.constructor.Event.FOCUSOUT;oe(i.element).on(e,i.config.selector,function(t){return i._enter(t)}).on(n,i.config.selector,function(t){return i._leave(t)})}oe(i.element).closest(".modal").on("hide.bs.modal",function(){return i.hide()})}),this.config.selector?this.config=h({},this.config,{trigger:"manual",selector:""}):this._fixTitle()},t._fixTitle=function(){var t=typeof this.element.getAttribute("data-original-title");(this.element.getAttribute("title")||"string"!==t)&&(this.element.setAttribute("data-original-title",this.element.getAttribute("title")||""),this.element.setAttribute("title",""))},t._enter=function(t,e){var n=this.constructor.DATA_KEY;(e=e||oe(t.currentTarget).data(n))||(e=new this.constructor(t.currentTarget,this._getDelegateConfig()),oe(t.currentTarget).data(n,e)),t&&(e._activeTrigger["focusin"===t.type?Ae:Ie]=!0),oe(e.getTipElement()).hasClass(ye)||e._hoverState===me?e._hoverState=me:(clearTimeout(e._timeout),e._hoverState=me,e.config.delay&&e.config.delay.show?e._timeout=setTimeout(function(){e._hoverState===me&&e.show()},e.config.delay.show):e.show())},t._leave=function(t,e){var n=this.constructor.DATA_KEY;(e=e||oe(t.currentTarget).data(n))||(e=new this.constructor(t.currentTarget,this._getDelegateConfig()),oe(t.currentTarget).data(n,e)),t&&(e._activeTrigger["focusout"===t.type?Ae:Ie]=!1),e._isWithActiveTrigger()||(clearTimeout(e._timeout),e._hoverState=pe,e.config.delay&&e.config.delay.hide?e._timeout=setTimeout(function(){e._hoverState===pe&&e.hide()},e.config.delay.hide):e.hide())},t._isWithActiveTrigger=function(){for(var t in this._activeTrigger)if(this._activeTrigger[t])return!0;return!1},t._getConfig=function(t){return"number"==typeof(t=h({},this.constructor.Default,oe(this.element).data(),"object"==typeof t&&t?t:{})).delay&&(t.delay={show:t.delay,hide:t.delay}),"number"==typeof t.title&&(t.title=t.title.toString()),"number"==typeof t.content&&(t.content=t.content.toString()),Cn.typeCheckConfig(ae,t,this.constructor.DefaultType),t},t._getDelegateConfig=function(){var t={};if(this.config)for(var e in this.config)this.constructor.Default[e]!==this.config[e]&&(t[e]=this.config[e]);return t},t._cleanTipClass=function(){var t=oe(this.getTipElement()),e=t.attr("class").match(fe);null!==e&&0

'}),He=h({},Nn.DefaultType,{content:"(string|element|function)"}),We="fade",xe=".popover-header",Ue=".popover-body",Ke={HIDE:"hide"+ke,HIDDEN:"hidden"+ke,SHOW:(Me="show")+ke,SHOWN:"shown"+ke,INSERTED:"inserted"+ke,CLICK:"click"+ke,FOCUSIN:"focusin"+ke,FOCUSOUT:"focusout"+ke,MOUSEENTER:"mouseenter"+ke,MOUSELEAVE:"mouseleave"+ke},Fe=function(t){var e,n;function i(){return t.apply(this,arguments)||this}n=t,(e=i).prototype=Object.create(n.prototype),(e.prototype.constructor=e).__proto__=n;var r=i.prototype;return r.isWithContent=function(){return this.getTitle()||this._getContent()},r.addAttachmentClass=function(t){we(this.getTipElement()).addClass(Le+"-"+t)},r.getTipElement=function(){return this.tip=this.tip||we(this.config.template)[0],this.tip},r.setContent=function(){var t=we(this.getTipElement());this.setElementContent(t.find(xe),this.getTitle());var e=this._getContent();"function"==typeof e&&(e=e.call(this.element)),this.setElementContent(t.find(Ue),e),t.removeClass(We+" "+Me)},r._getContent=function(){return this.element.getAttribute("data-content")||this.config.content},r._cleanTipClass=function(){var t=we(this.getTipElement()),e=t.attr("class").match(je);null!==e&&0=this._offsets[r]&&("undefined"==typeof this._offsets[r+1]||t 2 | 3 | 4 | 5 | 6 | fujinliang.top 7 | 8 | 9 | 15 | 16 | 17 |
18 | 23 | 31 | 32 | 39 | 40 | 44 |
45 | 46 | 47 | 73 | -------------------------------------------------------------------------------- /005_myWallet/config/config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | keystoreUrl : 'http://localhost:3000/keystore/' 3 | } -------------------------------------------------------------------------------- /005_myWallet/controllers/account.js: -------------------------------------------------------------------------------- 1 | const web3 = require("../utils/web3helper").getWeb3() 2 | const fileUtil = require('../utils/fileUtil') 3 | const path = require('path'); 4 | const config = require("../config/config") 5 | 6 | module.exports = { 7 | async createAccount (ctx) { 8 | let returnResult = { 9 | code: 0, 10 | msg: '成功!', 11 | data: {} 12 | } 13 | 14 | let data = ctx.request.body 15 | const pwd = data.pwd 16 | 17 | // 调用 web3 创建账户 18 | let account = await web3.eth.accounts.create(); 19 | 20 | // encrypt 返回一个JSON 对象 21 | const keystoreJson = await account.encrypt(pwd) 22 | 23 | // 将 JSON 对象转为字符串 24 | const keystoreStr = JSON.stringify(keystoreJson) 25 | 26 | // 生成随机文件存储 keystore 的字符串 27 | const randFilename = "UTC--"+new Date().toISOString()+"--"+account.address 28 | 29 | // 设置存储文件的目录 30 | const filePath =path.join(__dirname,"../static/keystore/"+randFilename) 31 | 32 | // 将 keystore 的内容写入文件中 33 | await fileUtil.writeFile(filePath,keystoreStr) 34 | 35 | // 将 用户地址、私钥、keystore 数据返回 36 | const result = {"account":account.address,"privateKey":account.privateKey,"keystore": config.keystoreUrl+randFilename} 37 | returnResult.data = result 38 | ctx.body = returnResult 39 | }, 40 | async getAccountList (ctx) { 41 | await ctx.render("account") 42 | }, 43 | async getAccountByPrivatekey(ctx) { 44 | 45 | let returnResult = { 46 | code: 0, 47 | msg: '成功!', 48 | data: {} 49 | } 50 | 51 | const data = ctx.request.body 52 | const privateKey = data.privateKey 53 | 54 | // 根据私钥获取用户地址 55 | const account = web3.eth.accounts.privateKeyToAccount(privateKey) 56 | 57 | // 查询账户的余额 58 | const balance = await web3.eth.getBalance(account.address) 59 | const ethNum = web3.utils.fromWei(balance, 'ether') 60 | 61 | returnResult.data.address = account.address 62 | returnResult.data.privateKey = account.privateKey 63 | returnResult.data.balance = ethNum 64 | ctx.body = returnResult 65 | }, 66 | async getAccountByKeystore(ctx) { 67 | 68 | let returnResult = { 69 | code: 0, 70 | msg: '成功!', 71 | data: {} 72 | } 73 | 74 | const data = ctx.request.body; // 获取上传文件 75 | 76 | const keystoreFile = ctx.request.files.file 77 | const filePath = keystoreFile.path 78 | 79 | // 获取 keystore 里面的json字符串 80 | const keystoreStr = await fileUtil.readFile(filePath) 81 | 82 | // 获取账户的密码 83 | const password = data.password 84 | 85 | // 获取账户的信息地址及私钥 86 | const account = web3.eth.accounts.decrypt(keystoreStr,password) 87 | 88 | const balance = await web3.eth.getBalance(account.address) 89 | 90 | const ethNum = web3.utils.fromWei(balance, 'ether') 91 | 92 | returnResult.data.address = account.address 93 | returnResult.data.privateKey = account.privateKey 94 | returnResult.data.balance = ethNum 95 | 96 | ctx.body = returnResult 97 | } 98 | } -------------------------------------------------------------------------------- /005_myWallet/controllers/transaction.js: -------------------------------------------------------------------------------- 1 | const web3 = require("../utils/web3helper").getWeb3() 2 | 3 | 4 | module.exports = { 5 | 6 | async transaction (ctx) { 7 | await ctx.render("transaction") 8 | }, 9 | 10 | async sendTransaction (ctx) { 11 | let returnResult = { 12 | code: 0, 13 | msg: '成功!', 14 | data: {} 15 | } 16 | 17 | const data = ctx.request.body 18 | 19 | const currentAccount = data.currAccount 20 | const privateKey = data.privateKey 21 | const reciptAccount = data.reciptAccount 22 | const txValue = data.txValue 23 | // 获取指定账户地址的交易数 24 | let nonce = await web3.eth.getTransactionCount(currentAccount); 25 | 26 | // 将 ether 转为 wei 27 | let value = web3.utils.toWei(txValue,'ether'); 28 | 29 | // 获取当前gasprice 30 | let gasPrice = await web3.eth.getGasPrice(); 31 | 32 | // 以太币转账参数 33 | let txParms = { 34 | from: currentAccount, 35 | to: reciptAccount, 36 | nonce: nonce, 37 | gasPrice: gasPrice, 38 | data: '0x00', // 当使用代币转账或者合约调用时 39 | value: value // value 是转账金额 40 | } 41 | // 获取一下预估gas 42 | let gas = await web3.eth.estimateGas(txParms); 43 | txParms.gas = gas; 44 | // 用密钥对账单进行签名 45 | let signTx = await web3.eth.accounts.signTransaction(txParms,privateKey) 46 | 47 | // 将签过名的账单进行发送 48 | try { 49 | await web3.eth.sendSignedTransaction(signTx.rawTransaction, function(error, hash){ 50 | if (!error) { 51 | returnResult.data.hash = hash 52 | } else { 53 | returnResult.code = "101" 54 | returnResult.msg = "失败!" 55 | returnResult.data.error = error.message 56 | 57 | } 58 | }) 59 | } catch (error) { 60 | console.log(error) 61 | } 62 | 63 | ctx.body = returnResult 64 | } 65 | } -------------------------------------------------------------------------------- /005_myWallet/index.js: -------------------------------------------------------------------------------- 1 | const Koa = require('koa'); 2 | const routers = require('./routers/index') 3 | const koaBody = require('koa-body'); 4 | const views = require('koa-views') 5 | const path = require('path') 6 | const static = require('koa-static') 7 | 8 | const app = new Koa(); 9 | 10 | // 引入 koa-body 中间件 11 | app.use(koaBody({ 12 | multipart: true 13 | })); 14 | 15 | // 加载模板引擎 16 | app.use(views(path.join(__dirname, './view'), { 17 | map : {html:'ejs'} 18 | })) 19 | 20 | // 静态资源目录对于相对入口文件index.js的路径 21 | const staticPath = './static' 22 | 23 | app.use(static( 24 | path.join( __dirname, staticPath) 25 | )) 26 | 27 | 28 | // 初始化路由中间件 29 | app.use(routers.routes()).use(routers.allowedMethods()) 30 | app.listen(3000); 31 | console.log('server is starting at port 3000') -------------------------------------------------------------------------------- /005_myWallet/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mywallet", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "", 10 | "license": "ISC", 11 | "dependencies": { 12 | "ejs": "^2.6.1", 13 | "koa": "^2.5.2", 14 | "koa-body": "^4.0.4", 15 | "koa-router": "^7.4.0", 16 | "koa-static": "^5.0.0", 17 | "koa-views": "^6.1.4", 18 | "web3": "^1.0.0-beta.34" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /005_myWallet/routers/index.js: -------------------------------------------------------------------------------- 1 | const router = require('koa-router')() 2 | 3 | const accountController = require("../controllers/account") 4 | const transactionController = require("../controllers/transaction") 5 | 6 | router.get('/', accountController.getAccountList); 7 | 8 | router.post('/', (ctx) => { 9 | 10 | const body = ctx.request.body; 11 | 12 | ctx.body = 'Hello Router POST '+ JSON.stringify(body); 13 | }); 14 | 15 | router.post('/account/create',accountController.createAccount) 16 | router.post('/account/privatekey',accountController.getAccountByPrivatekey) 17 | router.post('/account/keystore',accountController.getAccountByKeystore) 18 | 19 | router.get('/transaction', transactionController.transaction) 20 | router.post('/transaction/send', transactionController.sendTransaction) 21 | module.exports = router -------------------------------------------------------------------------------- /005_myWallet/static/js/bootstrap.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap v4.1.1 (https://getbootstrap.com/) 3 | * Copyright 2011-2018 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors) 4 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 5 | */ 6 | !function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports,require("jquery"),require("popper.js")):"function"==typeof define&&define.amd?define(["exports","jquery","popper.js"],e):e(t.bootstrap={},t.jQuery,t.Popper)}(this,function(t,e,c){"use strict";function i(t,e){for(var n=0;nthis._items.length-1||t<0))if(this._isSliding)P(this._element).one(Q.SLID,function(){return e.to(t)});else{if(n===t)return this.pause(),void this.cycle();var i=ndocument.documentElement.clientHeight;!this._isBodyOverflowing&&t&&(this._element.style.paddingLeft=this._scrollbarWidth+"px"),this._isBodyOverflowing&&!t&&(this._element.style.paddingRight=this._scrollbarWidth+"px")},t._resetAdjustments=function(){this._element.style.paddingLeft="",this._element.style.paddingRight=""},t._checkScrollbar=function(){var t=document.body.getBoundingClientRect();this._isBodyOverflowing=t.left+t.right
',trigger:"hover focus",title:"",delay:0,html:!(_e={AUTO:"auto",TOP:"top",RIGHT:"right",BOTTOM:"bottom",LEFT:"left"}),selector:!(de={animation:"boolean",template:"string",title:"(string|element|function)",trigger:"string",delay:"(number|object)",html:"boolean",selector:"(string|boolean)",placement:"(string|function)",offset:"(number|string)",container:"(string|element|boolean)",fallbackPlacement:"(string|array)",boundary:"(string|element)"}),placement:"top",offset:0,container:!1,fallbackPlacement:"flip",boundary:"scrollParent"},pe="out",ve={HIDE:"hide"+he,HIDDEN:"hidden"+he,SHOW:(me="show")+he,SHOWN:"shown"+he,INSERTED:"inserted"+he,CLICK:"click"+he,FOCUSIN:"focusin"+he,FOCUSOUT:"focusout"+he,MOUSEENTER:"mouseenter"+he,MOUSELEAVE:"mouseleave"+he},Ee="fade",ye="show",Te=".tooltip-inner",Ce=".arrow",Ie="hover",Ae="focus",De="click",be="manual",Se=function(){function i(t,e){if("undefined"==typeof c)throw new TypeError("Bootstrap tooltips require Popper.js (https://popper.js.org)");this._isEnabled=!0,this._timeout=0,this._hoverState="",this._activeTrigger={},this._popper=null,this.element=t,this.config=this._getConfig(e),this.tip=null,this._setListeners()}var t=i.prototype;return t.enable=function(){this._isEnabled=!0},t.disable=function(){this._isEnabled=!1},t.toggleEnabled=function(){this._isEnabled=!this._isEnabled},t.toggle=function(t){if(this._isEnabled)if(t){var e=this.constructor.DATA_KEY,n=oe(t.currentTarget).data(e);n||(n=new this.constructor(t.currentTarget,this._getDelegateConfig()),oe(t.currentTarget).data(e,n)),n._activeTrigger.click=!n._activeTrigger.click,n._isWithActiveTrigger()?n._enter(null,n):n._leave(null,n)}else{if(oe(this.getTipElement()).hasClass(ye))return void this._leave(null,this);this._enter(null,this)}},t.dispose=function(){clearTimeout(this._timeout),oe.removeData(this.element,this.constructor.DATA_KEY),oe(this.element).off(this.constructor.EVENT_KEY),oe(this.element).closest(".modal").off("hide.bs.modal"),this.tip&&oe(this.tip).remove(),this._isEnabled=null,this._timeout=null,this._hoverState=null,(this._activeTrigger=null)!==this._popper&&this._popper.destroy(),this._popper=null,this.element=null,this.config=null,this.tip=null},t.show=function(){var e=this;if("none"===oe(this.element).css("display"))throw new Error("Please use show on visible elements");var t=oe.Event(this.constructor.Event.SHOW);if(this.isWithContent()&&this._isEnabled){oe(this.element).trigger(t);var n=oe.contains(this.element.ownerDocument.documentElement,this.element);if(t.isDefaultPrevented()||!n)return;var i=this.getTipElement(),r=Cn.getUID(this.constructor.NAME);i.setAttribute("id",r),this.element.setAttribute("aria-describedby",r),this.setContent(),this.config.animation&&oe(i).addClass(Ee);var s="function"==typeof this.config.placement?this.config.placement.call(this,i,this.element):this.config.placement,o=this._getAttachment(s);this.addAttachmentClass(o);var a=!1===this.config.container?document.body:oe(this.config.container);oe(i).data(this.constructor.DATA_KEY,this),oe.contains(this.element.ownerDocument.documentElement,this.tip)||oe(i).appendTo(a),oe(this.element).trigger(this.constructor.Event.INSERTED),this._popper=new c(this.element,i,{placement:o,modifiers:{offset:{offset:this.config.offset},flip:{behavior:this.config.fallbackPlacement},arrow:{element:Ce},preventOverflow:{boundariesElement:this.config.boundary}},onCreate:function(t){t.originalPlacement!==t.placement&&e._handlePopperPlacementChange(t)},onUpdate:function(t){e._handlePopperPlacementChange(t)}}),oe(i).addClass(ye),"ontouchstart"in document.documentElement&&oe(document.body).children().on("mouseover",null,oe.noop);var l=function(){e.config.animation&&e._fixTransition();var t=e._hoverState;e._hoverState=null,oe(e.element).trigger(e.constructor.Event.SHOWN),t===pe&&e._leave(null,e)};if(oe(this.tip).hasClass(Ee)){var h=Cn.getTransitionDurationFromElement(this.tip);oe(this.tip).one(Cn.TRANSITION_END,l).emulateTransitionEnd(h)}else l()}},t.hide=function(t){var e=this,n=this.getTipElement(),i=oe.Event(this.constructor.Event.HIDE),r=function(){e._hoverState!==me&&n.parentNode&&n.parentNode.removeChild(n),e._cleanTipClass(),e.element.removeAttribute("aria-describedby"),oe(e.element).trigger(e.constructor.Event.HIDDEN),null!==e._popper&&e._popper.destroy(),t&&t()};if(oe(this.element).trigger(i),!i.isDefaultPrevented()){if(oe(n).removeClass(ye),"ontouchstart"in document.documentElement&&oe(document.body).children().off("mouseover",null,oe.noop),this._activeTrigger[De]=!1,this._activeTrigger[Ae]=!1,this._activeTrigger[Ie]=!1,oe(this.tip).hasClass(Ee)){var s=Cn.getTransitionDurationFromElement(n);oe(n).one(Cn.TRANSITION_END,r).emulateTransitionEnd(s)}else r();this._hoverState=""}},t.update=function(){null!==this._popper&&this._popper.scheduleUpdate()},t.isWithContent=function(){return Boolean(this.getTitle())},t.addAttachmentClass=function(t){oe(this.getTipElement()).addClass(ue+"-"+t)},t.getTipElement=function(){return this.tip=this.tip||oe(this.config.template)[0],this.tip},t.setContent=function(){var t=oe(this.getTipElement());this.setElementContent(t.find(Te),this.getTitle()),t.removeClass(Ee+" "+ye)},t.setElementContent=function(t,e){var n=this.config.html;"object"==typeof e&&(e.nodeType||e.jquery)?n?oe(e).parent().is(t)||t.empty().append(e):t.text(oe(e).text()):t[n?"html":"text"](e)},t.getTitle=function(){var t=this.element.getAttribute("data-original-title");return t||(t="function"==typeof this.config.title?this.config.title.call(this.element):this.config.title),t},t._getAttachment=function(t){return _e[t.toUpperCase()]},t._setListeners=function(){var i=this;this.config.trigger.split(" ").forEach(function(t){if("click"===t)oe(i.element).on(i.constructor.Event.CLICK,i.config.selector,function(t){return i.toggle(t)});else if(t!==be){var e=t===Ie?i.constructor.Event.MOUSEENTER:i.constructor.Event.FOCUSIN,n=t===Ie?i.constructor.Event.MOUSELEAVE:i.constructor.Event.FOCUSOUT;oe(i.element).on(e,i.config.selector,function(t){return i._enter(t)}).on(n,i.config.selector,function(t){return i._leave(t)})}oe(i.element).closest(".modal").on("hide.bs.modal",function(){return i.hide()})}),this.config.selector?this.config=h({},this.config,{trigger:"manual",selector:""}):this._fixTitle()},t._fixTitle=function(){var t=typeof this.element.getAttribute("data-original-title");(this.element.getAttribute("title")||"string"!==t)&&(this.element.setAttribute("data-original-title",this.element.getAttribute("title")||""),this.element.setAttribute("title",""))},t._enter=function(t,e){var n=this.constructor.DATA_KEY;(e=e||oe(t.currentTarget).data(n))||(e=new this.constructor(t.currentTarget,this._getDelegateConfig()),oe(t.currentTarget).data(n,e)),t&&(e._activeTrigger["focusin"===t.type?Ae:Ie]=!0),oe(e.getTipElement()).hasClass(ye)||e._hoverState===me?e._hoverState=me:(clearTimeout(e._timeout),e._hoverState=me,e.config.delay&&e.config.delay.show?e._timeout=setTimeout(function(){e._hoverState===me&&e.show()},e.config.delay.show):e.show())},t._leave=function(t,e){var n=this.constructor.DATA_KEY;(e=e||oe(t.currentTarget).data(n))||(e=new this.constructor(t.currentTarget,this._getDelegateConfig()),oe(t.currentTarget).data(n,e)),t&&(e._activeTrigger["focusout"===t.type?Ae:Ie]=!1),e._isWithActiveTrigger()||(clearTimeout(e._timeout),e._hoverState=pe,e.config.delay&&e.config.delay.hide?e._timeout=setTimeout(function(){e._hoverState===pe&&e.hide()},e.config.delay.hide):e.hide())},t._isWithActiveTrigger=function(){for(var t in this._activeTrigger)if(this._activeTrigger[t])return!0;return!1},t._getConfig=function(t){return"number"==typeof(t=h({},this.constructor.Default,oe(this.element).data(),"object"==typeof t&&t?t:{})).delay&&(t.delay={show:t.delay,hide:t.delay}),"number"==typeof t.title&&(t.title=t.title.toString()),"number"==typeof t.content&&(t.content=t.content.toString()),Cn.typeCheckConfig(ae,t,this.constructor.DefaultType),t},t._getDelegateConfig=function(){var t={};if(this.config)for(var e in this.config)this.constructor.Default[e]!==this.config[e]&&(t[e]=this.config[e]);return t},t._cleanTipClass=function(){var t=oe(this.getTipElement()),e=t.attr("class").match(fe);null!==e&&0

'}),He=h({},Nn.DefaultType,{content:"(string|element|function)"}),We="fade",xe=".popover-header",Ue=".popover-body",Ke={HIDE:"hide"+ke,HIDDEN:"hidden"+ke,SHOW:(Me="show")+ke,SHOWN:"shown"+ke,INSERTED:"inserted"+ke,CLICK:"click"+ke,FOCUSIN:"focusin"+ke,FOCUSOUT:"focusout"+ke,MOUSEENTER:"mouseenter"+ke,MOUSELEAVE:"mouseleave"+ke},Fe=function(t){var e,n;function i(){return t.apply(this,arguments)||this}n=t,(e=i).prototype=Object.create(n.prototype),(e.prototype.constructor=e).__proto__=n;var r=i.prototype;return r.isWithContent=function(){return this.getTitle()||this._getContent()},r.addAttachmentClass=function(t){we(this.getTipElement()).addClass(Le+"-"+t)},r.getTipElement=function(){return this.tip=this.tip||we(this.config.template)[0],this.tip},r.setContent=function(){var t=we(this.getTipElement());this.setElementContent(t.find(xe),this.getTitle());var e=this._getContent();"function"==typeof e&&(e=e.call(this.element)),this.setElementContent(t.find(Ue),e),t.removeClass(We+" "+Me)},r._getContent=function(){return this.element.getAttribute("data-content")||this.config.content},r._cleanTipClass=function(){var t=we(this.getTipElement()),e=t.attr("class").match(je);null!==e&&0=this._offsets[r]&&("undefined"==typeof this._offsets[r+1]||t 2 | 3 | 4 | 5 | 6 | fujinliang.top 7 | 8 | 9 | 15 | 16 | 17 |
18 | 29 | 37 | 38 | 45 | 46 | 50 |
51 | 52 | 53 | 79 | -------------------------------------------------------------------------------- /005_myWallet/view/transaction.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 钱包-孔壹学院 7 | 8 | 9 | 15 | 16 | 17 |
18 | 29 |
30 |
31 |

选择导入账户的方式

32 |
33 | 34 | 37 |
38 |
39 | 40 | 43 |
44 |
45 |
46 |
47 |
48 | 49 | 50 |
51 | 52 |
53 | 54 | 65 |
66 |
67 | 68 |
69 |
70 |
71 | 72 | 73 |
74 | 75 |
76 | 77 |
78 | 79 |
80 | 83 |
84 |
85 | 86 |
87 | 88 | 89 | 90 | 91 | 92 | 93 | 96 |
97 | 98 |
99 |
100 | 101 |
102 |
103 | 104 |
105 | 106 |
107 |
108 | 109 |
110 |
111 | 112 | 113 | 114 | 225 | -------------------------------------------------------------------------------- /006_myWallet/config/config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | keystoreUrl : 'http://localhost:3000/keystore/' 3 | } -------------------------------------------------------------------------------- /006_myWallet/controllers/account.js: -------------------------------------------------------------------------------- 1 | const web3 = require("../utils/web3helper").getWeb3() 2 | const fileUtil = require('../utils/fileUtil') 3 | const path = require('path'); 4 | const config = require("../config/config") 5 | const myContract = require("../utils/web3helper").getContract() 6 | 7 | module.exports = { 8 | async createAccount (ctx) { 9 | let returnResult = { 10 | code: 0, 11 | msg: '成功!', 12 | data: {} 13 | } 14 | 15 | let data = ctx.request.body 16 | const pwd = data.pwd 17 | 18 | // 调用 web3 创建账户 19 | let account = await web3.eth.accounts.create(); 20 | 21 | // encrypt 返回一个JSON 对象 22 | const keystoreJson = await account.encrypt(pwd) 23 | 24 | // 将 JSON 对象转为字符串 25 | const keystoreStr = JSON.stringify(keystoreJson) 26 | 27 | // 生成随机文件存储 keystore 的字符串 28 | const randFilename = "UTC--"+new Date().toISOString()+"--"+account.address 29 | 30 | // 设置存储文件的目录 31 | const filePath =path.join(__dirname,"../static/keystore/"+randFilename) 32 | 33 | // 将 keystore 的内容写入文件中 34 | await fileUtil.writeFile(filePath,keystoreStr) 35 | 36 | // 将 用户地址、私钥、keystore 数据返回 37 | const result = {"account":account.address,"privateKey":account.privateKey,"keystore": config.keystoreUrl+randFilename} 38 | returnResult.data = result 39 | ctx.body = returnResult 40 | }, 41 | async getAccountList (ctx) { 42 | await ctx.render("account") 43 | }, 44 | async getAccountByPrivatekey(ctx) { 45 | 46 | let returnResult = { 47 | code: 0, 48 | msg: '成功!', 49 | data: {} 50 | } 51 | 52 | const data = ctx.request.body 53 | const privateKey = data.privateKey 54 | 55 | // 根据私钥获取用户地址 56 | const account = web3.eth.accounts.privateKeyToAccount(privateKey) 57 | 58 | // 查询账户的余额 59 | const balance = await web3.eth.getBalance(account.address) 60 | const ethNum = web3.utils.fromWei(balance, 'ether') 61 | 62 | const tokenResult = await module.exports.getTokenBalance(account) 63 | 64 | returnResult.data.address = account.address 65 | returnResult.data.privateKey = account.privateKey 66 | returnResult.data.balance = ethNum 67 | returnResult.data.tokenBalance = tokenResult.balance 68 | returnResult.data.tokenSymbol = tokenResult.symbol 69 | ctx.body = returnResult 70 | }, 71 | async getAccountByKeystore(ctx) { 72 | 73 | let returnResult = { 74 | code: 0, 75 | msg: '成功!', 76 | data: {} 77 | } 78 | 79 | const data = ctx.request.body; // 获取上传文件 80 | 81 | const keystoreFile = ctx.request.files.file 82 | const filePath = keystoreFile.path 83 | 84 | // 获取 keystore 里面的json字符串 85 | const keystoreStr = await fileUtil.readFile(filePath) 86 | 87 | // 获取账户的密码 88 | const password = data.password 89 | 90 | // 获取账户的信息地址及私钥 91 | const account = web3.eth.accounts.decrypt(keystoreStr,password) 92 | 93 | const balance = await web3.eth.getBalance(account.address) 94 | 95 | const ethNum = web3.utils.fromWei(balance, 'ether') 96 | 97 | const tokenResult = await module.exports.getTokenBalance(account) 98 | 99 | returnResult.data.address = account.address 100 | returnResult.data.privateKey = account.privateKey 101 | returnResult.data.balance = ethNum 102 | returnResult.data.tokenBalance = tokenResult.balance 103 | returnResult.data.tokenSymbol = tokenResult.symbol 104 | 105 | ctx.body = returnResult 106 | }, 107 | 108 | async getTokenBalance(account){ 109 | 110 | let returnResult = { 111 | balance: 0, 112 | symbol: 'kongyixueyuan' 113 | } 114 | 115 | // 代币小数点位数 116 | const decimals = await myContract.methods.decimals().call() 117 | // 代币符号 118 | const symbol = await myContract.methods.symbol().call() 119 | const tokenBalance = await myContract.methods.balanceOf(account.address).call() 120 | const tokenBalanceNum = tokenBalance / Math.pow(10,decimals) 121 | 122 | returnResult.balance = tokenBalanceNum 123 | returnResult.symbol = symbol 124 | 125 | return returnResult 126 | } 127 | } -------------------------------------------------------------------------------- /006_myWallet/controllers/token.js: -------------------------------------------------------------------------------- 1 | const web3 = require("../utils/web3helper").getWeb3() 2 | const BigNumber = require('bignumber.js'); 3 | const myContract = require("../utils/web3helper").getContract() 4 | 5 | module.exports = { 6 | 7 | async sendTokenTransaction (ctx) { 8 | let returnResult = { 9 | code: 0, 10 | msg: '成功!', 11 | data: {} 12 | } 13 | 14 | const data = ctx.request.body 15 | 16 | const currentAccount = data.currAccount 17 | const privateKey = data.privateKey 18 | const reciptAccount = data.reciptAccount 19 | const txValue = data.txValue 20 | // 获取指定账户地址的交易数 21 | let nonce = await web3.eth.getTransactionCount(currentAccount); 22 | 23 | // 获取设置的位数 24 | const decimals = await myContract.methods.decimals().call() 25 | // 将输入的值 转为 最小单位的值 26 | const value = BigNumber(txValue * Math.pow(10,decimals)); 27 | const txData = myContract.methods.transfer(reciptAccount, value).encodeABI(); 28 | 29 | // 获取当前gasprice 30 | let gasPrice = await web3.eth.getGasPrice(); 31 | 32 | // 以太币转账参数 33 | let txParms = { 34 | from: currentAccount, 35 | // 合约地址 36 | to: myContract.options.address, 37 | nonce: nonce, 38 | gasPrice: gasPrice, 39 | data: txData // 当使用代币转账或者合约调用时 40 | } 41 | 42 | // 获取一下预估gas 43 | let gas = await web3.eth.estimateGas(txParms); 44 | txParms.gas = gas; 45 | // 用密钥对账单进行签名 46 | let signTx = await web3.eth.accounts.signTransaction(txParms,privateKey) 47 | 48 | // 将签过名的账单进行发送 49 | try { 50 | await web3.eth.sendSignedTransaction(signTx.rawTransaction, function(error, hash){ 51 | if (!error) { 52 | returnResult.data.hash = hash 53 | } else { 54 | returnResult.code = "101" 55 | returnResult.msg = "失败!" 56 | returnResult.data.error = error.message 57 | 58 | } 59 | }) 60 | } catch (error) { 61 | console.log(error) 62 | } 63 | 64 | ctx.body = returnResult 65 | } 66 | } -------------------------------------------------------------------------------- /006_myWallet/controllers/transaction.js: -------------------------------------------------------------------------------- 1 | const web3 = require("../utils/web3helper").getWeb3() 2 | 3 | 4 | module.exports = { 5 | 6 | async transaction (ctx) { 7 | await ctx.render("transaction") 8 | }, 9 | 10 | async sendTransaction (ctx) { 11 | let returnResult = { 12 | code: 0, 13 | msg: '成功!', 14 | data: {} 15 | } 16 | 17 | const data = ctx.request.body 18 | 19 | const currentAccount = data.currAccount 20 | const privateKey = data.privateKey 21 | const reciptAccount = data.reciptAccount 22 | const txValue = data.txValue 23 | // 获取指定账户地址的交易数 24 | let nonce = await web3.eth.getTransactionCount(currentAccount); 25 | 26 | // 将 ether 转为 wei 27 | let value = web3.utils.toWei(txValue,'ether'); 28 | 29 | // 获取当前gasprice 30 | let gasPrice = await web3.eth.getGasPrice(); 31 | 32 | // 以太币转账参数 33 | let txParms = { 34 | from: currentAccount, 35 | to: reciptAccount, 36 | nonce: nonce, 37 | gasPrice: gasPrice, 38 | data: '0x00', // 当使用代币转账或者合约调用时 39 | value: value // value 是转账金额 40 | } 41 | // 获取一下预估gas 42 | let gas = await web3.eth.estimateGas(txParms); 43 | txParms.gas = gas; 44 | // 用密钥对账单进行签名 45 | let signTx = await web3.eth.accounts.signTransaction(txParms,privateKey) 46 | 47 | // 将签过名的账单进行发送 48 | try { 49 | await web3.eth.sendSignedTransaction(signTx.rawTransaction, function(error, hash){ 50 | if (!error) { 51 | returnResult.data.hash = hash 52 | } else { 53 | returnResult.code = "101" 54 | returnResult.msg = "失败!" 55 | returnResult.data.error = error.message 56 | 57 | } 58 | }) 59 | } catch (error) { 60 | console.log(error) 61 | } 62 | 63 | ctx.body = returnResult 64 | } 65 | } -------------------------------------------------------------------------------- /006_myWallet/index.js: -------------------------------------------------------------------------------- 1 | const Koa = require('koa'); 2 | const routers = require('./routers/index') 3 | const koaBody = require('koa-body'); 4 | const views = require('koa-views') 5 | const path = require('path') 6 | const static = require('koa-static') 7 | 8 | const app = new Koa(); 9 | 10 | // 引入 koa-body 中间件 11 | app.use(koaBody({ 12 | multipart: true 13 | })); 14 | 15 | // 加载模板引擎 16 | app.use(views(path.join(__dirname, './view'), { 17 | map : {html:'ejs'} 18 | })) 19 | 20 | // 静态资源目录对于相对入口文件index.js的路径 21 | const staticPath = './static' 22 | 23 | app.use(static( 24 | path.join( __dirname, staticPath) 25 | )) 26 | 27 | 28 | // 初始化路由中间件 29 | app.use(routers.routes()).use(routers.allowedMethods()) 30 | app.listen(3000); 31 | console.log('server is starting at port 3000') -------------------------------------------------------------------------------- /006_myWallet/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mywallet", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "", 10 | "license": "ISC", 11 | "dependencies": { 12 | "bignumber.js": "^7.2.1", 13 | "ejs": "^2.6.1", 14 | "koa": "^2.5.2", 15 | "koa-body": "^4.0.4", 16 | "koa-router": "^7.4.0", 17 | "koa-static": "^5.0.0", 18 | "koa-views": "^6.1.4", 19 | "web3": "^1.0.0-beta.34" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /006_myWallet/routers/index.js: -------------------------------------------------------------------------------- 1 | const router = require('koa-router')() 2 | 3 | const accountController = require("../controllers/account") 4 | const transactionController = require("../controllers/transaction") 5 | const tokenController = require("../controllers/token") 6 | 7 | router.get('/', accountController.getAccountList); 8 | 9 | router.post('/', (ctx) => { 10 | 11 | const body = ctx.request.body; 12 | 13 | ctx.body = 'Hello Router POST '+ JSON.stringify(body); 14 | }); 15 | 16 | router.post('/account/create',accountController.createAccount) 17 | router.post('/account/privatekey',accountController.getAccountByPrivatekey) 18 | router.post('/account/keystore',accountController.getAccountByKeystore) 19 | 20 | router.get('/transaction', transactionController.transaction) 21 | router.post('/transaction/send', transactionController.sendTransaction) 22 | 23 | router.post('/token/send', tokenController.sendTokenTransaction) 24 | module.exports = router -------------------------------------------------------------------------------- /006_myWallet/static/keystore/UTC--2018-07-12T07:06:57.659Z--0x5c438a4430F6c06E7945084729bC72Fb94B28F05: -------------------------------------------------------------------------------- 1 | Hello Node.js -------------------------------------------------------------------------------- /006_myWallet/static/keystore/UTC--2018-07-12T07:41:06.111Z--0x31919378FD418e427D8fb021e41748d11067183E: -------------------------------------------------------------------------------- 1 | [object Object] -------------------------------------------------------------------------------- /006_myWallet/static/keystore/UTC--2018-07-12T09:29:58.857Z--0x3b517808584D546A44C6C5C013851D6b3d952f5B: -------------------------------------------------------------------------------- 1 | [object Object] -------------------------------------------------------------------------------- /006_myWallet/static/keystore/UTC--2018-07-12T09:30:42.943Z--0xd4e02f82b1A7144Df65E41DF2eb597Dd4DFF7359: -------------------------------------------------------------------------------- 1 | [object Object] -------------------------------------------------------------------------------- /006_myWallet/static/keystore/UTC--2018-07-12T09:43:12.015Z--0xC3e2d83BC37462F357cA5c7f8e5Ff7fAE99CcF56: -------------------------------------------------------------------------------- 1 | [object Object] -------------------------------------------------------------------------------- /006_myWallet/static/keystore/UTC--2018-07-12T09:45:15.771Z--0xd5d53E133c4e4150bAddF7Cd4Fe4078cb8e4B6b9: -------------------------------------------------------------------------------- 1 | [object Object] -------------------------------------------------------------------------------- /006_myWallet/static/keystore/UTC--2018-07-12T09:46:37.558Z--0x878a0Ab8201d11fdbe04e1b5cB1Af1D77a7A1294: -------------------------------------------------------------------------------- 1 | [object Object] -------------------------------------------------------------------------------- /006_myWallet/static/keystore/UTC--2018-07-12T09:49:25.152Z--0xa51A2dE9b643527fabaD5775Ac45Bdaed0651b02: -------------------------------------------------------------------------------- 1 | [object Object] -------------------------------------------------------------------------------- /006_myWallet/static/keystore/UTC--2018-07-12T09:54:18.944Z--0xe6E6e464995C14708b6B90b11d24fFf0F6b6E5DA: -------------------------------------------------------------------------------- 1 | {"version":3,"id":"2f890aab-fff0-47ea-8b3d-e5ccf8aed24f","address":"e6e6e464995c14708b6b90b11d24fff0f6b6e5da","crypto":{"ciphertext":"99cfb0dbbc8fecd1101688246283f34a6895ae373a9ff8eb41f4bff8ae467cb1","cipherparams":{"iv":"93ffc4f3309058f43ea685ef836b14a9"},"cipher":"aes-128-ctr","kdf":"scrypt","kdfparams":{"dklen":32,"salt":"922ad8060870203002c19047813976276072000ac5a9bc3944c86ec6062ffdd6","n":8192,"r":8,"p":1},"mac":"64ae1ec8e07ff376f2f8457a6f59102a9e589a8e3ecdca361405eb0122abe3fa"}} -------------------------------------------------------------------------------- /006_myWallet/static/keystore/UTC--2018-07-12T09:54:47.024Z--0xF05c267F4F256ff5C7cC5078022740c26D384Ab5: -------------------------------------------------------------------------------- 1 | {"version":3,"id":"354429fc-32f1-4081-9e58-54cc0aaa3b8f","address":"f05c267f4f256ff5c7cc5078022740c26d384ab5","crypto":{"ciphertext":"7b472d00fa185b3d785a6ae6e8e6d121a43fc4aa3b962cf8a2f4c3760e038f4c","cipherparams":{"iv":"6f57ee1c6589e495f95b9d2f177ae6fb"},"cipher":"aes-128-ctr","kdf":"scrypt","kdfparams":{"dklen":32,"salt":"394a6fa5e58479f4f96a890ae66af7c50125c87b7fcefc48b49bce2050f63162","n":8192,"r":8,"p":1},"mac":"255a9c8b9db27527f746e1d05087f73cf313a2e21fb5e2759ccf0990e8d6d274"}} -------------------------------------------------------------------------------- /006_myWallet/static/keystore/UTC--2018-07-13T01:23:34.519Z--0x24791a9EB7899A67E97369738EEC45bBb9b4Dc04: -------------------------------------------------------------------------------- 1 | {"version":3,"id":"5cdd4481-64d5-471b-84b3-cefb4a079b37","address":"24791a9eb7899a67e97369738eec45bbb9b4dc04","crypto":{"ciphertext":"2fcdcc68b22d3c517ef27d1cd5f407d561c64988188e0bcfd398848dff3fba82","cipherparams":{"iv":"13f3dcca6c07a7164b8195449d1c0abf"},"cipher":"aes-128-ctr","kdf":"scrypt","kdfparams":{"dklen":32,"salt":"6204cd7804d18344211bfa371bc74d2cd500721385f7c60cdcbcd9156c33043b","n":8192,"r":8,"p":1},"mac":"162febcc2ff5dcf2760cef227e0ea5fcca886ff9123329d05348d650150b32b4"}} -------------------------------------------------------------------------------- /006_myWallet/static/keystore/UTC--2018-07-13T01:24:33.724Z--0x740b94aFAbDaB9eB95848079AE743e06026CbE67: -------------------------------------------------------------------------------- 1 | {"version":3,"id":"a936529c-e396-4b9a-bf28-853bfdb49907","address":"740b94afabdab9eb95848079ae743e06026cbe67","crypto":{"ciphertext":"39038704835f5b60312586b610f99bc45ca54912b405b44c5fafa6b08070fe08","cipherparams":{"iv":"91e6b7be43e96714304d190ee191f3af"},"cipher":"aes-128-ctr","kdf":"scrypt","kdfparams":{"dklen":32,"salt":"638b8a14c49adec4bc61524cf347c9cdafd1a042d1b545459ace40bd0abe0f44","n":8192,"r":8,"p":1},"mac":"5fc4f8272a0d28eafe9d931628db56a83a5899f2b9c81c7eea4c1c1c4cafa2c1"}} -------------------------------------------------------------------------------- /006_myWallet/static/keystore/UTC--2018-07-13T02:22:11.919Z--0x6a3255db9A489A78fdE14F47B9c17a108784932c: -------------------------------------------------------------------------------- 1 | {"version":3,"id":"e57f95be-8859-4670-9026-afd484a22bf1","address":"6a3255db9a489a78fde14f47b9c17a108784932c","crypto":{"ciphertext":"dce2a98928ee820acd3df214dca656c7f64e54228bd7f7a5e72db917a8706b82","cipherparams":{"iv":"fc93c8f91260b23e26939556d049b2d6"},"cipher":"aes-128-ctr","kdf":"scrypt","kdfparams":{"dklen":32,"salt":"6b0c3f651cf7fdbe4487c3297dc4c4cf6c6add51ef154aa8637569c8b02af402","n":8192,"r":8,"p":1},"mac":"2318fa31121d3ade2e9a53956acacf19ae4cd190aa91049c7bb68cd9206e7c47"}} -------------------------------------------------------------------------------- /006_myWallet/static/keystore/UTC--2018-07-16T01:19:41.108Z--0x100CD4b78A67e689581AbC7c43CD7C650cE2CfFb: -------------------------------------------------------------------------------- 1 | {"version":3,"id":"6ba8e956-4234-4143-b4aa-55e1c77e261c","address":"100cd4b78a67e689581abc7c43cd7c650ce2cffb","crypto":{"ciphertext":"3c5522386bd8854224f51d09b4f45098a6a1f94f89ba161911907d5bc2e06ada","cipherparams":{"iv":"e167135d8dded9c6f86ce3d63543cded"},"cipher":"aes-128-ctr","kdf":"scrypt","kdfparams":{"dklen":32,"salt":"4dcdfccd231867d0b600d44b1eab71cd82eb937bca6d0feb739d71058583d4e6","n":8192,"r":8,"p":1},"mac":"2bc2801f60b4b37519fd51a69575e0348b9b18ea2b02234dbd8b3d064d80fa15"}} -------------------------------------------------------------------------------- /006_myWallet/static/keystore/UTC--2018-07-24T16:21:07.143Z--0xf3eda43f191Ba2eA6D264c77Ed80ae251cA79e09: -------------------------------------------------------------------------------- 1 | {"version":3,"id":"a1ee35ea-f083-41b6-b1b4-0389add6ab98","address":"f3eda43f191ba2ea6d264c77ed80ae251ca79e09","crypto":{"ciphertext":"9431917c07b963ebf6e1f0b5d71a83697af462ed507cddfa6972850ab5e8e220","cipherparams":{"iv":"d365423765c597a8d7e6d4a32f12d24a"},"cipher":"aes-128-ctr","kdf":"scrypt","kdfparams":{"dklen":32,"salt":"d71b7226869844343a5acdd149ce8f833ecb359504a6976224f910a69a617002","n":8192,"r":8,"p":1},"mac":"7935b97ef2640d82467175c6f673a1cdb80ae36ef8a7de0cfaedc5fbc1e8fd2c"}} -------------------------------------------------------------------------------- /006_myWallet/static/keystore/UTC--2018-07-24T16:23:04.957Z--0x1F8C49d69E5796C72f7f824f97d685aB5E91fF2A: -------------------------------------------------------------------------------- 1 | {"version":3,"id":"a8c5e921-a234-4687-8c72-e00471490f01","address":"1f8c49d69e5796c72f7f824f97d685ab5e91ff2a","crypto":{"ciphertext":"3a9c2108202c4aecb594adef838f193f1c4a1033bd133ccd0999869580f6725c","cipherparams":{"iv":"5fed5b4c60a3f6d15dfc785328411da9"},"cipher":"aes-128-ctr","kdf":"scrypt","kdfparams":{"dklen":32,"salt":"d84a3948eb2fc738fa2195d3cd519d73654d6e68dace574301393d62de173b59","n":8192,"r":8,"p":1},"mac":"28d72e22ca887bfe70d00f7f1c6d38accee608818e99f86180887756dec1429b"}} -------------------------------------------------------------------------------- /006_myWallet/utils/fileutil.js: -------------------------------------------------------------------------------- 1 | const fs = require("fs") 2 | 3 | module.exports = { 4 | 5 | readFile(fPath) { 6 | return new Promise(function (resolve, reject) { 7 | fs.readFile(fPath, 'utf-8', function(err, data) { 8 | if (err) reject(err); 9 | else resolve(data); 10 | }); 11 | }); 12 | }, 13 | 14 | writeFile(fPath, content) { 15 | return new Promise(function(resolve, reject) { 16 | fs.writeFile(fPath, content, function(err, data) { 17 | if (err) reject(err); 18 | else resolve("Successed"); 19 | }); 20 | }); 21 | } 22 | } -------------------------------------------------------------------------------- /006_myWallet/utils/web3helper.js: -------------------------------------------------------------------------------- 1 | const Web3 = require('web3'); 2 | 3 | module.exports = { 4 | getWeb3(){ 5 | const web3 = new Web3(Web3.givenProvider || "http://localhost:8545"); 6 | return web3 7 | }, 8 | 9 | getContract() { 10 | 11 | const web3 = module.exports.getWeb3() 12 | // 定义合约abi 13 | const contractAbi = [ { "constant": true, "inputs": [], "name": "name", "outputs": [ { "name": "", "type": "string", "value": "kongyixueyuan" } ], "payable": false, "stateMutability": "view", "type": "function", "signature": "0x06fdde03" }, { "constant": false, "inputs": [ { "name": "_spender", "type": "address" }, { "name": "_value", "type": "uint256" } ], "name": "approve", "outputs": [ { "name": "success", "type": "bool" } ], "payable": false, "stateMutability": "nonpayable", "type": "function", "signature": "0x095ea7b3" }, { "constant": true, "inputs": [], "name": "totalSupply", "outputs": [ { "name": "", "type": "uint256", "value": "10000000000000000000000000" } ], "payable": false, "stateMutability": "view", "type": "function", "signature": "0x18160ddd" }, { "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", "signature": "0x23b872dd" }, { "constant": true, "inputs": [], "name": "decimals", "outputs": [ { "name": "", "type": "uint8", "value": "18" } ], "payable": false, "stateMutability": "view", "type": "function", "signature": "0x313ce567" }, { "constant": false, "inputs": [ { "name": "_value", "type": "uint256" } ], "name": "burn", "outputs": [ { "name": "success", "type": "bool" } ], "payable": false, "stateMutability": "nonpayable", "type": "function", "signature": "0x42966c68" }, { "constant": true, "inputs": [ { "name": "", "type": "address" } ], "name": "balanceOf", "outputs": [ { "name": "", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function", "signature": "0x70a08231" }, { "constant": false, "inputs": [ { "name": "_from", "type": "address" }, { "name": "_value", "type": "uint256" } ], "name": "burnFrom", "outputs": [ { "name": "success", "type": "bool" } ], "payable": false, "stateMutability": "nonpayable", "type": "function", "signature": "0x79cc6790" }, { "constant": true, "inputs": [], "name": "symbol", "outputs": [ { "name": "", "type": "string", "value": "kyb" } ], "payable": false, "stateMutability": "view", "type": "function", "signature": "0x95d89b41" }, { "constant": false, "inputs": [ { "name": "_to", "type": "address" }, { "name": "_value", "type": "uint256" } ], "name": "transfer", "outputs": [ { "name": "success", "type": "bool" } ], "payable": false, "stateMutability": "nonpayable", "type": "function", "signature": "0xa9059cbb" }, { "constant": false, "inputs": [ { "name": "_spender", "type": "address" }, { "name": "_value", "type": "uint256" }, { "name": "_extraData", "type": "bytes" } ], "name": "approveAndCall", "outputs": [ { "name": "success", "type": "bool" } ], "payable": false, "stateMutability": "nonpayable", "type": "function", "signature": "0xcae9ca51" }, { "constant": true, "inputs": [ { "name": "", "type": "address" }, { "name": "", "type": "address" } ], "name": "allowance", "outputs": [ { "name": "", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function", "signature": "0xdd62ed3e" }, { "inputs": [ { "name": "initialSupply", "type": "uint256", "index": 0, "typeShort": "uint", "bits": "256", "displayName": "initial Supply", "template": "elements_input_uint", "value": "10000000" }, { "name": "tokenName", "type": "string", "index": 1, "typeShort": "string", "bits": "", "displayName": "token Name", "template": "elements_input_string", "value": "kongyixueyuan" }, { "name": "tokenSymbol", "type": "string", "index": 2, "typeShort": "string", "bits": "", "displayName": "token Symbol", "template": "elements_input_string", "value": "kyb" } ], "payable": false, "stateMutability": "nonpayable", "type": "constructor", "signature": "constructor" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "from", "type": "address" }, { "indexed": true, "name": "to", "type": "address" }, { "indexed": false, "name": "value", "type": "uint256" } ], "name": "Transfer", "type": "event", "signature": "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "_owner", "type": "address" }, { "indexed": true, "name": "_spender", "type": "address" }, { "indexed": false, "name": "_value", "type": "uint256" } ], "name": "Approval", "type": "event", "signature": "0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "from", "type": "address" }, { "indexed": false, "name": "value", "type": "uint256" } ], "name": "Burn", "type": "event", "signature": "0xcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d397ca5" } ] 14 | // 合约地址 15 | const contractAddress = "0xF2B6b76f1d0Ea4dC8ca543765640224819af3aA2" 16 | 17 | const myContract = new web3.eth.Contract(contractAbi,contractAddress) 18 | 19 | return myContract 20 | } 21 | } -------------------------------------------------------------------------------- /006_myWallet/view/account.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | fujinliang.top 7 | 8 | 9 | 15 | 16 | 17 |
18 | 29 | 37 | 38 | 45 | 46 | 50 |
51 | 52 | 53 | 79 | -------------------------------------------------------------------------------- /006_myWallet/view/transaction.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 钱包-孔壹学院 7 | 8 | 9 | 15 | 16 | 17 |
18 | 29 |
30 |
31 |

选择导入账户的方式

32 |
33 | 34 | 37 |
38 |
39 | 40 | 43 |
44 |
45 |
46 |
47 |
48 | 49 | 50 |
51 | 52 |
53 | 54 | 65 |
66 |
67 | 68 |
69 |
70 |
71 | 72 | 73 |
74 | 75 |
76 | 77 |
78 | 79 |
80 | 84 |
85 |
86 | 87 |
88 | 89 | 90 | 91 | 92 | 93 | 94 | 97 |
98 | 99 |
100 |
101 | 102 |
103 |
104 | 105 |
106 | 107 |
108 |
109 | 110 |
111 |
112 | 113 | 114 | 115 | 240 | -------------------------------------------------------------------------------- /008_myWallet/config/config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | keystoreUrl : 'http://localhost:3000/keystore/' 3 | } -------------------------------------------------------------------------------- /008_myWallet/controllers/account.js: -------------------------------------------------------------------------------- 1 | const web3 = require("../utils/web3helper").getWeb3() 2 | const fileUtil = require('../utils/fileUtil') 3 | const path = require('path'); 4 | const config = require("../config/config") 5 | 6 | module.exports = { 7 | async createAccount (ctx) { 8 | let returnResult = { 9 | code: 0, 10 | msg: '成功!', 11 | data: {} 12 | } 13 | 14 | let data = ctx.request.body 15 | const pwd = data.pwd 16 | 17 | // 调用 web3 创建账户 18 | let account = await web3.eth.accounts.create(); 19 | 20 | // encrypt 返回一个JSON 对象 21 | const keystoreJson = await account.encrypt(pwd) 22 | 23 | // 将 JSON 对象转为字符串 24 | const keystoreStr = JSON.stringify(keystoreJson) 25 | 26 | // 生成随机文件存储 keystore 的字符串 27 | const randFilename = "UTC--"+new Date().toISOString()+"--"+account.address 28 | 29 | // 设置存储文件的目录 30 | const filePath =path.join(__dirname,"../static/keystore/"+randFilename) 31 | 32 | // 将 keystore 的内容写入文件中 33 | await fileUtil.writeFile(filePath,keystoreStr) 34 | 35 | // 将 用户地址、私钥、keystore 数据返回 36 | const result = {"account":account.address,"privateKey":account.privateKey,"keystore": config.keystoreUrl+randFilename} 37 | returnResult.data = result 38 | ctx.body = returnResult 39 | }, 40 | async getAccountList (ctx) { 41 | await ctx.render("account") 42 | }, 43 | async getAccountByPrivatekey(ctx) { 44 | 45 | let returnResult = { 46 | code: 0, 47 | msg: '成功!', 48 | data: {} 49 | } 50 | 51 | const data = ctx.request.body 52 | const privateKey = data.privateKey 53 | 54 | // 根据私钥获取用户地址 55 | const account = web3.eth.accounts.privateKeyToAccount(privateKey) 56 | 57 | // 查询账户的余额 58 | const balance = await web3.eth.getBalance(account.address) 59 | const ethNum = web3.utils.fromWei(balance, 'ether') 60 | 61 | returnResult.data.address = account.address 62 | returnResult.data.privateKey = account.privateKey 63 | returnResult.data.balance = ethNum 64 | ctx.body = returnResult 65 | }, 66 | async getAccountByKeystore(ctx) { 67 | 68 | let returnResult = { 69 | code: 0, 70 | msg: '成功!', 71 | data: {} 72 | } 73 | 74 | const data = ctx.request.body; // 获取上传文件 75 | 76 | const keystoreFile = ctx.request.files.file 77 | const filePath = keystoreFile.path 78 | 79 | // 获取 keystore 里面的json字符串 80 | const keystoreStr = await fileUtil.readFile(filePath) 81 | 82 | // 获取账户的密码 83 | const password = data.password 84 | 85 | // 获取账户的信息地址及私钥 86 | const account = web3.eth.accounts.decrypt(keystoreStr,password) 87 | 88 | const balance = await web3.eth.getBalance(account.address) 89 | 90 | const ethNum = web3.utils.fromWei(balance, 'ether') 91 | 92 | returnResult.data.address = account.address 93 | returnResult.data.privateKey = account.privateKey 94 | returnResult.data.balance = ethNum 95 | 96 | ctx.body = returnResult 97 | } 98 | } -------------------------------------------------------------------------------- /008_myWallet/controllers/transaction.js: -------------------------------------------------------------------------------- 1 | const web3 = require("../utils/web3helper").getWeb3() 2 | 3 | 4 | module.exports = { 5 | 6 | async transaction (ctx) { 7 | await ctx.render("transaction") 8 | }, 9 | 10 | async sendTransaction (ctx) { 11 | let returnResult = { 12 | code: 0, 13 | msg: '成功!', 14 | data: {} 15 | } 16 | 17 | const data = ctx.request.body 18 | 19 | const currentAccount = data.currAccount 20 | const privateKey = data.privateKey 21 | const reciptAccount = data.reciptAccount 22 | const txValue = data.txValue 23 | // 获取指定账户地址的交易数 24 | let nonce = await web3.eth.getTransactionCount(currentAccount); 25 | 26 | // 将 ether 转为 wei 27 | let value = web3.utils.toWei(txValue,'ether'); 28 | 29 | // 获取当前gasprice 30 | let gasPrice = await web3.eth.getGasPrice(); 31 | 32 | // 以太币转账参数 33 | let txParms = { 34 | from: currentAccount, 35 | to: reciptAccount, 36 | nonce: nonce, 37 | gasPrice: gasPrice, 38 | data: '0x00', // 当使用代币转账或者合约调用时 39 | value: value // value 是转账金额 40 | } 41 | // 获取一下预估gas 42 | let gas = await web3.eth.estimateGas(txParms); 43 | txParms.gas = gas; 44 | // 用密钥对账单进行签名 45 | let signTx = await web3.eth.accounts.signTransaction(txParms,privateKey) 46 | 47 | // 将签过名的账单进行发送 48 | try { 49 | await web3.eth.sendSignedTransaction(signTx.rawTransaction, function(error, hash){ 50 | if (!error) { 51 | returnResult.data.hash = hash 52 | } else { 53 | returnResult.code = "101" 54 | returnResult.msg = "失败!" 55 | returnResult.data.error = error.message 56 | 57 | } 58 | }) 59 | } catch (error) { 60 | console.log(error) 61 | } 62 | 63 | ctx.body = returnResult 64 | } 65 | } -------------------------------------------------------------------------------- /008_myWallet/index.js: -------------------------------------------------------------------------------- 1 | const Koa = require('koa'); 2 | const routers = require('./routers/index') 3 | const koaBody = require('koa-body'); 4 | const views = require('koa-views') 5 | const path = require('path') 6 | const static = require('koa-static') 7 | 8 | const app = new Koa(); 9 | 10 | // 引入 koa-body 中间件 11 | app.use(koaBody({ 12 | multipart: true 13 | })); 14 | 15 | // 加载模板引擎 16 | app.use(views(path.join(__dirname, './view'), { 17 | map : {html:'ejs'} 18 | })) 19 | 20 | // 静态资源目录对于相对入口文件index.js的路径 21 | const staticPath = './static' 22 | 23 | app.use(static( 24 | path.join( __dirname, staticPath) 25 | )) 26 | 27 | 28 | // 初始化路由中间件 29 | app.use(routers.routes()).use(routers.allowedMethods()) 30 | app.listen(3000); 31 | console.log('server is starting at port 3000') -------------------------------------------------------------------------------- /008_myWallet/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mywallet", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "", 10 | "license": "ISC", 11 | "dependencies": { 12 | "ejs": "^2.6.1", 13 | "koa": "^2.5.2", 14 | "koa-body": "^4.0.4", 15 | "koa-router": "^7.4.0", 16 | "koa-static": "^5.0.0", 17 | "koa-views": "^6.1.4", 18 | "web3": "^1.0.0-beta.34" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /008_myWallet/routers/index.js: -------------------------------------------------------------------------------- 1 | const router = require('koa-router')() 2 | 3 | const accountController = require("../controllers/account") 4 | const transactionController = require("../controllers/transaction") 5 | 6 | router.get('/', accountController.getAccountList); 7 | 8 | router.post('/', (ctx) => { 9 | 10 | const body = ctx.request.body; 11 | 12 | ctx.body = 'Hello Router POST '+ JSON.stringify(body); 13 | }); 14 | 15 | router.post('/account/create',accountController.createAccount) 16 | router.post('/account/privatekey',accountController.getAccountByPrivatekey) 17 | router.post('/account/keystore',accountController.getAccountByKeystore) 18 | 19 | router.get('/transaction', transactionController.transaction) 20 | router.post('/transaction/send', transactionController.sendTransaction) 21 | module.exports = router -------------------------------------------------------------------------------- /008_myWallet/static/keystore/UTC--2018-07-12T07:06:57.659Z--0x5c438a4430F6c06E7945084729bC72Fb94B28F05: -------------------------------------------------------------------------------- 1 | Hello Node.js -------------------------------------------------------------------------------- /008_myWallet/static/keystore/UTC--2018-07-12T07:41:06.111Z--0x31919378FD418e427D8fb021e41748d11067183E: -------------------------------------------------------------------------------- 1 | [object Object] -------------------------------------------------------------------------------- /008_myWallet/static/keystore/UTC--2018-07-12T09:29:58.857Z--0x3b517808584D546A44C6C5C013851D6b3d952f5B: -------------------------------------------------------------------------------- 1 | [object Object] -------------------------------------------------------------------------------- /008_myWallet/static/keystore/UTC--2018-07-12T09:30:42.943Z--0xd4e02f82b1A7144Df65E41DF2eb597Dd4DFF7359: -------------------------------------------------------------------------------- 1 | [object Object] -------------------------------------------------------------------------------- /008_myWallet/static/keystore/UTC--2018-07-12T09:43:12.015Z--0xC3e2d83BC37462F357cA5c7f8e5Ff7fAE99CcF56: -------------------------------------------------------------------------------- 1 | [object Object] -------------------------------------------------------------------------------- /008_myWallet/static/keystore/UTC--2018-07-12T09:45:15.771Z--0xd5d53E133c4e4150bAddF7Cd4Fe4078cb8e4B6b9: -------------------------------------------------------------------------------- 1 | [object Object] -------------------------------------------------------------------------------- /008_myWallet/static/keystore/UTC--2018-07-12T09:46:37.558Z--0x878a0Ab8201d11fdbe04e1b5cB1Af1D77a7A1294: -------------------------------------------------------------------------------- 1 | [object Object] -------------------------------------------------------------------------------- /008_myWallet/static/keystore/UTC--2018-07-12T09:49:25.152Z--0xa51A2dE9b643527fabaD5775Ac45Bdaed0651b02: -------------------------------------------------------------------------------- 1 | [object Object] -------------------------------------------------------------------------------- /008_myWallet/static/keystore/UTC--2018-07-12T09:54:18.944Z--0xe6E6e464995C14708b6B90b11d24fFf0F6b6E5DA: -------------------------------------------------------------------------------- 1 | {"version":3,"id":"2f890aab-fff0-47ea-8b3d-e5ccf8aed24f","address":"e6e6e464995c14708b6b90b11d24fff0f6b6e5da","crypto":{"ciphertext":"99cfb0dbbc8fecd1101688246283f34a6895ae373a9ff8eb41f4bff8ae467cb1","cipherparams":{"iv":"93ffc4f3309058f43ea685ef836b14a9"},"cipher":"aes-128-ctr","kdf":"scrypt","kdfparams":{"dklen":32,"salt":"922ad8060870203002c19047813976276072000ac5a9bc3944c86ec6062ffdd6","n":8192,"r":8,"p":1},"mac":"64ae1ec8e07ff376f2f8457a6f59102a9e589a8e3ecdca361405eb0122abe3fa"}} -------------------------------------------------------------------------------- /008_myWallet/static/keystore/UTC--2018-07-12T09:54:47.024Z--0xF05c267F4F256ff5C7cC5078022740c26D384Ab5: -------------------------------------------------------------------------------- 1 | {"version":3,"id":"354429fc-32f1-4081-9e58-54cc0aaa3b8f","address":"f05c267f4f256ff5c7cc5078022740c26d384ab5","crypto":{"ciphertext":"7b472d00fa185b3d785a6ae6e8e6d121a43fc4aa3b962cf8a2f4c3760e038f4c","cipherparams":{"iv":"6f57ee1c6589e495f95b9d2f177ae6fb"},"cipher":"aes-128-ctr","kdf":"scrypt","kdfparams":{"dklen":32,"salt":"394a6fa5e58479f4f96a890ae66af7c50125c87b7fcefc48b49bce2050f63162","n":8192,"r":8,"p":1},"mac":"255a9c8b9db27527f746e1d05087f73cf313a2e21fb5e2759ccf0990e8d6d274"}} -------------------------------------------------------------------------------- /008_myWallet/static/keystore/UTC--2018-07-13T01:23:34.519Z--0x24791a9EB7899A67E97369738EEC45bBb9b4Dc04: -------------------------------------------------------------------------------- 1 | {"version":3,"id":"5cdd4481-64d5-471b-84b3-cefb4a079b37","address":"24791a9eb7899a67e97369738eec45bbb9b4dc04","crypto":{"ciphertext":"2fcdcc68b22d3c517ef27d1cd5f407d561c64988188e0bcfd398848dff3fba82","cipherparams":{"iv":"13f3dcca6c07a7164b8195449d1c0abf"},"cipher":"aes-128-ctr","kdf":"scrypt","kdfparams":{"dklen":32,"salt":"6204cd7804d18344211bfa371bc74d2cd500721385f7c60cdcbcd9156c33043b","n":8192,"r":8,"p":1},"mac":"162febcc2ff5dcf2760cef227e0ea5fcca886ff9123329d05348d650150b32b4"}} -------------------------------------------------------------------------------- /008_myWallet/static/keystore/UTC--2018-07-13T01:24:33.724Z--0x740b94aFAbDaB9eB95848079AE743e06026CbE67: -------------------------------------------------------------------------------- 1 | {"version":3,"id":"a936529c-e396-4b9a-bf28-853bfdb49907","address":"740b94afabdab9eb95848079ae743e06026cbe67","crypto":{"ciphertext":"39038704835f5b60312586b610f99bc45ca54912b405b44c5fafa6b08070fe08","cipherparams":{"iv":"91e6b7be43e96714304d190ee191f3af"},"cipher":"aes-128-ctr","kdf":"scrypt","kdfparams":{"dklen":32,"salt":"638b8a14c49adec4bc61524cf347c9cdafd1a042d1b545459ace40bd0abe0f44","n":8192,"r":8,"p":1},"mac":"5fc4f8272a0d28eafe9d931628db56a83a5899f2b9c81c7eea4c1c1c4cafa2c1"}} -------------------------------------------------------------------------------- /008_myWallet/static/keystore/UTC--2018-07-13T02:22:11.919Z--0x6a3255db9A489A78fdE14F47B9c17a108784932c: -------------------------------------------------------------------------------- 1 | {"version":3,"id":"e57f95be-8859-4670-9026-afd484a22bf1","address":"6a3255db9a489a78fde14f47b9c17a108784932c","crypto":{"ciphertext":"dce2a98928ee820acd3df214dca656c7f64e54228bd7f7a5e72db917a8706b82","cipherparams":{"iv":"fc93c8f91260b23e26939556d049b2d6"},"cipher":"aes-128-ctr","kdf":"scrypt","kdfparams":{"dklen":32,"salt":"6b0c3f651cf7fdbe4487c3297dc4c4cf6c6add51ef154aa8637569c8b02af402","n":8192,"r":8,"p":1},"mac":"2318fa31121d3ade2e9a53956acacf19ae4cd190aa91049c7bb68cd9206e7c47"}} -------------------------------------------------------------------------------- /008_myWallet/static/keystore/UTC--2018-07-16T01:19:41.108Z--0x100CD4b78A67e689581AbC7c43CD7C650cE2CfFb: -------------------------------------------------------------------------------- 1 | {"version":3,"id":"6ba8e956-4234-4143-b4aa-55e1c77e261c","address":"100cd4b78a67e689581abc7c43cd7c650ce2cffb","crypto":{"ciphertext":"3c5522386bd8854224f51d09b4f45098a6a1f94f89ba161911907d5bc2e06ada","cipherparams":{"iv":"e167135d8dded9c6f86ce3d63543cded"},"cipher":"aes-128-ctr","kdf":"scrypt","kdfparams":{"dklen":32,"salt":"4dcdfccd231867d0b600d44b1eab71cd82eb937bca6d0feb739d71058583d4e6","n":8192,"r":8,"p":1},"mac":"2bc2801f60b4b37519fd51a69575e0348b9b18ea2b02234dbd8b3d064d80fa15"}} -------------------------------------------------------------------------------- /008_myWallet/static/keystore/UTC--2018-07-24T16:21:07.143Z--0xf3eda43f191Ba2eA6D264c77Ed80ae251cA79e09: -------------------------------------------------------------------------------- 1 | {"version":3,"id":"a1ee35ea-f083-41b6-b1b4-0389add6ab98","address":"f3eda43f191ba2ea6d264c77ed80ae251ca79e09","crypto":{"ciphertext":"9431917c07b963ebf6e1f0b5d71a83697af462ed507cddfa6972850ab5e8e220","cipherparams":{"iv":"d365423765c597a8d7e6d4a32f12d24a"},"cipher":"aes-128-ctr","kdf":"scrypt","kdfparams":{"dklen":32,"salt":"d71b7226869844343a5acdd149ce8f833ecb359504a6976224f910a69a617002","n":8192,"r":8,"p":1},"mac":"7935b97ef2640d82467175c6f673a1cdb80ae36ef8a7de0cfaedc5fbc1e8fd2c"}} -------------------------------------------------------------------------------- /008_myWallet/static/keystore/UTC--2018-07-24T16:23:04.957Z--0x1F8C49d69E5796C72f7f824f97d685aB5E91fF2A: -------------------------------------------------------------------------------- 1 | {"version":3,"id":"a8c5e921-a234-4687-8c72-e00471490f01","address":"1f8c49d69e5796c72f7f824f97d685ab5e91ff2a","crypto":{"ciphertext":"3a9c2108202c4aecb594adef838f193f1c4a1033bd133ccd0999869580f6725c","cipherparams":{"iv":"5fed5b4c60a3f6d15dfc785328411da9"},"cipher":"aes-128-ctr","kdf":"scrypt","kdfparams":{"dklen":32,"salt":"d84a3948eb2fc738fa2195d3cd519d73654d6e68dace574301393d62de173b59","n":8192,"r":8,"p":1},"mac":"28d72e22ca887bfe70d00f7f1c6d38accee608818e99f86180887756dec1429b"}} -------------------------------------------------------------------------------- /008_myWallet/utils/fileutil.js: -------------------------------------------------------------------------------- 1 | const fs = require("fs") 2 | 3 | module.exports = { 4 | 5 | readFile(fPath) { 6 | return new Promise(function (resolve, reject) { 7 | fs.readFile(fPath, 'utf-8', function(err, data) { 8 | if (err) reject(err); 9 | else resolve(data); 10 | }); 11 | }); 12 | }, 13 | 14 | writeFile(fPath, content) { 15 | return new Promise(function(resolve, reject) { 16 | fs.writeFile(fPath, content, function(err, data) { 17 | if (err) reject(err); 18 | else resolve("Successed"); 19 | }); 20 | }); 21 | } 22 | } -------------------------------------------------------------------------------- /008_myWallet/utils/web3helper.js: -------------------------------------------------------------------------------- 1 | const Web3 = require('web3'); 2 | 3 | module.exports = { 4 | getWeb3(){ 5 | const web3 = new Web3(Web3.givenProvider || "https://kovan.infura.io/v3/defa81f315d0472d88e8d242099524e2"); 6 | return web3 7 | } 8 | } -------------------------------------------------------------------------------- /008_myWallet/view/account.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | fujinliang.top 7 | 8 | 9 | 15 | 16 | 17 |
18 | 29 | 37 | 38 | 45 | 46 | 50 |
51 | 52 | 53 | 79 | -------------------------------------------------------------------------------- /008_myWallet/view/transaction.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 钱包-孔壹学院 7 | 8 | 9 | 15 | 16 | 17 |
18 | 29 |
30 |
31 |

选择导入账户的方式

32 |
33 | 34 | 37 |
38 |
39 | 40 | 43 |
44 |
45 |
46 |
47 |
48 | 49 | 50 |
51 | 52 |
53 | 54 | 65 |
66 |
67 | 68 |
69 |
70 |
71 | 72 | 73 |
74 | 75 |
76 | 77 |
78 | 79 |
80 | 83 |
84 |
85 | 86 |
87 | 88 | 89 | 90 | 91 | 92 | 93 | 96 |
97 | 98 |
99 |
100 | 101 |
102 |
103 | 104 |
105 | 106 |
107 |
108 | 109 |
110 |
111 | 112 | 113 | 114 | 225 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # eth 钱包的主要功能 2 | 3 | * [001 以太坊钱包开发-下载、编译 go-ethereum,搭建 eth 私有链](http://fujinliang.top/2018/07/24/001%E4%BB%A5%E5%A4%AA%E5%9D%8A%E9%92%B1%E5%8C%85%E5%BC%80%E5%8F%91-%E4%B8%8B%E8%BD%BD%E7%BC%96%E8%AF%91go-ethereum%E6%90%AD%E5%BB%BAeth%E7%A7%81%E6%9C%89%E9%93%BE/) 4 | * [002 以太坊钱包开发-使用 koa 搭建钱包项目](http://fujinliang.top/2018/07/24/002%E4%BB%A5%E5%A4%AA%E5%9D%8A%E9%92%B1%E5%8C%85%E5%BC%80%E5%8F%91-%E4%BD%BF%E7%94%A8koa%E6%90%AD%E5%BB%BA%E9%92%B1%E5%8C%85%E9%A1%B9%E7%9B%AE/) 5 | * [003 以太坊钱包开发-引入 web3.js](http://fujinliang.top/2018/07/24/003%E4%BB%A5%E5%A4%AA%E5%9D%8A%E9%92%B1%E5%8C%85%E5%BC%80%E5%8F%91-%E5%BC%95%E5%85%A5web3-js/) 6 | * [004 以太坊钱包开发-创建用户](http://fujinliang.top/2018/07/25/004%E4%BB%A5%E5%A4%AA%E5%9D%8A%E9%92%B1%E5%8C%85%E5%BC%80%E5%8F%91-%E5%88%9B%E5%BB%BA%E7%94%A8%E6%88%B7/) 7 | * [005 以太坊钱包开发-账户转账](http://fujinliang.top/2018/07/29/005%E4%BB%A5%E5%A4%AA%E5%9D%8A%E9%92%B1%E5%8C%85%E5%BC%80%E5%8F%91-%E8%B4%A6%E6%88%B7%E8%BD%AC%E8%B4%A6/) 8 | * [006 以太坊钱包开发-发放token、token转账](http://fujinliang.top/2018/08/05/006%E4%BB%A5%E5%A4%AA%E5%9D%8A%E9%92%B1%E5%8C%85%E5%BC%80%E5%8F%91-%E5%8F%91%E6%94%BEtoken%E5%8F%8Atoken%E8%BD%AC%E8%B4%A6/) 9 | * [007 以太坊钱包开发-助记词、私钥、地址](http://fujinliang.top/2018/08/05/007%E4%BB%A5%E5%A4%AA%E5%9D%8A%E9%92%B1%E5%8C%85%E5%BC%80%E5%8F%91/) 10 | * [008 以太坊钱包开发-切换到测试网络、正式网络](http://fujinliang.top/2018/08/05/008%E4%BB%A5%E5%A4%AA%E5%9D%8A%E9%92%B1%E5%8C%85%E5%BC%80%E5%8F%91-%E5%88%87%E6%8D%A2%E5%88%B0%E6%B5%8B%E8%AF%95%E7%BD%91%E7%BB%9C/) 11 | 12 | 13 | ![公众号](http://pck6uk7jx.bkt.clouddn.com/wechat001.png) 14 | 15 | -------------------------------------------------------------------------------- /accountsWallet/index.js: -------------------------------------------------------------------------------- 1 | var bip39 = require('bip39') 2 | var hdkey = require('ethereumjs-wallet/hdkey') 3 | var util = require('ethereumjs-util') 4 | 5 | // 生成助记词 6 | var mnemonic = bip39.generateMnemonic() 7 | 8 | console.log(mnemonic) 9 | 10 | var seed = bip39.mnemonicToSeed(mnemonic) 11 | var hdWallet = hdkey.fromMasterSeed(seed) 12 | 13 | 14 | var key1 = hdWallet.derivePath("m/44'/60'/0'/0/0") 15 | console.log("私钥:"+util.bufferToHex(key1._hdkey._privateKey)) 16 | 17 | 18 | var address1 = util.pubToAddress(key1._hdkey._publicKey, true) 19 | console.log("地址:"+util.bufferToHex(address1)) 20 | 21 | address1 = util.toChecksumAddress(address1.toString('hex')) 22 | console.log("Encoding Address 地址:"+ address1) 23 | -------------------------------------------------------------------------------- /accountsWallet/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "accountswallet", 3 | "version": "1.0.0", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "aes-js": { 8 | "version": "0.2.4", 9 | "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-0.2.4.tgz", 10 | "integrity": "sha1-lLiBq3FyhtAV+iGeCPtmcJ3aWj0=" 11 | }, 12 | "base-x": { 13 | "version": "1.1.0", 14 | "resolved": "https://registry.npmjs.org/base-x/-/base-x-1.1.0.tgz", 15 | "integrity": "sha1-QtPXF0dPnqAiB/bRqh9CaRPut6w=" 16 | }, 17 | "bindings": { 18 | "version": "1.3.0", 19 | "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.3.0.tgz", 20 | "integrity": "sha512-DpLh5EzMR2kzvX1KIlVC0VkC3iZtHKTgdtZ0a3pglBZdaQFjt5S9g9xd1lE+YvXyfd6mtCeRnrUfOLYiTMlNSw==" 21 | }, 22 | "bip39": { 23 | "version": "2.5.0", 24 | "resolved": "https://registry.npmjs.org/bip39/-/bip39-2.5.0.tgz", 25 | "integrity": "sha512-xwIx/8JKoT2+IPJpFEfXoWdYwP7UVAoUxxLNfGCfVowaJE7yg1Y5B1BVPqlUNsBq5/nGwmFkwRJ8xDW4sX8OdA==", 26 | "requires": { 27 | "create-hash": "1.2.0", 28 | "pbkdf2": "3.0.16", 29 | "randombytes": "2.0.6", 30 | "safe-buffer": "5.1.2", 31 | "unorm": "1.4.1" 32 | } 33 | }, 34 | "bip66": { 35 | "version": "1.1.5", 36 | "resolved": "https://registry.npmjs.org/bip66/-/bip66-1.1.5.tgz", 37 | "integrity": "sha1-AfqHSHhcpwlV1QESF9GzE5lpyiI=", 38 | "requires": { 39 | "safe-buffer": "5.1.2" 40 | } 41 | }, 42 | "bn.js": { 43 | "version": "4.11.8", 44 | "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", 45 | "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==" 46 | }, 47 | "brorand": { 48 | "version": "1.1.0", 49 | "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", 50 | "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=" 51 | }, 52 | "browserify-aes": { 53 | "version": "1.2.0", 54 | "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", 55 | "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", 56 | "requires": { 57 | "buffer-xor": "1.0.3", 58 | "cipher-base": "1.0.4", 59 | "create-hash": "1.2.0", 60 | "evp_bytestokey": "1.0.3", 61 | "inherits": "2.0.3", 62 | "safe-buffer": "5.1.2" 63 | } 64 | }, 65 | "browserify-sha3": { 66 | "version": "0.0.1", 67 | "resolved": "https://registry.npmjs.org/browserify-sha3/-/browserify-sha3-0.0.1.tgz", 68 | "integrity": "sha1-P/NKMAbvFcD7NWflQbkaI0ASPRE=", 69 | "requires": { 70 | "js-sha3": "0.3.1" 71 | } 72 | }, 73 | "bs58": { 74 | "version": "3.1.0", 75 | "resolved": "https://registry.npmjs.org/bs58/-/bs58-3.1.0.tgz", 76 | "integrity": "sha1-1MJjiL9IBMrHFBQbGUWqR+XrJI4=", 77 | "requires": { 78 | "base-x": "1.1.0" 79 | } 80 | }, 81 | "bs58check": { 82 | "version": "1.3.4", 83 | "resolved": "https://registry.npmjs.org/bs58check/-/bs58check-1.3.4.tgz", 84 | "integrity": "sha1-xSVABzdJEXcU+gQsMEfrj5FRy/g=", 85 | "requires": { 86 | "bs58": "3.1.0", 87 | "create-hash": "1.2.0" 88 | } 89 | }, 90 | "buffer-xor": { 91 | "version": "1.0.3", 92 | "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", 93 | "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=" 94 | }, 95 | "cipher-base": { 96 | "version": "1.0.4", 97 | "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", 98 | "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", 99 | "requires": { 100 | "inherits": "2.0.3", 101 | "safe-buffer": "5.1.2" 102 | } 103 | }, 104 | "coinstring": { 105 | "version": "2.3.0", 106 | "resolved": "https://registry.npmjs.org/coinstring/-/coinstring-2.3.0.tgz", 107 | "integrity": "sha1-zbYzY6lhUCQEolr7gsLibV/2J6Q=", 108 | "requires": { 109 | "bs58": "2.0.1", 110 | "create-hash": "1.2.0" 111 | }, 112 | "dependencies": { 113 | "bs58": { 114 | "version": "2.0.1", 115 | "resolved": "https://registry.npmjs.org/bs58/-/bs58-2.0.1.tgz", 116 | "integrity": "sha1-VZCNWPGYKrogCPob7Y+RmYopv40=" 117 | } 118 | } 119 | }, 120 | "create-hash": { 121 | "version": "1.2.0", 122 | "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", 123 | "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", 124 | "requires": { 125 | "cipher-base": "1.0.4", 126 | "inherits": "2.0.3", 127 | "md5.js": "1.3.4", 128 | "ripemd160": "2.0.2", 129 | "sha.js": "2.4.11" 130 | } 131 | }, 132 | "create-hmac": { 133 | "version": "1.1.7", 134 | "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", 135 | "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", 136 | "requires": { 137 | "cipher-base": "1.0.4", 138 | "create-hash": "1.2.0", 139 | "inherits": "2.0.3", 140 | "ripemd160": "2.0.2", 141 | "safe-buffer": "5.1.2", 142 | "sha.js": "2.4.11" 143 | } 144 | }, 145 | "drbg.js": { 146 | "version": "1.0.1", 147 | "resolved": "https://registry.npmjs.org/drbg.js/-/drbg.js-1.0.1.tgz", 148 | "integrity": "sha1-Pja2xCs3BDgjzbwzLVjzHiRFSAs=", 149 | "requires": { 150 | "browserify-aes": "1.2.0", 151 | "create-hash": "1.2.0", 152 | "create-hmac": "1.1.7" 153 | } 154 | }, 155 | "elliptic": { 156 | "version": "6.4.0", 157 | "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.4.0.tgz", 158 | "integrity": "sha1-ysmvh2LIWDYYcAPI3+GT5eLq5d8=", 159 | "requires": { 160 | "bn.js": "4.11.8", 161 | "brorand": "1.1.0", 162 | "hash.js": "1.1.5", 163 | "hmac-drbg": "1.0.1", 164 | "inherits": "2.0.3", 165 | "minimalistic-assert": "1.0.1", 166 | "minimalistic-crypto-utils": "1.0.1" 167 | } 168 | }, 169 | "ethereumjs-util": { 170 | "version": "5.2.0", 171 | "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.2.0.tgz", 172 | "integrity": "sha512-CJAKdI0wgMbQFLlLRtZKGcy/L6pzVRgelIZqRqNbuVFM3K9VEnyfbcvz0ncWMRNCe4kaHWjwRYQcYMucmwsnWA==", 173 | "requires": { 174 | "bn.js": "4.11.8", 175 | "create-hash": "1.2.0", 176 | "ethjs-util": "0.1.6", 177 | "keccak": "1.4.0", 178 | "rlp": "2.1.0", 179 | "safe-buffer": "5.1.2", 180 | "secp256k1": "3.5.0" 181 | } 182 | }, 183 | "ethereumjs-wallet": { 184 | "version": "0.6.0", 185 | "resolved": "https://registry.npmjs.org/ethereumjs-wallet/-/ethereumjs-wallet-0.6.0.tgz", 186 | "integrity": "sha1-gnY7Fpfuenlr5xVdqd+0my+Yz9s=", 187 | "requires": { 188 | "aes-js": "0.2.4", 189 | "bs58check": "1.3.4", 190 | "ethereumjs-util": "4.5.0", 191 | "hdkey": "0.7.1", 192 | "scrypt.js": "0.2.0", 193 | "utf8": "2.1.2", 194 | "uuid": "2.0.3" 195 | }, 196 | "dependencies": { 197 | "ethereumjs-util": { 198 | "version": "4.5.0", 199 | "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-4.5.0.tgz", 200 | "integrity": "sha1-PpQosxfuvaPXJg2FT93alUsfG8Y=", 201 | "requires": { 202 | "bn.js": "4.11.8", 203 | "create-hash": "1.2.0", 204 | "keccakjs": "0.2.1", 205 | "rlp": "2.1.0", 206 | "secp256k1": "3.5.0" 207 | } 208 | } 209 | } 210 | }, 211 | "ethjs-util": { 212 | "version": "0.1.6", 213 | "resolved": "https://registry.npmjs.org/ethjs-util/-/ethjs-util-0.1.6.tgz", 214 | "integrity": "sha512-CUnVOQq7gSpDHZVVrQW8ExxUETWrnrvXYvYz55wOU8Uj4VCgw56XC2B/fVqQN+f7gmrnRHSLVnFAwsCuNwji8w==", 215 | "requires": { 216 | "is-hex-prefixed": "1.0.0", 217 | "strip-hex-prefix": "1.0.0" 218 | } 219 | }, 220 | "evp_bytestokey": { 221 | "version": "1.0.3", 222 | "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", 223 | "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", 224 | "requires": { 225 | "md5.js": "1.3.4", 226 | "safe-buffer": "5.1.2" 227 | } 228 | }, 229 | "hash-base": { 230 | "version": "3.0.4", 231 | "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz", 232 | "integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=", 233 | "requires": { 234 | "inherits": "2.0.3", 235 | "safe-buffer": "5.1.2" 236 | } 237 | }, 238 | "hash.js": { 239 | "version": "1.1.5", 240 | "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.5.tgz", 241 | "integrity": "sha512-eWI5HG9Np+eHV1KQhisXWwM+4EPPYe5dFX1UZZH7k/E3JzDEazVH+VGlZi6R94ZqImq+A3D1mCEtrFIfg/E7sA==", 242 | "requires": { 243 | "inherits": "2.0.3", 244 | "minimalistic-assert": "1.0.1" 245 | } 246 | }, 247 | "hdkey": { 248 | "version": "0.7.1", 249 | "resolved": "https://registry.npmjs.org/hdkey/-/hdkey-0.7.1.tgz", 250 | "integrity": "sha1-yu5L6BqneSHpCbjSKN0PKayu5jI=", 251 | "requires": { 252 | "coinstring": "2.3.0", 253 | "secp256k1": "3.5.0" 254 | } 255 | }, 256 | "hmac-drbg": { 257 | "version": "1.0.1", 258 | "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", 259 | "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", 260 | "requires": { 261 | "hash.js": "1.1.5", 262 | "minimalistic-assert": "1.0.1", 263 | "minimalistic-crypto-utils": "1.0.1" 264 | } 265 | }, 266 | "inherits": { 267 | "version": "2.0.3", 268 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", 269 | "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" 270 | }, 271 | "is-hex-prefixed": { 272 | "version": "1.0.0", 273 | "resolved": "https://registry.npmjs.org/is-hex-prefixed/-/is-hex-prefixed-1.0.0.tgz", 274 | "integrity": "sha1-fY035q135dEnFIkTxXPggtd39VQ=" 275 | }, 276 | "js-sha3": { 277 | "version": "0.3.1", 278 | "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.3.1.tgz", 279 | "integrity": "sha1-hhIoAhQvCChQKg0d7h2V4lO7AkM=" 280 | }, 281 | "keccak": { 282 | "version": "1.4.0", 283 | "resolved": "https://registry.npmjs.org/keccak/-/keccak-1.4.0.tgz", 284 | "integrity": "sha512-eZVaCpblK5formjPjeTBik7TAg+pqnDrMHIffSvi9Lh7PQgM1+hSzakUeZFCk9DVVG0dacZJuaz2ntwlzZUIBw==", 285 | "requires": { 286 | "bindings": "1.3.0", 287 | "inherits": "2.0.3", 288 | "nan": "2.10.0", 289 | "safe-buffer": "5.1.2" 290 | } 291 | }, 292 | "keccakjs": { 293 | "version": "0.2.1", 294 | "resolved": "https://registry.npmjs.org/keccakjs/-/keccakjs-0.2.1.tgz", 295 | "integrity": "sha1-HWM6+QfvMFu/ny+mFtVsRFYd+k0=", 296 | "requires": { 297 | "browserify-sha3": "0.0.1", 298 | "sha3": "1.2.2" 299 | } 300 | }, 301 | "md5.js": { 302 | "version": "1.3.4", 303 | "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.4.tgz", 304 | "integrity": "sha1-6b296UogpawYsENA/Fdk1bCdkB0=", 305 | "requires": { 306 | "hash-base": "3.0.4", 307 | "inherits": "2.0.3" 308 | } 309 | }, 310 | "minimalistic-assert": { 311 | "version": "1.0.1", 312 | "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", 313 | "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" 314 | }, 315 | "minimalistic-crypto-utils": { 316 | "version": "1.0.1", 317 | "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", 318 | "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=" 319 | }, 320 | "nan": { 321 | "version": "2.10.0", 322 | "resolved": "https://registry.npmjs.org/nan/-/nan-2.10.0.tgz", 323 | "integrity": "sha512-bAdJv7fBLhWC+/Bls0Oza+mvTaNQtP+1RyhhhvD95pgUJz6XM5IzgmxOkItJ9tkoCiplvAnXI1tNmmUD/eScyA==" 324 | }, 325 | "pbkdf2": { 326 | "version": "3.0.16", 327 | "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.16.tgz", 328 | "integrity": "sha512-y4CXP3thSxqf7c0qmOF+9UeOTrifiVTIM+u7NWlq+PRsHbr7r7dpCmvzrZxa96JJUNi0Y5w9VqG5ZNeCVMoDcA==", 329 | "requires": { 330 | "create-hash": "1.2.0", 331 | "create-hmac": "1.1.7", 332 | "ripemd160": "2.0.2", 333 | "safe-buffer": "5.1.2", 334 | "sha.js": "2.4.11" 335 | } 336 | }, 337 | "randombytes": { 338 | "version": "2.0.6", 339 | "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.0.6.tgz", 340 | "integrity": "sha512-CIQ5OFxf4Jou6uOKe9t1AOgqpeU5fd70A8NPdHSGeYXqXsPe6peOwI0cUl88RWZ6sP1vPMV3avd/R6cZ5/sP1A==", 341 | "requires": { 342 | "safe-buffer": "5.1.2" 343 | } 344 | }, 345 | "ripemd160": { 346 | "version": "2.0.2", 347 | "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", 348 | "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", 349 | "requires": { 350 | "hash-base": "3.0.4", 351 | "inherits": "2.0.3" 352 | } 353 | }, 354 | "rlp": { 355 | "version": "2.1.0", 356 | "resolved": "https://registry.npmjs.org/rlp/-/rlp-2.1.0.tgz", 357 | "integrity": "sha512-93U7IKH5j7nmXFVg19MeNBGzQW5uXW1pmCuKY8veeKIhYTE32C2d0mOegfiIAfXcHOKJjjPlJisn8iHDF5AezA==", 358 | "requires": { 359 | "safe-buffer": "5.1.2" 360 | } 361 | }, 362 | "safe-buffer": { 363 | "version": "5.1.2", 364 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", 365 | "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" 366 | }, 367 | "scrypt": { 368 | "version": "6.0.3", 369 | "resolved": "https://registry.npmjs.org/scrypt/-/scrypt-6.0.3.tgz", 370 | "integrity": "sha1-BOAUpWgrU/pQwtXM4WfXGcBthw0=", 371 | "requires": { 372 | "nan": "2.10.0" 373 | } 374 | }, 375 | "scrypt.js": { 376 | "version": "0.2.0", 377 | "resolved": "https://registry.npmjs.org/scrypt.js/-/scrypt.js-0.2.0.tgz", 378 | "integrity": "sha1-r40UZbcemZARC+38WTuUeeA6ito=", 379 | "requires": { 380 | "scrypt": "6.0.3", 381 | "scryptsy": "1.2.1" 382 | } 383 | }, 384 | "scryptsy": { 385 | "version": "1.2.1", 386 | "resolved": "https://registry.npmjs.org/scryptsy/-/scryptsy-1.2.1.tgz", 387 | "integrity": "sha1-oyJfpLJST4AnAHYeKFW987LZIWM=", 388 | "requires": { 389 | "pbkdf2": "3.0.16" 390 | } 391 | }, 392 | "secp256k1": { 393 | "version": "3.5.0", 394 | "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-3.5.0.tgz", 395 | "integrity": "sha512-e5QIJl8W7Y4tT6LHffVcZAxJjvpgE5Owawv6/XCYPQljE9aP2NFFddQ8OYMKhdLshNu88FfL3qCN3/xYkXGRsA==", 396 | "requires": { 397 | "bindings": "1.3.0", 398 | "bip66": "1.1.5", 399 | "bn.js": "4.11.8", 400 | "create-hash": "1.2.0", 401 | "drbg.js": "1.0.1", 402 | "elliptic": "6.4.0", 403 | "nan": "2.10.0", 404 | "safe-buffer": "5.1.2" 405 | } 406 | }, 407 | "sha.js": { 408 | "version": "2.4.11", 409 | "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", 410 | "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", 411 | "requires": { 412 | "inherits": "2.0.3", 413 | "safe-buffer": "5.1.2" 414 | } 415 | }, 416 | "sha3": { 417 | "version": "1.2.2", 418 | "resolved": "https://registry.npmjs.org/sha3/-/sha3-1.2.2.tgz", 419 | "integrity": "sha1-pmxQmN5MJbyIM27ItIF9AFvKe6k=", 420 | "requires": { 421 | "nan": "2.10.0" 422 | } 423 | }, 424 | "strip-hex-prefix": { 425 | "version": "1.0.0", 426 | "resolved": "https://registry.npmjs.org/strip-hex-prefix/-/strip-hex-prefix-1.0.0.tgz", 427 | "integrity": "sha1-DF8VX+8RUTczd96du1iNoFUA428=", 428 | "requires": { 429 | "is-hex-prefixed": "1.0.0" 430 | } 431 | }, 432 | "unorm": { 433 | "version": "1.4.1", 434 | "resolved": "https://registry.npmjs.org/unorm/-/unorm-1.4.1.tgz", 435 | "integrity": "sha1-NkIA1fE2RsqLzURJAnEzVhR5IwA=" 436 | }, 437 | "utf8": { 438 | "version": "2.1.2", 439 | "resolved": "https://registry.npmjs.org/utf8/-/utf8-2.1.2.tgz", 440 | "integrity": "sha1-H6DZJw6b6FDZsFAn9jUZv0ZFfZY=" 441 | }, 442 | "uuid": { 443 | "version": "2.0.3", 444 | "resolved": "https://registry.npmjs.org/uuid/-/uuid-2.0.3.tgz", 445 | "integrity": "sha1-Z+LoY3lyFVMN/zGOW/nc6/1Hsho=" 446 | } 447 | } 448 | } 449 | -------------------------------------------------------------------------------- /accountsWallet/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "accountswallet", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "", 10 | "license": "ISC", 11 | "dependencies": { 12 | "bip39": "^2.5.0", 13 | "ethereumjs-util": "^5.2.0", 14 | "ethereumjs-wallet": "^0.6.0" 15 | } 16 | } 17 | --------------------------------------------------------------------------------