如何从一个交易hashcoins 在哪交易得到汇款的地址

算法和数据结构(15)
虽然我们不希望发生冲突,但实际上发生冲突的可能性仍是存在的。当关键字值域远大于哈希表的长度,而且事先并不知道关键字的具体取值时。冲突就难免会发
生。另外,当关键字的实际取值大于哈希表的长度时,而且表中已装满了记录,如果插入一个新记录,不仅发生冲突,而且还会发生溢出。因此,处理冲突和溢出是
哈希技术中的两个重要问题。
1、开放定址法
&&&& 用开放定址法解决冲突的做法是:当冲突发生时,使用某种探查(亦称探测)技术在散列表中形成一个探查(测)序列。沿此序列逐个单元地查找,直到找到给定
的关键字,或者碰到一个开放的地址(即该地址单元为空)为止(若要插入,在探查到开放的地址,则可将待插入的新结点存人该地址单元)。查找时探查到开放的 地址则表明表中无待查的关键字,即查找失败。
①用开放定址法建立散列表时,建表前须将表中所有单元(更严格地说,是指单元中存储的关键字)置空。
②空单元的表示与具体的应用相关。
&&&& 按照形成探查序列的方法不同,可将开放定址法区分为线性探查法、线性补偿探测法、随机探测等。
(1)线性探查法(Linear Probing)
该方法的基本思想是:
&&&&将散列表T[0..m-1]看成是一个循环向量,若初始探查的地址为d(即h(key)=d),则最长的探查序列为:
&&&&&&&&d,d+l,d+2,…,m-1,0,1,…,d-1
&&&& 即:探查时从地址d开始,首先探查T[d],然后依次探查T[d+1],…,直到T[m-1],此后又循环到T[0],T[1],…,直到探查到T[d-1]为止。
探查过程终止于三种情况:
&&&& (1)若当前探查的单元为空,则表示查找失败(若是插入则将key写入其中);
&&&&(2)若当前探查的单元中含有key,则查找成功,但对于插入意味着失败;
&&&& (3)若探查到T[d-1]时仍未发现空单元也未找到key,则无论是查找还是插入均意味着失败(此时表满)。
利用开放地址法的一般形式,线性探查法的探查序列为:
&&&&&&&&hi=(h(key)+i)%m
0≤i≤m-1 //即di=i
用线性探测法处理冲突,思路清晰,算法简单,但存在下列缺点:
① 处理溢出需另编程序。一般可另外设立一个溢出表,专门用来存放上述哈希表中放不下的记录。此溢出表最简单的结构是顺序表,查找方法可用顺序查找。
② 按上述算法建立起来的哈希表,删除工作非常困难。假如要从哈希表 HT 中删除一个记录,按理应将这个记录所在位置置为空,但我们不能这样做,而只能标上已被删除的标记,否则,将会影响以后的查找。
③ 线性探测法很容易产生堆聚现象。所谓堆聚现象,就是存入哈希表的记录在表中连成一片。按照线性探测法处理冲突,如果生成哈希地址的连续序列愈长 ( 即不同关键字值的哈希地址相邻在一起愈长 ) ,则当新的记录加入该表时,与这个序列发生冲突的可能性愈大。因此,哈希地址的较长连续序列比较短连续序列生长得快,这就意味着,一旦出现堆聚
( 伴随着冲突 ) ,就将引起进一步的堆聚。
(2)线性补偿探测法
线性补偿探测法的基本思想是:
将线性探测的步长从 1 改为 Q ,即将上述算法中的 j = (j + 1) % m 改为: j = (j + Q) % m ,而且要求 Q 与 m 是互质的,以便能探测到哈希表中的所有单元。
【例】 PDP-11 小型计算机中的汇编程序所用的符合表,就采用此方法来解决冲突,所用表长 m = 1321 ,选用 Q = 25 。
(3)随机探测
随机探测的基本思想是:
将线性探测的步长从常数改为随机数,即令: j = (j + RN) % m ,其中 RN 是一个随机数。在实际程序中应预先用随机数发生器产生一个随机序列,将此序列作为依次探测的步长。这样就能使不同的关键字具有不同的探测次序,从而可以避 免或减少堆聚。基于与线性探测法相同的理由,在线性补偿探测法和随机探测法中,删除一个记录后也要打上删除标记。
(1)拉链法解决冲突的方法
&&&& 拉链法解决冲突的做法是:将所有关键字为同义词的结点链接在同一个单链表中。若选定的散列表长度为m,则可将散列表定义为一个由m个头指针组成的指针数
组T[0..m-1]。凡是散列地址为i的结点,均插入到以T[i]为头指针的单链表中。T中各分量的初值均应为空指针。在拉链法中,装填因子α可以大于 1,但一般均取α≤1。
【例】设有 m = 5 , H(K) = K mod 5 ,关键字值序例 5 , 21 , 17 , 9 , 15 , 36 , 41 , 24 ,按外链地址法所建立的哈希表如下图所示:
&&&&&&&&&&
(2)拉链法的优点
与开放定址法相比,拉链法有如下几个优点:
①拉链法处理冲突简单,且无堆积现象,即非同义词决不会发生冲突,因此平均查找长度较短;
②由于拉链法中各链表上的结点空间是动态申请的,故它更适合于造表前无法确定表长的情况;
③开放定址法为减少冲突,要求装填因子α较小,故当结点规模较大时会浪费很多空间。而拉链法中可取α≥1,且结点较大时,拉链法中增加的指针域可忽略不计,因此节省空间;
④在用拉链法构造的散列表中,删除结点的操作易于实现。只要简单地删去链表上相应的结点即可。而对开放地址法构造的散列表,删除结点不能简单地将被删结 点的空间置为空,否则将截断在它之后填人散列表的同义词结点的查找路径。这是因为各种开放地址法中,空地址单元(即开放地址)都是查找失败的条件。因此在
用开放地址法处理冲突的散列表上执行删除操作,只能在被删结点上做删除标记,而不能真正删除结点。
(3)拉链法的缺点
&&&& 拉链法的缺点是:指针需要额外的空间,故当结点规模较小时,开放定址法较为节省空间,而若将节省的指
哈希表及处理冲突的方法
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:106908次
积分:1493
积分:1493
排名:千里之外
原创:12篇
转载:251篇
(1)(4)(1)(4)(2)(1)(1)(37)(36)(65)(67)(7)(1)(3)(31)(1)(1)(1)(1)(1)后使用快捷导航没有帐号?
BTC电子货币系统背后的技术
查看: 22345|
评论: 0|来自: 网络
摘要: 开源 Bitcoin P2P电子货币是点对点的电子现金系统,创建于2009年。无需金融机构直接点对点支付。该电子货币系统的特色是无需信托中间人,能够方便的进行互联网上 的汇款。第三方不能够控制或者阻止您的交易。Bitcoin 交 ...
开源 Bitcoin
P2P电子货币是点对点的电子现金系统,创建于2009年。无需金融机构直接点对点支付。该电子货币系统的特色是无需信托中间人,能够方便的进行互联网上
的汇款。第三方不能够控制或者阻止您的交易。Bitcoin 交易几乎免费, 而信用卡的网上在线支付系统通常收取 1-5%
的交易费用,加上其他各种费用高达数百美元。避免了中央储备银行的不良政策和不稳定性所造成的安全隐患.
Bitcoin系统的有限货币通胀是均匀分布(由CPU决定)于整个网络, 而不是由银行垄断。
这被某些人认为是最危险的开源项目,但我觉得恰恰相反,这是有史以来最令人兴奋的开源项目。这样发行的币才是真正的“人 民 币”,人民才是被服务,而不是被管理。P2P必将从商业、政治、生活各个方面重新定义新的更加公平公正的意识形态。
名词解释以及背后的技术
Bitcoin涉及到很多有意思的技术,要想搞懂bitcoin首先必须对这些技术理解和把握然后是对Bitcoin术语的理解,bitcoin最重要的
技术支撑是P2P,数字签名(EC DSA),散列(SHA256, RIPEMD-160),
POW,和HashCash。而术语则是:transaction, block,& address, Merkle Tree.
工作证明 POW(Proof-Of-Work)机制
工作证明POW系统是要求对方服务前,必须要出据某种工作证明的机制。主要用于防止拒绝服务攻击和反垃圾信息。通常这种“工作证明”会花费一定的时间计算
才能得到。最常见的例子是CAPTCHA。另外用于防止DoS和垃圾信息的机制是HashCash,bitcoin使用的原理就类似于HashCash.
HashCash 机制
hashcash 的灵感来自于这样一个想法,即一些数学结果难于发现而易于校验。一个众所周知的例子是因数分解一个大的数字(尤其是因数较少的数字)。将数字相乘来获得它们的积的代价是低廉的,但首先找到那些因数的代价却要高得多。
对交互式质询来说,因数分解足以胜任。比如,希望客户端能象征性地为其付出代价方能访问在线资源。这个时候可以定义协议,首先服务器向客户端发送一个消
息,说“只要您能因数分解这个数,我将让您得到这个资源”。没有诚意的客户端将无法得到我的资源,只有那些能够证明自己有足够的兴趣、付出一些 CPU
周期来回答这个质询的才能得到这个资源。
不过,有一些资源无法很方便地进行交互式协商。比如电子邮件反垃圾或者支付交易,怎么才能避免邮箱不被垃圾邮件所占据?“我并不介意陌生人给我写信,但
是,我希望他们能以稍微认真的态度,亲自通过对我有价值的邮件与我取得联系。至少,我不希望他们是垃圾邮件制造者,那些人向我和上百万的其他人发送包含同
样消息的邮件(double-spending),期望我们中的某些人能购买某种产品或者落入一个骗局。”而对于电子货币,内容的复制几乎是没有代价的,
如何保证电子货币(内容)没有被交易(发送)多次?这和反垃圾邮件是同样的问题。
hashcash的解决之道就是:在电子邮件的消息头中,增加一个 hashcash 戳记(hashcash
stamp)散列值;该散列中包含收件人地址,发送时间,salt,该散列值特别之处在于它至少前20位必须是0才是一个合法的hashcash戳记。为
了得到合法的散列值,发送者必须经过许多次尝试(改变salt值)才能获得。一旦生成戳记,不希望每一个给我发送邮件的垃圾邮件制造者都能重复使用它。所
以,hashcash 戳记要带一个日期。这样可以指定时间更早的戳记是非法的。另外 hashcash
的接收端要实现一个double-spending数据库,用来记录戳记的历史信息。
Bitcoin中的术语解释
散列:bitcoin在计算散列时一般会计算2次。第一轮总是使用SHA-256散列,而第二次在大多数情况下,也是使用SHA-256散列,但用于生成较短的散列(例如生成 bitcoin接收地址的时候)会用RIPEMD-160散列。
&2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa ( sha-256)
&584b75bff782a510c6cdd50 (sha-256)
生成比特币地址时(RIPEMD-160):
&2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa (sha-256)
&b6a9c8ccb450f0f (ripemd-160)
Addresses: Bitcoin Address是ECDSA公钥(public key)的散列,计算方法如下:
if 正式网络
& Version=0x00
else if 测试网络
& Version=0x6F
key_hash=Version+RIPEMD-160(SHA-256(public_key))
Checksum = SHA-256(SHA-256(Key hash))[0..3]& #取两次散列值后的前4位
Bitcoin_Address = Base58Encode(Key_hash+Checksum)
#Base58编码做了特殊处理,与通用的base58有一些区别:转换的时候
#前面的0被作为单个0保留。
电子货币系统的核心功能是面对面(点对点)支付,就像真实货币一样,无需中间人,几乎不需要交易费。它背后的技术实现是很巧妙的通过将造币(Mint),
交易(transaction,这里提到的交易都是特指的支付),交易验证(transaction
verifiction)交织在一起,形成一个完美的圆。所以要想把它的机理理解清楚,就必须同时理解bitcoin的电子货币,交易,造币的确切含义。
首先从电子货币谈起。
电子货币和交易单(Transaction)
Bitcoin电子货币解决的是:
任意造币的问题:通过“挖矿”机制保证了不能任意造币。
重复花钱的问题(Double-Spending):利用P2P网络,通过HashCash的机制。
事实上Bitcoin系统中不存在独立的电子货币,货币值是依附于交易单存在的,所以在bitcoin中的电子货币的实质就是交易单,确切的说是货币交易
(Transactions)的 数字签名链,它的数字签名使用的是ECDSA(椭圆曲线数字签名算法 secp256k1曲线)进行签名的。
&交易单的数据如下:
Previous tx: f5d8ee39aadc19d6d1a0e9cea205b009ca73dd0
scriptSig: 798a42fae0e854281abd38bacd1aeed3ee6
618cdbacb82c0e88ffdfec6b64e3e6ba35e7ba5fd
d7d5d6cc8d25c6b241501
scriptPubKey: OP_DUP OP_HASH160 fa9bd789a2fcd52d2c580b65d35
549d OP_EQUALVERIFY OP_CHECKSIG
交易单记录的是本次交易的收入来源(in)和支出(out)。当你支出(给)一笔钱的时候,首先在交易单中就要描述清楚你要支出(out)的钱的收入来源
(in),然后在支出(out)项中,指明要支出的金额,以及通过脚本的形式写明接收者的公钥,然后用自己的私钥签名(scriptSig)认可该笔交
易,最后将交易单广播到网络。
收入来源(in):
Previous tx: 为收入来源交易单的散列值,也就是待支付的钱是谁给你的,经常会有多个收入来源被列在交易单中
index: 指明是收入来源交易单中具体哪一个out,也就是Previous tx交易单中的out索引值(因为out也可以有多个)。
scriptSig: 拥有者对该交易的ECDSA签名认可。
接收对象(out):
Value: 发送的币值,以Satoshi 为单位,1BTC = 100,000,000 Satoshi
scriptPubKey: 接收方的公钥脚本。
in与out的关系:
每一笔交易,out的总额应该等于in的总额。但是,在这个交易单里,只会有out的Value,没有in的Value,而是通过in的Pervious与index,追溯到上一个交易单的某一个out,获得Value。
一次send bitcoin,剩下的钱,应该out给自己,否则这个钱就丢了。
我有10个BTC,是某一次交易获得的,我要送给朋友A,10个BTC。这时候,有一个in,一个out。
我有10个BTC,是某一次交易获得的,我要送给朋友A,5个BTC,这时候,有一个in,两个out,一个指向朋友5个BTC,一个指向我自己,得到剩下的5个BTC。
我有10个BTC,是以前的两次交易获得的,我要送给朋友A,10个BTC,这时候,有两个in,一个out。
我有10个BTC,是以前的两次交易获得的,其中一次获得了6个BTC,另一次获得了4个BTC,我要送给我的朋友7个BTC,这时候,有两个in,两个out。
// An input of a transaction.& It contains the location of the previous
// transaction's output that it claims and a signature that matches the
// output's public key.
class CTxIn
& & CScript scriptS
& & unsigned int nS
// An output of a transaction.& It contains the public key that the next input
// must be able to sign with to claim it.
class CTxOut
& & int64 nV
& & CScript scriptPubK
// The basic transaction that is broadcasted on the network and contained in
// blocks.& A transaction can contain multiple inputs and outputs.
class CTransaction
& & int nV
& & std::vector&CTxIn&
& & std::vector&CTxOut&
& & unsigned int nLockT
每一笔交易单验证追查到最后,第一笔总是“挖矿”所得,这被称为coinbase。
&如果是第一次“挖矿”所得,电子货币的内容用JSON格式表示如下:
& "hash":"b7e6c03bc780ceaa2",
& "ver":1,
& "vin_sz":1,
& "vout_sz":1,
& "lock_time":0,
& "size":135,
& & & "prev_out":{
& & & & "hash":"0000",
& & & & "n":
& & & "coinbase":"f200"
& & & "value":"50.",
& & & "scriptPubKey":"ffeacfc0c78fcf2ceeaf04dc65da13d9cdaaaa2f540e9439b f38a1eea627cb56d6ed51ef6eee6ec OP_CHECKSIG"
每一笔交易都会向整个P2P网络广播该货币的交易记录。通过投票机制,来决定该支付交易是否正常。如节点认为该交易记录是正常的那么就通过CPU计算
POW(Proof-of-Work),然后广播,其它节点收到这个POW可以继续投票,形成Block
链(见挖矿)。如果节点收到不一致的两个交易记录,那么只信任链最长的。如果一笔Bitcoin被支出两次的情况广播出来,那么某些节点将先看到它第一次
发生的支付交易,其他节点则看到的是它第二次发生的支付交易。究竟是哪一个支付交易“赢”了,则是由恰好创建了下一个block的那个节点来决定 ——
无论是哪个节点找到了“小的散列值”, 它的block中包含的那个支付交易被判断为有效的,其他的支付交易被视为无效。
接下来讲讲交易单的类型和交易验证的实现细节。
交易的类型与验证
交易单(Transaction)目前被bitcoin分为3种:按IP地址转账(Transfer)按接收地址转账(Transfer)造币(Generation)通过前面对交易单的描述,我想大家应该已经知道,交易的验证是通过不断的追溯交易单来完成的。那么交易验证的细节是如何实现的,bitcoin的交易验证
的实现细节是很意思的,它是通过脚本来实现验证的,这样bitcoin就实现了一个可被脚本扩展的行为,更加广义的”交易”,这可以保证足够的灵活性和可
扩展,可以想象也许以后会有真正的分布式计算任务跑在上面作为一笔交易。因此要想讲清楚验证的细节,就不得不从脚本系统讲起了。
Bitcoin的脚本系统是使用类FORTH语言(FORTH在嵌入式设备中是我最喜欢的一种语言)实现的,FORTH系统是面向栈的“高级机器”语言,
它兼具了高级语言的特性(面向WORD)和机器语言的高性能与小尺寸,唯一的缺点就是可读性不高,基本上可以把FORTH当一种高级的机器语言吧。
Bitcoin在实现上做了许多简化和特殊实现,所以只能算是类FORTH的系统。
在FORTH系统中所有的命令(函数)都被称为单词(WORD),所有数据的处理都要压入数据栈上进行,所以FORTH被称为面向栈的语言。
&比如 1和2相加,在FORTH系统中则是 1 2 +,数字 1,2 表示将它们压入到数据栈中(在FORTH解释器执行后实际指令会有OP_PUSH),+的操作则是将栈顶和次栈顶的数字取出并相加,并将结果压回数据栈。
Bitcoin的脚本系统的所有的操作指令(单词)见后面的附录,不是所有的操作指令都能被执行支持,因为安全上的考虑有的操作指令被禁止掉了,比如大多数的字符串操作和乘除运算。
在FORTH系统中一般会定义该系统是8位FORTH,
16位FORTH还是32/64位FORTH,这和数据栈的值长有关。在Bitcoin中的脚本系统使用的堆栈是用
(vector&vector&unsigned char&
&)来模拟的,它在数据栈的每一项都是以字符串的形式存放,它的数值是统一用CBigNum来运算的(读到这里应该明白为啥bitcoin会限制乘
除运算了),每一次从数据栈中压入(CBigNum.getvch())或者取出数值(CastToBigNum(stacktop[-1]))都要进行
一次转换。看着这样的实现,让我有点发怵,本能的不喜欢,怎么能把高效的FORTH搞成这个样子。Bitcoin的脚本系统与FORTH一样,有两个堆
栈,一个数据栈,在Bitcoin中被称为main stack,一个返回栈,在Bitcoin中被称为alt
stack(事实上在Bitcoin中将alt stack作为数据栈的中转而还没有作为FORTH意义上的返回栈).
Bitcoin的脚本系统没有实现单词定义,流程跳转,循环控制(FOR,
WHILE),对IF的实现非常丑陋。事实上我对Bitcoin的脚本实现不是十分认可,堆栈采用变长的数据值,直接将big number
作为opcode,导致每一次opcode执行开销无法控制,由于没有完整实现FORTH的控制指令,导致用trick的方式来实现IF指令,在
bitcoin中也因此无法定义新的WORD。总之我很不喜欢bitcoin的这个脚本引擎实现(参见script.cpp)。
下一篇将接着介绍下和交易验证相关的几个操作符:OP_DUP, OP_HASH160, OP_EQUALVERIFY , OP_CHECKSIG 的功能,现在有点倦了。
enum opcodetype
& & // push value
& & OP_0=0,
& & OP_FALSE=OP_0,
& & OP_PUSHDATA1=76,
& & OP_PUSHDATA2,
& & OP_PUSHDATA4,
& & OP_1NEGATE,
& & OP_RESERVED,
& & OP_TRUE=OP_1,
& & OP_10,
& & OP_11,
& & OP_12,
& & OP_13,
& & OP_14,
& & OP_15,
& & OP_16,
& & // control
& & OP_NOP,
& & OP_VER,
& & OP_IF,
& & OP_NOTIF,
& & OP_VERIF,
& & OP_VERNOTIF,
& & OP_ELSE,
& & OP_ENDIF,
& & OP_VERIFY,
& & OP_RETURN,
& & // stack ops
& & OP_TOALTSTACK,
& & OP_FROMALTSTACK,
& & OP_2DROP,
& & OP_2DUP,
& & OP_3DUP,
& & OP_2OVER,
& & OP_2ROT,
& & OP_2SWAP,
& & OP_IFDUP,
& & OP_DEPTH,
& & OP_DROP,
& & OP_DUP,
& & OP_NIP,
& & OP_OVER,
& & OP_PICK,
& & OP_ROLL,
& & OP_ROT,
& & OP_SWAP,
& & OP_TUCK,
& & // splice ops
& & OP_CAT,
& & OP_SUBSTR,
& & OP_LEFT,
& & OP_RIGHT,
& & OP_SIZE,
& & // bit logic
& & OP_INVERT,
& & OP_AND,
& & OP_OR,
& & OP_XOR,
& & OP_EQUAL,
& & OP_EQUALVERIFY,
& & OP_RESERVED1,
& & OP_RESERVED2,
& & // numeric
& & OP_1ADD,
& & OP_1SUB,
& & OP_2MUL,
& & OP_2DIV,
& & OP_NEGATE,
& & OP_ABS,
& & OP_NOT,
& & OP_0NOTEQUAL,
& & OP_ADD,
& & OP_SUB,
& & OP_MUL,
& & OP_DIV,
& & OP_MOD,
& & OP_LSHIFT,
& & OP_RSHIFT,
& & OP_BOOLAND,
& & OP_BOOLOR,
& & OP_NUMEQUAL,
& & OP_NUMEQUALVERIFY,
& & OP_NUMNOTEQUAL,
& & OP_LESSTHAN,
& & OP_GREATERTHAN,
& & OP_LESSTHANOREQUAL,
& & OP_GREATERTHANOREQUAL,
& & OP_MIN,
& & OP_MAX,
& & OP_WITHIN,
& & // crypto
& & OP_RIPEMD160,
& & OP_SHA1,
& & OP_SHA256,
& & OP_HASH160,
& & OP_HASH256,
& & OP_CODESEPARATOR,
& & OP_CHECKSIG,
& & OP_CHECKSIGVERIFY,
& & OP_CHECKMULTISIG,
& & OP_CHECKMULTISIGVERIFY,
& & // expansion
& & OP_NOP1,
& & OP_NOP2,
& & OP_NOP3,
& & OP_NOP4,
& & OP_NOP5,
& & OP_NOP6,
& & OP_NOP7,
& & OP_NOP8,
& & OP_NOP9,
& & OP_NOP10,
& & // template matching params
& & OP_PUBKEYHASH = 0xfd,
& & OP_PUBKEY = 0xfe,
& & OP_INVALIDOPCODE = 0xff,
附录Bitcoin脚本系统单词列表
参见:https://en.bitcoin.it/wiki/Script:
常量就是用来把数据压入栈中的单词:单词&&&虚拟指令(opcode)&&&输入&&&输出&&&Description
OP_0, OP_FALSE&&&0&&&Nothing.&&&0&&&压入数字0到栈中
N/A&&&1-75&&&(special)&&&data&&&将紧随 opcode 的data数据 opcode个字节压入到堆栈。opcode兼作数据长度指示。
OP_PUSHDATA1&&&76&&&(special)&&&data&&&紧随该指令的下一个字节是被压入数据大小,然后是被压入数据
OP_PUSHDATA2&&&77&&&(special)&&&data&&&紧随该指令的两个字节是被压入数据大小,然后是被压入数据.
OP_PUSHDATA4&&&78&&&(special)&&&data&&&紧随该指令的4个字节是被压入数据大小,然后是被压入数据.
OP_1NEGATE&&&79&&&无.&&&-1&&&压入-1
OP_1, OP_TRUE&&&81&&&无.&&&1&&&压入1.
OP_2-OP_16&&&82-96&&&无.&&&2-16&&&2-16被压入.
控制流单词&&&Opcode&&&输入&&&输出&&&描述
OP_NOP&&&97&&&无&&&无&&&空指令.
OP_IF&&&99&&&&expression& if [statements] [else [statements]] endif&&&If 判断指令,取出栈顶值,如果栈顶值为1, 则if后面的语句被执行,否则else中的语句被执行。
OP_NOTIF&&&100&&&&expression& ifnot [statements] [else
[statements]] endif&&&Ifnot 判断指令,取出栈顶值,如果栈顶值为0,
则if后面的语句被执行,否则else中的语句被执行。
OP_ELSE&&&103&&&&expression& if [statements] [else [statements]] endif&&&放置在 OP_IF 或OP_NOTIF 后的指令,当前面的条件不满足的时候执行
OP_ENDIF&&&104&&&&expression& if [statements] [else [statements]] endif&&&结束& if/else 执行块.
OP_VERIFY&&&105&&&True / false&&&Nothing / False&&&标记交易单无效
&如果栈顶值不为真。当栈顶值为真,移除该栈顶值,否则保留该值。
OP_RETURN&&&106&&&Nothing&&&Nothing&&&标记交易单无效.
堆栈操作Word&&&Opcode&&&Input&&&Output&&&Description
OP_TOALTSTACK&&&107&&&x1&&&(alt)x1&&&从数据栈中弹出栈顶 数据,压入辅助栈。
OP_FROMALTSTACK&&&108&&&(alt)x1&&&x1&&&从辅助栈弹出栈顶数据压入到数据栈
OP_IFDUP&&&115&&&x&&&x / x x&&&如果栈顶非0则复制栈顶
OP_DEPTH&&&116&&&Nothing&&&&Stack size&&&&获取堆栈数据个数
OP_DROP&&&117&&&x&&&Nothing&&&丢弃栈顶数据.
OP_DUP&&&118&&&x&&&x x&&&复制栈顶数据.
OP_NIP&&&119&&&x1 x2&&&x2&&&丢弃次栈顶数据
OP_OVER&&&120&&&x1 x2&&&x1 x2 x1&&&复制次栈顶数据到栈顶.
OP_PICK&&&121&&&xn … x2 x1 x0 &n&&&&xn … x2 x1 x0 xn&&&复制第n项数据到栈顶.
OP_ROLL&&&122&&&xn … x2 x1 x0 &n&&&&… x2 x1 x0 xn&&&将第n项数据移到栈顶.
OP_ROT&&&123&&&x1 x2 x3&&&x2 x3 x1&&&栈顶3项数据向左旋转.
OP_SWAP&&&124&&&x1 x2&&&x2 x1&&&栈顶2项数据交换.
OP_TUCK&&&125&&&x1 x2&&&x2 x1 x2&&&栈顶数据复制并插入到次栈顶数据前
OP_2DROP&&&109&&&x1 x2&&&Nothing&&&同 DROP,只是数据项是2项.
OP_2DUP&&&110&&&x1 x2&&&x1 x2 x1 x2&&&同 DUP,只是数据项是2项.
OP_3DUP&&&111&&&x1 x2 x3&&&x1 x2 x3 x1 x2 x3&&&同 DUP,只是数据项是3项.
OP_2OVER&&&112&&&x1 x2 x3 x4&&&x1 x2 x3 x4 x1 x2&&&同 OVER,只是数据项是2项.
OP_2ROT&&&113&&&x1 x2 x3 x4 x5 x6&&&x3 x4 x5 x6 x1 x2&&&同 ROT,只是数据项是2项.
OP_2SWAP&&&114&&&x1 x2 x3 x4&&&x3 x4 x1 x2&&&同 SWAP,只是数据项是2项.
字符串处理
字符串处理的大多数指令都被禁止了。Word&&&Opcode&&&Input&&&Output&&&Description
OP_CAT&&&126&&&x1 x2&&&out&&&Concatenates two strings. [禁止]
OP_SUBSTR&&&127&&&in begin size&&&out&&&Returns a section of a string. [禁止]
OP_LEFT&&&128&&&in size&&&out&&&Keeps only characters left of the specified point in a string. [禁止]
OP_RIGHT&&&129&&&in size&&&out&&&Keeps only characters right of the specified point in a string. [禁止]
OP_SIZE&&&130&&&in&&&in size&&&返回字符串长度
位运算Word&&&Opcode&&&Input&&&Output&&&Description
OP_INVERT&&&131&&&in&&&out&&&Flips all of the bits in the input. [禁止]
OP_AND&&&132&&&x1 x2&&&out&&&Boolean and between each bit in the inputs. [禁止]
OP_OR&&&133&&&x1 x2&&&out&&&Boolean or between each bit in the inputs. [禁止]
OP_XOR&&&134&&&x1 x2&&&out&&&Boolean exclusive or between each bit in the inputs. [禁止]
OP_EQUAL&&&135&&&x1 x2&&&True / false&&&Returns 1 if the inputs are exactly equal, 0 otherwise.
OP_EQUALVERIFY&&&136&&&x1 x2&&&True / false&&&Same as OP_EQUAL, but runs OP_VERIFY afterward.
数学运算Word&&&Opcode&&&Input&&&Output&&&Description
OP_1ADD&&&139&&&in&&&out&&&1 is added to the input.
OP_1SUB&&&140&&&in&&&out&&&1 is subtracted from the input.
OP_2MUL&&&141&&&in&&&out&&&The input is multiplied by 2. [禁止]
OP_2DIV&&&142&&&in&&&out&&&The input is divided by 2. [禁止]
OP_NEGATE&&&143&&&in&&&out&&&The sign of the input is flipped.
OP_ABS&&&144&&&in&&&out&&&The input is made positive.
OP_NOT&&&145&&&in&&&out&&&If the input is 0 or 1, it is flipped. Otherwise the output will be 0.
OP_0NOTEQUAL&&&146&&&in&&&out&&&Returns 1 if the input is 0. 0 otherwise.
OP_ADD&&&147&&&a b&&&out&&&a is added to b.
OP_SUB&&&148&&&a b&&&out&&&b is subtracted from a.
OP_MUL&&&149&&&a b&&&out&&&a is multiplied by b. [禁止]
OP_DIV&&&150&&&a b&&&out&&&a is divided by b. [禁止]
OP_MOD&&&151&&&a b&&&out&&&Returns the remainder after dividing a by b. [禁止]
OP_LSHIFT&&&152&&&a b&&&out&&&Shifts a left b bits, preserving sign. [禁止]
OP_RSHIFT&&&153&&&a b&&&out&&&Shifts a right b bits, preserving sign. [禁止]
OP_BOOLAND&&&154&&&a b&&&out&&&If both a and b are not 0, the output is 1. Otherwise 0.
OP_BOOLOR&&&155&&&a b&&&out&&&If a or b is not 0, the output is 1. Otherwise 0.
OP_NUMEQUAL&&&156&&&a b&&&out&&&Returns 1 if the numbers are equal, 0 otherwise.
OP_NUMEQUALVERIFY&&&157&&&a b&&&out&&&Same as OP_NUMEQUAL, but runs OP_VERIFY afterward.
OP_NUMNOTEQUAL&&&158&&&a b&&&out&&&Returns 1 if the numbers are not equal, 0 otherwise.
OP_LESSTHAN&&&159&&&a b&&&out&&&Returns 1 if a is less than b, 0 otherwise.
OP_GREATERTHAN&&&160&&&a b&&&out&&&Returns 1 if a is greater than b, 0 otherwise.
OP_LESSTHANOREQUAL&&&161&&&a b&&&out&&&Returns 1 if a is less than or equal to b, 0 otherwise.
OP_GREATERTHANOREQUAL&&&162&&&a b&&&out&&&Returns 1 if a is greater than or equal to b, 0 otherwise.
OP_MIN&&&163&&&a b&&&out&&&Returns the smaller of a and b.
OP_MAX&&&164&&&a b&&&out&&&Returns the larger of a and b.
OP_WITHIN&&&165&&&x min max&&&out&&&Returns 1 if x is within the specified range (left-inclusive), 0 otherwise.
加密相关Word&&&Opcode&&&Input&&&Output&&&Description
OP_RIPEMD160&&&166&&&in&&&hash&&&The input is hashed using RIPEMD-160.
OP_SHA1&&&167&&&in&&&hash&&&The input is hashed using SHA-1.
OP_SHA256&&&168&&&in&&&hash&&&The input is hashed using SHA-256.
OP_HASH160&&&169&&&in&&&hash&&&The input is hashed twice: first with SHA-256 and then with RIPEMD-160.
OP_HASH256&&&170&&&in&&&hash&&&The input is hashed two times with SHA-256.
OP_CODESEPARATOR&&&171&&&Nothing&&&Nothing&&&All of the signature
checking words will only match signatures to the data after the most
recently-executed OP_CODESEPARATOR.
OP_CHECKSIG&&&172&&&sig pubkey&&&True / false&&&The entire transaction’s
outputs, inputs, and script (from the most recently-executed
OP_CODESEPARATOR to the end) are hashed. The signature used by
OP_CHECKSIG must be a valid signature for this hash and public key. If
it is, 1 is returned, 0 otherwise.
OP_CHECKSIGVERIFY&&&173&&&sig pubkey&&&True / false&&&Same as OP_CHECKSIG, but OP_VERIFY is executed afterward.
OP_CHECKMULTISIG&&&174&&&sig1 sig2 … &number of signatures& pub1
pub2 &number of public keys&&&&True / False&&&For each signature
and public key pair, OP_CHECKSIG is executed. If more public keys than
signatures are listed, some key/sig pairs can fail. All signatures need
to match a public key. If all signatures are valid, 1 is returned, 0
otherwise.
OP_CHECKMULTISIGVERIFY&&&175&&&sig1 sig2 … &number of signatures&
pub1 pub2 … &number of public keys&&&&True / False&&&Same as
OP_CHECKMULTISIG, but OP_VERIFY is executed afterward.
伪词(Pseudo-words)
下列词汇用于在内部使用,在脚本系统中实际上不存在的词。Word&&&Opcode&&&Description
OP_PUBKEYHASH&&&253&&&表示OP_HASH160 后的公开密钥散列
OP_PUBKEY&&&254&&&表示一个公开密钥(可以被 OP_CHECKSIG).
OP_INVALIDOPCODE&&&255&&&
保留词(Reserved words)
没有被定义的opcode被保留以后使用,如果在脚本中使用这些保留词,要么被忽略,要么使得交易无效。Word&&&Opcode&&&When used…
OP_RESERVED&&&80&&&Transaction is invalid
OP_VER&&&98&&&Transaction is invalid
OP_VERIF&&&101&&&Transaction is invalid
OP_VERNOTIF&&&102&&&Transaction is invalid
OP_RESERVED1&&&137&&&Transaction is invalid
OP_RESERVED2&&&138&&&Transaction is invalid
OP_NOP1-OP_NOP10&&&176-185&&&The word is ignored.
Ok,接着描述交易验证的具体的过程。
涉及的脚本命令(操作符)
首先讲讲涉及到的脚本命令(操作符),描述栈顶项的变化方式如下:(n1 n2 — ) 用 “–”分隔操作符执行前后的栈中元素的变化,左边表示操作前,右边表示操作后。最右边的项表示栈顶元素。这里例子中,n2 表示栈顶,n1表示次栈顶,操作后n1,n2均被弹出。
OP_EQUAL(n1 n2 — true/false): 判断栈顶两项是否相等的脚本命令,如果相等则压入true,否则false
OP_VERIFY(true/false — NOTHING/false): 如果栈顶项为true,标记改交易单为有效,否则失败,压入false并返回
OP_CODESEPARATOR( — ): 将当前执行PC(ProgramCount)保存到变量: pbegincodehash
OP_CHECKSIG(&sig& &pubKey&– true/false): 校验收入来源(in)的签名是否有效。栈顶是公开密钥(PubKey),次栈顶是签名(Sig)。如果验证通过会压入True,否则压入False。
OP_EQUALVERIFY(n1 n2 — NOTHING/false): 等于 OP_EQUAL OP_VERIFY 两个操作符的联合。
以最常见的接收地址交易转账为例描述交易验证的过程(SendMoneyToBitcoinAddress)
首先示例交易如下:
& "hash":"23c9e8ac73fa4c8eeef486a4ab14107fcce54fbf768c",
& "ver":1,
& "vin_sz":1,
& "vout_sz":2,
& "lock_time":0,
& "size":258,
& & & "prev_out":{
& & & & "hash":"0740c9ecdef03e46e4c0f7cb24c7d4c6",
& & & & "n":0
& & & "scriptSig":"931b310bfec094bbd04275f69beba6bf5f44ab3dbbecbc1ddc022100d 37c214efcd31b203eb4b1c69be9d57b0e2f843ad93501
& & & a51bfecbba668c67ac975fb096d07ef65b852ac18c9c16e5887c 3f03be519fd42cae52f6d1a05d10a2fa7c783b19e9b74be07d6"
& & & "value":"12.",
& & & "scriptPubKey":"OP_DUP OP_HASH160 ef055cb1e8e192cbd8b6a89ccf1ebb OP_EQUALVERIFY OP_CHECKSIG"
& & & "value":"17.",
& & & "scriptPubKey":"OP_DUP OP_HASH160 923f3cdf648c97d22f0be6add7c7c OP_EQUALVERIFY OP_CHECKSIG"
ScriptSig(&sig& &pubKey&): 中有两个值,一是当前拥有者的该交易单的签名,二是拥有者的公开密钥(用来验证签名)。
Sig: 931b310bfec094bbd04275f69beba6bf5f44ab3dbbec9564
c34ef9bc1ddcc214efcd31b203eb4b1c69
be9d57b0e2f843ad93501
PubKey:a51bfecbba668c67ac975fb096d07ef65b852a6
864d9e9c18c9c16ebe519fd42cae52f6d1a05d10a2fa7c783b19e9b7
脚本执行验证过程:
执行 scriptSig:
压入 &sig& 和 &pubKey& : &sig& &pubKey&
执行 scriptPubKey:
OP_DUP 复制栈顶&pubKey&: &sig& &pubKey& &pubKey&
OP_HASH160 对栈顶项做HASH160(RIPEMD-160(SHA256(&pubKey&))散列: &sig& &pubKey& &pubKeyhashA&
&pubKeyHash& : 压入 &pubKeyHash&
OP_EQUALVERIFY: 对栈顶两个元素 &pubKeyHashA& &pubKeyHash& 做是否相等校验,如果不相等那么标记交易单无效并返回,如果等于继续: &sig& &pubKey&
OP_CHECKSIG: 校验收入来源的In的签名是否有效,根据pubKey去校验签名&sig&,签名的内容为交易单的Ins,
Outs和脚本(从最近一次的 OP_CODESEPARATOR 到脚本结束的位置)的散列。
PubKey.Verify(SignatureHash(scriptCode, nIn, Outs), Sig)
//nIn 当前的交易单的in的索引号
//scriptCode: 保存的当前执行的代码从OP_CODESEPARATOR(如果没有就从脚本开始) 到脚本结束。
uint256 SignatureHash(CScript scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType)
& & if (nIn &= txTo.vin.size())
& & & & printf("ERROR: SignatureHash() : nIn=%d out of range\n", nIn);
& & & & return 1;
& & CTransaction txTmp(txTo);
& & // In case concatenating two scripts ends up with two codeseparators,
& & // or an extra one at the end, this prevents all those possible incompatibilities.
& & scriptCode.FindAndDelete(CScript(OP_CODESEPARATOR));
& & // Blank out other inputs' signatures
& & for (int i = 0; i & txTmp.vin.size(); i++)
& & & & txTmp.vin.scriptSig = CScript();
& & txTmp.vin[nIn].scriptSig = scriptC
& & // Blank out some of the outputs
& & if ((nHashType & 0x1f) == SIGHASH_NONE)
& & & & // Wildcard payee
& & & & txTmp.vout.clear();
& & & & // Let the others update at will
& & & & for (int i = 0; i & txTmp.vin.size(); i++)
& & & & & & if (i != nIn)
& & & & & & & & txTmp.vin.nSequence = 0;
& & else if ((nHashType & 0x1f) == SIGHASH_SINGLE)
& & & & // Only lockin the txout payee at same index as txin
& & & & unsigned int nOut = nIn;
& & & & if (nOut &= txTmp.vout.size())
& & & & & & printf("ERROR: SignatureHash() : nOut=%d out of range\n", nOut);
& & & & & & return 1;
& & & & txTmp.vout.resize(nOut+1);
& & & & for (int i = 0; i & nO i++)
& & & & & & txTmp.vout.SetNull();
& & & & // Let the others update at will
& & & & for (int i = 0; i & txTmp.vin.size(); i++)
& & & & & & if (i != nIn)
& & & & & & & & txTmp.vin.nSequence = 0;
& & // Blank out other inputs completely, not recommended for open transactions
& & if (nHashType & SIGHASH_ANYONECANPAY)
& & & & txTmp.vin[0] = txTmp.vin[nIn];
& & & & txTmp.vin.resize(1);
& & // Serialize and hash
& & CDataStream ss(SER_GETHASH);
& & ss.reserve(10000);
& & ss && txTmp && nHashT
& & return Hash(ss.begin(), ss.end());
挖矿与块(Blocks)
接下来讲的是什么是挖矿,以及交易单在P2P网络上的存放,其实这个过程也是挖矿的过程。
所有的交易单是以Block的形式在Bitcoin P2P网络上存放的。每一个Block包含了最近所有的有效交易单。Block中最为重要数据为:
最近交易单集合
Nonce随机数
前一个块的散列值
在造币的Node总在侦听网络,接收信息,然后各自将接收到的新交易打包到一个新block(CBlock Class in
main.h)。在块交易单集合中的第一个交易单总是“造币单”:给创建该块的人以新的货币,节点只需要校验货币金额是否合法即可:形成一个合法的新块得
到的回报是初始金额为50BTC,每产生210,000块的时候这个金额减半(大约每隔4年会发生一次)。产生合法的新块是不容易的,需要通过无数次的计
算尝试得到,另外如果大家都在计算同一个新块,那么还存在竞争关系,这个时候只有最困难(Difficulty)的那个块(指整个块链的困难度值加起来最
大的)才会被网络认可。另外如果块中的某笔交易size大于该块中交易单的平均size,那么该笔交易单会被收取一笔小的交易费用。
块的数据结构
块的数据结构可以分为块头(block header)和块体(block body)
块头(Block Header)
块头的数据是用于校验块、产生块ID(256位散列值),这个块ID也是决定块是否合法的数字。计算块ID的公式如下:
BlockID = SHA256(SHA256(Block_Header))
块头(Block Header)的内容如下:
ver: 版本号(4字节)
prev_block: 前一个块的256位散列值
mrkl_root: 所有交易单的256位散列
time: 时间戳(4字节)
一个紧凑格式的4字节的数字,它表示一个256位的当前目标(Target)数值,这也表示困难度(Difficulty),最后产生块的ID值必须不大
于目标值才能被接受(如果有多人同时产生同一个块,那么最困难的将被接受)。这个数值会每隔2016个block(网络大约每小时创建6个块,创建
2016块大约2周)调整一次,当产生前一个2016块的时间大于2周的时候,难度值将会被调低,当小于两周的时候难度值将被调高(关于Target和
Difficulty详见后述)。
nonce: 32位随机数。节点在产生Block的时候,会增量尝试改变nonce的值,直到产生的块的散列值符合bits的要求
计算目标(Target)和困难度(Difficulty)
计算目标(Target)
计算目标(Target)是一个256位的数值,块的散列值ID必须小于或等于该目标数值,放可被接受。块头中的BITS是一个用紧凑的4字节格式表示的目标(Target)数值,它表示一个256位的当前目标数值,方式如下:
//假设BITS为:
BITS = 0x1B0406CC
//那么target的数值则是:
Target = 0x0406CC * 2^(8*(0x1B-3))= 0x06CC
当前网络的目标值为:Current target。
困难度(Difficulty)
困难度(Difficulty)表示该块ID的计算难度,值越大表示越困难,1表示最容易。
1困难度(Difficulty)的Target被定义为:
0x1D00FFFF(BITS)
0x00FFFF * 2^(8*(0x1D - 3)) = 0xFFFF0000
因此困难度的计算公式为:1 困难度(Target) / 当前目标
我们可以在这里查看当前网络的困难度:Current difficulty(BitCoin的 getDifficulty 接口输出)。也可以通过这个网站查看困难度值的变化情况图:Graphs。
块体(Block Body)
Block Body 实际上就是交易单的集合。
你可以在这个网站上看到当前网络所有的交易单(Blocks):&
一个具体的块的示例:
& &//hash: 自身ID的sha256散列值
& "hash":"d73c1c74a4babb057be5ad5ffed659bb",
& "ver":1,
& "prev_block":"158adac6bfeb5c08644a8",
& "mrkl_root":"cc427b79a730dca8d4a5eb6a482fa21f82cc37c84ae01ea5945fc3",
& "time":,
& "bits":,
& "nonce":,
& //交易单数量
& "n_tx":6,
& "size":2193,
& & & "hash":"67dbdbc6c4a49bc3364d34aebe76b6f470ced66eb731f9d099d0da6c58e466cf",
& & & "ver":1,
& & & "vin_sz":1,
& & & "vout_sz":1,
& & & "lock_time":0,
& & & "size":135,
& & & "in":[
& & & & & "prev_out":{
& & & & & & "hash":"0000",
& & & & & & "n":
& & & & & },
& & & & & "coinbase":"042f931d1a022301"
& & & "out":[
& & & & & "value":"50.",
& & & & & "scriptPubKey":"049db428c1bebdcf69a93c192daef8a73ebb4e1f83d4cc61 9eebc9be9e9c502fdab655ac2e95137 OP_CHECKSIG"
& & & "hash":"c96eb8f874d105e24121cdcaf27bfcc26e40938ad2",
& & & "ver":1,
& & & "vin_sz":1,
& & & "vout_sz":2,
& & & "lock_time":0,
& & & "size":258,
& & & "in":[
& & & & & "prev_out":{
& & & & & & "hash":"c8caedb7edba1e6b1dee2bf4c423db08efa570d65",
& & & & & & "n":0
& & & & & },
& & & & & "scriptSig":"b47c10ebd63363fe9cad7f0fdcbefca9dd219bd345bcfeff98a102204 9d9aa28b8f4cdccee383801
& & & & & 041fb81af0999a4add012e6580db5edc7dabf99bc2aff1a01bb10a9e2d 3ebe0daacc56e24aff1c9b130ee414f72"
& & & "out":[
& & & & & "value":"3.",
& & & & & "scriptPubKey":"OP_DUP OP_HASH160 b8f6 OP_EQUALVERIFY OP_CHECKSIG"
& & & & },
& & & & & "value":"0.",
& & & & & "scriptPubKey":"OP_DUP OP_HASH160 de7a84dcd2afed9a92 OP_EQUALVERIFY OP_CHECKSIG"
& & & "hash":"cd746bdbef02cde4bc0ed19b5cc5a869b2f51287c",
& & & "ver":1,
& & & "vin_sz":2,
& & & "vout_sz":2,
& & & "lock_time":0,
& & & "size":437,
& & & "in":[
& & & & & "prev_out":{
& & & & & & "hash":"e38b71a8ce9bac77d536d9ac5febbca104",
& & & & & & "n":1
& & & & & },
& & & & & "scriptSig":"ed5c3626adf84a6d364d7b58fb182ee3bdebe2e642e83f206 3f61a1d89c1a30f713c2ca277c08c1c4ceb585babeffdc
& & & & & 047baca4a4de705ec2b79a461 55a0d59e8a39b5d450ac73d485bdad55d5e"
& & & & },
& & & & & "prev_out":{
& & & & & & "hash":"a6fc46a5a4a6b202c644cc4854feb2d8cf7befcf695addfb4cc18138",
& & & & & & "n":1
& & & & & },
& & & & & "scriptSig":"de219304bfca0e2d7cedcf3d0124 4a1ce47c2f3aab6c205e75e433371efb01dad488ea1ad064301
& & & & & 04d74d74c0f2bd415a94090c83bbe10bf3bbfb50f3e1ddc5ab79a28b1228e af5e4f34a00ef6a5"
& & & "out":[
& & & & & "value":"0.",
& & & & & "scriptPubKey":"OP_DUP OP_HASH160 efc37bb2aabd3a6ac99 OP_EQUALVERIFY OP_CHECKSIG"
& & & & },
& & & & & "value":"2.",
& & & & & "scriptPubKey":"OP_DUP OP_HASH160 234c6c0dc OP_EQUALVERIFY OP_CHECKSIG"
& & & "hash":"9d4f130995dbc1ddcc95eff51dc00109afc5cad7d",
& & & "ver":1,
& & & "vin_sz":1,
& & & "vout_sz":2,
& & & "lock_time":0,
& & & "size":258,
& & & "in":[
& & & & & "prev_out":{
& & & & & & "hash":"d84cd74d4b470f9c43be544e4e57f33e83fc8bf26f232ec5ea97b5",
& & & & & & "n":0
& & & & & },
& & & & & "scriptSig":"d8f3bbb19b4df6acfce1fb60ed5 adb52e37f87592bea7bae84c883cf2e52e7eb061e201
& & & & & f57cccf442eebca7e9f6c96ca1ec754b9d8a9f2bd727a15c78 21cbcaff29c166dc71b"
& & & "out":[
& & & & & "value":"30.",
& & & & & "scriptPubKey":"OP_DUP OP_HASH160 7fa1dc6bc1b23ff644ef OP_EQUALVERIFY OP_CHECKSIG"
& & & & },
& & & & & "value":"4.",
& & & & & "scriptPubKey":"OP_DUP OP_HASH160 847fa2103796cca3d58 OP_EQUALVERIFY OP_CHECKSIG"
& & & "hash":"60e1e5e9eb3de523a6f26d8b880eb7",
& & & "ver":1,
& & & "vin_sz":4,
& & & "vout_sz":1,
& & & "lock_time":0,
& & & "size":766,
& & & "in":[
& & & & & "prev_out":{
& & & & & & "hash":"07aefb329afa037f8ae425c3e",
& & & & & & "n":17
& & & & & },
& & & & & "scriptSig":"c3ce1ee6c222d74ff9c97d2c3cabdb61ea0fb3ae8632eae36f03fb02210 09cea5a9f94fe14e50e1d151f6e846c371d8e4af72b5d213bb5c001
& & & & & 04ee9e4cac91eec04abdc4ec00b14dc01e56c26acf90f 1cb1bdd3e3ca0b3e3acbdb"
& & & & },
& & & & & "prev_out":{
& & & & & & "hash":"07f95bfdd09e98bf7ce0543e8fdd82f9e67f69aa3d1f",
& & & & & & "n":0
& & & & & },
& & & & & "scriptSig":"fe5ce8a32edc836e420d2347dae9df12e1022018d 9d4e48dea2b821e01d3253dfaa03af801d01e79ab4eb3ef48f22f84f196aa01
& & & & & eafea724f7c13e1df6c43afb8e4f6f9abd8eae75 12a3dbeb36109d3fcb6391fbcfd0a3"
& & & & },
& & & & & "prev_out":{
& & & & & & "hash":"6cfbf2a386ba53bc3aad8f5bcdda73b855a24628d7eae80cf3f9",
& & & & & & "n":0
& & & & & },
& & & & & "scriptSig":"b688feeb6b5b9bdb61b48a0edffc9a1f202210 0eda732e646ba5af7ed5a0d896c7db0a10757aeccc9c58a67ec42ec7501
& & & & & 047e79adbe50aebfdaecb866b261755cbba27fe344c6fc67f3fc2593edc 0bb053b0fde62c4d42d152b6525c10bde365d80a8d2d8d77a85"
& & & & },
& & & & & "prev_out":{
& & & & & & "hash":"ed416acb1373bcce28ec63e6e600e0da7fbce8c034f",
& & & & & & "n":1
& & & & & },
& & & & & "scriptSig":"c1ffdf383d108a9b1e8e33ed3ef8bd6b368b1edebfc5b02210 0f7bfb8f0b17c3bd04a8a28b6a63d9cd4501
& & & & & 04ee9e4cac91eec04abdc4ec00b14dc01e56c26acf90f 1cb1bdd3e3ca0b3e3acbdb"
& & & "out":[
& & & & & "value":"1.",
& & & & & "scriptPubKey":"OP_DUP OP_HASH160 71b9ea593ba56db37a03f368fb6c40 OP_EQUALVERIFY OP_CHECKSIG"
& & & "hash":"4e6e47f0fa7a9db20c5ccf47dc8ca92",
& & & "ver":1,
& & & "vin_sz":1,
& & & "vout_sz":2,
& & & "lock_time":0,
& & & "size":258,
& & & "in":[
& & & & & "prev_out":{
& & & & & & "hash":"897f67e6ec0b5a64b511ce1bb",
& & & & & & "n":1
& & & & & },
& & & & & "scriptSig":"dbe53f77f947b12dfabb737edb06c08710ccdb0b 379ab597d8df20e68c1ee7eaad83801
& & & & & 04bdd996cd29ca3d83d1fadf978ae43c12c1e832ce803ae5a40dc1e5f caac622c82e271b59c66fb1f8fa7edf"
& & & "out":[
& & & & & "value":"0.",
& & & & & "scriptPubKey":"OP_DUP OP_HASH160 50e44bbe08cda95eb43a9c621fa0ac OP_EQUALVERIFY OP_CHECKSIG"
& & & & },
& & & & & "value":"0.",
& & & & & "scriptPubKey":"OP_DUP OP_HASH160 ecd8feed4f98dbccb86b4 OP_EQUALVERIFY OP_CHECKSIG"
& "mrkl_tree":[
& & "67dbdbc6c4a49bc3364d34aebe76b6f470ced66eb731f9d099d0da6c58e466cf",
& & "c96eb8f874d105e24121cdcaf27bfcc26e40938ad2",
& & "cd746bdbef02cde4bc0ed19b5cc5a869b2f51287c",
& & "9d4f130995dbc1ddcc95eff51dc00109afc5cad7d",
& & "60e1e5e9eb3de523a6f26d8b880eb7",
& & "4e6e47f0fa7a9db20c5ccf47dc8ca92",
& & "fd154dc1b35d8fffaceaa25da17ebad5",
& & "b63d4760f81eda7ae90b79a224ba704a3c21fd6feb",
& & "0427a2dbd54fa6ec034d5f6c139e6d7b9bf803714cfbc9dcc61b85",
& & "c91336e69bae9f7eb39b1c6d94bea5f675a25a082",
& & "4af79ccb4bf857df3e75aaa73a209efa3ff70ab93d",
& & "cc427b79a730dca8d4a5eb6a482fa21f82cc37c84ae01ea5945fc3"
刚表态过的朋友 ()}

我要回帖

更多关于 infohash 得到磁力链 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信