Block头部解析

2023-11-12

Block解析介绍了Block的各个组成部分:魔法数、块大小、块头部、交易个数、交易,本文将详细介绍块魔法数和块头部的各个组成部分。


魔法数

魔法数是比特币客户端解析Block数据时的识别码,比特币正式网络的魔法数是0xD9B4BEF9。不同的币种的魔法数一般不同,比如打开莱特币的.dat文件我们可以发现莱特币的魔法数是0xDCB7C1FC。


版本号

目前比特币网络块链上的块的版本号有两个:1和2,两者的区别在于版本2块中的Coinbase交易加入了块高度,我们来看高度为227836和227835两个块中的Coinbase交易数据。


两个版本的Coinbase交易数据在结构上并没有区别,版本2在输入脚本上添加了4个字节的高度数据,其中第1个字节的值是指后面描述块高度的字节数,比如块227836的Coinbase交易输入脚本

03表示后面3个字节描述块高度,fc7903是小端顺序,所以实际的值是0x0379fc,转换为十进制值是227836。


为什么版本2要在Coinbase交易的输入脚本里面要加块高度呢?原因至少有两个:

1.能进一步保证接下来的每个块的哈希都是唯一的。由于在Coinbase交易里面加入了块高度,所以块头部的Merkle树根哈希一定是唯一的,所以该Block的块头部哈希一定唯一,所以接下来的块的上一个块头部哈希是唯一的,所以接下来的块头部哈希唯一。

2.能更好的了解那些孤立块形成的原因。比如可能是由于块高度冲突造成的。

上一个块哈希依然以块227836和227835为例,块227835的哈希值是

00000000000001aa077d7aa84c532a4d69bdbff519609d1da0835261b7a74eb6 块227836的块头部数据是

其中标红的是上一个块哈希,由于是小端序列所以实际值跟块227835的块哈希相同。

创世块没有上一个块,所以上一个块哈希是0。

Merkle树根哈希

Merkle树是哈希的二叉树,在比特币中使用两次SHA-256算法来生成Merkle树,如果叶子个数为奇数,则要重复计算最后一个叶子的两次SHA-256傎,以达到偶数叶子节点的要求:

计算过程:首先按照交易顺序将交易id放在最底层;第二层的每个元素是相连续的两个HASH值的两次HASH值;重复这个过程,直到某一层只有一个HASH值,这就是Merkle根。

下面以块100000演示计算过程:

第一步:使用比特币客户端获取块100000的数据。

getblock 000000000003ba27aa200b1cecaad478d2b00432346c3f1f3986da1afd33e506

{

"hash" : "000000000003ba27aa200b1cecaad478d2b00432346c3f1f3986da1afd33e506",

"confirmations" : 211828,

"size" : 957,

"height" : 100000,

"version" : 1,

"merkleroot" : "f3e94742aca4b5ef85488dc37c06c3282295ffec960994b2c0d5ac2a25a95766",

"tx" : [

"8c14f0db3df150123e6f3dbbf30f8b955a8249b62ac1d1ff16284aefa3d06d87",

"fff2525b8931402dd09222c50775608f75787bd2b87e56995a7bdd30f79702c4",

"6359f0868171b1d194cbee1af2f16ea598ae8fad666d9b012c8ed2b79a236ec4",

"e9a66845e05d5abc0ad04ec80f774a7e585c6e8db975962d069a522137b80c1d"

],

"time" : 1293623863,

"nonce" : 274148111,

"bits" : "1b04864c",

"difficulty" : 14484.16236123,

"chainwork" : "0000000000000000000000000000000000000000000000000644cb7f5234089e",

"previousblockhash" : "000000000002d01c1fccc21636b607dfd930d31d01c3a62104612a1719011250",

"nextblockhash" : "00000000000080b66c911bd5ba14a74260057311eaeb1982802f7010f1a9f090"

}

第二步:将txid转换为小端序列,得到最下层的Merkle树叶节点。

[

"876dd0a3ef4a2816ffd1c12ab649825a958b0ff3bb3d6f3e1250f13ddbf0148c",

"c40297f730dd7b5a99567eb8d27b78758f607507c52292d02d4031895b52f2ff",

"c46e239ab7d28e2c019b6d66ad8fae98a56ef1f21aeecb94d1b1718186f05963",

"1d0cb83721529a062d9675b98d6e5c587e4a770fc84ed00abc5a5de04568a6e9"

]

第三步:将第1,2两个txid,3,4两个txid连接起来进行双重哈希,需要注意的是并不是用它们的字符串形式而是要用对应的16进制编码,最后得到第二层的Merkle树节点。

[

"15b88c5107195bf09eb9da89b83d95b3d070079a3c5c5d3d17d0dcd873fbdacc",

"49aef42d78e3e9999c9e6ec9e1dddd6cb880bf3b076a03be1318ca789089308e",

]

第四步:重复第三步的操作,得到第三层的Merkle树节点

[

"6657a9252aacd5c0b2940996ecff952228c3067cc38d4885efb5a4ac4247e9f3"

]

由于只剩下一个,所以这就是最终的Merkle数根节点。

第五步:将根节点转换成大端序列,得到

"f3e94742aca4b5ef85488dc37c06c3282295ffec960994b2c0d5ac2a25a95766"

Github上有一个python程序描述了这个计算过程,可参考如下链接:

https://gist.github.com/shirriff/c9fb5d98e6da79d9a772#file-merkle-py


为什么要构建这样一颗Merkle树并保存根节点的哈希值到块头部呢?原因至少有如下几点:

1.在不存储块中完整交易信息的情况保证块哈希的唯一性。由于块哈希是对整个块进行哈希,因此只要其中的代表交易的信息是唯一的,那么块哈希就是唯一的,所以如果不存储交易信息而使用Merkle根部哈希参与到块哈希中就能大大减小数据量的存储。

2.在不存储块中完整交易信息的情况下验证块中的交易。假如节点要验证块100000中的第1笔交易数据是否正确,它可以从别的节点那里获取第1,2两笔交易,以及第3,4两笔交易的Merkle树上层节点值,而无需从对方那里下载完整的交易数据。

时间戳

时间戳是块被创造出来时加上的一个Unix时间,这个时间必须之前的11个块时间的中间值要大,并且要比当前网络校准时间小2小时。当前网络校准时间是指与你的节点相连的其它节点时间的中间值。

当一个节点连接另外一个节点时,它会收到对方的Unix时间并保存与本地时间的偏差,最终的网络校准时间就是所有偏差的中间值加上本地时间,不过比特币协议规定偏差最大就是70分钟。

需要注意的是,比特币的时间戳系统并非单调递增的,比如块139793的时间戳是1312599459,而块139792的时间戳是1312599808比139793的要大。

目标值

前文简要介绍了下根据块数据得到目标值的计算方式,那么目标值到底是怎么设置的呢?在此之前我先介绍下怎样把一个正整数转换成目标值的那种结构(以下简称目标值结构)。

第一步:将正整数转换成base256,得到base256的个数。

第二步:如果base256中的第1个字节大于127(0x7f),则在头部插入00。

第三步:截取base256的前3个字节,不足3个的在尾部补00。

第四步:将第一步得到的base256个数放在最前面。

例一:将1000转换成目标值结构

第一步:1000 = 03 e8,base256的个数是2个。

第二步:03比7f小,所以头部不插入一个00,依然是03 e8。

第三步:截取不足3个,所以尾部补00得到03 e8 00。

第四步:将02放在最前面,最终得到02 03 e8 00。

例二:将2^(256-32)-1转换成目标值结构

2^(256-32)-1= ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff

一共28个ff

由于ff>7f,所以在前面插入00,得到

00 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff

截取3个,再加上base256的个数,得到

1d 00 ff ff

目标值的设定通过比特币源代码可以获得计算方式

首先,初始的目标值就是网络设定的1d 00 ff ff

其次,一个周期(两周, 2016个块)内下一个块的难度值保持不变。

最后,新的周期的难度值根据上个周期产出2016个块的实际时间进行调整。

难度

说完目标值,顺带说下难度。难度用于描述在给定的目标值下寻找合适的哈希值的困难程度,难度并不存储在块数据中,它是根据一个公式计算出来的。

难度 = 最大目标值/当前目标值

最大目标值有不同的取值方式,比特币客户端一般取初始目标值

0xFFFF0000000000000000000000000000000000000000000000000000

以块311931为例,它的目标值是406809574转换成目标值结构是183F6BE6,因此

难度=0xFFFF0000000000000000000000000000000000000000000000000000/

0x3F6BE6000000000000000000000000000000000000000000

=17336316978.51

随机数

在介绍随机数前先介绍下块哈希是怎么来的,比如块125552的哈希是00000000000000001e8d6829a8a21adc5d38d0a473b144b6765798e61f98bd1d

这个值并没有存储在块数据中,它是根据块头部进行双重哈希得来的,算法如下:

第一步:将块版本,上一个块哈希,Merkle根哈希,时间戳,目标值,随机数连接起来。

第二步:将连接数进行双重哈希,得到的结果就是块的哈希。

可参考如下Python代码:


Block解析介绍了Block的各个组成部分:魔法数、块大小、块头部、交易个数、交易,本文将详细介绍块魔法数和块头部的各个组成部分。


魔法数

魔法数是比特币客户端解析Block数据时的识别码,比特币正式网络的魔法数是0xD9B4BEF9。不同的币种的魔法数一般不同,比如打开莱特币的.dat文件我们可以发现莱特币的魔法数是0xDCB7C1FC。


版本号

目前比特币网络块链上的块的版本号有两个:1和2,两者的区别在于版本2块中的Coinbase交易加入了块高度,我们来看高度为227836和227835两个块中的Coinbase交易数据。


两个版本的Coinbase交易数据在结构上并没有区别,版本2在输入脚本上添加了4个字节的高度数据,其中第1个字节的值是指后面描述块高度的字节数,比如块227836的Coinbase交易输入脚本

03表示后面3个字节描述块高度,fc7903是小端顺序,所以实际的值是0x0379fc,转换为十进制值是227836。


为什么版本2要在Coinbase交易的输入脚本里面要加块高度呢?原因至少有两个:

1.能进一步保证接下来的每个块的哈希都是唯一的。由于在Coinbase交易里面加入了块高度,所以块头部的Merkle树根哈希一定是唯一的,所以该Block的块头部哈希一定唯一,所以接下来的块的上一个块头部哈希是唯一的,所以接下来的块头部哈希唯一。

2.能更好的了解那些孤立块形成的原因。比如可能是由于块高度冲突造成的。

上一个块哈希依然以块227836和227835为例,块227835的哈希值是

00000000000001aa077d7aa84c532a4d69bdbff519609d1da0835261b7a74eb6 块227836的块头部数据是

其中标红的是上一个块哈希,由于是小端序列所以实际值跟块227835的块哈希相同。

创世块没有上一个块,所以上一个块哈希是0。

Merkle树根哈希

Merkle树是哈希的二叉树,在比特币中使用两次SHA-256算法来生成Merkle树,如果叶子个数为奇数,则要重复计算最后一个叶子的两次SHA-256傎,以达到偶数叶子节点的要求:

计算过程:首先按照交易顺序将交易id放在最底层;第二层的每个元素是相连续的两个HASH值的两次HASH值;重复这个过程,直到某一层只有一个HASH值,这就是Merkle根。

下面以块100000演示计算过程:

第一步:使用比特币客户端获取块100000的数据。

getblock 000000000003ba27aa200b1cecaad478d2b00432346c3f1f3986da1afd33e506

{

"hash" : "000000000003ba27aa200b1cecaad478d2b00432346c3f1f3986da1afd33e506",

"confirmations" : 211828,

"size" : 957,

"height" : 100000,

"version" : 1,

"merkleroot" : "f3e94742aca4b5ef85488dc37c06c3282295ffec960994b2c0d5ac2a25a95766",

"tx" : [

"8c14f0db3df150123e6f3dbbf30f8b955a8249b62ac1d1ff16284aefa3d06d87",

"fff2525b8931402dd09222c50775608f75787bd2b87e56995a7bdd30f79702c4",

"6359f0868171b1d194cbee1af2f16ea598ae8fad666d9b012c8ed2b79a236ec4",

"e9a66845e05d5abc0ad04ec80f774a7e585c6e8db975962d069a522137b80c1d"

],

"time" : 1293623863,

"nonce" : 274148111,

"bits" : "1b04864c",

"difficulty" : 14484.16236123,

"chainwork" : "0000000000000000000000000000000000000000000000000644cb7f5234089e",

"previousblockhash" : "000000000002d01c1fccc21636b607dfd930d31d01c3a62104612a1719011250",

"nextblockhash" : "00000000000080b66c911bd5ba14a74260057311eaeb1982802f7010f1a9f090"

}

第二步:将txid转换为小端序列,得到最下层的Merkle树叶节点。

[

"876dd0a3ef4a2816ffd1c12ab649825a958b0ff3bb3d6f3e1250f13ddbf0148c",

"c40297f730dd7b5a99567eb8d27b78758f607507c52292d02d4031895b52f2ff",

"c46e239ab7d28e2c019b6d66ad8fae98a56ef1f21aeecb94d1b1718186f05963",

"1d0cb83721529a062d9675b98d6e5c587e4a770fc84ed00abc5a5de04568a6e9"

]

第三步:将第1,2两个txid,3,4两个txid连接起来进行双重哈希,需要注意的是并不是用它们的字符串形式而是要用对应的16进制编码,最后得到第二层的Merkle树节点。

[

"15b88c5107195bf09eb9da89b83d95b3d070079a3c5c5d3d17d0dcd873fbdacc",

"49aef42d78e3e9999c9e6ec9e1dddd6cb880bf3b076a03be1318ca789089308e",

]

第四步:重复第三步的操作,得到第三层的Merkle树节点

[

"6657a9252aacd5c0b2940996ecff952228c3067cc38d4885efb5a4ac4247e9f3"

]

由于只剩下一个,所以这就是最终的Merkle数根节点。

第五步:将根节点转换成大端序列,得到

"f3e94742aca4b5ef85488dc37c06c3282295ffec960994b2c0d5ac2a25a95766"

Github上有一个python程序描述了这个计算过程,可参考如下链接:

https://gist.github.com/shirriff/c9fb5d98e6da79d9a772#file-merkle-py


为什么要构建这样一颗Merkle树并保存根节点的哈希值到块头部呢?原因至少有如下几点:

1.在不存储块中完整交易信息的情况保证块哈希的唯一性。由于块哈希是对整个块进行哈希,因此只要其中的代表交易的信息是唯一的,那么块哈希就是唯一的,所以如果不存储交易信息而使用Merkle根部哈希参与到块哈希中就能大大减小数据量的存储。

2.在不存储块中完整交易信息的情况下验证块中的交易。假如节点要验证块100000中的第1笔交易数据是否正确,它可以从别的节点那里获取第1,2两笔交易,以及第3,4两笔交易的Merkle树上层节点值,而无需从对方那里下载完整的交易数据。

时间戳

时间戳是块被创造出来时加上的一个Unix时间,这个时间必须之前的11个块时间的中间值要大,并且要比当前网络校准时间小2小时。当前网络校准时间是指与你的节点相连的其它节点时间的中间值。

当一个节点连接另外一个节点时,它会收到对方的Unix时间并保存与本地时间的偏差,最终的网络校准时间就是所有偏差的中间值加上本地时间,不过比特币协议规定偏差最大就是70分钟。

需要注意的是,比特币的时间戳系统并非单调递增的,比如块139793的时间戳是1312599459,而块139792的时间戳是1312599808比139793的要大。

目标值

前文简要介绍了下根据块数据得到目标值的计算方式,那么目标值到底是怎么设置的呢?在此之前我先介绍下怎样把一个正整数转换成目标值的那种结构(以下简称目标值结构)。

第一步:将正整数转换成base256,得到base256的个数。

第二步:如果base256中的第1个字节大于127(0x7f),则在头部插入00。

第三步:截取base256的前3个字节,不足3个的在尾部补00。

第四步:将第一步得到的base256个数放在最前面。

例一:将1000转换成目标值结构

第一步:1000 = 03 e8,base256的个数是2个。

第二步:03比7f小,所以头部不插入一个00,依然是03 e8。

第三步:截取不足3个,所以尾部补00得到03 e8 00。

第四步:将02放在最前面,最终得到02 03 e8 00。

例二:将2^(256-32)-1转换成目标值结构

2^(256-32)-1= ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff

一共28个ff

由于ff>7f,所以在前面插入00,得到

00 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff

截取3个,再加上base256的个数,得到

1d 00 ff ff

目标值的设定通过比特币源代码可以获得计算方式

首先,初始的目标值就是网络设定的1d 00 ff ff

其次,一个周期(两周, 2016个块)内下一个块的难度值保持不变。

最后,新的周期的难度值根据上个周期产出2016个块的实际时间进行调整。

难度

说完目标值,顺带说下难度。难度用于描述在给定的目标值下寻找合适的哈希值的困难程度,难度并不存储在块数据中,它是根据一个公式计算出来的。

难度 = 最大目标值/当前目标值

最大目标值有不同的取值方式,比特币客户端一般取初始目标值

0xFFFF0000000000000000000000000000000000000000000000000000

以块311931为例,它的目标值是406809574转换成目标值结构是183F6BE6,因此

难度=0xFFFF0000000000000000000000000000000000000000000000000000/

0x3F6BE6000000000000000000000000000000000000000000

=17336316978.51

随机数

在介绍随机数前先介绍下块哈希是怎么来的,比如块125552的哈希是00000000000000001e8d6829a8a21adc5d38d0a473b144b6765798e61f98bd1d

这个值并没有存储在块数据中,它是根据块头部进行双重哈希得来的,算法如下:

第一步:将块版本,上一个块哈希,Merkle根哈希,时间戳,目标值,随机数连接起来。

第二步:将连接数进行双重哈希,得到的结果就是块的哈希。

可参考如下Python代码:


由于块头部的其它字段都是固定的,但生成一个不超过目标值的块哈希并非一次就能成功的事情,所以需要一个随机数不停的变化去尝试去生成块哈希直到符合要求。

参考

http://bitcoin.stackexchange.com/questions/2924/how-to-calculate-new-bits-value

http://www.righto.com/2014/02/bitcoin-mining-hard-way-algorithms.html

https://en.bitcoin.it/wiki/Category:Technical

参考

http://bitcoin.stackexchange.com/questions/2924/how-to-calculate-new-bits-value

http://www.righto.com/2014/02/bitcoin-mining-hard-way-algorithms.html

https://en.bitcoin.it/wiki/Category:Technical

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Block头部解析 的相关文章

  • 在 MySQL 中插入时检查并防止相似字符串

    简要信息 我有3张桌子 Set id name SetItem set id item id position TempSet id 我有一个函数可以生成新的随机组合Item桌子 基本上 总是在成功生成之后 我在中创建一个新行Set表 获取
  • 如何将文件的元素放入哈希中? -红宝石

    所以我有一个以下形式的文件 Key1 Value1 Key2 Value2 Key3 Value3 用制表符分隔 我的问题是如何打开这个文件并将其放入哈希中 我曾尝试这样做 fp File open file path fp each do
  • ruby 字符串到哈希值的转换

    我有一个这样的字符串 str uu p xx m yy n zz m 我想知道如何将给定的字符串转换为哈希值 即我的实际要求是 有多少个值 符号之前 有m n和p 我不需要计数 我需要一个精确的值 这样输出效果会更好 m gt xx zz
  • 使用 crypt() 加密

    我目前正在做一个非常安全的登录系统 但我是 crypt 函数的新手 需要一些快速帮助 我在注册过程中使用 crypt 加密密码字符串并将其保存到数据库中 但是 我如何在登录过程中解密密钥 或者我应该怎么做 或者是否可以对提交的密码字符串进行
  • 从哈希中删除 nil 值

    我希望从哈希中删除具有nil value article是一个存储每篇文章的类 并且attributes方法将文章存储为散列 预期结果 articles results author null title Former bar manage
  • 如何通过 md5 比较图像?

    该方法是否比较图像的像素值 我猜它不会起作用 因为它们的尺寸彼此不同 但如果它们相同但格式不同怎么办 例如 我截图并保存为 jpg另一个并保存为 gif MD5哈希是实际的二进制数据 因此不同的格式将具有完全不同的二进制数据 因此 要使 M
  • 我仍然认为在客户端哈希密码更好。我错了吗?

    我读过这些 https hackernoon com im harvesting credit card numbers and passwords from your site here s how 9a8cb347c5b5 https
  • 使用 OCMock 以代码块作为参数的存根方法

    有没有一种方法可以存根方法 以块作为参数 例如方法 void reverseGeocodeLocation CLLocation location completionHandler CLGeocodeCompletionHandler c
  • 重新加载页面时删除哈希值?

    我使用哈希来切换我的图像滑块 当我重新加载页面并且哈希值设置为 e h 3 没有图片 当图库在几秒钟后自动滑动时 它显示下一个 所以几秒钟内什么也没有 有没有办法在加载页面时检查哈希并将其删除 我只想关心那些用散列为页面添加书签的人 问候
  • 当我使用加盐 CRYPT_MD5 加密我的密码时,正在加密什么?

    对字符串使用 md5 总是会产生字母数字加密结果 即 没有符号 然而 当我使用 php crypt 函数 特别是带有盐的 CRYPT MD5 并且它已打开 我已经检查过 时 它返回的假定 md5 哈希看起来不像 md5 哈希 例如 如果我
  • 使用 2 个不同的哈希函数是检查文件完整性的好方法吗?

    我有一个网站 用户可以上传他们的文件 它们存储在服务器上 其元数据记录在数据库中 我正在实施一些简单的完整性检查 即 该文件的内容现在逐字节与上传时是否相同 示例 对于内容userfile jpg MD5 哈希为39f9031a154dc7
  • 如果计算的哈希码超过整数最大限制,会发生什么?

    这是 Java HashTable 类的 hashCode 实现 如果哈希表中的元素数量很大并且哈希码超过 INTEGER MAX LIMIT 2 147 483 648 到 2 147 483 647 该怎么办 我假设 hashCodes
  • 直接对文件的哈希值进行数字签名,而不是对文件进行签名

    我的问题是 是否可以直接对文件的哈希值而不是文件进行数字签名 我必须通过电子令牌在 Web 环境中对 xml 文件进行数字签名 所以我必须将文件从服务器下载到客户端 然后从客户端计算机上的电子令牌 USB 获取证书并对文件进行签名并将其上传
  • 数字签名(PKCS#7 - 延迟签名)/自应用签名以来文档已被更改或损坏

    我已经浏览了所有类似的问题 但找不到应用 itextsharp 延迟签名的情况 基本上 我的应用程序使用以下方式签署 pdf 文档PKCS 7由远程 Web 服务创建的签名 我的应用程序向此 Web 服务发送原始文档的哈希值 添加空签名字段
  • 如何在没有循环的情况下初始化哈希中的值?

    我正在尝试找出一种无需经过循环即可初始化哈希的方法 我希望使用切片来实现这一点 但它似乎没有产生预期的结果 考虑以下代码 usr bin perl use Data Dumper my hash hash currency symbol B
  • 使用您正在散列的内容的散列作为盐?

    假设用户注册了您的网站 您对他们选择的密码进行哈希处理 然后使用该哈希值作为盐 并使用该盐重新哈希其密码 Example String hash1 MD5 password String endHash MD5 hash1 password
  • JavaScript 文件中的快速低冲突非加密哈希

    我正在寻找一种用 JavaScript 实现的低冲突的快速哈希 它不需要是加密哈希 我基本上使用它作为查看给定文件是否已上传 或部分上传 到用户帐户的方式 以节省他们在大型 视频 文件上上传的时间 我正在使用新的 HTML5 文件 API
  • 迭代哈希数组

    我编写了下面的例程 迭代哈希值 0 7 并打印出每个哈希值中特定键的值 我需要获取每个哈希中 b4 的值 我想取消 0 7 当存在不同数量的哈希值时使用更智能的东西 例如 有时只有 2 个 也可能有 160 个 my out decode
  • ruby 的 String .hash 方法如何工作?

    我只是红宝石的新手 我见过一个字符串方法 String hash 例如 在irb 我试过了 gt gt mgpyone hash returns gt 144611910 这个方法是如何工作的 The hash方法是为所有对象定义的 看文档
  • 在表单中编辑序列化哈希?

    我正在序列化存储在settings表中的字段 并且希望能够在表单字段中编辑该哈希 class Template lt ActiveRecord Base serialize settings end 但我就是这么做那么文本区域只显示序列化数

随机推荐

  • Redis入门——Key、五大数据类型图文详解

    文章目录 1 Redis简介 2 Redis常见命令 3 Redis Key关键字 4 五大数据类型简介 4 1 String 字符串 4 2 List 列表 4 3 Set 4 3 Hash 4 4 ZSet 1 Redis简介 Redi
  • 什么是索引?MySQL常见的几种索引类型和原理

    来源 素文宅博客 地址 https blog yoodb com yoodb article detail 1536 在关系数据库中 索引是一种单独的 物理的对数据库表中一列或多列的值进行排序的一种存储结构 它是某个表中一列或若干列值的集合
  • Java---JUC并发篇(多线程详细版)

    Java 多线程 1 并发基础 线程篇 1 1 java线程状态及线程状态之间的转化 1 2 操作系统层面有5种状态 2 线程池的核心参数 7个核心参数 3 sleep与wait方法对比 4 lock锁与synchronized锁区别 5
  • docker启动容器及启动一个挂载数据卷的容器

    在docker运行容器前可以先使用docker images列出本地镜像 docker运行容器前需要本地存在对应的镜像 如果本地不存在该镜像 Docker会从镜像仓库下载此镜像 先创建 usr share nginx html 目录 创建数
  • python: more Layer Architecture and its Implementation in Python

    sql server 学生表 DROP TABLE DuStudentList GO create table DuStudentList StudentId INT IDENTITY 1 1 PRIMARY KEY StudentName
  • python操作图像处理

    绘制图形方式一 1 图像读取 img cv imread C Users asus Desktop QQ jpg source cv cvtColor img cv COLOR BGR2RGB 2 均值滤波 blur cv blur img
  • AcWing 99. 激光炸弹(二维前缀和)

    输入样例 2 1 0 0 1 1 1 1 输出样例 1 解析 二维前缀和 枚举每个正方形区间的最大值即可 本题只能开一个5000的二维数组 两个会MLE 代码 include
  • flask+APScheduler定时任务的使用

    APScheduler定时任务使用以及在flask中的调用 APScheduler简介 组成部分 调度器 安装 普通使用安装 结合flask使用安装 使用 添加job add job参数详解 interval 间隔时间 每隔一段时间执行 d
  • Linux下实现编写汇编程序

    本学期的微机原理课程上机使用的是MASM汇编器 上课时使用的是Windows上的DOS 而Linux中的汇编工具是nasm 具体的可以点击链接 http os 51cto com art 201101 243138 htm 这里写代码片 下
  • C++11智能指针的基本原理及使用

    介绍 智能指针是一个类 用来存储指向动态分配对象的指针 负责自动释放动态分配的对象 防止堆内存泄漏 动态分配的资源 交给一个类对象去管理 当类对象声明周期结束时 自动调用析构函数释放资源 分类 auto ptr 已弃用 使用unique p
  • 神经网络算法和遗传算法,数据挖掘神经网络算法

    神经网络算法与进化算是什么关系 应该没有太大的关系吧 我对遗传算法了解一点 遗传算法主要用来优化神经网络第一次运行时所用的连接权值 因为随机的连接权值往往不能对针对的问题有比较好的收敛效果 Matlab神经网络工具箱自动生成的初始权值其实已
  • Tracy 小笔记 Vue - 网络模块封装(axios)

    安装 axios 和 引入 安装 npm install axios save 引用 import axios from axios 网络请求可以测试的几个接口地址 http httpbin org get http 123 207 32
  • Linux中的JDK安装和配置

    Linux中的JDK安装和配置 1 查看是否已安装JDK yum list installed grep java 2 卸载系统Java环境 yum y remove java 1 8 0 openjdk 3 卸载tzdata java y
  • 那年的夏天很笛子

    原文 salance moon spaces live com 在某个阶段 我想应该是时候把至今为止影响自己走上美工 设计 程序之路的历程整理一下了 但是下笔的时候才发现 其实这几乎成了我童年的回忆录 因为程序暂且不算 美工 设计就是我人格
  • Connect函数阻塞

    1 采用select 在学习嵌入式Linux网络编程中 很多同学都发现了一个问题 那就是调用connect函数时 如果服务端关闭 客户 端调用connect 函数时 发现阻塞在那里 而且利用ctrl c信号去停止客户端程序时 需要等待一个较
  • git:一次回滚多个commit

    说明 独立分散的commit共同回滚 git revert n sha 1 git 单次commit对应的sha 1值 sha 1 sha 1 ps n代表不会生成新的commit 如果想直接生成commit请去掉 n 最近连续的coomi
  • hr谈薪资后说请示领导_如何巧妙回答面试中的薪资问题呢?

    好不容易挺过了群面 单面 没想到在HR面被薪资问题打个措手不及 你的期望薪资是多少 说低了总觉得委屈自己 说高了又怕offer不保 好不容易在前面几轮面试积攒的自信 在这个问题上就变成 emm差不多就行吧 然后面试一结束就开始无限后悔 对于
  • 【ML特征工程】第 1 章 :机器学习管道

    大家好 我是Sonhhxg 柒 希望你看完之后 能对你有所帮助 不足请指正 共同学习交流 个人主页 Sonhhxg 柒的博客 CSDN博客 欢迎各位 点赞 收藏 留言 系列专栏 机器学习 ML 自然语言处理 NLP 深度学习 DL fore
  • STM32F407 单片机+DMA+环形缓冲区+GPS报文解析

    本文采用DMA 环形缓冲区对GPS报文进行解析 思路是通过DMA中断接收到GPS报文后 存放到环形缓冲区 然后在主程序中解析GPS报文 解析GPS报文的关键是 将环形缓冲区中的字节转换成字符串 然后在字符串中查找GPS报文头标识 例如 GP
  • Block头部解析

    Block解析介绍了Block的各个组成部分 魔法数 块大小 块头部 交易个数 交易 本文将详细介绍块魔法数和块头部的各个组成部分 魔法数 魔法数是比特币客户端解析Block数据时的识别码 比特币正式网络的魔法数是0xD9B4BEF9 不同