±à¼ÍƼö: |
±¾ÎÄÀ´×ÔÓÚSam Lewis ÓÉÑ㾪º®·Ò룬±¾ÎĽéÉÜÁ˱ÈÌØ±ÒµÄһЩµ×²ãµÄ¼¼Êõ£¬°üÀ¨µØÖ·¡¢P2PÍøÂç¡¢´´½¨ºÍ·¢²¼½»Ò׵ȵȡ£ÎÄÕ»¹¸ø³öÁ˹ؼüÐÔµÄPython´úÂëÆ¬¶Î£¬Í¨¹ýÕâЩ´úÂë¿ÉÒÔ¹¹½¨³öÒ»¸ö×îС×î»ù±¾µÄ±ÈÌØ±Ò¿Í»§¶Ë³ÌÐò¡£ |
|
±ÈÌØ±ÒÕæµÄºÜ¿á¡£µ±È»£¬¹ØÓÚÕâÏî¼¼ÊõĿǰ»¹´æÔÚ×Ų»ÉÙµÄÕùÒ飬°üÀ¨£ºËüÊÇ·ñÊÇÒ»ÏîÓÐÓõļ¼Êõ£¬¼ÓÃÜÊý×Ö»õ±ÒÊÇ·ñ´æÔÚ×ÅÅÝÄ£¬Ä¿Ç°ÃæÁٵĹÜÀíÎÊÌâÊÇ·ñÄܹ»µÃµ½½â¾ö¡£µ«ÊÇ´Ó´¿¼¼Êõ²ãÃæÀ´Ëµ£¬ÉñÃØµÄSatoshi Nakamoto´´ÔìÁËÕâ¸öÒýÈËעĿµÄ¼¼Êõ¡£
²»ÐÒµÄÊÇ£¬¾¡¹Ü¿ÉÒÔÕÒµ½ºÜ¶à×ÊÔ´Õ¾ÔڽϸߵIJã´Î½âÊÍÁ˱ÈÌØ±ÒµÄ¹¤×÷ÔÀí£¬µ«È´Ã»ÓÐÓйصײãµÄ×ÊÁÏ¡£ÔÚÎÒ¿´À´£¬Èç¹ûÄã´ÓÒ»ÍòÓ¢³ßµÄ¸ß¶È¿´µÄ»°£¬ÄãÖ»Äܹ»Æ¾¸Ð¾õÀ´Òâ»áÁË¡£
¶ÔÓÚÕâôһ¸öÐÂÐ˵ÄÁìÓò£¬ÎÒ·¢ÏÖÎÒ×Ô¼º·Ç³£¿ÊÍûÈ¥Á˽â±ÈÌØ±ÒµÄ¹¤×÷»úÖÆ¡£ÐÒÔ˵ÄÊÇ£¬ÒòΪ±ÈÌØ±Ò±¾ÖÊÉÏÊÇ·ÖÉ¢µÄ£¬²¢ÇÒÊǶԵȵģ¬ËùÒÔÈκÎÈ˶¼Äܹ»¿ª·¢³öÒ»¿î·ûºÏÐÒé±ê×¼µÄ¿Í»§¶Ë¡£ÎªÁËÄܹ»¸üºÃµØÁ˽â±ÈÌØ±ÒµÄ¹¤×÷ÔÀí£¬ÎÒ¾ö¶¨¿ª·¢Ò»¿îÊôÓÚÎÒ×Ô¼ºµÄ±ÈÌØ±Ò¿Í»§¶Ë£¬¿ÉÒÔÏò±ÈÌØ±ÒÇø¿éÁ´·¢²¼½»Òס£
ÕâÆªÎÄÕ½éÉÜÁË¿ª·¢Ò»¸ö×îС¶øÓÖ¿ÉÓõıÈÌØ±Ò¿Í»§¶ËµÄ¹ý³Ì£¬Ëü¿ÉÒÔ´´½¨Ò»±Ê½»Òײ¢½«ÆäÌá½»µ½±ÈÌØ±Ò¶ÔµÈÍøÂçÉÏ£¬ÒÔ±ãÈÃËü°üº¬ÔÚÇø¿éÁ´ÖС£Èç¹ûÄãÖ»ÊÇÏë¶ÁÒ»ÏÂÔʼ´úÂ룬¿ÉÒÔËæÊ±²é¿´ÎÒµÄGithub´úÂë¿â¡£
µØÖ·µÄÉú³É
Òª³ÉΪ±ÈÌØ±ÒÍøÂçµÄÒ»²¿·Ö£¬±ØÐëÒªÓÐÒ»¸ö¿ÉÒÔ·¢ËͺͽÓÊÕ×ʽðµÄµØÖ·¡£±ÈÌØ±ÒʹÓÃÁ˹«Ô¿¼ÓÃܼ¼Êõ£¬¶øµØÖ·ÊÇ´Ó˽ԿÅÉÉú³öÀ´µÄ¹«Ô¿µÄÉ¢Áа汾¡£ÁîÈ˳ԾªµÄÊÇ£¬Óë´ó¶àÊýµÄ¹«¹²ÃÜÔ¿¼ÓÃܼ¼Êõ²»Í¬£¬ËüµÄ¹«¹²ÃÜÔ¿»áÒ»Ö±±£ÃÜ´æ·Å£¬Ö±µ½×ʽð´ÓÕâ¸öµØÖ··¢ËͳöÈ¥¡£
ÊõÓï½âÊÍ£ºÔÚ±ÈÌØ±ÒÖУ¬¿Í»§¶ËʹÓõÄÊõÓï¡°Ç®°ü¡±±íʾµÄÊǵØÖ·¼¯ºÏ¡£´ÓÐÒé²ãÃæÀ´½²£¬Ã»ÓÐÇ®°üÕâ¸ö¸ÅÄֻÓеØÖ·¡£
±ÈÌØ±Ò¶ÔÆäµØÖ·Ê¹ÓÃÁËÍÖÔ²ÇúÏß¹«Ô¿ÃÜÂë¼¼Êõ¡£ÍÖÔ²ÇúÏß¼ÓÃܼ¼ÊõÓëRSAÒ»Ñù£¬ÓÃÓÚ´Ó˽ԿÉú³É¹«Ô¿£¬µ«ÆäÕ¼ÓõĿռä¸üС¡£Èç¹ûÄãÓÐÐËȤÁ˽âÒ»ÏÂÕâÖÖ¼ÓÃܼ¼Êõ±³ºóµÄÊýѧ֪ʶµÄ»°£¬ÄÇô CloudflareÉϵÄһƪÈëÃÅÎÄÕ ֵµÃÒ»¶Á¡£
´Ó256λµÄ˽Կ¿ªÊ¼£¬Éú³É±ÈÌØ±ÒµØÖ·µÄ¹ý³ÌÈçÏÂͼËùʾ£º

ÔÚPythonÖУ¬ÎÒʹÓà ecsda¿â À´ÊµÏÖÍÖÔ²ÇúÏß¼ÓÃÜ¡£ÒÔÏ´úÂëÆ¬¶ÎչʾÁË´ÓÒ»¸öÏàµ±ÖØÒª£¨Ò²Ï൱²»°²È«£©µÄ˽Կ0xFEEDB0BDEADBEEF£¨Ç°Ãæ²¹ÁãÒÔ´ïµ½64»òÕß256¸öÊ®Áù½øÖÆ×Ö·û´®£©À´»ñÈ¡¹«Ô¿µÄ¹ý³Ì¡£Èç¹ûÄãÏëÔÚµØÖ·Öд洢ÈκÎʵ¼ÊµÄÖµ£¬ÄÇôÐèÒªÒ»ÖÖ¸ü°²È«µÄ˽ԿÉú³É·½·¨£¡
ȤÊ£ºÎÒ×î³õʹÓÃ0xFACEBEEFÕâ¸öÃÜÔ¿´´½¨ÁËÒ»¸öµØÖ·£¬²¢ÏòËü·¢ËÍÁË0.0005±ÈÌØ±Ò¡£Ò»¸öÔºó£¬ÓÐÈË͵ÁËÎÒµÄ0.0005±ÈÌØ±Ò£¡ÎҲ£¬ÓÐÈ˿϶¨Å¼¶û»áÓÃһЩ¼òµ¥»òÕßͨÓõÄ˽ԿÀ´·ÃÎʵØÖ·¡£ÄãÕæµÄÓ¦¸ÃʹÓÃһЩ¸üºÏÊʵÄÃÜÔ¿ÅÉÉú¼¼Êõ£¡
from ecdsa import SECP256k1, SigningKey
def get_private_key(hex_string):
return bytes.fromhex (hex_string.zfill(64)) # ÔÚÊ®Áù½øÖÆ×Ö·û´®µÄÇ°Ãæ²¹ÁãÒÔ´ïµ½64¸ö×Ö·ûµÄ³¤¶È
def get_public_key(private_key):
# this returns the concatenated x and y coordinates for the supplied private address
# the prepended 04 is used to signify that it's uncompressed
return (bytes.fromhex("04") + SigningKey.from_string (private_key, curve=SECP256k1).verifying_key.to_string())
private_key = get_private_key ("FEEDB0BDEADBEEF")
public_key = get_public_key(private_key) |
ÔËÐдúÂ룬»ñÈ¡µ½Ë½Ô¿£¨Ê®Áù½øÖÆ£©£º
0000000000000000000000000000000000000000000000000
feedb0bdeadbeef |
»ñÈ¡µ½µÄ¹«Ô¿£¨Ê®Áù½øÖÆ£©£º
04d077e18fd45c031e0d256d75dfa8 c3c21c589a861c4c33b99e64 cf613113fcff9fc9d90a9d8 1346bcac64d3c01e6e0ef0828 543edad73c0e257b845812cc8d28 |
ÒÔ0x04¿ªÍ·µÄ¹«Ô¿±íÃ÷ÕâÊÇÒ»¸öûÓо¹ýѹËõµÄ¹«Ô¿£¬ÕâÒâζ×ÅECDSA£¨ÍÖÔ²ÇúÏßÊý×ÖÇ©ÃûËã·¨£©ÖÐxºÍyÖá×ø±ê¼òµ¥µÄ¹ØÁªÔÚÒ»Æð¡£¸ù¾ÝECSDAµÄÔÀí£¬Èç¹ûÄãÖªµÀxÖµ£¬ÄÇôyÖµÖ»ÄÜÈ¡Á½¸öÖµ£¬Ò»¸öżÊýºÍÒ»¸öÆæÊý¡£»ùÓÚÕâ¸öÐÅÏ¢£¬¿ÉÒÔ½öʹÓÃxÖеÄÒ»¸öÖµºÍyµÄ¼«ÐÔÀ´±í´ïÒ»¸ö¹«Ô¿¡£ÕâʹµÃ¹«Ô¿µÄ´óС´Ó65λ¼õÉÙµ½33룬Õâ¸ö¹ý³Ì£¨ºÍºóÐø¼ÆËãµÄµØÖ·£©³ÆÖ®ÎªÑ¹Ëõ¡£¶ÔÓÚѹËõºóµÄ¹«Ô¿£¬¸ù¾ÝyµÄ¼«ÐÔ£¬½«ÒÔ0x02»ò0x03¿ªÍ·¡£Î´Ñ¹ËõµÄ¹«Ô¿³£ÓÃÓÚ±ÈÌØ±Ò£¬ÕâÒ²ÊÇÎÒÔÚÕâÀïËùʹÓõġ£
Òª´Ó¹«Ô¿Éú³É±ÈÌØ±ÒµØÖ·£¬¹«Ô¿ÏÈÒª¼ÆËãsha256É¢ÁУ¬È»ºóÔÙ¼ÆËãripemd160É¢ÁС£ÕâÖÖË«ÖØÉ¢ÁÐÌṩÁ˶îÍâµÄ°²È«²ã£¬ripemd160É¢ÁÐÌṩÁËsha256µÄ256λɢÁÐÖ®ºóµÄ160λɢÁУ¬ÕâÑùËõ¶ÌÁ˵ØÖ·µÄ³¤¶È¡£Ò»¸öÓÐȤµÄ½á¹ûÊÇ£¬Á½¸ö²»Í¬µÄ¹«Ô¿¿ÉÒÔ¹þÏ£Éú³ÉÒ»¸öÏàͬµÄµØÖ·£¡È»¶ø£¬¶ÔÓÚ2µÄ160´Î·½¸ö²»Í¬µÄµØÖ·£¬Õⲻ̫¿ÉÄÜÔÚ¶Ìʱ¼äÄÚ·¢Éú¡£
import hashlib
def get_public_address(public_key):
address = hashlib.sha256(public_key).digest()
h = hashlib.new('ripemd160')
h.update(address)
address = h.digest()
return address
public_address = get_public_address(public_key) |
Õ⽫Éú³É c8db639c24f6dc026378225e40459ba8a9e54d1a Õâ¸ö¹«¹²µØÖ·£¬ÕâÓÐʱ»á±»³ÆÎª ¹þÏ£160µØÖ· ¡£
ÈçǰËùÊö£¬ÓÐÒ»µã±È½ÏÓÐÒâ˼£¬´Ó˽Կµ½¹«Ô¿µÄת»»ÒÔ¼°´Ó¹«Ô¿µ½¹«¹²µØÖ·µÄת»»¶¼Êǵ¥Ïòת»»¡£Èç¹ûÄãÓÐÒ»¸öµØÖ·£¬ÄÇôÕÒµ½¹ØÁª¹«Ô¿µÄΨһ°ì·¨¾ÍÊǽâ¾öSHA256¹þÏ£ÎÊÌâ¡£ÕâÓë´ó¶àÊýµÄ¹«Ô¿¼ÓÃܼ¼Êõ²»Í¬£¬ÄÇЩ»úÃܼ¼ÊõÖй«Ô¿Êǹ«¿ªµÄ£¬¶øË½Ô¿»áÒþ²ØÆðÀ´¡£¶øÔÚµ±Ç°Õâ¸öÇé¿öÏ£¬¹«Ô¿ºÍ˽Կ¶¼»áÒþ²ØÆðÀ´£¬¶øÖ»¹«²¼µØÖ·£¨¹þÏ£¹ýµÄ¹«Ô¿£©¡£
Òþ²Ø¹«Ô¿ÊÇÓÐÔÒòµÄ¡£ËäÈ»´Ó¹«Ô¿¼ÆËãµÃµ½ÏàÓ¦µÄ˽Կͨ³£ÊDz»¿ÉÐе쬵«ÊÇÈç¹ûÉú³É˽ԿµÄ·½·¨ÒѾ±»ÆÆ½â£¬ÄÇô¾ÍÄܺÜÈÝÒ×µØÍ¨¹ý¹«Ô¿Íƶϳö˽Կ¡£ÔÚ2013Ä꣬ÕâÖÖÊÂÇé·¢ÉúÔÚÁËAndroid±ÈÌØ±ÒÇ®°üµÄÉíÉÏ¡£ AndroidÔÚËæ»úÊýµÄÉú³ÉÉÏÓÐÒ»¸ö¹Ø¼üÐÔµÄȱÏÝ£¬Ëü»á´ò¿ªÒ»¸öÏòÁ¿£¬¹¥»÷Õßͨ¹ýÕâ¸öÏòÁ¿¿ÉÒÔ´Ó¹«Ô¿ÕÒµ½Ë½Ô¿¡£ÕâÒ²¾ÍÊÇΪʲô²»¹ÄÀøµØÖ·ÖØÓã¬ÒòΪҪǩÊð½»Ò×£¬Äã¾ÍµÃ¹«¿ª¹«Ô¿¡£Èç¹ûÄãÔÚÏòij¸öµØÖ··¢Ëͽ»Ò׺ó²»ÖØÓøõØÖ·£¬ÄÇÄã¾ÍÎÞÐèµ£ÐĸõØÖ·µÄ˽Կ»á±©Â¶¡£
±íʾһ¸ö±ÈÌØ±ÒµØÖ·µÄ±ê×¼·½Ê½ÊÇʹÓà Base58Check ½øÐбàÂë¡£¸Ã±àÂëÖ»ÊǵØÖ·µÄÒ»ÖÖ±íʾÐÎʽ£¨Òò´Ë¿ÉÒÔ±»½âÂë/·´ÍÆ£©¡£ËüÉú³ÉÀàËÆÓÚ 1661HxZpSy5jhcJ2k6av2dxuspa8aafDac ÕâÖÖÐÎʽµÄµØÖ·¡£ Base58Check±àÂëÌṩÁËÒ»¸ö½Ï¶ÌµÄµØÖ·±íʾ·½·¨£¬²¢ÇÒ»¹ÄÚÖÃУÑéºÍ£¬¿ÉÒÔ¼ì²â³ö´íÎóµÄµØÖ·¡£¼¸ºõÔÚÿ¸ö±ÈÌØ±Ò¿Í»§¶ËÖУ¬Äã¿´µ½µÄµØÖ·¶¼ÊÇBase58Check±àÂëºóµÄµØÖ·¡£ Base58Check»¹°üº¬Ò»¸ö°æ±¾ºÅ£¬ÔÚÏÂÃæµÄ´úÂëÖÐÎÒ°ÑËüÉèÖÃΪ0£¬Õâ±íʾ¸ÃµØÖ·ÊÇÒ»¸öpubkeyÉ¢ÁС£
# 58 character alphabet used
BASE58_ALPHABET = '123456789ABCDEFGHJKLMNPQRSTUVWXYZ abcdefghijkmnopqrstuvwxyz'
def base58_encode (version, public_address):
"""
»ñÈ¡Base58Check±àÂëµÄ×Ö·û´®
Çë²ÎÔÄ£ºhttps://en.bitcoin.it/wiki/ base58Check_encoding
"""
version = bytes.fromhex(version)
checksum = hashlib.sha256(hashlib.sha256 (version + public_address).digest()).digest()[:4]
payload = version + public_address + checksum
result = int.from_bytes (payload, byteorder="big")
print(result)
# ¼ÆËãÇ°ÃæµÄ0µÄÊýÁ¿
padding = len(payload) - len(payload.lstrip(b'\0'))
encoded = []
while result != 0:
result, remainder = divmod(result, 58)
encoded.append (BASE58_ALPHABET[remainder])
return padding*" 1" + "".join(encoded)[::-1]
bitcoin_address = base58_encode ("00", public_address) |
ÒÔÉÏËùÓеĴúÂëչʾÁËÎÒ´Ó˽Կ FEEDB0BDEADBEEF £¨Ç°ÃæÐèÒªÌî³äÁ㣩µ½µ½±ÈÌØ±ÒµØÖ· KK2xni6gmTtdnSGRiuAf94jciFgRjDj7W µÄÕû¸ö¹ý³Ì£¡
ͨ¹ýÕâ¸öµØÖ·£¬ÎÒÏÖÔھͿÉÒÔÀ´»ñµÃ±ÈÌØ±ÒÁË£¡ÎªÁ˰ѱÈÌØ±Ò·ÅÈëÎҵĵØÖ·£¬ÎÒÓðÄÔª´Ó
btcmarkets ¹ºÂòÁË0.0045±ÈÌØ±Ò£¨ÔÚ׫д±¾ÎÄʱԼΪ11ÃÀÔª£©¡£ ʹÓÃbtcmarketµÄ½»Ò×ÃÅ»§£¬ÎÒ½«Æä×ªÒÆµ½ÉÏÃæµÄµØÖ·£¬Ôڴ˹ý³ÌÖлáËðʧ0.0005±ÈÌØ±ÒµÄ½»Ò×·ÑÓá£Äã¿ÉÒÔÔÚ½»Ò×
* 95855ba9f46c6936d7 b5ee6733c81e715ac92199938ce30ac3e1214b8c2cd8d7*
ÖеÄÇø¿éÁ´ÉÏ¿´µ½Õâ±Ê½»Òס£
Á¬½Óµ½P2P£¨µã¶Ôµã£©ÍøÂç
ÏÖÔÚ£¬ÎÒÓÐÁËÒ»¸öµØÖ·£¬¶øÇÒÉÏÃæ»¹ÓÐһЩ±ÈÌØ±Ò£¬ÊÂÇé±äµÃ¸üÓÐȤÁË¡£Èç¹ûÎÒÏ뽫±ÈÌØ±Ò·¢Ë͵½±ðµÄµØ·½£¬ÄÇô¾Í±ØÐëÁ¬½Óµ½±ÈÌØ±ÒµÄP2PÍøÂçÉÏ¡£
Òýµ¼
µ±ÎÒµÚÒ»´Îѧϰ±ÈÌØ±ÒµÄʱºò£¬ÎÒ·¢ÏÖÁËÒ»¸ö¹Ø¼üµÄÎÊÌ⣺ÓÉÓÚÍøÂçµÄ·ÖÉ¢ÐÔ£¬ÍøÂçÉϵĽڵãÊÇÈçºÎÕÒµ½ÆäËû½ÚµãµÄ£¿Ã»ÓÐÖÐÑë¿ØÖÆµã£¬±ÈÌØ±Ò¿Í»§¶ËÊÇÈçºÎÖªµÀÈçºÎÒýµ¼²¢ÓëÍøÂçµÄÆäËû½Úµã½øÐн»»¥µÄ£¿
ÀíÂÛ·þ´Óʵ¼ù£¬ÔÚ×î³õµÄ½Úµã·¢ÏÖ¹ý³ÌÖÐÊÇ´æÔÚ׿«ÉÙÊýµÄ¼¯ÖпØÖÆÆ÷¡£Ò»¸öеĽڵãѰÕÒÆäËû½ÚµãµÄ·½·¨ÔÚÔÀíÉϾÍÊÇͨ¹ýDNSÈ¥²éÕÒBitcoinÉçÇø³ÉԱά»¤µÄ¡°DNSÖÖ×Ó¡±·þÎñÆ÷¡£
ÊÂʵ֤Ã÷£¬DNS·Ç³£ÊʺÏÓÚÒýµ¼¿Í»§¶Ë£¬ÒòΪDNSÐÒé»ùÓÚUDP£¬ÇáÁ¿¼¶£¬²»Ì«ÈÝÒ×Êܵ½DDoS¹¥»÷¡£IRCÒÔÇ°Ôø±»ÓÃ×÷Òýµ¼µÄ·½·¨£¬µ«ÊÇÒòΪÈÝÒ×ÊÜDDoS¹¥»÷Õâ¸öÈõµã¶øÍ£Ö¹Ê¹ÓÃÁË¡£
ÖÖ×ÓDNS±»Ó²±àÂëµ½BitcoinµÄºËÐÄÔ´´úÂëÖУ¬²¢ÓɺËÐÄ¿ª·¢ÈËÔ±¸ºÔðÐ޸ġ£
ÏÂÃæµÄPython´úÂëÊ×ÏÈÁ¬½Óµ½Ò»¸öDNSÖÖ×Ó£¬È»ºó´òÓ¡³öÒ»¸ö¿ÉÒÔÁ¬½ÓµÄ½ÚµãÁÐ±í¡£Ê¹ÓÃsocket¿â£¬Ëü»ù±¾ÉÏÖ´ÐеÄÊÇÒ»¸önslookup²Ù×÷£¬È»ºó·µ»Ø´Óseed.bitcoin.sipa.be²éѯµÃµ½IPv4µØÖ·½á¹ûÖеĵÚÒ»¸ö¡£
import socket
# Ïòbitcoin DNS·þÎñÆ÷·¢ËÍDNSÇëÇóÀ´²éÕÒ½Úµã
nodes = socket.getaddrinfo("seed.bitcoin.sipa.be", None)
# Ñ¡ÔñµÚÒ»¸ö½Úµã
node = nodes[0][4][0] |
²éµ½µÄµØÖ·ÊÇ208.67.251.126£¬ÕâÊÇÒ»¸öÓѺõĶԶ˽ڵ㣬ÎÒ¿ÉÒÔÈ¥Á¬½ÓÕâ¸öµØÖ·ÁË£¡
¸ú¶Ô¶Ë½Úµã´òÕкô
¸÷¸ö½ÚµãÖ®¼äÊÇͨ¹ýTCPÀ´½¨Á¢Á¬½ÓµÄ¡£Á¬½Ó¶Ô¶Ë½Úµãʱ£¬±ÈÌØ±ÒÐÒé×ʼµÄÎÕÊÖÏûÏ¢ÊÇÒ»¸ö°æ±¾ÏûÏ¢¡£Ôڽڵ㽻»»°æ±¾ÏûÏ¢Ö®ºó£¬²Å»á½ÓÊÜÆäËûÏûÏ¢¡£
±ÈÌØ±ÒÐÒéÏûÏ¢ÔÚ¡°Bitcoin¿ª·¢ÈËÔ±²Î¿¼ÊֲᡱÖÐÓÐÏêϸµÄ¼Ç¼¡£Ê¹Óÿª·¢ÈËÔ±²Î¿¼ÊÖ²á×÷ΪָÄÏ£¬¿ÉÒÔÔÚPythonÖд´½¨ version ÏûÏ¢£¬ÈçÏÂÃæµÄ´úÂëÆ¬¶ÎËùʾ¡£ ÆäÖдó¶àÊýµÄ´úÂë¶¼ÊÇÓÃÓÚ´ò¿ªÓë¶Ô¶Ë½ÚµãµÄÁ¬½Ó¡£Èç¹ûÄã¶Ôϸ½Ú¸ÐÐËȤµÄ»°£¬¿ÉÒԲ鿴¿ª·¢Õ߲ο¼Êֲᡣ
version = 70014
services = 1 # not a full node, cant provide any data
timestamp = int(time.time())
addr_recvservices = 1
addr_recvipaddress = s ocket.inet_pton(socket.AF_INET6, "::ffff:127.0.0.1") #ip address of receiving node in big endian
addr_recvport = 8333
addr_transservices = 1
addr_transipaddress = socket.inet_pton (socket.AF_INET6, "::ffff:127.0.0.1")
addr_transport = 8333
nonce = 0
user_agentbytes = 0
start_height = 329167
relay = 0 |
ʹÓÃPythonµÄ struct¿â£¬°æ±¾ÓÐÐ§ÔØºÉÊý¾Ý¿ÉÒÔ´ò°ü³ÉÕýÈ·µÄ¸ñʽ£¬ÇëÌØ±ð×¢ÒâÒ»ÏÂÊý¾ÝµÄ×Ö½Ú˳ÐòºÍ×Ö½Ú¿í¶È¡£½«Êý¾Ý´ò°ü³ÉÕýÈ·µÄ¸ñʽºÜÖØÒª£¬²»È»¶Ô¶Ë½Úµã½«ÎÞ·¨Àí½âÊÕµ½µÄÔʼÊý¾Ý¡£
payload = struct.pack("<I", version)
payload += struct.pack ("<Q", services)
payload += struct.pack ("<Q", timestamp)
payload += struct.pack ("<Q", addr_recvservices)
payload += struct.pack ("16s", addr_recvipaddress)
payload += struct.pack (">H", addr_recvport)
payload += struct.pack ("<Q", addr_transservices)
payload += struct.pack ("16s", addr_transipaddress)
payload += struct.pack (">H", addr_transport)
payload += struct.pack ("<Q", nonce)
payload += struct.pack ("<H", user_agentbytes)
payload += struct.pack ("<I", start_height) |
ÔÙ˵һ±é£¬¿ÉÒÔÔÚ¿ª·¢ÈËÔ±²Î¿¼ÊÖ²áÖÐÕÒµ½ÕâЩÊý¾ÝµÄ˵Ã÷¡£×îºó£¬ÔÚ±ÈÌØ±ÒÍøÂçÉÏ´«ÊäµÄÿ¸öÓÐÐ§ÔØºÉ¶¼ÐèÒª¼ÓÉÏÒ»¸ö°üÍ·£¬ÆäÖаüº¬ÁËÓÐÐ§ÔØºÉµÄ³¤¶È¡¢Ð£ÑéºÍÒÔ¼°ÏûÏ¢ÀàÐÍ¡£°üÍ·»¹°üº¬ÁËħÊõ³£Êý0xF9BEB4D9£¬ËüÔÚËùÓÐÖ÷ÒªµÄ±ÈÌØ±ÒÏûÏ¢Öж¼ÓС£ÒÔϺ¯Êý·µ»ØÒ»¸ö´øÓаüÍ·µÄ±ÈÌØ±ÒÏûÏ¢¡£
def get_bitcoin_message(message_type, payload):
header = struct.pack(">L", 0xF9BEB4D9)
header += struct.pack("12s", bytes(message_type, 'utf-8'))
header += struct.pack("<L", len(payload))
header += hashlib.sha256(hashlib.sha256(payload).digest()).digest()[:4]
return header + payload |
½«Êý¾Ý´ò°ü³ÉÕýÈ·µÄ¸ñʽ£¬²¢Ìí¼Ó°üÍ·£¬È»ºó·¢Ë͸ø¶ÔµÈ½Úµã£¡
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((node, 8333))
s.send(get_bitcoin_message ("version", payload))
print(s.recv(1024)) |
±ÈÌØ±ÒÐÒéÒªÇóÔÚ½ÓÊÕµ½°æ±¾ÏûÏ¢ºó£¬·µ»ØÒ»¸öVerackÈ·ÈÏÏûÏ¢¡£ ÒòΪÎÒÕýÔÚ¹¹½¨µÄÊÇÒ»¸ö΢Ð͵ġ°ÎªÁËÐËȤ¶ø×ö¡±µÄ¿Í»§¶Ë£¬²¢ÇÒÒòΪ¼´Ê¹ÎÒ²»°´ÕÕÐÒéÕâô×öµÄ»°£¬ÆäËû½ÚµãÒ²²»»áÈÏΪÎÒÕâ¸ö¿Í»§¶ËÓÐʲô²»Í¬£¬ËùÒÔÎÒºöÂÔÁËËûÃǵİ汾ÐÅÏ¢£¬²¢ÇÒûÓз¢ËÍÏìÓ¦ÏûÏ¢¡£ÔÚÁ¬½Óʱ·¢ËͰ汾ÏûÏ¢×ãÒÔÈÃÎÒÔÚºóÃæÄܹ»·¢Ë͸ü¼ÓÓÐÒâÒåµÄÏûÏ¢¡£
ÔËÐÐÉÏÃæµÄ´úÂë»á´òÓ¡³öÒÔÏÂÄÚÈÝ¡£½á¹û¿´ÆðÀ´ºÜÓÐÏ£Íû£¬¡°Satoshi¡±ºÍ¡°Verack¡±ÊÇÔÚÏûϢת´¢Öп´µ½µÄ×îºÃµÄµ¥´Ê£¡ÒòΪÈç¹ûÎҵİ汾ÏûÏ¢¸ñʽ´íÎóµÄ»°£¬¶Ô¶Ë¸ù±¾¾Í²»»á×ö³ö»ØÓ¦¡£
b'\xf9\xbe\xb4\xd9version\x00\x00
\x00\x00\x00f\x00\x00\x00 \xf8\xdd\x9aL\x7f\x11\x01\x00\r\x00
\x00\x00\x00\x00\x00\x00 \xddR1Y\x00\x00\x00\x00\x00\x00\x00
\x00\x00\x00\x00\x00\x00 \x00\x00\x00\x00\x00\x00\x00\x00\x00
\xff\xff\xcb\xce\x1d\xfc \xe9j\r\x00\x00\x00\x00\x00\x00\x00
\x00\x00\x00\x00\x00\x00 \x00\x00\x00\x00\x00\x00\x00\x00\x00
\x00\x00\x00\x06\xb8>* \x88@I\x8e\x10/Satoshi:0.14.0/t)\x07
\x00\x01\xf9\xbe\xb4\ xd9verack\x00\x00\x00\x00\x00\x00\x00
\x00\x00\x00]\xf6\xe0\xe2' |
±ÈÌØ±Ò½»Ò×
Òª×ªÒÆ±ÈÌØ±Ò£¬±ØÐëÏò±ÈÌØ±ÒÍøÂç¹ã²¥Õâ±Ê½»Òס£
ÓÐÒ»¸öºÜÖØÒªµÄ¸ÅÄîÐèÒªÖªµÀ£¬ÄǾÍÊDZÈÌØ±ÒµØÖ·µÄÓà¶î½öÓɸõØÖ·¿ÉÒÔÖ§³öµÄ¡°Î´»¨·ÑµÄ½»Ò×Êä³ö¡±£¨UTXO£©µÄÊýÁ¿×é³É¡£µ±±«²ªÏò°®ÀöË¿·¢ËͱÈÌØ±Òʱ£¬ËûÖ»ÊÇ´´½¨ÁËÒ»¸öUTXO£¬¶øAlice£¨¶øÇÒÖ»ÓÐAlice£©¿ÉÒÔÒÔ´ËÀ´´´½¨ÁíÒ»¸öUTXO£¬²¢·¢ËͱÈÌØ±Ò¡£Òò´Ë£¬±ÈÌØ±ÒµØÖ·µÄÓà¶îÊÇÓÉ¿ÉÒÔ×ªÒÆµ½ÁíÒ»¸öµØÖ·µÄ±ÈÌØ±ÒµÄÊýÁ¿¾ö¶¨£¬¶ø²»ÊÇÖ±½ÓÓɱÈÌØ±ÒµÄÊýÁ¿¾ö¶¨¡£
Ҫǿµ÷µÄÊÇ£¬µ±ÓÐÈË˵ËûÃÇÓµÓÐXÊýÁ¿µÄ±ÈÌØ±Òʱ£¬ËûÃǵÄÒâ˼ÊÇ˵ËùÓпÉÒÔÓÃÀ´Ö§¸¶µÄUTXOµÄ×ܺÍÊǼÛÖµX±ÈÌØ±Ò¡£Çø±ðºÜС£¬µ«ÊǺÜÖØÒª£¬±ÈÌØ±ÒµØÖ·µÄÓà¶î²»Ö±½Ó¼Ç¼ÔÚij¸öµØ·½£¬¶øÊÇ¿ÉÒÔͨ¹ý¶Ô¿ÉÒÔÖ§¸¶µÄËùÓеÄUTXO½øÐÐÇóºÍÀ´µÃµ½µÄ¡£µ±ÎÒÒâʶµ½Õâ¸öµÄʱºò£¬ÎÒ´ó´ó¾ªÌ¾ÁËÒ»¾ä£º¡°Å¶£¬ÔÀ´ËüÊÇÕâÑù¹¤×÷µÄ£¡¡±¡£
ÕâÑù×öµÄÒ»¸ö¸±×÷ÓþÍÊǽ»Ò×Êä³ö¿ÉÒÔÊÇ仨·ÑµÄ£¨UTXO£©£¬Ò²¿ÉÒÔÊÇÒÑ»¨·ÑµÄ¡£²»¿ÉÄÜÖ»»¨·ÑijÈËΪÄ㻨·ÑµÄÊýÁ¿µÄÒ»°ë£¬È»ºóÔÚÒԺ󻨷ÑÊ£ÓàµÄÊýÁ¿¡£¶ÔÓÚÊÕµ½µÄÊä³ö£¬Èç¹ûÄãÖ»ÏëÒª»¨·ÑÆäÖÐһС²¿·Ö£¬ÄÇÄã¿ÉÒÔ·¢ËÍÕâһС²¿·Ö¸øÆäËûÈË£¬¶ø½«ÆäÓಿ·Ö·¢Ë͸ø×Ô¼º¡£Æä¼ò»¯°æ±¾ÈçÏÂͼËùʾ¡£

ÔÚ´´½¨½»Ò×Êä³öµÄʱºò£¬½«Í¬Ê±´´½¨Ò»¸öËø¶¨Ìõ¼þ£¬Õ⽫ÔÊÐí½«À´µÄijÈËͨ¹ýËùνµÄ½»Ò׽ű¾À´»¨·ÑËü¡£×î³£¼ûµÄËø¶¨Ìõ¼þÊÇ£º¡°Òª»¨·ÑÕâ¸öÊä³ö£¬ÄãÐèÒªÖ¤Ã÷ÄãÓµÓÐÓëÌØ¶¨¹«¹²µØÖ·¶ÔÓ¦µÄ˽Կ¡±¡£Õâ±»³ÆÎª¡°Ö§¸¶¹«Ô¿¹þÏ£¡±½Å±¾¡£È»¶ø£¬Í¨¹ý±ÈÌØ±Ò½Å±¾´´½¨ÆäËûÀàÐ͵ÄÌõ¼þÒ²ÊÇ¿ÉÒԵġ£ÀýÈ磬´´½¨¿ÉÒÔÓÉÈκÎÒ»¸öÓµÓÐij¸ö¹þÏ£µÄÈË»¨·ÑµÄ½»Ò×Êä³ö£¬»òÕß´´½¨ÈκÎÈ˶¼¿ÉÒÔ»¨·ÑµÄ½»Ò×Êä³ö¡£
ͨ¹ý½Å±¾£¬¿ÉÒÔ´´½¨¼òµ¥µÄ»ùÓÚºÏͬµÄ½»Òס£½Å±¾ÊÇÒ»ÖÖ»ù±¾µÄ»ùÓÚÕ»µÄÓïÑÔ£¬Ëü°üº¬ÁË´óÁ¿µÄ²Ù×÷£¬ÒÔ´ËÀ´¼ì²é¹þÏ£ÊÇ·ñÏàµÈÒÔ¼°Ñé֤ǩÃû¡£½Å±¾²¢²»ÊÇÍêÕûµÄͼÁé»ú£¬Ëü²»Ö§³ÖÈκÎÑ»·¹¦ÄÜ¡£ÓëÖ®ÓоºÕù¹ØÏµµÄ¼ÓÃÜÊý×Ö»õ±ÒÒÔÌ«·»£¨Ethereum£©¾ÍÊǽ¨Á¢ÔÚÕâÒ»µãÉÏ£¬ËüÓµÓС°ÖÇÄܺÏͬ¡±£¬²¢¾ßÓÐͼÁé»úµÄÍêÕûÓïÑÔ¡£¹ØÓÚÔÚ¼ÓÃÜ»õ±ÒÖаüº¬Í¼Áé»úÍêÕûÓïÑÔµÄʵÓÃÐÔ¡¢±ØÒªÐԺͰ²È«ÐÔ·½ÃæÓкܶàµÄÕùÂÛ£¬µ«ÎÒ»¹ÊǰÑÕùÂÛÁô¸øÆäËûÈ˰ɣ¡
ÔÚ±ê×¼ÊõÓïÖУ¬±ÈÌØ±Ò½»Ò×ÓÉÊäÈëºÍÊä³ö×é³É¡£ÊäÈëÊÇÒ»¸öUTXO£¨µ±Ç°ÕýÔÚ»¨·ÑµÄ£©£¬Êä³öÊÇÒ»¸öеÄUTXO¡£µ¥¸öÊäÈë¿ÉÒÔÓжà¸öÊä³ö£¬µ«ÊäÈëÐèÒªÔÚ½»Ò×ÖÐÍêÈ«ÏûºÄ¡£ÊäÈëÊ£ÓàÎïµÄÈκÎÒ»²¿·Ö¶¼Êǿ󹤵IJɿó·Ñ¡£
¶ÔÓÚÎÒÕâ¸ö¿Í»§¶Ë£¬ÎÒÏ£ÍûÄܹ»½«ÒÔǰ´Ó½»Ò×Ëù×ªÒÆµ½µÄ±ÈÌØ±Ò·¢Ë͵½ÎÒµÄ FEEDB0BDEADBEEF µØÖ·¡£Ê¹ÓÃÓë֮ǰÏàͬµÄ¹ý³Ì£¬ÎÒʹÓÃ˽Կ BADCAFEFABC0FFEE Éú³ÉÁËÁíÍâÒ»¸öµØÖ· 1QGNXLzGXhWTKF3HTSjuBMpQyUYFkWfgVC ¡£
´´½¨Ôʼ½»Ò×
Òª´´½¨Ò»±Ê½»Ò×£¬Ê×ÏÈÊǶԡ°Ôʼ½»Òס±½øÐдò°ü£¬È»ºó¶ÔÔʼ½»Ò×½øÐÐÇ©Ãû¡£¿ª·¢ÈËÔ±²Î¿¼ÊÖ²áÖÐÏêϸ˵Ã÷Á˽»Ò×µÄÄÚÈÝ¡£ÏÂÎĽ«½²Êö½»Ò׵Ĺ¹³ÉÔªËØ£¬µ«ÕâÀïÏÈ˵¼¸¸ö×¢ÒâÊÂÏ
- ±ÈÌØ±ÒÖг£¼ûµÄÊõÓï°üÀ¨Ç©Ãû½Å±¾ºÍpubkey½Å±¾£¬ÎÒ·¢ÏÖÕâÓеã»ìÂÒ¡£Ç©Ãû½Å±¾ÓÃÓÚÂú×ãÎÒÃÇÒªÔÚ½»Ò×ÖÐʹÓõÄUTXOµÄÌõ¼þ£¬¶øpubkey½Å±¾ÓÃÓÚÉèÖÃÌõ¼þÒÔÂú×ãÎÒÃÇÕýÔÚ´´½¨µÄUTXOµÄ»¨·Ñ¡£Ç©Ãû½Å±¾µÄÁíÒ»¸ö¸üºÃµÄÃû³ÆÊǽâËø½Å±¾£¬¶øpubkey½Å±¾µÄÁíÒ»¸ö¸üºÃÃû³ÆÊÇËø¶¨½Å±¾¡£
- ±ÈÌØ±Ò½»Ò×ÖµÔÚSatoshisÖÐÖ¸¶¨¡£Satoshi´ú±í±ÈÌØ±Ò¿É·Ö¸îµÄ×îС²¿·Ö£¬ÊÇÒ»¸ö±ÈÌØ±ÒµÄÊ®ÒÚ·ÖÖ®Ò»¡£
ΪÁ˼òµ¥Æð¼û£¬ÏÂÃæÏÔʾµÄÊÇÒ»¸öÊä³öºÍÒ»¸öÊäÈëµÄ½»Òס£¿ÉÒÔÒÔÏàͬµÄ·½Ê½À´´´½¨¾ßÓжà¸öÊäÈëºÍÊä³öµÄ¸ü¸´ÔӵĽ»Òס£
×Ö¶Î |
ÃèÊö |
Version |
½»Ò׵İ汾 (µ±Ç°ÊÇ1) |
Number of inputs |
ÐèÒª»¨·ÑµÄÊäÈëµÄÊýÁ¿ |
Transaction ID |
ÐèÒª»¨·ÑµØ½»Ò×µØÔ´Í· |
Output number |
ÐèÒª»¨·ÑµÄ½»Ò×µÄÊä³ö |
Signature script length |
Ç©Ãû½Å±¾µÄ³¤¶È£¨×Ö½Ú£© |
Signature script |
Ç©Ãû½Å±¾ |
Sequence number |
³ý·ÇÄãҪʹÓÃÒ»¸öËø¶¨Ê±¼ä£¬·ñÔò×ÜÊÇ0xffffffff |
Number of outputs |
ÐèÒª´´½¨µÄÊä³öµÄÊýÁ¿ |
Value |
ÐèÒª»¨·ÑµÄSatoshisµÄÊýÁ¿ |
Pubkey script length |
pubkey½Å±¾µÄ³¤¶È£¨×Ö½Ú£© |
Pubkey script |
pubkey½Å±¾ |
Lock time |
°üº¬ÔÚÇø¿éÖеĽ»Ò×µÄ×îÔçʱ¼ä/Çø¿éºÅ |
ºöÂÔÇ©Ãû½Å±¾ºÍpubkey½Å±¾£¬ÎÒÃÇ¿ÉÒÔºÜÈÝÒ׵ؿ´µ½Ôʼ½»Ò×ÖÐµÄÆäËû×Ö¶ÎÓ¦¸ÃÔõôÉèÖá£Òª½«ÎÒµÄFEEDB0BDEADBEEFµØÖ·ÖеÄ×ʽð·¢Ë͵½ÎÒµÄBADCAFEFABC0FFEEµØÖ·£¬ÎÒÃÇÀ´¿´¿´½»Ò×Ëù´´½¨µÄÕâ±Ê½»Ò×£º
- ½»Ò×IDΪ 95855ba9f46c6936d7b5ee6733c81e 715ac92199938ce30 ac3e1214b8c2cd8d7 ¡£
- ·¢Ë͵½ÎҵĵØÖ·µÄÊä³öÊǵڶþ¸öÊä³ö£¬Êä³ö1£¨Êä³ö±àºÅ´Ó0¿ªÊ¼£©¡£
- Êä³öµÄÊýÁ¿Îª1£¬ÒòΪÎÒÏ뽫 FEEDB0BDEADBEEF ÖеÄËùÓÐÄÚÈÝ·¢Ë͵½ BADCAFEFABC0FFEE ¡£
- Öµ×î´ó¿ÉÒÔ´ïµ½40ÍòµÄSatoshis¡£ÎªÁËÁô³öһЩ·ÑÓÃÀ´£¬Ò»¶¨Òª½«ÖµÉèÖõØÐ¡ÓÚÕâ¸ö×î´óÖµ¡£ÎÒÔÊÐíÓÐ2ÍòµÄSatoshi×÷Ϊ·ÑÓã¬ËùÒÔ½«ÖµÉ趨Ϊ38Íò¡£
- Ëø¶¨Ê±¼ä½«±»ÉèÖÃΪ0£¬ÕâÑù¿ÉÒÔÔÚÈκÎʱºò»òÇø¿éÖаüº¬½»Òס£
¶ÔÓÚÎÒÃǵĽ»Ò×µÄPubkey½Å±¾£¬ÎÒÃÇʹÓÃÁË¡°Ö§¸¶Pubkey¹þÏ£¡±£¨»òp2pk£©½Å±¾¡£¸Ã½Å±¾È·±£Ö»ÓÐÓµÓй«Ô¿µÄÈ˲ÅÄܹ»Ê¹ÓÃËùÌṩµÄ±ÈÌØ±ÒµØÖ·À´Ö§¸¶Ëù´´½¨µÄÊä³ö£¬²¢ÇÒËùÌṩµÄÇ©ÃûÒѾÓɱ£´æÏàӦ˽ԿµÄÈËÀ´Éú³É¹«Ô¿¡£
Òª½âËøÒÑÓÉp2pk½Å±¾Ëø¶¨µÄ½»Ò×£¬Óû§ÐèÒªÌṩ¹«Ô¿ºÍÔʼ½»Ò׵ĹþϣǩÃû¡£¸ù¾Ý¹«Ô¿¼ÆËã³öÉ¢ÁÐÖµ£¬²¢Óë½Å±¾´´½¨µÄµØÖ·½øÐбȽϣ¬²¢¶ÔËùÌṩµÄ¹«Ô¿½øÐÐÇ©ÃûÑéÖ¤¡£Èç¹û¹«Ô¿µÄÉ¢ÁÐÖµºÍµØÖ·ÏàµÈ£¬²¢ÇÒÇ©Ãûͨ¹ýÑéÖ¤£¬Ôò¿ÉÒÔ»¨·ÑÊä³öÁË¡£
ÔÚ±ÈÌØ±Ò½Å±¾µÄÔËËã¶ÔÏóÖУ¬p2pk½Å±¾ÈçÏÂËùʾ£º
OP_DUP
OP_HASH160
<Length of address in bytes>
<Bitcoin address>
OP_EQUALVERIFY
OP_CHECKSIG |
½«ÔËËã¶ÔÏóת»»ÎªÖµ£¨¿ÉÒÔÔÚwikiÉÏÕÒµ½£©²¢ÊäÈ빫¹²µØÖ·£¨ÔÚBase58Check±àÂë֮ǰ£©¿ÉÒԵõ½ÈçÏÂÊ®Áù½øÖÆÐÎʽµÄ½Å±¾£º
0x76 0xA9 0x14 0xFF33195EC053D6E58D5FD3CC67747D3E1C71B280 0x88 0xAC |
¶Ô½»Ò×½øÐÐÇ©Ãû
p2pk½»Ò×ÖеÄÇ©Ãû½Å±¾ÓÐÁ½¸öµ¥¶Àµ«¹ØÁªµÄÓÃ;£º
- ͨ¹ýÌṩ¹«Ô¿É¢Áе½UTXOÒÑ·¢Ë͵ĵØÖ·£¬½Å±¾¶ÔÎÒÃÇÕýÔÚ³¢ÊÔ»¨·ÑµÄUTXO½øÐÐУÑ飨½âËø£©¡£
- ½Å±¾»¹»á¸øÎÒÃÇÕýÔÚÌá½»µ½ÍøÂçµÄ½»Ò×½øÐÐÇ©Ãû£¬ÕâÑù¾ÍûÓÐÈËÄܹ»ÔÚ²»Ê¹Ç©ÃûʧЧµÄÇé¿öÏÂÐ޸Ľ»Ò×ÁË¡£
µ«ÊÇ£¬Ôʼ½»Ò×°üº¬ÁËÒ»¸öÇ©Ãû½Å±¾£¬¶øÕâ¸öÇ©Ãû½Å±¾ÓÖÓ¦¸Ã°üº¬Ôʼ½»Ò×£¡Òª½â¾öÕâ¸ö¼¦ºÍ¼¦µ°µÄÎÊÌ⣬ÐèÒªÔÚ¶Ô½»Ò×Ç©Ãû֮ǰ°ÑÎÒÃÇÔÚÇ©Ãû½Å±¾ÖÐʹÓõÄUTXOµÄPubkey½Å±¾·Å½øÈ¥¡£¾ÝÎÒËùÖª£¬Ê¹ÓÃPubkey×÷Ϊռλ·ûËÆºõ²¢Ã»ÓÐʲôÔÒò£¬Õ¼Î»·û¿ÉÒÔÊÇÈÎÒâÊý¾Ý¡£
ÔÚÔʼ½»Ò×±»¹þϣ֮ǰ£¬Ëü»¹ÐèÒª¸½¼ÓÒ»¸ö HashtypeÖµ¡£×î³£¼ûµÄHashtypeÖµÊÇSIGHASH_ALL£¬Ëü±êʶÕû¸ö½á¹¹£¬Ê¹µÃÊäÈë»òÊä³ö¶¼²»Äܱ»Ð޸ġ£Õâ¸öWikiÒ³ÃæÁгöÁËÆäËû¹þÏ£ÀàÐÍ£¬ÕâЩÀàÐÍÔÊÐíÔÚ½»Ò×Ç©Ãûºó¶ÔÊäÈëºÍÊä³öµÄ×éºÏ½øÐÐÐ޸ġ£
ÏÂÃæÕâ¸öº¯Êý½«Ôʼ½»Ò×µÄÖµ·ÅÔÚÒ»Æð£¬·µ»ØÒ»¸öpython×ֵ䡣
def get_p2pkh_script(pub_key):
"""
ÕâÊÇÒ»¸ö±ê×¼µÄ¡°Ö§¸¶pubkeyÉ¢ÁС±½Å±¾
"""
# ÏÈÊÇOP_DUP£¬È»ºóÊÇOP_HASH160£¬È»ºóÊÇ20 bytes (pubµØÖ·µÄ³¤¶È)
script = bytes.fromhex("76a914")
# ÒªÖ§¸¶µÄµØÖ·
script += pub_key
# OP_EQUALVERIFY£¬È»ºóÊÇOP_CHECKSIG
script += bytes.fromhex("88ac")
return script
def get_raw_transaction(from_addr, to_addr, transaction_hash, output_index, satoshis_spend):
"""
»ñȡһ¸öÊäÈë¶ÔÓ¦Ò»¸öÊä³öµÄ½»Ò×µÄÔʼ½»Ò×
"""
transaction = {}
transaction["version"] = 1
transaction["num_inputs"] = 1
# ½»Ò×µÄ×Ö½ÚÐòÐèÒª·´¹ýÀ´£º
# https://bitcoin.org/en/developer-reference#hash-byte-order
transaction["transaction_hash"] = bytes.fromhex(transaction_hash)[::-1]
transaction["output_index"] = output_index
# ÁÙʱÈÃÇ©Ãû½Å±¾³ÉΪÀϵÄpubkey½Å±¾£¬Õâ¸ö½Å±¾ºóÃæ»á±»È¡´ú
# ÎÒ¼ÙÉè֮ǰµÄpubkey½Å±¾¾ÍÊÇÕâÀïµÄp2pkh½Å±¾
transaction["sig_script_length"] = 25
transaction["sig_script"] = get_p2pkh_script(from_addr)
transaction["sequence"] = 0xffffffff
transaction["num_outputs"] = 1
transaction["satoshis"] = satoshis_spend
transaction["pubkey_length"] = 25
transaction["pubkey_script"] = get_p2pkh_script(to_addr)
transaction["lock_time"] = 0
transaction["hash_code_type"] = 1
return transaction |
ʹÓÃÒÔÏÂÖµµ÷ÓôúÂëÄÜ´´½¨³öÎÒËù¸ÐÐËȤµÄÔʼ½»Òס£
private_key = address_utils.get_private_key("FEEDB0BDEADBEEF")
public_key = address_utils.get_public_key(private_key)
from_address = address_utils.get_public_address(public_key)
to_address = address_utils.get_public_address (address_utils.get_public_key (address_utils.get_private_key ("BADCAFEFABC0FFEE")))
transaction_id = "95855ba9f46c6936d7b5ee6733c81e71 5ac92199938ce30ac3e1214b8c2cd8d7"
satoshis = 380000
output_index = 1
raw = get_raw_transaction(from_address, to_address, transaction_id, output_index, satoshis) |
ÔÚÉÏÃæµÄ´úÂëÖÐÎÒʹÓÃÁË˽ԿÀ´Éú³Éto_address£¬Õâ¸ö¿´ÆðÀ´¿ÉÄÜ»áÈÃÈ˸е½À§»ó¡£ÆäʵÕâÖ»ÊÇΪÁË·½±ã£¬²¢ÄÜչʾ³öÈçºÎÕÒµ½to_address¡£ÔÚÄãºÍ±ðÈ˽»Ò×µÄʱºò£¬ÄãÐèÒªÎÊËûÃÇÒª¹«¹²µØÖ·£¬¶ø²»ÐèÒªÖªµÀËûÃǵÄ˽Կ¡£
ΪÁËÄܹ»½øÐÐÇ©Ãû£¬²¢×îÖÕ½«½»Ò×·¢²¼µ½ÍøÉÏÈ¥£¬Ôʼ½»Ò×ÐèÒª²ÉÓÃÊʵ±µÄÊֶνøÐдò°ü¡£Õâ¸ö¹ý³ÌÊÇÔÚget_packed_transactionº¯ÊýÖÐʵÏֵģ¬ÎÒ²»»á°Ñ´úÂë¸´ÖÆµ½ÕâÀÒòΪËü±¾ÖÊÉÏÖ»ÊÇһЩ½á¹¹´ò°ü´úÂë¡£ Èç¹ûÄã¸ÐÐËȤµÄ»°£¬¿ÉÒÔÔÚÎÒµÄGithub´úÂë¿âµÄbitcoin_transaction_utils.pyÎļþÖÐÕÒµ½Ëü¡£
ÎÒ¶¨ÒåÁËÒ»¸öÉú³ÉÇ©Ãû½Å±¾µÄº¯Êý¡£Éú³ÉÇ©Ãû½Å±¾ºó£¬Ó¦¸ÃÌæ»»µôռλ·ûÇ©Ãû½Å±¾¡£
def get_transaction_signature(transaction, private_key):
"""
»ñµÃÔʼ½»Ò×µÄÇ©Ãû½Å±¾
"""
packed_raw_transaction = get_packed_transaction(transaction)
hash = hashlib.sha256 (hashlib.sha256 (packed_raw_transaction).digest()).digest()
public_key = address_utils.get_public_key (private_key)
key = SigningKey.from_string (private_key, curve =SECP256k1)
signature = key.sign_digest(hash, sigencode= util.sigencode_der)
signature += bytes.fromhex("01") #hash code type
sigscript = struct.pack ("<B", len(signature))
sigscript += signature
sigscript += struct.pack("<B", len (public_key))
sigscript += public_key
return sigscript |
´Ó±¾ÖÊÉϽ²£¬Ç©Ãû½Å±¾µÄÌṩÊÇΪÁËÖ¤Ã÷ÎÒ¿ÉÒÔ°ÑÊä³öµ±×öÊäÈëÀ´»¨·Ñ£¬Õâ¸öÇ©Ãû½Å±¾ÊÇÎÒ֮ǰ½»Ò×µÄpubkey½Å±¾µÄÊäÈë¡£Õâ¸ö¹¤×÷»úÖÆÈçÏÂËùʾ£¬ÕâÊÇ´Ó±ÈÌØ±ÒwikiÉÏ»ñÈ¡µÄ¡£´Ó±í¸ñµÄµÚÒ»Ðе½ÏÂÃæµÄ×îºóÒ»ÐУ¬Ã¿Ðж¼Êǽű¾µÄÒ»¸öµü´ú¡£ ÕâÊÇÓÃÓÚÖ§¸¶pubkeyÉ¢ÁÐpubkey½Å±¾£¬ÉÏÎÄÌáµ½¹ýÕâÊÇÒ»¸ö×î³£¼ûµÄ½Å±¾¡£ ËüÒ²ÊÇÎÒÕýÔÚ´´½¨µÄ½»Ò׺ÍÎÒÒªÂÄÐеĽ»Ò׵Ľű¾¡£
Õ» |
½Å±¾ |
ÃèÊö |
¿Õ |
signature
publicKey
OP_DUP
OP_HASH160
pubKeyHash
OP_EQUALVERIFY
OP_CHECKSIG |
Ç©Ãû½Å±¾ÖÐµÄ signature ºÍ publicKey ºÏ²¢µ½pubkey½Å±¾ÖС£ |
signature
publicKey |
OP_DUP
OP_HASH160
pubKeyHash
OP_EQUALVERIFY
OP_CHECKSIG |
signature ºÍ publicKey Ìí¼Óµ½Õ»ÖÐ |
signature
publicKey
publicKey |
OP_HASH160
pubKeyHash
OP_EQUALVERIFY
OP_CHECKSIG |
Õ»¶¥µÄÔªËØ£¨ publicKey £©±»OP_DUP¸´ÖÆÁËÒ»·Ý |
signature
publicKey
pubHashA |
pubKeyHash
OP_EQUALVERIFY
OP_CHECKSIG |
Õ»¶¥µÄÔªËØ£¨ publicKey £©±»OP_HASH160¼ÆËã¹þÏ££¬²¢°Ñ pubHashA ѹÈëÕ»ÖС£ |
signature
publicKey
pubHashA
pubKeyHash |
OP_EQUALVERIFY
OP_CHECKSIG |
pubKeyHash Ìí¼Óµ½Õ»ÖС£ |
signature
publicKey |
OP_CHECKSIG |
¼ì²é pubHashA ºÍ pubKeyHash ÊÇ·ñÏàµÈ£¬Èç¹û²»ÏàµÈ£¬ÔòÖжϳÌÐòÔËÐС£ |
True |
- |
¸ù¾ÝÌṩµÄ publicKey À´¼ì²é signature ÊÇ·ñÊÇÓÐЧµÄ½»Ò×Ç©ÃûÉ¢ÁС£ |
Èç¹ûÌṩµÄ¹«Ô¿É¢Áв»Êǽű¾ÖеĹ«Ô¿É¢ÁУ¬»òÕßÌṩµÄÇ©ÃûÓëÌṩµÄ¹«Ô¿²»Æ¥Å䣬ÄÇôÕâ¸ö½Å±¾¾Í»áÖ´ÐÐʧ°Ü¡£ÕâÊÇΪÁËÈ·±£Ö»ÓÐÓµÓÐpubkey½Å±¾ÖеØÖ·µÄ˽ԿµÄÈ˲ÅÄܹ»»¨·ÑÊä³ö¡£
Äã¿ÉÒÔ¿´µ½£¬ÕâÊÇÎÒµÚÒ»´ÎÌṩ¹«Ô¿¡£µ½Ä¿Ç°ÎªÖ¹£¬Ö»Óй«¹²µØÖ·±»¹«²¼³öÀ´¡£ÔÚÕâÀïÌṩ¹«Ô¿ÊÇΪÁËÄܹ»ÑéÖ¤½»Ò×µÄÇ©Ãû¡£
ΪÁËÄÜÔÚÍøÂçÉϽøÐд«Ê䣬ÎÒÃÇ¿ÉÒÔʹÓÃget_transaction_signatureº¯Êý¶Ô½»Ò×½øÐÐÇ©ÃûºÍ´ò°üÁË£¡ÕâÉæ¼°µ½Ê¹ÓÃÕæÊµÇ©Ãû½Å±¾Ì滻ռλ·ûÇ©Ãû½Å±¾£¬²¢´Ó½»Ò×ÖÐÒÆ³ýhash_code_type£¬ÈçÏÂËùʾ¡£
signature = get_transaction_signature(raw, private_key )
raw["sig_script_length"] = len(signature)
raw["sig_script"] = signature
del raw["hash_code_type"]
transaction = get_packed_transaction(raw) |
·¢²¼½»Ò×
Ëæ×Ž»Ò×´ò°üºÍÇ©ÃûµÄÍê³É£¬ÏÂÒ»²½¾ÍÊÇÍøÂçµÄÊÂÇéÁË¡£Í¨¹ýʹÓñ¾ÎÄ֮ǰÔÚbitcoin_p2p_message_utils.pyÖж¨ÒåµÄһЩº¯Êý£¬ÏÂÃæµÄ´úÂëÆ¬¶Î½«ÏûϢͷÌí¼Óµ½´ý·¢Ë͵ÄÊý¾ÝÉÏ£¬²¢½«Æä·¢Ë͸ø¶Ô¶Ë½Úµã¡£ÈçǰËùÊö£¬Ê×ÏÈÐèÒª·¢ËÍÒ»¸ö°æ±¾ÏûÏ¢£¬ÒÔ±ãÄܹ»½ÓÊܺóÐøµÄÏûÏ¢¡£
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((get_bitcoin_peer(), 8333))
s.send(get_bitcoin_message("version", get_version_payload())
s.send(get_bitcoin_message("tx", transaction) |
·¢Ëͽ»Ò×ÊÇ×î·³È˵ÄÒ»²¿·Ö¡£Èç¹ûÎÒ·¢ËÍÁËÒ»¸ö½á¹¹»òÇ©Ãû´íÎóµÄ½»Ò×£¬Ôò¶Ô¶Ë½Úµãͨ³£»áɾ³ýÁ¬½Ó£¬»òÕ߸üºÃÒ»µã£¬»Ø¸´Ò»¸ö°üº¬´íÎóÐÅÏ¢µÄÏûÏ¢¡£ÀàËÆÓÚÕâÑùµÄ´íÎóÏûÏ¢£¨·Ç³£µÃ·³ÈË£©£º¡°SÖµ²»ÐèÒªÕâô¸ß¡±£¬ÕâÊÇÓÉÓÚʹÓÃsigencode_derµÄECSDA±àÂë·½·¨¶Ô½»Ò×É¢ÁнøÐÐÇ©Ãûµ¼Öµġ£¾¡¹ÜÇ©ÃûÊÇÓÐЧµÄ£¬µ«Êµ¼ÊÉϱÈÌØ±Ò¿ó¹¤²¢²»Ï²»¶ÒÔÔÊÐíÍøÂçÀ¬»øÓʼþÐÎʽ¸ñʽ»¯µÄECSDAÇ©Ãû¡£Õâ¸öÎÊÌâµÄ½â¾ö·½°¸¾ÍÊÇʹÓÃsigencode_der_canonizeº¯Êý£¬¸Ãº¯ÊýÓÃÓÚ½«Ç©Ãû¸ñʽ»¯ÎªÆäËûµÄ¸ñʽ¡£ÕâÊÇÒ»¸ö¼òµ¥µ«·Ç³£Äѵ÷ÊÔµÄÎÊÌ⣡
²»¹ÜÔõôÑù£¬ÎÒÖÕÓÚÈóÌÐòÔËÐÐÆðÀ´ÁË£¬¿´µ½ÎҵĽ»Ò×½øÈëÁËÇø¿éÁ´£¬Îҷdz£µÃÐË·Ü£¡µ±»ñÖªÎÒµÄÕâ¸öСÇɼò½à²¢ÇÒÊÇ´¿ÊÖ¹¤´òÔìµÄ½»Ò×½«ÓÀÔ¶³ÉΪ±ÈÌØ±ÒÕË»§µÄÒ»²¿·ÖµÄʱºò£¬ÐÄÖеijɾ͸ÐÓÍÈ»¶øÉú¡£

µ±ÎÒÌá½»½»Ò×µÄʱºò£¬ÎҵĽ»Ò×·ÑÓÃÏà¶ÔÓÚÖÐλÊýÀ´ËµÏ൱µÃµÍ£¨ÎÒͨ¹ý±ÈÌØ±Ò·ÑÓÃÍøÕ¾²éµ½µÄ£©£¬Òò´ËÕ⻨Á˿󹤴óÔ¼5¸öСʱµÄʱ¼äÀ´¾ö¶¨½«Æä°üº¬ÔÚÒ»¸öÇø¿éÖС£ÎÒͨ¹ý²é¿´½»Ò×µÄÈ·ÈÏ´ÎÊýÀ´¼ì²éÕâÒ»µã£¬ÕâÊǶԽ»Ò×ËùÉæ¼°µÄÇø¿éÊýÁ¿µÄ¶ÈÁ¿¡£ÔÚдÕâÆªÎÄÕµÄʱºò£¬ÓÐ190¸öÈ·ÈÏ¡£ÕâÒâζ×ÅÔÚÎҵĽ»Ò×µÄÇø¿éÖ®ºó£¬»¹ÓÐ190¸öÇø¿é¡£Õâ¿ÉÒÔÏ൱°²È«µØµÃµ½È·ÈÏ£¬ÒòΪÐèÒª¶ÔÍøÂç½øÐÐÃÍÁҵĹ¥»÷²ÅÄÜÖØÐ´190¸ö¿éÀ´É¾³ýÎҵĽ»Òס£
×ܽá
ÎÒÏ£ÍûÄãÄÜͨ¹ýÔĶÁ±¾ÎÄÀ´¶Ô±ÈÌØ±ÒµÄ¹¤×÷ÔÀíÓÐËùÁ˽⡣ËäÈ»ÕâÀïÌṩµÄ´ó²¿·ÖÐÅÏ¢²¢²»ÊǺÜʵÓ㬲¢ÇÒÄãͨ³£Ö»»áʹÓÃij¸ö¿Í»§¶ËÀ´Íê³ÉËùÓеIJÙ×÷£¬µ«ÊÇÎÒÈÏΪ¸üºÃµØÀí½â¹¤×÷ÔÀíÄܹ»ÈÃÄã¸üºÃµÄÁ˽â¿Í»§¶ËÄÚ²¿·¢ÉúµÄÊÂÇ飬²¢ÈÃÄã¶ÔÕâÏî¼¼Êõ¸üÓÐÐÅÐÄ¡£
Èç¹ûÄãÏëÔĶÁ¸üÏêϸµÄ´úÂ룬»òÕßÉîÈëµØÑо¿Õâ¸öʾÀý£¬Çë²é¿´ÎÒµÄ Github´úÂë¿â¡£ÔÚ±ÈÌØ±ÒÊÀ½çÀﻹÓкܶàµÄ̽Ë÷¿Õ¼ä£¬ÎÒÖ»ÊÇÌṩÁËÒ»¸ö·Ç³£³£¼ûµÄ±ÈÌØ±ÒµÄÀý×Ó¡£ÄÇÀï¿Ï¶¨»¹Óиü¶à¸ü¿áµÄ¹¦ÄÜ£¬¶ø²»½ö½öÊÇÔÚÁ½¸öµØÖ·Ö®¼ä×ªÒÆ¼ÛÖµ£¡ÎÒҲûÓÐÑо¿ÍÚ¾ò±ÈÌØ±ÒÒÔ¼°ÏòÇø¿éÁ´Ìí¼Ó½»Ò׵Ĺý³Ì¡£
Èç¹ûÄã¿´µ½ÕâÀÄã¿ÉÄÜÒѾÒâʶµ½£¬ÎÒ×ªÒÆµ½ 1QGNXLzGXhWTKF3HTSjuBMpQyUYFkWfgVC µÄ380000µÄSatoshi£¨»ò0.0038±ÈÌØ±Ò£©Äܱ»ÈκÎÈËÈ¡×ߣ¬ÒòΪ±¾ÎÄÖÐÓиõØÖ·µÄ˽Կ¡£Îҷdz£¸ÐÐËȤµØÏëÖªµÀ¶à¾ÃÖ®ºóÕâЩ±ÈÌØ±Ò»á±»×ªÒÆ×ߣ¬ÎÒÏ£Íû´ó¼ÒÄܹ»²ÉÓÃÎÒÕâÀï½éÉܵÄһЩ¼¼ÇÉÀ´×öµ½ÕâÒ»µã¡£Èç¹ûÄã¸Õ¸Õ½«Ë½Ô¿¼ÓÔØµ½Ç®°üÓ¦ÓóÌÐòÖУ¬ÄÇôÎÒ»á±ÉÊÓÄ㣬µ«ÎÒ²»»á×èÖ¹Ä㣡ÔÚ׫д±¾ÎÄʱ£¬ÕâЩ±ÈÌØ±Ò¼ÛֵԼΪ10ÃÀÔª£¬µ«Èç¹û°Ñ±ÈÌØ±Ò¡°Äõ½ÔÂÇòÈ¥¡±£¬ËÖªµÀËüÖµ¶àÉÙÄØ£¡
Èç¹ûÄãÕýÔÚ³¢ÊÔ±ÈÌØ±ÒÕâ¸öÍæÒâ²¢ÔÚѰÕÒÒ»¸öµØÖ·À´·¢ËͱÈÌØ±Ò£¬»òÕßÈç¹ûÄãÈÏΪÕâÆªÎÄÕÂÓмÛÖµ£¬ÄܸøÄãһЩÆô·¢µÄ»°£¬ÄÇôÎҵĵØÖ· 18uKa5c9S84tkN1ktuG568CR23vmeU7F5H ½«ºÜ¸ßÐËÄÜÊÕµ½ÈÎÒâÊýÁ¿µÄ¾è¿î£¡»òÕߣ¬Èç¹ûÄãÏë¸æËßÎÒijЩµØ·½ÓдíÎó£¬ÎÒÒ²ºÜÀÖÒâÄÜÌýµ½¡£
¸ü¶àµÄ×ÊÔ´
Èç¹ûÄã·¢ÏÖÕâÆªÎÄÕºÜÓÐȤ£¬ÄÇô¿ÉÒԲ鿴ÒÔϸü¶àµÄ×ÊÔ´£º
- ÕÆÎÕ±ÈÌØ±ÒÊÇÒ»±¾½âÊͱÈÌØ±Ò¼¼Êõϸ½ÚµÄÊé¡£ÎÒûÓÐÍêÕûµØÔĶÁÕâ±¾Ê飬µ«Ëü°üº¬Á˺ܶàºÜÓÐÓõÄÐÅÏ¢¡£
- Ken SheriffµÄ²©¿ÍÊÇÒ»¸öºÜºÃµÄÐÅÏ¢À´Ô´£¬ÓµÓкܶàÓë±¾ÎÄÏàͬÖ÷ÌâµÄÎÄÕ¡£ºÜ²»ÐÒ£¬ÎÒÔÚдÕâÆªÎÄÕµÄʱºò²Å·¢ÏÖÕâ¸ö²©¿Í¡£Èç¹ûÔÚÕâÆªÎÄÕÂÖÐÓÐÄã²»Ã÷°×µÄµØ·½£¬ÄÇôÔĶÁËûµÄÌû×Ó½«ÊÇÒ»¸öºÜºÃµÄ¿ªÊ¼¡£
- °²µÂ˹¡¤²¼ÀÊÎÖ˼£¨Anders Brownworth£©µÄÃλðãµÄ blockchain visual 101 ÊÓÆµÊÇÑ§Ï°Çø¿é¼¼Êõ¹¤×÷ÔÀíµÄ¾ø¼Ñ×ÊÁÏ¡£
- ³ý·ÇÄãÊÇÒ»¸öÌÛÍ´µÄÊÜŰ¿ñ£¬·ñÔòÎÒ½¨ÒéÄã²»Òª´ÓÁ㿪ʼ£¬³ý·ÇÄãΪÁËѧϰ¶øÌØÒâÏ£ÍûÕâô×ö¡£pycoin¿âÊÇÒ»¸öPython±ÈÌØ±Ò¿â£¬»áÈÃÄãÉÙһЩͷʹ¡£
- ΪÁ˼õÉÙ×Ô¼ºµÄÍ´¿à£¬¿ÉÒÔÍæÍæ Bitcoin testnet£¬¶ø²»ÊÇÏñÎÒÒ»ÑùʹÓÃÖ÷ÍøÂç¡£
- ×îºó£¬ÔÙ˵һ±é£¬±¾ÎĵÄÏà¹Ø´úÂë¿ÉÒÔÔÚÎÒµÄGithub´úÂë¿âÖÐÕÒµ½¡£
|