区块链基础二

Posted by Alex Kinhoom on July 4, 2018

输入和输出

输入是对其他交易输出的引用。一个交易中通常列有多个输入。所有被引用的输出值相加。得到的总和值会在该交易A的输出中用到。previous tx是以前交易的hash值,index是被引用交易的特定输出号,scriptSig是一个脚本的前一半。
脚本包含两个部分,一个签名一个公钥,公钥属于交易输出的收款人,并且表明交易创建者允许收款人获得的输出金额。另一部分是ECDSA签名,是通过对交易的hash值进行ECDSA签名而得到的。签名和公钥一起。证明原地址的真正所有者创建了该交易。
输出中包含了发送比特币的指令。金额value以聪Satoshi,1BTC = 100000000聪它们共享了输入金额。scriptPubKey是脚本的另一半,可以有多个输出,它们共享了输入金额。一个交易中的每一个输出都只能被后来的交易当成输入引用一次。如果你不想丢币。那就需要把所有输入值的总和值发送到一个输出地址。如果输入的是50BTC,但是你仅想发送25BTC。那么比特币将创建225BTC的输出,一个发往目标地址,一个则回到你的地址称之为找零。在交易的过程中,会产生一笔交易费。作为交易费支付的任何比特币都不能被赎回。生成这个区块矿工将获得这笔交易费。
为了验证某个交易的输入已经被授权,可以收集被引用的输出中的所有金额,输入的scriptSig和被引用的输出的scriptPubKey会按顺序执行。如果scriptPubKey返回真。则输入被授权。证明是地址拥有人发出了比特币。

交易类型

根据目标地址的不同。可以把交易分成以下几种类型。

  • 支付到公钥hash
    scriptPubKey: OP_DUP OP_HASH160 <pubKeyHash> OP_EQUALVERIFY OP_CHECKSIG
    scriptSig: <sig><pubKey>
    

    一个比特币地址只是一个Hash值。因而发送者无法在scriptPubKey中提供完整的公钥。当要赎回比特币时。接受者需要同时提供签名scriptSigscriptPubKey,脚本会验证公钥的Hash值与scriptPubKey中的Hash值是否匹配。同时会检查公钥和签名是否匹配。

  • 支付到脚本hash 该类交易非常有意义。未来应该会在某些场合频繁使用。该类交易的接收地址不是通常意义上的地址。而是一个多签地址,以3开头。比如,三对公钥对可以生成一个多签地址。以3开头。需要在生成过程中指定n of 3中的nn的范围是[1,3],若n = 1,生成一个私钥签名即可花费该地址的币。若n=3,则需要3把私锁依次签名才可以。
    地址以3开头,可以实现多方管理资产。极大的提高安全性,可以轻松的实现基于比特币原生的三方交易担保支付。一个m-of-n的模式。 其中,1<=n<=20,m<=n mn可以是1 of 1,1 of 2,2 of 3等组合,通常选择n = 3
    1 of 3。最大程度私锁冗余,防止私钥损失,3把私钥中任意一把即可签名发币,即使丢失2把也可以保障不受损失。
    2 of 3,提高私钥冗余度的同时解决单点信任问题,3把私钥中的任意2把私钥可签名发币。适用于中介交易。
    3 of 3,最大程度解决资金信任问题,无私钥冗余。

找零地址

在实际的区块链交易中。设A有一个比特币地址,里面包含有还没有花费的10个比特币,B也有一个比特币地址,里面一分钱也没有。 A->B支付10个比特币,A地址未花费比特币变为0,B的则会变为10BTC。不存在找0的问题。
假设A的地址上有35个比特币,A->B 支付8个比特币时,只需要使用包含着20个比特币的那一笔未消费支出,并设置好支持的金额即可。剩下的12个比特币则会返回给A,以便A在将来可以继续使用。
这样就有了一个找零机制,实际上,比特币在交易时会把消费时所用的地址的余额设置为0,当需要支付的金额小于可用余额时,在交易信息中必须告诉比特币网络零钱将要被发送到那个地址,即找零地址,找零地址可能是也可能不是原先的发送地址。除此之外,发送地址所留下的剩余款项将由网络作为交易费支付给矿工,A可以选择将找回的零钱发送到一个新创建的找零地址上。或者将原先发送的地址设置为找零地址。并将零钱返回。
设置原先地址为找零地址的话,AB的隐私性匿名性都会降低,而创建新的找零地址,那么其他人所知道的,只有一个交易拆分了地址A的余额至地址B和C,而B和C 的主人可以也可能不是A。所以要想知道其主人,就必须消耗更多的资源。

区块和区块链

比特币网络中,数据会以文件的形式被永久记录,我们称这些文件为区块。在绝大多数情况下,新区快被加入到记录的最后,一旦写上,就无法删除和修改,每一个区块记录了他被创建之前发生的所有事件。

  • 区块结构
    数据项 | 描述 | 大小
  • Magic no 魔法数 总是0*D9B4BEF9 4字节
    Blocksize 区块大小 到区块结束的字节长度 4字节
    Blockheader 区块头 包含6个数据项 80字节
    Transaction counter 交易数量 正整数VI=VarInt 1 ~ 9 字节
    Transactions 交易列表(非空) -许多交易

在每个区块中,对整个区块链起决定性作用的是区块头。

  • 区块头
    字节 | 字段 | 说明
  • | :-: | :-: | -: 4 | 版本 | 区块版本号,表示本区块遵守的验证规则 32 | 父区块头哈希值 | 前一区块的哈希值,使用SHA256(SHA256(父区块头))计算 32 | Merkle根 | 该区块中交易的Merkle树根的哈希值,同样采用SHA256(SHA256())计算 4 | 时间戳 | 该区块产生的近似时间,精确到秒的UNIX时间戳,必须严格大于前11个区块时间的中值,同时全节点也会拒绝那些超出自己2个小时时间戳的区块 4 | 难度目标 | 该区块工作量证明算法的难度目标,已经使用特定算法编码 4 | Nonce | 为了找到满足难度目标所设定的随机数,为了解决32位随机数在算力飞升的情况下不够用的问题,规定时间戳和coinbase交易信息均可更改,以此扩展nonce的位数 说明:

版本、父区块头哈希值和Merkle根采用的是小端格式编码,即低有效位放在前面。 时间戳表示的是自1970年1月1日0时0分0秒以来的秒数,1231731025秒转为十六进制值为0x496AB951,然后采用小端格式编码表示为0x51b96a49。 难度目标486604799转化为十六进制值为0x1d00ffff,该值采用小端格式编码。而当前区块的难度值0x1d00ffff需要采用一种特殊的编码方式才能正确转化为目标哈希值。 随机数nonce表示的随机数值转化为十六进制为0x709E3E28,然后采用小端格式编码表示为0x283e9e70。

创世区块

区块链创世块得意思就是,链上出来的第一个区块,也称为 原始区块 ,整个区块链所有的区块,只有创世块,第一个块出现后,接下来才会进行第二个第三个区块的产生,比特币创世块意识就是比特币链上出现的第一个区块。

矿池的分配模式

PPLNS模式:(最纯正的组队挖矿)全称Pay Per Last N Shares,意思是说“根据过去的N个股份来支付收益”,这意味着,所有的矿工一旦发现了一个区块,大家将根据每个人自己贡献的股份数量占比来分配区块中的货币。 在PPLNS模式下,运气成份非常重要,如果矿池一天能够发现很多个区块,那么大家的分红时间会非常快,如果矿池一天下来都没有能够发现区块,那么大家当天也就没有任何收益,收益要等到你参加的区块被完全挖掘出来才能得到分配。同时,由于PPLNS下,具有一定的滞后惯性,你的挖矿收益会有一定的延迟,比如说,你加入到一个新的PPLNS矿池,这个时候你会发现前面几个小时的收益比较低,那是因为别人在这个矿池里已经贡献了很多个share了,你是新来的,你的贡献还很少,所以分红时你的收益都是比较低的。随着时间的推移,该结算的也结算了,大家又开始进行了新一轮的运算时,你就回到和别人一样的水平了。同样道理,若你离开了PPLNS矿池不再挖矿,你贡献的share还在,在此后的一段时间里,你依然会得到分红收益,直到你的share被结算完毕。 PPS模式:Pay-Per-Share方式—该方式为立即为每一个share支付报酬。该支出来源于矿池现有的比特币资金,因此可以立即取现,而不用等待区块生成完毕或者确认。这样可以避免矿池运营者幕后操纵。这种方法减少了矿工的风险,但将风险转移给了矿池的运营者。运营者可以收取手续费来弥补这些风险可能造成的损失。为了解决PPLNS那种有时候收益很高,有时候没有收益的情况,PPS采用了新的算法。PPS根据你的算力在矿池中的占比,并估算了矿池每天可以获得的矿产,给你每天基本固定的收益。 PROP模式:比特币区块的产生是:由矿池发现区块后向全网络广播,经过120次确认后,才会产生区块。PPS模式是:矿工每贡献一点速度,矿池就向矿工支付相应的比特币,矿池的币还是要来自真正的区块产生,只不过在真正的区块产生之前,矿池就提前支付给了矿工。PROP模式是:矿池经过120次确认产生真正区块后,会把比特币按每个矿工的贡献分配给矿工,这种模式更符合比特币区块的产生。在PROP模式,即使暂时没有产生真正的区块,以后产生出来了真正的区块,还是会根据挖这个区块的贡献,分配给每个矿工。矿工挖矿至少都是挖几个月,甚至几年,所以从长远来看,这两种模式挖出币的数量是一样。