本文写于2018.12
https://anders.com/blockchain/blockchain.html
请先安装geth, 并将geth添加到环境变量
1.在某个目录下, 这里以C:\Users\yqq\eth\persondata
为例, 创建创世区块信息 文件genesis.json, 内容如下:
{
"config": {
"chainId": 15,
"homesteadBlock": 0,
"eip155Block": 0,
"eip158Block": 0
},
"coinbase": "0x0000000000000000000000000000000000000000",
"difficulty": "0x40000",
"extraData": "",
"gasLimit": "0xffffffff",
"nonce": "0x0000000000000042",
"mixhash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"timestamp": "0x00",
"alloc": {
}
}
2.初始化 geth --datadir node1 init genesis.json
, 特别注意: 每创建一个新节点, 必须先初始化, 否则后面会各种坑!!!
C:\Users\yqq\eth\persondata>geth --datadir node1 init genesis.json
INFO [12-17|23:57:12.910] Maximum peer count ETH=25 LES=0 total=25
INFO [12-17|23:57:12.947] Allocated cache and file handles database=C:\\Users\\yqq\\eth\\persondata\\node1\\geth\\chaindata cache=16 handles=16
INFO [12-17|23:57:12.981] Writing custom genesis block
INFO [12-17|23:57:12.984] Persisted trie from memory database nodes=0 size=0.00B time=0s gcnodes=0 gcsize=0.00B gctime=0s livenodes=1 livesize=0.00B
INFO [12-17|23:57:12.990] Successfully wrote genesis state database=chaindata hash=a0e580…a5e82e
INFO [12-17|23:57:12.998] Allocated cache and file handles database=C:\\Users\\yqq\\eth\\persondata\\node1\\geth\\lightchaindata cache=16 handles=16
INFO [12-17|23:57:13.022] Writing custom genesis block
INFO [12-17|23:57:13.027] Persisted trie from memory database nodes=0 size=0.00B time=0s gcnodes=0 gcsize=0.00B gctime=0s livenodes=1 livesize=0.00B
INFO [12-17|23:57:13.031] Successfully wrote genesis state database=lightchaindata hash=a0e580…a5e82e
3.打开一个cmd窗口, 启动服务器geth --datadir node1 --ipcpath node1/geth.ipc --networkid 55 --port 10009 --nodiscover
--datadir 指定数据存放目录
--ipcpath 指定ipc文件存放目录, 控制台连接时需要用到ipc文件
--networkid 指定网络id, 如果要搭建多个节点, 必须使用同一个networkid, 否则, admin.addPeer会失败(这是我踩过的坑!!)
--port 指定端口, 多节点必须使用不同的端口, 否则会冲突
--nodiscover 防止被网络上其他人发现, 但是可以通过 admin.addPeer进行添加对端节点
4.打开另外一个cmd窗口进行连接服务器 geth attach ipc:\\.\pipe\node1\geth.ipc
> eth.accounts
[]
> personal.newAccount("111") //创建用户, 密码是 "111"
"0xe41aa565490e3d7971c25c1c1218e61a48455c92"
>
> personal.newAccount("111")
"0x808fd82922556f0148787e3663ed0181e65c0f61"
>
>
> eth.accounts //查看用户
["0xe41aa565490e3d7971c25c1c1218e61a48455c92", "0x808fd82922556f0148787e3663ed0181e65c0f61"]
>
>
> eth.getBalance(eth.accounts[0])
0
>
> eth.coinbase //查看挖矿人
"0xe41aa565490e3d7971c25c1c1218e61a48455c92"
>
> miner.start(5) //开启5个线程, 开始挖矿, 此时服务端开始挖矿 , 耐心等待两分钟
//Generating DAG in progress epoch=1 percentage=XXX , 当达到100%时就可以开始挖到矿了
null
> miner.stop()
null
> eth.getBalance(eth.accounts[0])
25000000000000000000
>
> eth.blockNumber
5
>
> eth.sendTransaction({from:eth.accounts[0], to:eth.accounts[1], value:web3.toWei(2, "ether")}) //这里需要解锁
Error: authentication needed: password or unlock
at web3.js:3143:20
at web3.js:6347:15
at web3.js:5081:36
at <anonymous>:1:1
> personal.unlockAccount(eth.accounts[0])
Unlock account 0xe41aa565490e3d7971c25c1c1218e61a48455c92
Passphrase: //这里输入密码 111 即可
true
> eth.sendTransaction({from:eth.accounts[0], to:eth.accounts[1], value:web3.toWei(2, "ether")})
"0x7973906595c5b3bd066c126f7f966a4d94b36c0383fc5050a85239af05ccf80a"
>
> txpool.status //查看交易池中的状态, 可以看到一个交易在pending
{
pending: 1,
queued: 0
}
>
> miner.setEtherbase(eth.accounts[1]) //设置挖矿用户
true
> miner.start(5) //开始挖矿, 稍微等待, 等服务器显示挖到了矿在停止挖矿
> eth.blockNumber
9
> eth.blockNumber
9
> eth.blockNumber
10
> miner.stop()
null
> eth.getBalance(eth.accounts[1])
52000021000000000000
> web3.fromWei( eth.getBalance(eth.accounts[1]), "ether")
52.000021 挖矿所得 + 交易手续费
>
>
5.总结: 经过上面几步我们实现了单个节点的挖矿+转账交易.
在上面的基础上, 我们在新建一个节点node2, 命令如下:
1.初始化(新建节点前必须初始化!!): geth --datadir node2 init genesis.json
2.启动服务端: geth --datadir node2 --ipcpath node2/geth.ipc --networkid 55 --port 10010 --nodiscover //注意: --networkid 必须与node1节点保持一致!!
3.打开另外的cmd, 进行连接服务端: geth attach ipc:\\.\pipe\node2\geth.ipc
node1控制台
> admin.nodeInfo.enode //查看本节点地址
"enode://0e83568d7f443764ac036080f694c1278b3df6d1f507616db91fabfc4c6ce080901a9fc0ab3b9c36757b7d2743184d8bf8c0dea918988686c7447cb5e1d2ae51@163.125.179.72:10009?discport=0"
node2控制台
> personal.newAccount("111")
"0x48e33e5121497eda40697341e405d4adb8b60984"
>
> eth.coinbase
"0xd18d089990d8d6e8aeeb3965edac1df740fb749e"
>
> admin.peers
[]
>
> admin.nodeInfo
{
enode: "enode://72634a41f51c8c75650ec5e416daa5578edb98592ee2898cde6ac1ca50c44b14016bf0a353dbd85cf1ef42c841a06052f5d253de329c2bf5324d211d8756d0c0@163.125.179.72:10010?discport=0",
enr: "0xf88fb8408b691c58760e023c9ab87efcec4bd9582c76b2a8f948444bf2262d4f0b0143b638d42ece43c951ccc910c3946222ead456956514e52142890ca4101af375e3f60283636170c6c5836574683f82696482763482697084a37db34889736563703235366b31a10272634a41f51c8c75650ec5e416daa5578edb98592ee2898cde6ac1ca50c44b148374637082271a",
id: "11ef6d692fc5ce19e67767bc9661df9088031254304064808e8af5e00e3f2392",
ip: "163.125.179.72",
listenAddr: "[::]:10010",
name: "Geth/v1.8.20-stable-24d727b6/windows-amd64/go1.11.2",
ports: {
discovery: 0,
listener: 10010
},
protocols: {
eth: {
config: {
chainId: 15,
eip150Hash: "0x0000000000000000000000000000000000000000000000000000000000000000",
eip155Block: 0,
eip158Block: 0,
homesteadBlock: 0
},
difficulty: 262144,
genesis: "0xa0e580c6769ac3dd80894b2a256164a76b796839d2eb7f799ef6b9850ea5e82e",
head: "0xa0e580c6769ac3dd80894b2a256164a76b796839d2eb7f799ef6b9850ea5e82e",
network: 55
}
}
}
>
>
> admin.addPeer("enode://0e83568d7f443764ac036080f694c1278b3df6d1f507616db91fabfc4c6ce080901a9fc0ab3b9c36757b7d2743184d8bf8c0dea918988686c7447cb5e1d2ae51@163.125.179.72:10009?discport=0") //添加node1
true
>
> admin.peers //可以看到, 已经添加成功
[{
caps: ["eth/63"],
enode: "enode://0e83568d7f443764ac036080f694c1278b3df6d1f507616db91fabfc4c6ce080901a9fc0ab3b9c36757b7d2743184d8bf8c0dea918988686c7447cb5e1d2ae51@163.125.179.72:10009?discport=0",
id: "6fb555a6ec8b19e3c3c1a4dd2b8a15e6f50dede36dedec6dea4bb905fd082f86", //node1的id
name: "Geth/v1.8.20-stable-24d727b6/windows-amd64/go1.11.2",
network: {
inbound: false,
localAddress: "192.168.10.126:56674",
remoteAddress: "163.125.179.72:10009",
static: true,
trusted: false
},
protocols: {
eth: {
difficulty: 3947161,
head: "0x15df03da3ca1c75857fee397d768bb4dab3d924009984020a53fa4b642676ee5",
version: 63
}
}
}]
>
node1 eth.accounts[0] 向node2 eth.accounts[0]转账, node2 eth.accounts[1] 负责挖矿.
node1
> eth.getBalance(user1)
ReferenceError: 'user1' is not defined
at <anonymous>:1:16
> eth.getBalance(eth.accounts[0])
22999979000000000000
>
>
> eth.sendTransaction({from:eth.accounts[0], to:"0xd18d089990d8d6e8aeeb3965edac1df740fb749e", value:web3.toWei(15, "ether")})
Error: authentication needed: password or unlock
at web3.js:3143:20
at web3.js:6347:15
at web3.js:5081:36
at <anonymous>:1:1
> personal.unlockAccount(eth.accounts[0])
Unlock account 0xe41aa565490e3d7971c25c1c1218e61a48455c92
Passphrase: //输入密码, 进行解锁
true
> eth.sendTransaction({from:eth.accounts[0], to:"0xd18d089990d8d6e8aeeb3965edac1df740fb749e", value:web3.toWei(15, "ether")})
"0xb7e392e0f8edb744f9c15716e8a4f5fef1c6ce944284e7f6a23abd875b09eb75"
> txpool.status
{
pending: 1, //交易pending中
queued: 0
}
> txpool.status
{
pending: 0, //交易完成
queued: 0
}
> eth.getBalance(eth.accounts[0])
7999958000000000000 //减少了 15eth + 一些手续费
>
node2
> admin.peers //查看对端节点信息
[{
caps: ["eth/63"],
enode: "enode://0e83568d7f443764ac036080f694c1278b3df6d1f507616db91fabfc4c6ce080901a9fc0ab3b9c36757b7d2743184d8bf8c0dea918988686c7447cb5e1d2ae51@163.125.179.72:10009?discport=0",
id: "6fb555a6ec8b19e3c3c1a4dd2b8a15e6f50dede36dedec6dea4bb905fd082f86", //节点1 的信息
name: "Geth/v1.8.20-stable-24d727b6/windows-amd64/go1.11.2",
network: {
inbound: false,
localAddress: "192.168.10.126:56674",
remoteAddress: "163.125.179.72:10009",
static: true,
trusted: false
},
protocols: {
eth: {
difficulty: 3947161,
head: "0x15df03da3ca1c75857fee397d768bb4dab3d924009984020a53fa4b642676ee5",
version: 63
}
}
}]
>
> eth.getBalance( eth.accounts[0])
0
> eth.accounts[0]
"0xd18d089990d8d6e8aeeb3965edac1df740fb749e"
>
> txpool.status
{
pending: 1, //node1的转账交易, 已经处于 pending状态, 等待矿工挖矿
queued: 0
}
>
>
> miner.setEtherbase(eth.accounts[1]) //设置挖矿人
true
>
> miner.start(5) //开始挖矿(将交易打包), 指定开启5个线程
null
> miner.stop() //停止挖矿
null
>
> eth.getBalance(eth.accounts[0])
15000000000000000000 //已经收到node1第0个用户转来的钱
> eth.getBalance(eth.accounts[1])
70000021000000000000 //node2节点 挖矿 + 一笔交易手续费
>
Generating DAG in progress epoch=1 percentage=XXX
中的percentage为100时, 才真正挖到了矿. miner.stop() 返回null, 其实也需要等待一下才真正停止挖矿.--networkid
设置的不一样, 导致 admin.addPeer()时总是不成功!!\\.\\pipe\\你指定目录
请参考上面的例子; linux实在 --datadir目录下geth.ipc
1.关闭Mist, 在一个新目录(这里以C:\Windows\System32\cmd.exe
为例)初始化一个新的节点
C:\Users\yqq\eth\gethmist>geth --datadir nodeA init genesis.json
2.启动节点服务端, 启动的时候指定创建ipc的路径, Mist会使用这个ipc(即\\.\pipe\geth.ipc
)与当前节点相连
C:\Users\yqq\eth\gethmist>geth --datadir nodeA --networkid 55 --port 10999 --nodiscover --ipcpath \\.\pipe\geth.ipc
3.启动客户端console , 连接nodeA
C:\Users\yqq\eth\gethmist>geth attach ipc:\\.\pipe\geth.ipc //指定ipc, 连接服务端
Welcome to the Geth JavaScript console!
instance: Geth/v1.8.20-stable-24d727b6/windows-amd64/go1.11.2
modules: admin:1.0 debug:1.0 eth:1.0 ethash:1.0 miner:1.0 net:1.0 personal:1.0 rpc:1.0 txpool:1.0 web3:1.0
>
> eth.accounts
[]
> personal.newAccount("111") //创建一个用户
"0xc1b58d997c122208103a74aa3b12a4a9c73cf4e7"
>
4.启动Mist, 设置网络是 Rinkeby, 如果本来是Rinkeby就不需要设置(Mist默认是Rinbkey,可以根据自己需要设置其他网络). 当Mist启动后, 可以看到刚创建的用户了, 如下图:
5.启动C:\Users\yqq\eth\persondata
中的node1节点
geth --datadir node1 --networkid 55 --nodiscover --port 10333 --ipcpath node1\geth.ipc
geth attach ipc:\\.\pipe\node1\geth.ipc //启动console
在nodeA中添加node1为对端节点, 然后, 从nodeA的账户想node1节点账户转账, 并开始挖矿, 转账结果如下:
\\.\pipe\geth.ipc
, 所以, 在启动nodeA节点时需要指定 --ipcpath \\.\pipe\geth.ipc
文章浏览阅读1w次,点赞7次,收藏62次。什么是裂脑?当两台高可用服务器在指定的时间内,无法互相检测到对方心跳而各自启动故障转移功能,取得了资源以及服务的所有权,而此时的两台高可用服务器对都还活着并作正常运行,这样就会导致同一个服务在两端同时启动而发生冲突的严重问题,最严重的就是两台主机同时占用一个VIP的地址(类似双端导入概念),当用户写入数据的时候可能会分别写入到两端,这样可能会导致服务器两端的数据不一致或造成数据的丢失,这种情况..._集群脑裂
文章浏览阅读771次。ezCM直至比赛结束,这道题目都是 0 解题,一方面是因为比赛时间较短,另一方面还是因为这道题目较难,考察了不常见的椭圆曲线算法(ECC),大大增加了对做题者的要求。题目信息题目是使用 Golang 来编写的一个 CrackMe 程序,程序内符号没有被去除,所以这篇文章就不会讲解如何恢复 Golang 程序符号,另外 IDA Pro 7.6 已经支持 Golang 程序分析,打开就可以直接恢复被去除的符号信息。题目要求打开一个 KeyFile ,并且通过读取其文件的内容来注册程序,我们要做的就是通_ezcm
文章浏览阅读284次。任务四MySQL实战_gbdt 即利用线性搜索估计叶节点区域的值,使损失函数极小化
文章浏览阅读1w次。Lua:Module ‘Bit’ not found/no file ./bit.so[已解决]问题描述:问题解决:问题描述:执行lua程序时报错如下:Module ‘Bit’ not found/no file ./bit.so问题解决:在bitop下载最新包:http://bitop.luajit.org/download.html下载到本地后解压:然后在本机ma..._module 'bit' not found:
文章浏览阅读3.5k次,点赞3次,收藏15次。ESP32调试-快速入门_esp32调试
文章浏览阅读2w次,点赞184次,收藏973次。一个工程师能走多远,取决于他对数学工具掌握的深度。_卡尔曼滤波 精髓
文章浏览阅读71次。在java中,当对象不存在任何引用的时候,它就成为了垃圾,如果不及时回收,释放内存,垃圾便会越积越多,最终out of memory!,jvm也就结束运行了。有人疑惑了:我们平时编码时并没有显示的进行对象的销毁,怎么程序跑的好好的?这就要谈到今天的主角,jvm的守护式线程GC,GC是一个垃圾回收器,按照一定的算法,不定时的进行垃圾对象的释放,同时进行内存碎片的整理...
文章浏览阅读2.1k次。命令go env用于打印Go语言的环境信息。其中的一些信息我们在之前已经多次提及,但是却没有进行详细的说明。在本小节,我们会对这些信息进行深入介绍。我们先来看一看go env命令情况下都会打印出哪些Go语言通用环境信息。go env命令可打印出的Go语言通用环境信息> runtime 包 包含与 Go 的运行时系统交互的操作,例如控制 goroutines 的函数。 > 也包含 reflect 包使用的低级别的类型信息;查看 reflect 的文档了解运行时类型的可编程接口。 _go env
文章浏览阅读129次。本文件涵盖用于建筑的实木板、胶合板、OSB、树脂或水泥粘合刨花板(刨花板)、湿加工纤维板(硬纸板、中板、软纸板)和干加工纤维板(MDF)形式的人造板。它们可能含有化学药剂,以改善其对火灾的反应和抵抗生物攻击的能力,例如真菌和昆虫。人造板CE认证(欧盟强制认证)-简介在欧盟市场“CE”标志属强制性认证标志,以表明产品符合欧盟《技术协调与标准化新方法》指令的基本要求。这是欧盟法律对产品提出的一种强制性要求。在矿棉上加贴CE标志不但可以证明其产品符合建筑产品指令(CPR 305/2011/EU_mdf ce 认证
文章浏览阅读1.4k次。在本文中,我们介绍了一些使用IntelliJ IDEA的技巧和入门教程,包括安装和配置IDEA、创建和打开项目、使用代码编辑器、调试代码、使用版本控制、使用插件和扩展、以及使用快捷键等。这些技巧和教程将帮助你更高效地使用IDEA,并提高你的开发效率和代码质量。_idea编辑线上代码
文章浏览阅读2.8k次,点赞8次,收藏10次。mysql8.0 主从复制 Authentication plugin 'caching_sha2_password' Error_code: MY-002061解决办法_error_code: my-002061
文章浏览阅读5k次,点赞3次,收藏11次。那么我们只需要在home.vue想要的地方添加比如我们需要在 home.vue 中引用 headView.Vue。_vue一个页面引用另一个页面