最近一直在学习区块链的基础知识,想了想决定将2个任务(学区块链和写作)相融合。写区块链相关的文字,既可以让自己梳理出思路不清的地方,可以让战友们帮忙检验自己没说明白的地方。(争取之后在币乎里面发表)
最近的感悟
先谈谈最近的感悟,几件小事情:
最近和室友住在一起,为了健身(减肥),每天一起做俯卧两头起。第一天的时候,我只做了30个(1组)。由于身体的酸痛时间是从运动后48-72小时的时间段,所以第二天我又做了60个两头起(2组)。第三天,明显感到肋骨前肌肉的疼痛感,但也坚持做90个,虽然是上午2组,下午1组,但由于使用同一位置的肌肉,所以反而觉得酸痛被缓解了。目前已经坚持到8天了,每天90个两头起(3组)和10个俯卧撑(因为自己手臂无力,所以下沉的深度不够,不过慢慢有好转)。
感受最深的是坚持健身和健康的饮食搭配,真的会让人(主要是肠胃)感觉到舒服。同时,也会让自己变瘦变健康。最大的动力来自于室友的鼓励,每次做完一组,她都会在旁边说,“你好棒呀!” 这种真心实意的赞美让人如沐春风,也会觉得自己特别棒!跟007er宣扬评价机制的在本质上是一致的。当然啦,室友也是一名007er,世界总是那么小,目前学习区块链的同学里面也很多007er。鼓励机制真的会有一种魔力,有种让人想变得越来越好的冲动,同时也觉得自己能做的事情有很多呀,比如每次做完饭的时候,留下食物的照片或者视频,等到课程结束时,我们就可以剪辑出小视频,留下自己的处女电影作品或者写成小小说,纪念我们的小日子。将日子过的越来越有仪式感。
还一件007内的事情,昨天总结上期的优秀作品,我的点评竟然被选做最佳的点评。这是我从来不敢妄想的。总觉得自己做的很一般,并不会觉得做的很好。所以,惊喜之外,联系了巫同学,他说感觉到我的进步。点评的那天,我有回顾笑来老师的《通往财富自由之路》的一篇文章,所以点评才会言之有物,联想到的东西就会更多。
以前总觉得自己什么也做不好,跟身边的人比起来,总觉得自己的学历不够,所以觉得自己的脑子运转起来也不如他们的感觉。但是当我自己从这种想法中解救出来之后 ,我发现自己并不比别人差,甚至有些事情上,还会超越他们。这样的转变,在上次的家庭聚餐上,也体现了出来,当我表达关于投资的概念就应该是把自己的多余钱拿去投资,并在心里将这部分钱认为是丢了的状态时,家里人对我的评价在那一瞬间就改变了。(当然是笑来老师的概念啦,我觉得是正确的,所以使用起来了)我从没有想过,自己的想法能够震撼到他们。而且之后家里人对我学习的事情,品头论足了一番(我没在家的情况下)。我本以为他们会很难理解,并会使用批评的语气来评价此事的。结果却出乎了我的想象。
好像最近很多的事情都超出了我的想象呢?
最近学习的东西
双拼输入法 (手指还不是很熟悉这种输入法,每天练习30分钟)
使用在行 约见老师
学习使用Markdown 好更加快速的记笔记及敲入代码
学习区块链的代码
联系英语口语(应该更专注)
练习自己的专注力(刚刚开始了2次)
区块链的内容
如何创建文件/保存数据
计算机保存所有数据都是以数字的形式,然后再用不同的协议来使用数字代表文字、图片等。
byte(字节)
byte 是最小的有明确地址的储存单位( bit 就没有明确地址)
1 byte = 8 bits
bit: 1 or 0
是指针的大小。在32位系统里,为4个字节;在64位系统中,为8个字节。
是最大的加减乘除的单操作单位。
在 Intel 的文档里,word 指 2 个 byte。
本课程中,指 4 个 byte。
4 个 byte,范围为 -21亿 ~ 21亿,或 0 ~ 42 亿。(注释:4 个 byte 是4 * 8 = 32位,即2^32 = 4294967296,约 4.29 Billion)
8 个 byte 可保存的数字范围为 0 ~ 1019
比特币的最小单位是 10-8,你如果要发送 1个 BTC 给别人,在内存中要保存的数字为 108,4个 byte 对比特币系统来说太小,最大只能存 42个BTC。所以BTC系统中是使用 8 个 byte。比特币总量为 2100万个,21 x 106 x 108 = 21 x 1014,还是小于 1019 。
程序语言如何保存数据
计算机只有两种保存数据的方式:
转换成数字
转换成数字的排列(Vector of numbers)
100 | 140 | 200 | 300
我们从操作系统得到的是一整块内存,程序语言需要把内存进行分配,分成不同的部分来使用。程序语言有两种方式使用内存保存数据:
将数据保存在一块连续的内存部分(vector), 更常用在硬盘(深储存,计算机重启后不会被删除)中使用这种方式。
使用指针,数据是树状的。更常用在内存(浅储存,重启计算机后会被删除)中使用这种方式。
例子:保存一套关于人的信息
属性 身份号码 电话号码 名字地址
类型 4 byte 11位的string string string
存储方式数据结构分配方式
vector 连续静态&动态
指针 树状动态
使用指针的好处是:每个指针的大小是固定的,比如本例中我要查找地址,只需要找到身份号码的指针后,跳4格,即可找到地址的指针。
但如果不用指针,你就要先顺序跳到名字,然后确定名字占几个字节,然后才知道要再跳过几个字节,才能找到地址。
Ruby、Python等高级语言会默认用指针的方式,不会给你选择。由于高级语言都是用指针的方式,而文件格式的内部用的都是 vector 方式,所以用高级语言操作文件不太适合。
C语言分配内存的主要是用 malloc 函数,C语言对内存比较节省,尽量用静态分配,因为对内存的管理是手动的。
在Ruby、Python 这样的动态语言中,会频繁呼叫 malloc 函数,比如新建一个字符串、数组、从数组中取出一个元素等。
任何数据都可以通过数字和指针来表示,什么样的关系都可以。
但现实中的实际问题,要用数据结构来表示,需要程序员一定的思考和设计,才能找到最合适的数据结构。因为数据结构指序列,树,图这些基本机构以及它们的组合,在描述实际问题时,必然会用到,比如区块链对应的大的数据结构是链表,而分叉对应的数据结构是树。)
游戏开发者们需要经常设计内存数据结构,因为他们总在创造新的概念,新的概念需要新的对象来代表。
SQL 通过数据表(Table),你给它一个抽象的数据结构的描述,它能自动做内存管理,你就不需要去手动管理了。 区块链的储存与 SQL 的对接,还有待研究。
区块的结构
区块(在BTC中 < 1MB) = 区块头(大小固定,BTC中为80字节) | 区块body(大小有变化)
body里含有多个 transaction(one to many),
Transaction -> 多个input —— 参数
-> 多个output—— 参数
BTC 中每个交易下也要参数,而XCY 中交易层面是没有参数的,做了简化。
一个 block 里面至少有一个交易——generational transaction 或 coinbase,用于奖励矿工。其他交易可能为 0 个。
解析区块(parsing/analysis):得到一个区块后,如何写函数来把头切出来,把 coinbase 切出来,然后写函数进一步切开各个部分。
创建区块(create)
区块链系统的格式
每一个区块链系统有三套格式:
A. 区块链的储存格式
B. 节点和应用之间的通讯格式——创造自己的交易所、钱包要用到
C. 节点和节点之间的通讯格式——主要是P2P网络的知识,引入少部分区块链部分
A和C最重要。今天我们的学习内容是 A。
BTC 格式的非官方说明文档
A: https://en.bitcoin.it/wiki/Block
B: https://en.bitcoin.it/wiki/API_reference_(JSON-RPC)
C: https://en.bitcoin.it/wiki/Protocol_documentation
ETH 格式的官方说明文档
C: https://github.com/ethereum/wiki/wiki/Ethereum-Wire-Protocol
XCY(Concise Yuan)
A: protocol-for-data-representation
B: protocol-for-applications
C: protocol-for-relays
protocol.txt
BTC相关网站:
查看开放节点:https://bitnotes.earn.com
查看虚拟货币市值:https://coinmarketcap.com
查看区块信息:https://blockchain.info/
*表示0个以上,+表示1个以上
concise Yuan (XCY)
BLOCK := HEAD, BODY
HEAD :=
BODY := TRANSACTION+
TRANSACTION := INPUT+, OUTPUT+ //一个交易,有一个以上输入、有一个以上输出
INPUT := A(4), index(4), B(4), public(B), C(4), signature(C), transaction(32)
OUTPUT := A(4), B(4), address(B), amount(8)
public(B),数据的长度是灵活的,需要的是公钥,长度不固定。
signature©,签名的长度不固定。72-68,更小的签名也存在。
一个input的总大小:4 + 4 + 4 + B +4 + C + 32 = 48 + B + C
一个output的总大小:4 + 4 + B + 8 = 16 + B
你要想发送钱,就必须在 INPUT 中说明你的钱来自哪笔交易,才能证明你真的拥有这笔钱。
input的目的:
1)指定钱的来源:index 和transaction 是来指明你的钱来自哪笔交易;
2)证明钱是你的:public(公钥的长度可能会不同) 和 signature(签名的长度也不固定) 是来证明这笔钱是属于你的,与加密验证相关。
output 的目的是来指定:
1)发送多少钱
2)向哪一个账号发送
OUTPUT:
A: 50 = OUTPUT 的总长度,4+4+34+8=50
B: 34 = address 的长度,当前使用地址的长度
address: 1NrrHYZMum2JaHJeSZufFitqg9W8uNdfzM
amount: 200,000,000 //额度是2个XCY
在内存中是这样:
0 4 8 42 50
[50, 34, 1NrrHYZMum2JaHJeSZufFitqg9W8uNdfzM, 200000000]
INPUT:
A: 总共的大小
index: 一笔交易可以有多个收款人,所以要把transaction内的输出号(你是第几个收款人)写在这里。
B: public 的大小
public: 我的公钥
C: signature 的大小
signature: 自己的私钥的签名(签名能证明这个私钥是你的,但不会暴露你的私钥)
transaction:之前接受钱是在哪个交易?把交易的身份号写这里 (交易身份号TxID 32 个字节)
区块 = 头部(总是存在的)+ coinbase(总是存在的)+ 其他交易(可能有0 个或者以上)
HEAD 包含如下内容:
current(32) 当前区块的身部的身份号 Merkle Tree
nonce (4) 挖矿中被设定的数值,在 0-42 亿间猜数字。目前改成了 12 个字节(BTC 在 body 又中加了 8 个字节)
previous: 前一个区块的身份号
target(32) 挖矿的难度。target越大,挖矿难道越小。target 的难度会根据时间调整。
time(4) 时间
valence(4) 包含多少个交易
XCY的头部有 108 个字节,BTC的头部是 80 个字节(经过了压缩)
挖矿的过程是
猜测 nonce,nonce就是那个随机数啦
计算 SHA256(current + nonce)
查看小不小于target
要是不小于,重复 #1
1/65536
分叉
自然分叉:如果同一时刻有不只一个区块被挖出来,就会暂时将这几个区块都上链,然后再继续看后面新产生的区块连接到哪个分支上,最终会只保留最长的分支,其余分支会被废弃。