18 |
24 |
25 |
保存你的私钥
26 |
27 | <%= privatekey %>
28 |
29 |
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/MyEtherWallet:07-解锁钱包账号姿势一:私钥/views/newaccount.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
18 |
发送以太币或者Token代币
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
请输入你的私钥
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
--------------------------------------------------------------------------------
/MyEtherWallet:08-解锁钱包账号姿势二:keystore+密码/controllers/account.js:
--------------------------------------------------------------------------------
1 | let { success, fail } = require("../utils/myUtils")
2 | let web3 = require("../utils/myUtils").getweb3()
3 | let fs = require("fs")
4 |
5 | //获取以太币余额
6 | async function getAccountBalance(address) {
7 | let balance = await web3.eth.getBalance(address)
8 | return web3.utils.fromWei(balance, "ether")
9 | }
10 |
11 | //配置返回给前端的数据,包含以太币的数据,还会有Token的数据
12 | async function setResponseData(account) {
13 | //获取账户余额
14 | let balance = await getAccountBalance(account.address)
15 | console.log(balance)
16 |
17 | let resData = success({
18 | balance: balance,
19 | address: account.address,
20 | privatekey: account.privateKey
21 | })
22 |
23 | //返回相应数据给前端
24 | return resData
25 | }
26 |
27 | module.exports = {
28 | unlockAccountWithPrivate: async (ctx) => {
29 | //1.获取私钥
30 | let privatekey = ctx.request.body.privatekey
31 | console.log(privatekey)
32 | //2.通过私钥解锁账户
33 | let account = web3.eth.accounts.privateKeyToAccount(privatekey)
34 | console.log(account)
35 | //3.将账户信息返回给前端
36 | ctx.body = await setResponseData(account)
37 | },
38 |
39 | unlockAccountWithKeystore: async (ctx) => {
40 | //1. 获取前端传递的数据,包括keystore、密码
41 | let password = ctx.request.body.password
42 | console.log(password)
43 | let keystore = ctx.request.files.file
44 | console.log(keystore)
45 | //2.读取缓存文件中keystore的数据
46 | let keystoreData = fs.readFileSync(keystore.path, "utf8")
47 | console.log(keystoreData)
48 | //3. 通过keystore和密码解锁账户
49 | let account = web3.eth.accounts.decrypt(JSON.parse(keystoreData), password)
50 | console.log(account)
51 | //4.将账户信息返回给前端
52 | ctx.body = await setResponseData(account)
53 | },
54 | }
--------------------------------------------------------------------------------
/MyEtherWallet:08-解锁钱包账号姿势二:keystore+密码/controllers/newAccount.js:
--------------------------------------------------------------------------------
1 | let web3 = require("../utils/myUtils").getweb3()
2 | let fs = require("fs")
3 | let path = require("path")
4 |
5 | module.exports = {
6 | //获取创建账号的页面
7 | newAccountHtml: async (ctx) => {
8 | await ctx.render("newaccount.html")
9 | },
10 |
11 | //创建账户的表单提交被触发的方法
12 | newAccount: async (ctx) => {
13 | console.log("password:", ctx.request.body.password)
14 |
15 | //1.创建钱包账号
16 | let account = web3.eth.accounts.create(ctx.request.body.password)
17 | console.log(account)
18 |
19 | //2.根据账号和密码生成keystore文件
20 | let keystore = account.encrypt(ctx.request.body.password)
21 | console.log(keystore)
22 |
23 | //3.将keysotr保存到文件
24 | let keystoreString = JSON.stringify(keystore)
25 | let time = new Date()
26 | let fileName = 'UTC--'+time.toISOString()+'--'+account.address.slice(2)
27 | console.log(fileName)
28 | let filePath = path.join(__dirname, "../static/keystore", fileName)
29 | fs.writeFileSync(filePath, keystoreString)
30 |
31 | //4.将账号信息返回给客户端
32 | await ctx.render("downloadkeystore.html", {
33 | "downloadurl":"/keystore/"+fileName,
34 | "privatekey":account.privateKey
35 | })
36 | }
37 | }
--------------------------------------------------------------------------------
/MyEtherWallet:08-解锁钱包账号姿势二:keystore+密码/controllers/transaction.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | transactionHtml: async (ctx) => {
3 | await ctx.render("transaction.html")
4 | },
5 | }
--------------------------------------------------------------------------------
/MyEtherWallet:08-解锁钱包账号姿势二:keystore+密码/index.js:
--------------------------------------------------------------------------------
1 |
2 | let koa = require("koa")
3 | //通过koa创建一个应用程序
4 | let app = new koa()
5 | //导入./router/route这个包,赋值给的router就是 ./router/router导出的数据
6 | let router = require("./router/router")
7 | let static = require("koa-static")
8 | let path = require("path")
9 | let views = require("koa-views")
10 | let koaBody = require("koa-body")
11 |
12 | app.use(async (ctx, next) => {
13 | console.log(`${ctx.method} ${ctx.url} ..........`)
14 | await next()
15 | })
16 |
17 | //针对于文件上传的时候,可以解析多个字段
18 | app.use(koaBody({multipart:true}))
19 | //注册静态文件的库到中间件
20 | app.use(static(path.join(__dirname, "static")))
21 | //注册模板引擎的库到中间件
22 | app.use(views(path.join(__dirname, "views"), {extension:"ejs", map:{html:"ejs"}}))
23 | app.use(router.routes())
24 |
25 | console.log("正在监听3000端口")
26 | app.listen(3000)
27 |
--------------------------------------------------------------------------------
/MyEtherWallet:08-解锁钱包账号姿势二:keystore+密码/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "4-wallet",
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": "^1.1.0",
13 | "ejs": "^2.6.1",
14 | "ethereumjs-tx": "^1.3.7",
15 | "koa": "^2.5.2",
16 | "koa-body": "^4.0.4",
17 | "koa-router": "^7.4.0",
18 | "koa-static": "^5.0.0",
19 | "koa-views": "^6.1.4",
20 | "web3": "^1.0.0-beta.35",
21 | "bip39": "^2.5.0",
22 | "ethereumjs-util": "^5.2.0",
23 | "ethereumjs-wallet": "^0.6.2"
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/MyEtherWallet:08-解锁钱包账号姿势二:keystore+密码/router/router.js:
--------------------------------------------------------------------------------
1 |
2 | let router = require("koa-router")()
3 | let newAccountController = require("../controllers/newAccount")
4 | let trasactionConytoller = require("../controllers/transaction")
5 | let accountController = require("../controllers/account")
6 |
7 |
8 | router.get("/", async (ctx) => {
9 | //重定向
10 | ctx.response.redirect("/account/new.html")
11 | })
12 |
13 | //获取创建钱包账户的页面
14 | router.get("/account/new.html", newAccountController.newAccountHtml)
15 | //提交创建钱包账户的表单
16 | router.post("/account/new", newAccountController.newAccount)
17 |
18 | //获取转账的页面
19 | router.get("/transaction.html", trasactionConytoller.transactionHtml)
20 |
21 | //通过私钥解锁账户
22 | router.post("/unlock/private", accountController.unlockAccountWithPrivate)
23 | //通过keystore解锁账户
24 | router.post("/unlock/keystore", accountController.unlockAccountWithKeystore)
25 |
26 | module.exports = router
27 |
--------------------------------------------------------------------------------
/MyEtherWallet:08-解锁钱包账号姿势二:keystore+密码/static/css/wallet.css:
--------------------------------------------------------------------------------
1 |
2 | #main{
3 | /*background-color: #8bc34a;*/
4 | margin: 100px 50px 50px 50px;
5 |
6 | }
7 | .error{
8 | color: red;
9 | }
10 | a{
11 | color: black;
12 | text-decoration: none;
13 | }
14 | a:hover{
15 | color: #666;
16 | }
17 | body{
18 | margin: 0px;
19 | }
20 | .global-color{
21 | color: #0abc9c;
22 | }
23 | a[class=button]{
24 | background-color: beige;
25 | padding: 2px 10px;
26 | border: 1px solid gray;
27 | }
28 |
29 | /*导航-------------------------------------------------------------------------------------------------------*/
30 | #nav{
31 | display: flex;
32 | justify-content: space-between;
33 | background-color: #0abc9c;
34 | position: fixed;
35 | top: 0px;
36 | left: 0px;
37 | right: 0px;
38 | }
39 | #nav li{
40 | display: inline-block;
41 | margin: 10px 2px;
42 | }
43 | #nav ul{
44 | padding: 0px;
45 | }
46 | #nav a{
47 | padding: 10px;
48 | font-size: 24px;
49 | }
50 | #nav-left{
51 | margin-left: 20px;
52 | }
53 | #nav-right{
54 | margin-right: 20px;
55 | }
56 |
--------------------------------------------------------------------------------
/MyEtherWallet:08-解锁钱包账号姿势二:keystore+密码/static/html/nav.html:
--------------------------------------------------------------------------------
1 |
2 |
18 |
24 |
25 |
保存你的私钥
26 |
27 | <%= privatekey %>
28 |
29 |
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/MyEtherWallet:08-解锁钱包账号姿势二:keystore+密码/views/newaccount.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
18 |
发送以太币或者Token代币
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
请输入你的私钥
33 |
34 |
35 |
36 |
37 |
38 |
39 |
请选择你的keystore文件
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
--------------------------------------------------------------------------------
/MyEtherWallet:09-解锁钱包账号姿势三:助记词/controllers/account.js:
--------------------------------------------------------------------------------
1 | let { success, fail } = require("../utils/myUtils")
2 | let web3 = require("../utils/myUtils").getweb3()
3 | let fs = require("fs")
4 | let menmonicModel = require("../models/mnemonic")
5 |
6 | //获取以太币余额
7 | async function getAccountBalance(address) {
8 | let balance = await web3.eth.getBalance(address)
9 | return web3.utils.fromWei(balance, "ether")
10 | }
11 |
12 | //配置返回给前端的数据,包含以太币的数据,还会有Token的数据
13 | async function setResponseData(account) {
14 | //获取账户余额
15 | let balance = await getAccountBalance(account.address)
16 | console.log(balance)
17 |
18 | let resData = success({
19 | balance: balance,
20 | address: account.address,
21 | privatekey: account.privateKey
22 | })
23 |
24 | //返回相应数据给前端
25 | return resData
26 | }
27 |
28 | module.exports = {
29 | unlockAccountWithPrivate: async (ctx) => {
30 | //1.获取私钥
31 | let privatekey = ctx.request.body.privatekey
32 | console.log(privatekey)
33 | //2.通过私钥解锁账户
34 | let account = web3.eth.accounts.privateKeyToAccount(privatekey)
35 | console.log(account)
36 | //3.将账户信息返回给前端
37 | ctx.body = await setResponseData(account)
38 | },
39 |
40 | unlockAccountWithKeystore: async (ctx) => {
41 | //1. 获取前端传递的数据,包括keystore、密码
42 | let password = ctx.request.body.password
43 | console.log(password)
44 | let keystore = ctx.request.files.file
45 | console.log(keystore)
46 | //2.读取缓存文件中keystore的数据
47 | let keystoreData = fs.readFileSync(keystore.path, "utf8")
48 | console.log(keystoreData)
49 | //3. 通过keystore和密码解锁账户
50 | let account = web3.eth.accounts.decrypt(JSON.parse(keystoreData), password)
51 | console.log(account)
52 | //4.将账户信息返回给前端
53 | ctx.body = await setResponseData(account)
54 | },
55 |
56 | unlockAccountWithMnemonic: async (ctx) => {
57 | //1.获取助记词
58 | let mnemonic = ctx.request.body.mnemonic
59 | console.log("mnemonic:",mnemonic)
60 |
61 | //2.通过助记词获取私钥
62 | /*
63 | 注意这里为了简化前端实现过程,故只获取了助记词的第一对公私钥,即"m/44'/60'/0'/0/0",在实际开发工作中需枚举路径"m/44'/60'/0'/0/0"的最后一位0,可继续取值为0,1,2,3,4……
64 | */
65 | let privatekey = menmonicModel.getPrivatekeyWithMnemonic(mnemonic, "m/44'/60'/0'/0/0")
66 | console.log("私钥:"+privatekey)
67 |
68 | //3.通过私钥解锁账户
69 | let account = web3.eth.accounts.privateKeyToAccount(privatekey)
70 | console.log("account:",account)
71 |
72 | //4.将账户信息返回给前端
73 | ctx.body = await setResponseData(account)
74 | },
75 | }
--------------------------------------------------------------------------------
/MyEtherWallet:09-解锁钱包账号姿势三:助记词/controllers/newAccount.js:
--------------------------------------------------------------------------------
1 | let web3 = require("../utils/myUtils").getweb3()
2 | let fs = require("fs")
3 | let path = require("path")
4 |
5 | module.exports = {
6 | //获取创建账号的页面
7 | newAccountHtml: async (ctx) => {
8 | await ctx.render("newaccount.html")
9 | },
10 |
11 | //创建账户的表单提交被触发的方法
12 | newAccount: async (ctx) => {
13 | console.log("password:", ctx.request.body.password)
14 |
15 | //1.创建钱包账号
16 | let account = web3.eth.accounts.create(ctx.request.body.password)
17 | console.log(account)
18 |
19 | //2.根据账号和密码生成keystore文件
20 | let keystore = account.encrypt(ctx.request.body.password)
21 | console.log(keystore)
22 |
23 | //3.将keysotr保存到文件
24 | let keystoreString = JSON.stringify(keystore)
25 | let time = new Date()
26 | let fileName = 'UTC--'+time.toISOString()+'--'+account.address.slice(2)
27 | console.log(fileName)
28 | let filePath = path.join(__dirname, "../static/keystore", fileName)
29 | fs.writeFileSync(filePath, keystoreString)
30 |
31 | //4.将账号信息返回给客户端
32 | await ctx.render("downloadkeystore.html", {
33 | "downloadurl":"/keystore/"+fileName,
34 | "privatekey":account.privateKey
35 | })
36 | }
37 | }
--------------------------------------------------------------------------------
/MyEtherWallet:09-解锁钱包账号姿势三:助记词/controllers/transaction.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | transactionHtml: async (ctx) => {
3 | await ctx.render("transaction.html")
4 | },
5 | }
--------------------------------------------------------------------------------
/MyEtherWallet:09-解锁钱包账号姿势三:助记词/index.js:
--------------------------------------------------------------------------------
1 |
2 | let koa = require("koa")
3 | //通过koa创建一个应用程序
4 | let app = new koa()
5 | //导入./router/route这个包,赋值给的router就是 ./router/router导出的数据
6 | let router = require("./router/router")
7 | let static = require("koa-static")
8 | let path = require("path")
9 | let views = require("koa-views")
10 | let koaBody = require("koa-body")
11 |
12 | app.use(async (ctx, next) => {
13 | console.log(`${ctx.method} ${ctx.url} ..........`)
14 | await next()
15 | })
16 |
17 | //针对于文件上传的时候,可以解析多个字段
18 | app.use(koaBody({multipart:true}))
19 | //注册静态文件的库到中间件
20 | app.use(static(path.join(__dirname, "static")))
21 | //注册模板引擎的库到中间件
22 | app.use(views(path.join(__dirname, "views"), {extension:"ejs", map:{html:"ejs"}}))
23 | app.use(router.routes())
24 |
25 | console.log("正在监听3000端口")
26 | app.listen(3000)
27 |
--------------------------------------------------------------------------------
/MyEtherWallet:09-解锁钱包账号姿势三:助记词/models/mnemonic.js:
--------------------------------------------------------------------------------
1 | let bip39 = require('bip39')
2 | let hdkey = require('ethereumjs-wallet/hdkey')
3 | let util = require('ethereumjs-util')
4 |
5 | module.exports = {
6 | getPrivatekeyWithMnemonic: (mnemonic, derivePath) => {
7 | //将助记词转成seed
8 | let seed = bip39.mnemonicToSeed(mnemonic)
9 | //通过hdkey将seed生成HDWallet
10 | let hdWallet = hdkey.fromMasterSeed(seed)
11 | //生成钱包中在m/44'/60'/0'/0/0路径的第一个帐户的keypair。
12 | let key = hdWallet.derivePath(derivePath)
13 | //获取私钥
14 | return util.bufferToHex(key._hdkey._privateKey)
15 | }
16 | }
--------------------------------------------------------------------------------
/MyEtherWallet:09-解锁钱包账号姿势三:助记词/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "4-wallet",
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": "^1.1.0",
13 | "ejs": "^2.6.1",
14 | "ethereumjs-tx": "^1.3.7",
15 | "koa": "^2.5.2",
16 | "koa-body": "^4.0.4",
17 | "koa-router": "^7.4.0",
18 | "koa-static": "^5.0.0",
19 | "koa-views": "^6.1.4",
20 | "web3": "^1.0.0-beta.35",
21 | "bip39": "^2.5.0",
22 | "ethereumjs-util": "^5.2.0",
23 | "ethereumjs-wallet": "^0.6.2"
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/MyEtherWallet:09-解锁钱包账号姿势三:助记词/router/router.js:
--------------------------------------------------------------------------------
1 |
2 | let router = require("koa-router")()
3 | let newAccountController = require("../controllers/newAccount")
4 | let trasactionConytoller = require("../controllers/transaction")
5 | let accountController = require("../controllers/account")
6 |
7 |
8 | router.get("/", async (ctx) => {
9 | //重定向
10 | ctx.response.redirect("/account/new.html")
11 | })
12 |
13 | //获取创建钱包账户的页面
14 | router.get("/account/new.html", newAccountController.newAccountHtml)
15 | //提交创建钱包账户的表单
16 | router.post("/account/new", newAccountController.newAccount)
17 |
18 | //获取转账的页面
19 | router.get("/transaction.html", trasactionConytoller.transactionHtml)
20 |
21 | //通过私钥解锁账户
22 | router.post("/unlock/private", accountController.unlockAccountWithPrivate)
23 | //通过keystore解锁账户
24 | router.post("/unlock/keystore", accountController.unlockAccountWithKeystore)
25 | //通过助记词解锁账户
26 | router.post("/unlock/mnemonic", accountController.unlockAccountWithMnemonic)
27 |
28 | module.exports = router
29 |
--------------------------------------------------------------------------------
/MyEtherWallet:09-解锁钱包账号姿势三:助记词/static/css/wallet.css:
--------------------------------------------------------------------------------
1 |
2 | #main{
3 | /*background-color: #8bc34a;*/
4 | margin: 100px 50px 50px 50px;
5 |
6 | }
7 | .error{
8 | color: red;
9 | }
10 | a{
11 | color: black;
12 | text-decoration: none;
13 | }
14 | a:hover{
15 | color: #666;
16 | }
17 | body{
18 | margin: 0px;
19 | }
20 | .global-color{
21 | color: #0abc9c;
22 | }
23 | a[class=button]{
24 | background-color: beige;
25 | padding: 2px 10px;
26 | border: 1px solid gray;
27 | }
28 |
29 | /*导航-------------------------------------------------------------------------------------------------------*/
30 | #nav{
31 | display: flex;
32 | justify-content: space-between;
33 | background-color: #0abc9c;
34 | position: fixed;
35 | top: 0px;
36 | left: 0px;
37 | right: 0px;
38 | }
39 | #nav li{
40 | display: inline-block;
41 | margin: 10px 2px;
42 | }
43 | #nav ul{
44 | padding: 0px;
45 | }
46 | #nav a{
47 | padding: 10px;
48 | font-size: 24px;
49 | }
50 | #nav-left{
51 | margin-left: 20px;
52 | }
53 | #nav-right{
54 | margin-right: 20px;
55 | }
56 |
--------------------------------------------------------------------------------
/MyEtherWallet:09-解锁钱包账号姿势三:助记词/static/html/nav.html:
--------------------------------------------------------------------------------
1 |
2 |
18 |
24 |
25 |
保存你的私钥
26 |
27 | <%= privatekey %>
28 |
29 |
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/MyEtherWallet:09-解锁钱包账号姿势三:助记词/views/newaccount.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
18 |
发送以太币或者Token代币
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
请输入你的私钥
33 |
34 |
35 |
36 |
37 |
38 |
39 |
请选择你的keystore文件
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
请输入你的助记词
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
--------------------------------------------------------------------------------
/MyEtherWallet:10-浅出:如何实现以太币转账/controllers/account.js:
--------------------------------------------------------------------------------
1 | let { success, fail } = require("../utils/myUtils")
2 | let web3 = require("../utils/myUtils").getweb3()
3 | let fs = require("fs")
4 | let menmonicModel = require("../models/mnemonic")
5 |
6 | //获取以太币余额
7 | async function getAccountBalance(address) {
8 | let balance = await web3.eth.getBalance(address)
9 | return web3.utils.fromWei(balance, "ether")
10 | }
11 |
12 | //配置返回给前端的数据,包含以太币的数据,还会有Token的数据
13 | async function setResponseData(account) {
14 | //获取账户余额
15 | let balance = await getAccountBalance(account.address)
16 | console.log(balance)
17 |
18 | let resData = success({
19 | balance: balance,
20 | address: account.address,
21 | privatekey: account.privateKey
22 | })
23 |
24 | //返回相应数据给前端
25 | return resData
26 | }
27 |
28 | module.exports = {
29 | unlockAccountWithPrivate: async (ctx) => {
30 | //1.获取私钥
31 | let privatekey = ctx.request.body.privatekey
32 | console.log(privatekey)
33 | //2.通过私钥解锁账户
34 | let account = web3.eth.accounts.privateKeyToAccount(privatekey)
35 | console.log(account)
36 | //3.将账户信息返回给前端
37 | ctx.body = await setResponseData(account)
38 | },
39 |
40 | unlockAccountWithKeystore: async (ctx) => {
41 | //1. 获取前端传递的数据,包括keystore、密码
42 | let password = ctx.request.body.password
43 | console.log(password)
44 | let keystore = ctx.request.files.file
45 | console.log(keystore)
46 | //2.读取缓存文件中keystore的数据
47 | let keystoreData = fs.readFileSync(keystore.path, "utf8")
48 | console.log(keystoreData)
49 | //3. 通过keystore和密码解锁账户
50 | let account = web3.eth.accounts.decrypt(JSON.parse(keystoreData), password)
51 | console.log(account)
52 | //4.将账户信息返回给前端
53 | ctx.body = await setResponseData(account)
54 | },
55 |
56 | unlockAccountWithMnemonic: async (ctx) => {
57 | //1.获取助记词
58 | let mnemonic = ctx.request.body.mnemonic
59 | console.log("mnemonic:",mnemonic)
60 |
61 | //2.通过助记词获取私钥
62 | /*
63 | 注意这里为了简化前端实现过程,故只获取了助记词的第一对公私钥,即"m/44'/60'/0'/0/0",在实际开发工作中需枚举路径"m/44'/60'/0'/0/0"的最后一位0,可继续取值为0,1,2,3,4……
64 | */
65 | let privatekey = menmonicModel.getPrivatekeyWithMnemonic(mnemonic, "m/44'/60'/0'/0/0")
66 | console.log("私钥:"+privatekey)
67 |
68 | //3.通过私钥解锁账户
69 | let account = web3.eth.accounts.privateKeyToAccount(privatekey)
70 | console.log("account:",account)
71 |
72 | //4.将账户信息返回给前端
73 | ctx.body = await setResponseData(account)
74 | },
75 | }
--------------------------------------------------------------------------------
/MyEtherWallet:10-浅出:如何实现以太币转账/controllers/newAccount.js:
--------------------------------------------------------------------------------
1 | let web3 = require("../utils/myUtils").getweb3()
2 | let fs = require("fs")
3 | let path = require("path")
4 |
5 | module.exports = {
6 | //获取创建账号的页面
7 | newAccountHtml: async (ctx) => {
8 | await ctx.render("newaccount.html")
9 | },
10 |
11 | //创建账户的表单提交被触发的方法
12 | newAccount: async (ctx) => {
13 | console.log("password:", ctx.request.body.password)
14 |
15 | //1.创建钱包账号
16 | let account = web3.eth.accounts.create(ctx.request.body.password)
17 | console.log(account)
18 |
19 | //2.根据账号和密码生成keystore文件
20 | let keystore = account.encrypt(ctx.request.body.password)
21 | console.log(keystore)
22 |
23 | //3.将keysotr保存到文件
24 | let keystoreString = JSON.stringify(keystore)
25 | let time = new Date()
26 | let fileName = 'UTC--'+time.toISOString()+'--'+account.address.slice(2)
27 | console.log(fileName)
28 | let filePath = path.join(__dirname, "../static/keystore", fileName)
29 | fs.writeFileSync(filePath, keystoreString)
30 |
31 | //4.将账号信息返回给客户端
32 | await ctx.render("downloadkeystore.html", {
33 | "downloadurl":"/keystore/"+fileName,
34 | "privatekey":account.privateKey
35 | })
36 | }
37 | }
--------------------------------------------------------------------------------
/MyEtherWallet:10-浅出:如何实现以太币转账/controllers/transaction.js:
--------------------------------------------------------------------------------
1 | let { success, fail } = require("../utils/myUtils")
2 | let web3 = require("../utils/myUtils").getweb3()
3 |
4 | module.exports = {
5 | transactionHtml: async (ctx) => {
6 | await ctx.render("transaction.html")
7 | },
8 |
9 | sendTransaction: async (ctx) => {
10 | let { fromaddress, toaddress, number, privatekey } = ctx.request.body
11 | console.log(JSON.stringify(ctx.request.body))
12 |
13 | let nonce = await web3.eth.getTransactionCount(fromaddress)
14 | let gasPrice = await web3.eth.getGasPrice()
15 | let balance = await web3.utils.toWei(number)
16 |
17 | var rawTx = {
18 | nonce: nonce,
19 | gasPrice: gasPrice,
20 | to: toaddress,
21 | value: balance,
22 | data: '0x00'//转Token代币会用到的一个字段
23 | }
24 | //需要将交易的数据进行预估gas计算,然后将gas值设置到数据参数中
25 | let gas = await web3.eth.estimateGas(rawTx)
26 | rawTx.gas = gas
27 |
28 | var Tx = require('ethereumjs-tx');
29 | var tx = new Tx(rawTx);
30 | var privateKey = new Buffer(privatekey.slice(2), 'hex')
31 | tx.sign(privateKey);
32 |
33 | var serializedTx = tx.serialize();
34 | let responseData;
35 | await web3.eth.sendSignedTransaction('0x' + serializedTx.toString('hex'), function(err, data) {
36 | console.log(err)
37 | console.log(data)
38 |
39 | if (err) {
40 | responseData = fail(err)
41 | }
42 | })
43 | .then(function(data) {
44 | console.log(data)
45 | if (data) {
46 | responseData = success({
47 | "blockHash":data.blockHash,
48 | "transactionHash":data.transactionHash
49 | })
50 | } else {
51 | responseData = fail("交易失败")
52 | }
53 | })
54 |
55 | ctx.body = responseData
56 | },
57 | }
--------------------------------------------------------------------------------
/MyEtherWallet:10-浅出:如何实现以太币转账/index.js:
--------------------------------------------------------------------------------
1 |
2 | let koa = require("koa")
3 | //通过koa创建一个应用程序
4 | let app = new koa()
5 | //导入./router/route这个包,赋值给的router就是 ./router/router导出的数据
6 | let router = require("./router/router")
7 | let static = require("koa-static")
8 | let path = require("path")
9 | let views = require("koa-views")
10 | let koaBody = require("koa-body")
11 |
12 | app.use(async (ctx, next) => {
13 | console.log(`${ctx.method} ${ctx.url} ..........`)
14 | await next()
15 | })
16 |
17 | //针对于文件上传的时候,可以解析多个字段
18 | app.use(koaBody({multipart:true}))
19 | //注册静态文件的库到中间件
20 | app.use(static(path.join(__dirname, "static")))
21 | //注册模板引擎的库到中间件
22 | app.use(views(path.join(__dirname, "views"), {extension:"ejs", map:{html:"ejs"}}))
23 | app.use(router.routes())
24 |
25 | console.log("正在监听3000端口")
26 | app.listen(3000)
27 |
--------------------------------------------------------------------------------
/MyEtherWallet:10-浅出:如何实现以太币转账/models/mnemonic.js:
--------------------------------------------------------------------------------
1 | let bip39 = require('bip39')
2 | let hdkey = require('ethereumjs-wallet/hdkey')
3 | let util = require('ethereumjs-util')
4 |
5 | module.exports = {
6 | getPrivatekeyWithMnemonic: (mnemonic, derivePath) => {
7 | //将助记词转成seed
8 | let seed = bip39.mnemonicToSeed(mnemonic)
9 | //通过hdkey将seed生成HDWallet
10 | let hdWallet = hdkey.fromMasterSeed(seed)
11 | //生成钱包中在m/44'/60'/0'/0/0路径的第一个帐户的keypair。
12 | let key = hdWallet.derivePath(derivePath)
13 | //获取私钥
14 | return util.bufferToHex(key._hdkey._privateKey)
15 | }
16 | }
--------------------------------------------------------------------------------
/MyEtherWallet:10-浅出:如何实现以太币转账/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "4-wallet",
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": "^1.1.0",
13 | "ejs": "^2.6.1",
14 | "ethereumjs-tx": "^1.3.7",
15 | "koa": "^2.5.2",
16 | "koa-body": "^4.0.4",
17 | "koa-router": "^7.4.0",
18 | "koa-static": "^5.0.0",
19 | "koa-views": "^6.1.4",
20 | "web3": "^1.0.0-beta.35",
21 | "bip39": "^2.5.0",
22 | "ethereumjs-util": "^5.2.0",
23 | "ethereumjs-wallet": "^0.6.2"
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/MyEtherWallet:10-浅出:如何实现以太币转账/router/router.js:
--------------------------------------------------------------------------------
1 |
2 | let router = require("koa-router")()
3 | let newAccountController = require("../controllers/newAccount")
4 | let trasactionConytoller = require("../controllers/transaction")
5 | let accountController = require("../controllers/account")
6 |
7 |
8 | router.get("/", async (ctx) => {
9 | //重定向
10 | ctx.response.redirect("/account/new.html")
11 | })
12 |
13 | //获取创建钱包账户的页面
14 | router.get("/account/new.html", newAccountController.newAccountHtml)
15 | //提交创建钱包账户的表单
16 | router.post("/account/new", newAccountController.newAccount)
17 |
18 | //获取转账的页面
19 | router.get("/transaction.html", trasactionConytoller.transactionHtml)
20 | //发送转账交易
21 | router.post("/transaction/send", trasactionConytoller.sendTransaction)
22 |
23 | //通过私钥解锁账户
24 | router.post("/unlock/private", accountController.unlockAccountWithPrivate)
25 | //通过keystore解锁账户
26 | router.post("/unlock/keystore", accountController.unlockAccountWithKeystore)
27 | //通过助记词解锁账户
28 | router.post("/unlock/mnemonic", accountController.unlockAccountWithMnemonic)
29 |
30 | module.exports = router
31 |
--------------------------------------------------------------------------------
/MyEtherWallet:10-浅出:如何实现以太币转账/static/css/wallet.css:
--------------------------------------------------------------------------------
1 |
2 | #main{
3 | /*background-color: #8bc34a;*/
4 | margin: 100px 50px 50px 50px;
5 |
6 | }
7 | .error{
8 | color: red;
9 | }
10 | a{
11 | color: black;
12 | text-decoration: none;
13 | }
14 | a:hover{
15 | color: #666;
16 | }
17 | body{
18 | margin: 0px;
19 | }
20 | .global-color{
21 | color: #0abc9c;
22 | }
23 | a[class=button]{
24 | background-color: beige;
25 | padding: 2px 10px;
26 | border: 1px solid gray;
27 | }
28 |
29 | /*导航-------------------------------------------------------------------------------------------------------*/
30 | #nav{
31 | display: flex;
32 | justify-content: space-between;
33 | background-color: #0abc9c;
34 | position: fixed;
35 | top: 0px;
36 | left: 0px;
37 | right: 0px;
38 | }
39 | #nav li{
40 | display: inline-block;
41 | margin: 10px 2px;
42 | }
43 | #nav ul{
44 | padding: 0px;
45 | }
46 | #nav a{
47 | padding: 10px;
48 | font-size: 24px;
49 | }
50 | #nav-left{
51 | margin-left: 20px;
52 | }
53 | #nav-right{
54 | margin-right: 20px;
55 | }
56 |
--------------------------------------------------------------------------------
/MyEtherWallet:10-浅出:如何实现以太币转账/static/html/nav.html:
--------------------------------------------------------------------------------
1 |
2 |