一文看懂怎样用 Python 创建比特币澳门永利yl网址

2018-04-04 15:20

 

比特币价格的上上下下,始终撩动着每一个人无比关切的小心脏。从去年初的 800 美元左右,飞涨到去年底到 19783.21 美元最高点,不到1年,便有将近 25 倍的升值速度。尽管眼下又掉回 8000 多美元的价格,但价格差不多能搞出去年同期一个数量级,币圈人士“过去一年比以往 10 年挣的都多”,已经是不争的事实。

而对区块链开发者来说,据说也已经有拿到年新 500 万的天价。所以“跑步进入区块链”,已经成为不少程序员的共识。但是看过很多远离,我们如何才能迅速上手呢?国外网友 Ken Shirriff 在博客中分享了他在手动茶古剑比特币澳门永利yl网址时的代码与对比特币协议的心得,区块链大本营编译如下。

 

近期,媒体行业对比特币表现出极大的热情,这鼓舞着我从网络底层的数据流开始,认真学习比特币的工作原理。通常人们会使用钱包软件来进行比特币澳门永利yl网址,钱包软件在方便用户的同时,向用户隐藏了比特币的澳门永利yl网址流程,而我想亲自动手来体验比特币澳门永利yl网址,我的目标是用Python手动创建一笔比特币澳门永利yl网址,以十六进制数据的形式将澳门永利yl网址广播到比特币网络中,然后观察这笔澳门永利yl网址是怎么被加入到区块链中的。事实证明,这个过程很有趣,希望你也对它感兴趣。

 

在本篇文章中,首先我会对比特币进行一个简单的概述,之后,我会从以下几个方面带领你们学习比特币:创建一个比特币地址(比特币中的账户),进行一笔比特币澳门永利yl网址,签署澳门永利yl网址,将澳门永利yl网址广播到比特币网络中,最后等待澳门永利yl网址的确认。

 

比特币简述:

 

首先,我会介绍一下比特币系统是怎么运转的,然后再深入探讨整个细节。比特币是一个基于点对点网络的电子货币,你可以用现金在网上购买比特币,用比特币向他人转账,在有些商家,你可以像使用支付宝一样使用比特币付款,当然,你也可以卖出所持有的比特币换回现金。

 

简而言之,在比特币网络中,分布式账本(区块链)记录并随时更新着每个比特币的所有权。与银行不同的是,比特币并没有与个人或个人的账户绑定,相反的,比特币只属于一个个比特币地址,比如:1KKKK6N21XKo48zWKuQKXdvSsCf95ibHFa。这里你可能已经绕晕了,难道这段字符中藏着比特币?当然不是,比特币地址是比特币网络中的一个身份,也可以通俗地说是你在比特币中开的一个“银行账户”,我们用这个“账户”来进行澳门永利yl网址。在网站:blockchain.info中,你可以查到所有的澳门永利yl网址信息:

 

比特币账户信息

 

但是怎么证明这个账户是我的呢,不急,先往下看,你的疑问我会为你一一解答。

 

比特币澳门永利yl网址

 

如何如何使用现金一一圈用途比特币?这是一个创建一个笔。在一个笔澳门永利yl网址中,比特兰的猎犬(上文提到过比特征的所有怪物是在特色地区)将所有望转移到一卷新的比特拉地址。比特价的一个颠覆性创新闻(銇鼓励銈銈銈銈銈銈銈銈銈銈銈銈銈銈銈銈銈銈銈除了比特币网站中产一,为区块链记录的一分,为之,为之,为之了,为之,为之了,为之了。所以是一个东西。现在是一切成人的。记账呢?是矿工,矿工的挖矿程梦是在往区块链中记账,矿工要核实笔澳门永利yl网址澳门永利yl网址正式,核实核实后,矿兵们开始,矿们的数学题(发音中的圆数),最早算出答案答案的人就生成一卷区块,也叫挖出了一个新的区块,这个挖出将成为之,这个区块将成为之的新一分。

 

也许你会问了,明明是记账,干着会话的活,为什么叫挖矿呢?和传统叫挖矿呢?和传统在地下挖矿石矿石一般,比特币挖矿也会有很多。比特价的历程,当前,每每到一个,矿个比得到系统奖励的12.5个比特兰,按目前一个比特币一件美丽的市场,这就是一个12.5万美丽的巨款。户外,工工还可以是本地区块中所说的,举例来,在高度为512587的区块中,幸运的矿矿总共了12.829个比特拉。正因如此,工工之间的激烈,采矿的难度与工工间歇的是比特征安妮的重要,而是这样可以保证有人能操纵系统。

 

点对点网络

 

比特币有一张中间央闻具器,相反,比特币在一起,在一起,比你行一间比特币节,那你就成是网友,那特币网站中的一分。块,以及ip地址信息(用作节点间建立建立互相通信)。当你一九次到比特色网站,你的念堂从随中间下游区块链的。反进来,你的节点也会向后加入信息。当你要创建一件儿比特征,你,你要把这澳门永利yl网址发表给一绝一音,这些节点会在当时的特点网站中广播笔笔澳门永利yl网址,直到全网都收澳门永利yl网址到这笔澳门永利yl网址。矿工理会话你的象征,生成一件儿没有你这笔,向全网广播,你的节点也会收到这个信用,通讯验证,这这澳门永利yl网址澳门永利yl网址加入到了中,你就澳门永利yl网址成了。 

 

加密技术

 

现在回到证明比特币账户是谁的这个问题。比特币使用数字签名技术以确保只有比特币账户的所有者才能使用账户中的比特币。比特币地址的所有者拥有与该地址相匹配的私钥,当花费比特币时,你用要这个私钥在澳门永利yl网址上签名,证明自己是这个账户的所有者。这有点像现实生活中的盖章,盖章就意味着授权。怎么验证呢,公钥与比特币账户相关联,用公钥就可以验证签名是否正确。这样就解决了比特币账户是谁的这个问题。

 

怎么来区分不同的澳门永利yl网址呢?澳门永利yl网址和区块都使用密码学上的哈希值进行索引,是不是有点耳熟,对,在比特币协议中,多处使用到了哈希函数,矿工们刚才算的数学题就是在算哈希函数。

 

比特币协议探究

 

在接下来的文章里,我将逐步介绍我是怎样手动进行一次比特币澳门永利yl网址的。首先,我生成了一个比特币账户以及对应的公钥,私钥。接下来我发起了一笔比特币澳门永利yl网址,我向这个新生成的账户转了一小笔比特币。期间手动签署这笔澳门永利yl网址很困难,它花费了我很多的时间。最后,我将这笔澳门永利yl网址发送到比特币网络,等待它被加入区块链。本文的其余部分会详细地介绍这些步骤。

 

事实证明,手动进行比特币澳门永利yl网址比我想象中的更加困难。正如你所看到的,比特币的协议有些许混乱:它使用了大端格式数字(高位编址,将高序字节存储在起始地址),小端格式数字(低位编址,将低序字节存储在起始位置),固定长度数字,可变长度数字,自定义编码格式,DER编码格式以及各种加密算法。因此,仅仅是将数据转换为正确的格式就浪费了很多时间。

 

我遇到的第二个难题就是加密,尝试一下手动加密,你就会发现密码学对人们多不友好,甚至可以说是无情。即使你只输错了一个字节,澳门永利yl网址就会因出错被拒绝,而且它不会告诉你哪里出错了,你只能重来。

 

最后,手动签署澳门永利yl网址的过程也比想象中难得多,签署澳门永利yl网址时每个环节都必须零失误,要么又要退回重来。

 

比特币地址和密钥

 

第一步,我创建了一个比特币地址。通常情况下,人们都是使用比特币客户端软件来创建比特币地址和与之相关的密钥。本着学习的态度,我写了一些Python代码来生成比特币地址,从而揭示地址创建的机理。

 

比特币使用了一系列的密钥和地址,下图解释了它们的关系。首先你要创建一个随机的256位的私钥,这个私钥用于在花费比特币时签署澳门永利yl网址。因此,私钥必须保密,否则你的比特币可能会被盗用。

 

椭圆曲线数字签名算法(Elliptic Curve Digital Signature Algorithm,ECDSA,美国政府的标准,接下来我们会讨论它)会从私钥中生成一个512位的公钥,这个公钥用于验证澳门永利yl网址的签名。但不方便的是,比特币协议中需要在这个公钥上添加了前缀04,这个公钥在澳门永利yl网址签署之前不会被泄露,不像其它系统中公钥就是为了公之于众的。

 

比特币地址与公钥的关系

 

下一件事是生成与人澳门永利yl网址时机的比特币了地址.512位的公园太长不方式使因此使哈希算将其小为160位。然后然后使用比特征定义的base58Check编码将密钥编码别为ascii(美国信息交汇处的美国标准代码,美国信息息标准代码)格式的地址,你无法从比特价地址中间复原出出出或或私钥或或或或或或或或或或或或或或私钥私钥私钥私钥私钥私钥私钥私钥私钥私钥私钥私钥私钥私钥私钥私钥私钥私钥私钥私钥私钥私钥私钥私钥私钥私钥私钥私钥私钥私钥丢失了私钥私钥私钥私钥私钥丢失你私钥私钥如果你你你私钥私钥私钥私钥或私钥私钥你私钥私钥私钥私钥

 

最后,钱包交换格式密钥(WIF)用于将私钥添加到你的钱包软件中,这只是将私钥进行Base58Check编码转换为ASCII格式,这一步是可逆的,而且很容易经过逆变换恢复出256位的私钥。(图中有我的私钥,我很好奇是否有人会用我的私钥去偷(通过私钥签署澳门永利yl网址,从而转走)我那价值80美分的比特币,然而真有人那么做了,可以在

//blockchain.info/address/1KKKK6N21XKo48zWKuQKXdvSsCf95ibHFa 看到,也算是为教学做贡献了。)

 

总之,共有三种密钥:私钥,公钥,公钥的哈希值,经过使用Base58Check编码,它们对外都是以ASCII格式表示。私钥是其中最重要的密钥,因为花费比特币时需要私钥签署澳门永利yl网址,而且其他的密钥都可以从私钥中产生。公钥的哈希值就是你们刚看的的比特币地址。

 

我使用下面的代码片段来生成WIF格式的私钥和地址。私钥只是一个随机的256位的数字,使用椭圆曲线数字签名算法从私钥中生成公钥,公钥使用SHA-256算法,RIPEMD-160算法进行哈希计算,再经Base58编码并进行校验后得到比特币地址。最后,私钥用Base58Check编码以生成用于将私钥输入钱包软件的WIF编码。注意,这段Python随机函数代码在密码学上安全性并不高,如果你想要尝试这一步骤,建议使用更安全的钱包软件来生成比特币地址和密钥。

 

def privateKeyToWif(key_hex):       return utils.base58CheckEncode(0x80, key_hex.decode('hex'))    def privateKeyToPublicKey(s):   sk = ecdsa.SigningKey.from_string(s.decode('hex'),曲线= ECDSA.SECP256K1)   vk = sk.verifying_key   
   return ('\04'+ sk.verifying_key.to_string()).encode('hex')  
 def pubKeyToAddr(s):   ripemd160 = hashlib.new('ripemd160')    ripemd160.update(hashlib.sha256(s.decode('hex')).digest())    
   return utils.base58CheckEncode(0, ripemd160.digest())

def keyToAddr(s):    
   return pubKeyToAddr(privateKeyToPublicKey(s))

# Warning: this random function is not cryptographically strong and is just for example
private_key = ''.join(['%x'% random.randrange(16) for x in range(0, 64)]) print keyUtils.privateKeyToWif(private_key) print keyUtils.keyToAddr(private_key)

keyUtils.py

 

从内部分析一笔澳门永利yl网址

 

澳门永利yl网址是比特币系统的基本操作,也许你会认为澳门永利yl网址就是简单地把比特币从一个地址转移到另一个地址,但澳门永利yl网址其实并不简单。一笔澳门永利yl网址包含一个或多个输入和输出,澳门永利yl网址中的每个输入的地址都提供比特币,每个输出的地址都接受比特币。

 

一笔简单的比特币澳门永利yl网址,澳门永利yl网址C花费了从澳门永利yl网址A和澳门永利yl网址B获得的0.008个比特币,其中0.001个比特币被当作澳门永利yl网址费付给矿工

 

上图显示了一笔简单的比特币澳门永利yl网址“C”,在这笔澳门永利yl网址中,有0.005个比特币是在澳门永利yl网址A中获得的,0.003个比特币是在澳门永利yl网址B中获得的。(图中箭头是由新澳门永利yl网址的输入指向得到这些比特币的澳门永利yl网址的输出,所以比特币的流向是逆着箭头方向的。)对于输出,有0.003个比特币给了第一个比特币地址,有0.004个比特币给了第二个比特币地址,剩余的0.001个比特币作为澳门永利yl网址费付给矿工。请注意,本次澳门永利yl网址并没有影响到在澳门永利yl网址A中另一个输出为0.015的比特币。 

 

在一笔澳门永利yl网址中,输入的比特币地址必须花出所有的比特币,假如你在之前的澳门永利yl网址收到了100个比特币,但你只想花1个比特币,创建这笔澳门永利yl网址你必须花完所有的100个比特币,那剩下的99个比特币怎么办呢?解决方案就是在澳门永利yl网址中再增加一个输出,将剩余的99个比特币转给自己。这样你就可以花费任意数额的比特币。 

 

通常澳门永利yl网址要支付澳门永利yl网址费,如果一笔澳门永利yl网址中输入的比特币总和大于输出的比特币的总和,剩余的费用就是给矿工的澳门永利yl网址费。这笔费用并没有明确要求,但是对于矿工而言,没有澳门永利yl网址费的澳门永利yl网址就会被列为低优先级澳门永利yl网址,可能要等上几天才会被处理甚至被矿工直接丢弃。澳门永利yl网址费通常并不高,但它可能影响着你的澳门永利yl网址。

 

手动创建一笔澳门永利yl网址

 

如下图所示,在我的实验中我发起了一笔只有一个输入一个输出的澳门永利yl网址。我在Coinbase上买了一些比特币,并将0.00101234个比特币放入地址:

1MMMMSUb1piy2ufrSguNUdFmAcvqrQF8M5中,这笔澳门永利yl网址哈希为:

81b4c832d70cb56ff957589752eb4125a4cab78a25a8fc52d6a09e5bd4404d48,我的目标是创建一笔澳门永利yl网址,将这些比特币转入我的另一个地址:

1KKKK6N21XKo48zWKuQKXdvSsCf95ibHFa,扣除0.0001个比特币的澳门永利yl网址费后,目标地址将获得0.00091234个比特币。

比特币澳门永利yl网址结构实例

 

 Blockchain.info上的澳门永利yl网址记录

//blockchain.info/address/1MMMMSUb1piy2ufrSguNUdFmAcvqrQF8M5?filter=4

 

按照协议标准,创建这笔澳门永利yl网址很简单。如下表所示,这笔澳门永利yl网址只有一个输入,源自于81b4c832d70cb56ff957589752eb4125a4cab78a25a8fc52d6a09e5bd4404d48中的输出0(第一个输出)。输出为0.00091234个比特币(91234在十六进制中用0x016462表示),它以小端格式存储在值区域中。加密过程中的scriptSig和scriptPubKey较为复杂,我们稍后再做讨论。

version

01 00 00 00

input count

01

input

previous output hash(reversed)

48 4d 40 d4 5b 9e a0 d6 52 fc a8 25 8a b7 ca a4 25 41 eb 52 97 58 57 f9 6f b5 0c d7 32 c8 b4 81

previous output index

00 00 00 00

script length

 

scriptSig

script containing signature

sequence

ff ff ff ff

output count

01

output

value

62 64 01 00 00 00 00 00

script length

 

scriptPubKey

script containing destination address

block lock time

00 00 00 00

这是我生成澳门永利yl网址使用的代码,这段代码只是把数据打包成二进制文件。签署澳门永利yl网址较为困难,我们等一会儿再说。

 


 

# Makes a transaction from the inputs# outputs is a list of [redemptionSatoshis, outputScript]
def makeRawTransaction(outputTransactionHash, sourceIndex, scriptSig, outputs):   
         def makeOutput(data):             redemptionSatoshis, outputScript = data
             return (struct.pack("<Q", redemptionSatoshis).encode('hex') +
              '%02x'% len(outputScript.decode('hex')) + outputScript)           formattedOutputs = ''.join(map(makeOutput, outputs))
          return (        
              "01000000"+ # 4 bytes version              "01"+ # varint for number of inputs             outputTransactionHash.decode('hex')[::-1].encode('hex') + # reverse outputTransactionHash              struct.pack('<L', sourceIndex).encode('hex') +        
              '%02x'% len(scriptSig.decode('hex')) + scriptSig +        
              "ffffffff" + # sequence               "%02x"% len(outputs) + # number of outputs              formattedOutputs +        
              "00000000" # lockTime
              )

txnUtils.py

 

比特币澳门永利yl网址怎样签署

 

下图为我们简单描述了澳门永利yl网址是如何签署并相互连接的。针对中间这笔从比特币地址B转账到比特币地址C的澳门永利yl网址。澳门永利yl网址的内容(包括前一个澳门永利yl网址的哈希值(索引))被进行哈希计算并用B的私钥签名。另外,B的公钥也被包含在了澳门永利yl网址中。 

 

通过执行几个简单运算,任何人都能验证B是否签署了这笔澳门永利yl网址。首先,B的公钥与之前收到这笔比特币澳门永利yl网址的地址做验证,证明B的公钥有效。(正如前面所说的,地址很容易从公钥中计算获得)。接下来,可以通过B的公钥验证B澳门永利yl网址签名的真伪。这些步骤能确保澳门永利yl网址的有效性和澳门永利yl网址得到B的授权。比特币于众不同的一点是,B的公钥在B发起澳门永利yl网址之前是不公开的。 

 

在比特币系统中,比特币通过区块链上的一笔笔澳门永利yl网址在不同的地址间传递。区块链上的每一笔澳门永利yl网址都能被验证以确保比特币澳门永利yl网址的有效性。

 

比特币脚本语言

 

你可能会以为仅仅通过在澳门永利yl网址内容中附上签名就可以签署比特币澳门永利yl网址,其实不然,这个过程十分复杂。实际上,每一笔澳门永利yl网址中都包含一个“小程序”,用于确认澳门永利yl网址是否有效。这个“小程序”用脚本语言写成,通过这种基于堆栈的比特币脚本语言,我们可以应对许多复杂的比特币支付场景。例如,托管系统可以设定只要经过三分之二的用户授权,就可执行澳门永利yl网址的规则,也可以设置其他的合约。 

 

脚本语言十分复杂,大约有80种操作码,包括算数计算,按位操作,字符串处理,条件语句和堆栈操作。脚本语言也包含一些必要的密码学操作(SHA-256,RIPEMD等等)作为原语(原语是执行过程中不可被打断的基本操作,你可以理解为一段代码)。为了确保脚本语言可以运行完毕自动退出,该语言不支持任何循环操作,因此它不是图灵完备的。然而,实际上,它只支持少数类型的澳门永利yl网址。 

 

前一个澳门永利yl网址中的脚本称为scriptPubKey,当前澳门永利yl网址中的脚本称为scriptSig。要验证澳门永利yl网址时,先执行scriptSig,然后再执行scriptPubKey。如果两个脚本都成功执行,澳门永利yl网址就被认定为有效,澳门永利yl网址中的比特币就可以成功花出。否则,澳门永利yl网址无效。要注意的是前一个澳门永利yl网址中的scriptPubKey规定了花费比特币的条件,当前澳门永利yl网址的scriptSig必须满足这个条件。 

 

在一个标准的澳门永利yl网址中,scriptSig脚本将从私钥中生成的签名并压入堆栈中,再压入公钥。接下来scriptPubKey脚本会执行运算先验证公钥的有效性,再验证签名的有效性。

 

正如脚本中所表示,scriptSig:

 


 

PUSHDATA
signature data and SIGHASH_ALL
PUSHDATA
public key data

 

scriptPubKey:

 


 

OP_DUP OP_HASH160 PUSHDATA Bitcoin address (public key hash) OP_EQUALVERIFY OP_CHECKSIG

 

当这段代码执行时,普什图塔操作业把名单。压入堆栈,接着把公共公主的160位哈希值,pushdata操作品再中的输入地址(输入牌号)压入堆栈,然后,op-complyverify操作品验证验证两个堆栈中的值否相等(验证这笔澳门永利yl网址中你工人) - 如果公共的哈希等于你自己) - 的输出地址,这就证明公共公主是有罪的证明澳门永利yl网址的到你的♥)

 

签署澳门永利yl网址

 

我发现签署这笔澳门永利yl网址是手动使用比特币时最难的地方,这一过程出奇地困难且容易出错。签名的基本思想很简单,使用椭圆曲线签名算法和私钥来生成澳门永利yl网址的数字签名,但细节非常棘手。签署澳门永利yl网址的过程可以通过这19个步骤描述。

 

 

签署澳门永利yl网址的19个步骤

 

对澳门永利yl网址的签名让我面临巨大的挑战,这涉及到一个如何在澳门永利yl网址内容中还没有加入签名时签署这笔澳门永利yl网址的问题。为了避免这个问题,在计算生成签名之前,我把scriptPubKey这个脚本从上一笔澳门永利yl网址复制到当前澳门永利yl网址中(当前这笔澳门永利yl网址正在被签署),然后将签名转换为脚本语言的代码,创建嵌入在当前澳门永利yl网址中的scriptSig脚本。对于具有多个输入的澳门永利yl网址,签署澳门永利yl网址环节更加复杂,因为每个输入都需要单独的签名,这里我就不做详细讨论了。

 

哈希值这一步骤难倒了我。在签名之前,澳门永利yl网址中有一个临时附加的哈希值常量。对于常规的澳门永利yl网址,这个值是SIGHASH_ALL(0x00000001)。签名后,这个哈希值将从澳门永利yl网址内容的最后删除,附加到scriptSig脚本中。

 

在比特币中另一件令人讨厌的事情是虽然签名和公钥都是512位的椭圆曲线值,但它们的表示方式完全不同:签名用DER编码方式编码,而公钥用纯字节表示。另外,两个值都有一个额外的字节,但位置并不一致:SIGHASH_ALL这个附加的哈希值常量放在签名后面,而04这个值放在公钥前面。

 

由于ECDSA算法需要使用随机数,所以调试签名十分困难。每次计算出的签名都会有所不同,因此无法与已知正确的签名进行比较。

 

正是由于上述的复杂性,我花了很长时间才得到了一个签名。不过,最终我找出了签名代码中所有的错误,并成功用它签署了一笔澳门永利yl网址。这是我使用的签名代码:

 

def forignedtransaction(privateKey,OutputTransachhash,SourceIndex,ScriptPubkey,Outputs):   mytxn_forsig =(makerawtransaction(outputTransactionHash,SourceIndex,ScriptPubkey,输出)        + "01000000") # hash code    s256 = hashlib.sha256(hashlib.sha256(mytxn_forsig.decode('hex'))。DIGEST())。DIGEST()   sk = ecdsa.signingkey.from_string(privatekey.decode('hex'),曲线= ECDSA.SECP256K1)   sig = sk.sign_digest(s256,sigencode = ecdsa.util.sigencode_der)+'\01' # 01 is hashtype    pubkey = keyutils.privatekeytopublic(privatekey)   scriptsig = utils.varstr(sig).encode('hex')+ utils.varstr(pubkey.decode('hex')).encode('hex')    signed_txn = makerawtransaction(OutputTransachhash,SourceIndex,ScriptSig,输出)   VerifyTXSignature(签名_txn)   
   return signed2_txn

txnUtils.py

 

最终的scriptSig脚本中包含签名以及比特币源地址的公钥(1MMMMSUb1piy2ufrSguNUdFmAcvqrQF8M5)。 这证明这笔澳门永利yl网址有效,我可以花费这些比特币。

 

PUSHDATA 47

47

signature(DER)

sequence

30

length

44

integer

02

length

20

X

2c b2 65 bf 10 70 7b f4 93 46 c3 51 5d d3 d1 6f c4 54 61 8c 58 ec 0a 0f f4 48 a6 76 c5 4f f7 13

integer

02

length

20

Y

6c 66 24 d7 62 a1 fc ef 46 18 28 4e ad 8f 08 67 8a c0 5b 13 c8 42 35 f1 65 4e 6a d1 68 23 3e 82

SIGHASH_ALL

01

PUSHDATA 41

41

public key

type

04

X

14 e3 01 b2 32 8f 17 44 2c 0b 83 10 d7 87 bf 3d 8a 40 4c fb d0 70 4f 13 5b 6a d4 b2 d3 ee 75 13

Y

10 f9 81 92 6e 53 a6 e8 c3 9b d7 d3 fe fd 57 6c 54 3c ce 49 3c ba c0 63 88 f2 65 1d 1a ac bf cd

   
   

 

最终的scriptPubKey脚本包含成功花费比特币时必须执行的脚本。需要注意的是,这个脚本将在未来花费这些比特币的时候执行。它包含以十六进制表示而不是以Base58Check表示的目标地址1KKKK6N21XKo48zWKuQKXdvSsCf95ibHFa,脚本的效果是只有这个目标地址的私钥所有者才能使用比特币,因此目标地址实际上是这些比特币的所有者

 

OP_DUP

76

OP_HASH160

a9

PUSHDATA 14

14

public key hash

c8 e9 09 96 c7 c6 08 0e e0 62 84 60 0c 68 4e d9 04 d1 4c 5c

OP_EQUALVERIFY

88

OP_CHECKSIG

ac

 

最终的澳门永利yl网址

 

经过上述的一系列操作,我们完成了最终的澳门永利yl网址。但是,别忘了,此时的澳门永利yl网址还没加入区块链中,接收方还没有收到你的比特币。

 

privateKey = keyUtils.wifToPrivateKey("5HusYj2b2x4nroApgfvaSfKYZhRbKFH41bVyPooymbC6KfgSXdD") #1MMMM

signed_txn = txnUtils.makeSignedTransaction(privateKey,       

"81b4c832d70cb56ff957589752eb4125a4cab78a25a8fc52d6a09e5bd4404d48", # output (prev) transaction hash       0, # sourceIndex        
keyUtils.addrHashToScriptPubKey("1MMMMSUb1piy2ufrSguNUdFmAcvqrQF8M5"),        [[91234, #satoshis        
keyUtils.addrHashToScriptPubKey("1KKKK6N21XKo48zWKuQKXdvSsCf95ibHFa")]]        )    txnUtils.verifyTxnSignature(signed_txn)
print'SIGNED TXN', signed_txn

makeTransaction.py

 

最终的澳门永利yl网址信息如下所示:

version

01 00 00 00

input count

01

input

previous output hash(reversed)

48 4d 40 d4 5b 9e a0 d6 52 fc a8 25 8a b7 ca a4 25 41 eb 52 97 58 57 f9 6f b5 0c d7 32 c8 b4 81

previous output index

00 00 00 00

script length

8a

scriptSig

47 30 44 02 20 2C B2 65 BF 10 70 7B F4 93 46 C3 51 5D D3 D1 6F C4 54 61 8C 58 EC 0A 0F F4 48 A6 76 C5 4F F7 13 02 20 6C 66 24 D7 62 A1 FC EF 46 18 28图4E广告8F 08 67 8A C0 5B 13 C8 42 35 F1 65 4E 6A D1 68 23 3E 82 01 41 04 14 E3 01 B2 32 8F 14 44 2C 0B 83 10 D7 87 BF 3D 8A 40 4C FB​​ D0 70 40 4F13 5B 6A D4 B2 D3 EE 75 13 10 F9 81 92 6E 53 A6 E8 C3 9B D7 D3 FE FD 57 6C 54 3C CE 49 3C BA CO 63 88 F2 65 1D 1A AC BF CD

sequence

ff ff ff ff

output count

01

output

value

62 64 01 00 00 00 00 00

script length

19

scriptPubKey

76 a9 14 c8 e9 09 96 c7 c6 08 0e e0 62 84 60 0c 68 4e d9 04 d1 4c 5c 88 ac

block lock time

00 00 00 00

 

小插曲:椭圆曲线签名

 

比特币的签名算法使用到了椭圆曲线签名算法,这么实用的功能,你可能会好奇它是怎么做到的?在当年英国数学家安德鲁·怀尔斯攻克费马大定理时,我第一次接触到了椭圆曲线的算法。椭圆曲线的数学思想很有意思,所以在这里我给大家做一个快速的概述。

 

椭圆曲线这个叫法令人迷惑,因为椭圆曲线并不是椭圆,而且看起来也不像椭圆,甚至椭圆曲线与椭圆相关性都很少。通俗地讲,椭圆曲线就是满足一个简单方程y ^ 2 = x ^ 3 + ax + b的曲线。比特币中使用的称为secp256k1的椭圆曲线,它满足的方程为y ^ 2 = x ^ 3 + 7。

 

 

secp256k1椭圆曲线

 

椭圆曲线的一个重要特性就是你可以用一个简单的规则来定义椭圆曲线上点的相加:如果在曲线上绘制一条直线,这条直线与曲线交与A,B,C三个点,那么这个加法定义为A+B+C=0。由这个加法的定义,我们可以定义整数乘法:例如4A = A + A + A + A。

 

为什么椭圆曲线在密码学上很有用?因为椭圆曲线做整数乘法运算速度很快,但做除法时需要蛮力。例如,你可以快速地计算一个乘法12345678*A = Q,但是如果你只知道A和Q,求解n*A=Q中的n十分困难。因此在椭圆曲线算法中,这里的12345678将是私钥,曲线上的点Q将是公钥。

 

在密码学中,点的坐标并不是它在曲线上的实值点,而是对整数的模数。椭圆曲线的一个好用的特性就是对实数或模数进行运算的数学运算几乎相同。正因为如此,比特币的椭圆曲线并不像上面的图片,而是一团杂乱无章的256位点集(想想在一个空间中充满了大量杂乱无章的点)。

 

椭圆曲线数字签名算法(ECDSA)接收澳门永利yl网址的哈希值,使用该澳门永利yl网址数据,私钥,以及一个随机数从椭圆曲线上生成一个新的点,从而实现对澳门永利yl网址的签名。任何拥有公钥,澳门永利yl网址数据,和签名的人都可以通过做一个简单的椭圆曲线运算来验证签名的有效性。读到这里,你应该明白了为什么只有拥有私钥的人才能签署消息,但拥有公钥的任何人都可以验证该消息。

 

把澳门永利yl网址发送到比特币网络

 

回到澳门永利yl网址中来,别忘了此时我们的澳门永利yl网址还没有被加入到区块链中,还不是一笔有效澳门永利yl网址。刚刚我创建并签署了一笔澳门永利yl网址。下一步就是将这笔澳门永利yl网址发送到比特币网络中,网络中的矿工会收集澳门永利yl网址并把它打包进区块中。

 

如何找到比特币网络的节点

 

首先我要在比特币的点对点网络中找到一个节点。节点的列表会随节点的进出动态更新,当一个比特币节点连接到另一个节点时,它们就会不断交换彼此新发现的比特币节点信息,因此,新节点加入的消息会快速地传遍整个网络。

 

然而,新的比特币节点如何第一次找到比特币节点?这是一个先有鸡还是先有蛋的问题。比特币节点通过以下几种方法来解决这个问题。有几个可信的比特币节点会以bitseed.xf2.org的域名在DNS系统(Domain Name System,域名系统,万维网上作为域名和IP地址相互映射的一个分布式数据库)上注册,通过执行nslookup命令,你就可以得到这些节点的IP地址,只要有一个在工作即可。如果很不幸它们都没有工作的话,你可以试着连接那几个已经在你的客户端中硬编码记录下来的地址。

 

 

Nslookup命令可以用来寻找比特币节点

 

当用户启动或停止比特币客户端时,节点就会加入或离开比特币网络。所以连接节点有很大的不确定性,在我实验时,就遇到了连接的节点已经离开比特币网络的情况,如果你想重复我的实验,最好多找几个节点,可能需要多次尝试才能找到一个运行着的节点。

 

与比特币节点通信

 

一旦获得了一个正在工作的比特币节点的IP地址,当务之急就通过这个节点是把我的澳门永利yl网址发送到比特币的点对点网络中。使用点对点的网络协议十分简单,我在端口8333上打开了一个到任意对等端的TCP连接,发送消息,然后接受反馈消息。比特币的点对点协议对用户很友好,即使我的请求数据出错时,还是继续与我保持通信。 

 

重要提示:正如一些人指出的那样,如果你想重复我的实验,切记要使用比特币的测试网络,在测试网络上,你可以使用“虚拟”的比特币来进行澳门永利yl网址。因为在真实网络上,万一你不小心,有可能会失去所有的比特币。还记得上面提到的那个100个比特币转账1个的澳门永利yl网址么,如果你忘了将剩余的比特币转给自己,那么剩余的99个比特币就会作为澳门永利yl网址费支付给矿工。但是本着科学的态度,我并不在意在真实的比特币网络中损失我这些价值1美元的比特币。

 

协议中包含24种不同的信息种类。每一条信息都是一个简单的二进制大对象(binary large object ,BLOB,是一个可以存储二进制文件的容器),其中包含一个ASCII命令和一个适用该命令的二进制有效参数。该协议可以在比特币的维基上查询。 

 

连接到比特币网络的第一步就是通过交换客户端版本信息来建立连接。首先,我发送了一条客户端版本信息,其中包含我的协议版本号,IP地址和其他内容。比特币节点也向我回复了它的版本信息。在此之后,我应该回复一个verack信息(version acknowledgement,版本确认)来确认它的版本信息。正如我所说,比特币点对点网络协议对用户十分友好,即使我跳过了verack信息,之后的操作也是一切正常。 

 

交换版本信息这一步并不简单,因为信息具有标准的格式,不过不用害怕,可以用几行代码来创建这些信息。下面代码段中的makeMessage函数可以由随机数,命令名以及命令的参数来生成一条消息。getVersionMessage函数通过将各个字段打包在一起来为版本消息创建参数。

 

magic = 0xd9b4bef9

def makeMessage(magic, command, payload):   checksum =
hashlib.sha256(hashlib.sha256(payload).digest()).digest()[0:4]   
   return struct.pack('L12sL4s', magic, command, len(payload), checksum) + payload
   
def getVersionMsg():   
   version = 60002    services = 1    时间戳= int(time.time())   addr_me = utils.netaddr(socket.inet_aton("127.0.0.1"), 8333)    addr_you = utils.netaddr(socket.inet_aton("127.0.0.1"), 8333)    nonce = random.getRandBits(64)   sub_version_num = utils.varstr('')    start_height = 0    payload = struct.pack('<LQQ26s26sQsL',版本,服务,时间戳,addr_me,       Addr_you,nonce,sub_version_num,start_height)   
   返回makemessage(魔术,'version', payload)

msgUtils.py

 

发送澳门永利yl网址tx

 

我使用下面精简的Python代码把我的澳门永利yl网址发送到比特币网络中,这个代码发送一条客户端版本信息,接受(也可以忽略)比特币节点的版本信息和verack信息。最后将我的澳门永利yl网址以tx信息发送。代码中这个16进制的字符串是我之前创建的澳门永利yl网址。

 

def gettxmsg(有效载荷): 返回makemessage(魔术,'tx',有效载荷)sock = socket.socket(socket.af_inet,socket.sock_stream)sock.connect(("97.88.151.164",8333))sock.send(msgutils.getversionmsg())sock.recv(1000)#接收版本sock.recv(1000)#接收Verack Sock.send(msgutils.gettxmsg("0100000001484d40d45b9ea0d652fca8258ab7caa42541eb52975857f96fb50cd732c8b481000000008a47304402202cb265bf10707bf49346c3515dd3d16fc454618c58ec0a0ff448a676c54ff71302206c6624d762a1fcef4618284ead8f08678ac05b13c84235f1654e6ad168233e8201410414e301b2328f17442c0b8310d787bf3d8a404cfbd0704f135b6ad4b2d3ee751310f981926e53a6e8c39bd7d3fefd576c543cce493cbac06388f2651d1aacbfcdffffffff0162640100000000001976a914c8e90996c7c6080ee06284600c684ed904d14c5c88ac00000000".decode('hex')))

minimalSendTxn.py

 

以下Wireshark(一个抓取,分析网络封包的软件)软件的截图显示出我是如何将澳门永利yl网址发送到比特币网络中的。我用Python编写了脚本来分析网络数据,为了简单起见,在这里我使用Wireshark。从图中可以看到我的这笔tx澳门永利yl网址。

 

 

 

Wireshark中抓取的这笔正在上传至比特币网络的澳门永利yl网址tx

 

为了实时监控我这笔澳门永利yl网址的进度,我在比特币网络中新运行了一个节点,在把我澳门永利yl网址发到比特币网络5秒钟之后,另一个节点给我发送了这个tx消息,其中包含我刚刚发送的这笔澳门永利yl网址的哈希,由此可见,在仅仅这几秒中,我的澳门永利yl网址已经传遍了比特币网络,至少也是比特币网络的一部分。

 

澳门永利yl网址成功:我的澳门永利yl网址被加入区块链

 

在将我的诀窍比特价网站之迹,我需要等待它矿兵开工开采偏出加载到区块链中,然后才能宣称我的实验实验成就.10分别后,我的比特征节点收到有新区块信息的inv消息(参见下图Wireshark抓到的网页封包),检查这个区块后发表意见我的澳门永利yl网址被包含在了了中,我的实验明我是有罪的,我的实验成就了。通讯我的比特币钱包软件和在线查询,再一次确认了我已经成功。可怕,经过不错的武力,我成都驾驶创建了笔澳门永利yl网址,并让比特币接受了。(当然了,我也了几次失败的尝试,这些错误的澳门永利yl网址都消失在了网中之中,永远都不会被到。

 

Wireshark中抓取的新区块产生的封包信息

 

我的澳门永利yl网址是被当时哈希算力(挖矿速度)最大的矿池(多个矿工一起挖矿)GHash.IO挖出,区块高度为279068,区块哈希为0000000000000001a27b1d6eb8c405410398ece796e742da3b3e35363c2219ee,在上图Wireshark数据包中inv消息的哈希值是经前后反转得到的ee192……。你应该会发现区块的哈希值以大量的0开头,在一个16进制的哈希值中发现一个以这么多0开头的数,这就是为什么挖矿如此困难的原因。这个区块中由462笔澳门永利yl网址,我的澳门永利yl网址是其中之一。

高度为279068的区块以及我发起的这笔澳门永利yl网址

(//blockchain.info/block-index/341440/0000000000000001a27b1d6eb8c405410398ece796e742da3b3e35363c2219ee)

 

挖到这个区块的矿工们收到了25个比特币的奖励,澳门永利yl网址费总共是0.104个比特币,按当时的市价分别为19000美元和80美元。我支付了0.0001个比特币的澳门永利yl网址费,大约是我澳门永利yl网址额的10%,按当时的市价为8美分。

 

结论

 

手动进行比特币澳门永利yl网址比我想象中困难得多,但是在这个过程中我学到了很多,希望你也是。我的Python代码仅仅是为了介绍,如果你想跟我一样用Python手动进行比特币澳门永利yl网址,也可以试试这几个项目。

 

//en.bitcoin.it/wiki/Bitcoin-python

//github.com/richardkiss/pycoin

//github.com/jgarzik/python-bitcoinlib

 

 

写在最后

2017年是区块链的井喷之年,经过一年的积攒,2018年将迎来区块链的落地之年,区块链会逐渐颠覆各行各业。对于个人,区块链的机会会越来越多,也许你错过了比特币的投资,不妨现在抓住区块链这个风口,投资自己,多学习相关知识,区块链大有可为,投身区块链的你将大有作为!

*声明:推送内容及图片来源于网络,部分内容会有所改动,版权归原作者所有,如来源信息有误或侵犯权益,请联系我们删除或授权事宜。