ãããã³ã€ã³ãåŒãç¶ã泚ç®ãéããŠããçç±ã®1ã€ã¯ããã®äŸå€çãªãæ°åŠãã§ãã äžæ¬Sã¯ãåå è
éã®ä¿¡é ŒããŸã£ãããªããŠãæ©èœããã·ã¹ãã ãäœæããããšãã§ããŸããã ãã¹ãŠã®çžäºäœçšã¯å³å¯ãªæ°åŠã«åºã¥ããŠããã人çèŠå ã¯ãããŸãããå€ãã®äººãèããããã«ãããã¯ãã¢ããŒãã¢ãããã¯ãŒã¯ã§ã¯ãªããé©åœã®ã¢ã€ãã¢ã§ããã ãããã£ãŠãç§ã¯ãããã³ã€ã³ã®æ°åŠçåºç€ã«æåã®ç« ãæ§ããããšã«ããŸããã
以äžã§ã¯ãæ¥åæ²ç·ãECCãç§å¯/å
¬éããŒãªã©ãæãåºæ¬çãªããšã説æããããšããŸãã å¯èœã§ããã°ãäž»ã«Python 2.7ã§ãããäœãæç¢ºã§ãªãå Žåã¯ãã³ã¡ã³ãã§è³ªåããŠãã ããã

æ¬
ç®æ¬¡
- ã¯ããã«
- æ¥åæ²ç·
- ããžã¿ã«çœ²å
- ç§å¯éµ
- å
¬ééµ
- ãã©ãŒããããšäœæ
- ãµã€ã³
- 確èªãã
- æžåŒ
- ãªã³ã¯é
ã¯ããã«
äžã§èšã£ãããã«ãæå·åã¯ãããã³ã€ã³ã®åºæ¬çãªéšåã§ãã ããããªããã°ãäœãæ©èœããªãã£ãã®ã§ãããããå§ããå¿
èŠããããŸãã
ãããã³ã€ã³ã¯ã
æ¥åæ²ç·ã®ãããã
æå·å ïŒ
æ¥åæ²ç·æå·åãECC ïŒã䜿çšããŸãã ç¹å¥ãªæ©èœã«åºã¥ããŠããŸã-æ¥åæ²ç·ïŒæ¥åãšæ··åããªãã§ãã ããïŒã ãã®æ©èœãšã¯äœãããããŠãªããããéåžžã«æ³šç®ã«å€ããã®ããããã«èª¬æããŸãã
æ¥åæ²ç·
ãã£ãŒã«ãäžã®æ¥åæ²ç·
äžã®å°åœ±å¹³é¢äžã®éç¹ç°3次æ²ç·
ïŒãã£ãŒã«ãã®ä»£æ°çéå
ïŒãã£ãŒã«ãããã®ä¿æ°ãæã€æ¬¡æ°3ã®æ¹çšåŒã§å®çŸ©
ããã³ãç¡é倧ãæãã- ãŠã£ãããã£ã¢
æã®å Žåãæ¥åæ²ç·ã¯å€åãã«ããªãåçŽãªé¢æ°ã§ãããéåžžãããããã¯ã€ãšã«ã·ã¥ãã©ã¹åã®åœ¢åŒã§èšè¿°ãããŸãã

ãã©ã¡ãŒã¿å€ã«å¿ããŠ

ãããŠ

ããã®é¢æ°ã®ã°ã©ãã¯ç°ãªã£ãŠèŠããå ŽåããããŸãã

Pythonã§ã°ã©ããã¬ã³ããªã³ã°ããããã®ã¹ã¯ãªããïŒ
import numpy as np import matplotlib.pyplot as plt def main(): a = -1 b = 1 y, x = np.ogrid[-5:5:100j, -5:5:100j] plt.contour(x.ravel(), y.ravel(), pow(y, 2) - pow(x, 3) - x * a - b, [0]) plt.grid() plt.show() if __name__ == '__main__': main()
Wikiãä¿¡ãããªããåããŠãã®æ©èœããã£ãªãã¡ã³ãã¹ã®èäœã§ã©ã€ãã¢ããããããã®åŸ17äžçŽã«ãã¥ãŒãã³èªèº«ãããã«èå³ãæã€ããã«ãªããŸããã 圌ã®ç ç©¶ã¯å€ãã®ç¹ã§ãæ¥åæ²ç·äžã®ç¹ã远å ããããã®å
¬åŒãå°ããŸããã ãããšäžã§ãæ¥åæ²ç·ãèããŸã

ã
2ã€ã®ç¹ããããŸã

ã 圌ãã®åèšã¯ãã€ã³ããšåŒã°ããŸã

ãæãåçŽãªå Žåã§ã¯ã次ã®ããã«å®çŸ©ãããŸãã

ãããŠ

-åœŒå¥³ã¯æ²ç·ã暪åã

äžç¹ã§åœŒå¥³ã«é»è©±ããŸããã

ã å€ãã

ç¹åº§æš

ãµã€ã³ã®å察åŽã«ããã€ã³ããååŸããŸã

ããããåèšãšåŒã³ãŸã

ãããŠ

ããã¯

ã

ç§ãã¡ã¯ãã®ãããªå ç®æäœã
å°å
¥ããŠããããšã«æ³šæããå¿
èŠããããšæããŸã-éåžžã®æå³ã§ãã€ã³ãã远å ããå Žåãã€ãŸã察å¿ãã座æšã远å ããå Žåãããªãã¯å®å
šã«ç°ãªããã€ã³ããååŸããŸã
)
ãã»ãšãã©ã®å Žåãäœã®é¢ä¿ããããŸãã

ãŸãã¯

æ²ç·äžã«ã¯ãŸã£ãããããŸãã

ã
æãè³¢ã人ã¯ãã§ã«è³ªåãèªåããŠããŸã-ããšãã°ããã©ãŒã ã®åº§æšãæã€2ã€ã®ç¹ãéãçŽç·ãæãããå Žåãã©ããªããŸãã
)
ãããŠ
)
ãã€ãŸããããããéãç·ã¯çžŠåº§æšè»žïŒäžå³ã®3çªç®ã®ãã¬ãŒã ïŒãšå¹³è¡ã«ãªããŸãã

ãã®å Žåãæ²ç·ãš3çªç®ã®äº€å·®ç¹ããªãããšãç°¡åã«ããããŸãã

ç§ãã¡ãåŒãã

ã ãã®äºä»¶ãé¿ããããã«ãéåžžç¡é倧ãšåŒã°ããããããç¡éé ç¹ãå°å
¥ããŸã

ãŸãã¯åã«

åçã®ããã«ã ãããŠãæã
ã¯äº€å·®ç¹ããªããšèšããŸã

ã
ç¹ã«è峿·±ãã®ã¯ããã€ã³ããèªåèªèº«ã«è¿œå ãããå Žåã§ãïŒ2ãã¬ãŒã ã1ãã€ã³ã

ïŒ ãã®å Žåãåã«ç¹ã«æ¥ç·ãåŒããŸã

ã«é¢ããŠåŸããã亀ç¹ãåæ ããŸã

ã
ããŠãæéŠã軜ãããããšããã€ã³ããæ°åããæäœã«å
¥ãããšãã§ããŸã

æ°ã ãã®çµæãæ°ãããã€ã³ããç²åŸããŸã

ããã¯

åã åçã§ãã¹ãŠãæããã«ãªãã¯ãã§ãã

æéäœäžã®æ¥åæ²ç·
ECCã¯ãæ£ç¢ºã«åãæ²ç·ã䜿çšããŸãããæéãã£ãŒã«ãã§ã®ã¿èæ
®ãããŸã


çŽ æ°ã§ãã ããã¯
ãã®ãããªé¢æ°ã®ååä»ãããããã£ïŒå ç®ãä¹ç®ãç¡éé ç¹ïŒã¯ãã¹ãŠæå¹ãªãŸãŸã§ããããã®é¢æ°ãæç»ããããšãããšãããªãã¿ã®æ¥åæ²ç·ã«ãã䌌ãŠããŸããïŒããããïŒã ãŸãããããç¹ã§ã®é¢æ°ã«æ¥ããããšããæŠå¿µã¯ãäžè¬ã«ãã¹ãŠã®æå³ã倱ããŸãããããã¯å€§äžå€«ã§ãã 以äžã¯é¢æ°ã®äŸã§ã

ã®ããã«

ïŒ

ãããã

ãäžè¬ã«ã»ãŒæ··oticãšãããã€ã³ãã®ã»ããããããŸãã ãã®ã°ã©ãã®èµ·æºãæãåºãããå¯äžã®ãã®ã¯ã軞ã«ã€ããŠã®å¯Ÿç§°æ§ã§ã

ã
PSæéäœäžã®æ²ç·ã®å Žåã®ããã«èå³ãããå Žåã¯ãç¹ã®åº§æšãèšç®ããŸã
)
座æšãç¥ã
)
ãããŠ
-N. Mistryã«
ããããããã³ã€ã³ãæ¥åæ²ç·ãããã³ECDSAã®æ°åŠå
¥éããåç
§ããŠãã ãã
ããã¹ãŠã詳现ã«èšèŒãããŠããã8幎çã¬ãã«ã®æ°åŠãç¥ã£ãŠããã ãã§ååã§ãã
PPSç§ã®äŸãããªãã®æ¢ç©¶å¿ãæºãããªãã£ãå Žåãããã«ããããçš®é¡ã®æ²ç·ãæãããã®
ãµã€ãããã
ãŸã ãå®éšã
SECP256k1
ãããã³ã€ã³ã«æ»ããšã
SECP256k1æ²ç·ã䜿çšããŸãã 圌女ã®åœ¢ã¯

ãã£ãŒã«ãäžã§è¡šç€º

ã©ãã§

-éåžžã«å€§ããªçŽ æ°ãããªãã¡

ã
ãããã
ããŒã¹ãã€ã³ãã¯SECP256k1ã«ãå®çŸ©ãããŠããŸããããã¯
ãžã§ãã¬ãŒã¿ãã€ã³ãã§ããã
ãŸã -ããã¯åãªããã€ã³ãã§ãããéåžžã¯

ãã®æ²ç·ã®äžã«æšªãããã 以äžã§èª¬æããå
¬ééµãäœæããå¿
èŠããããŸãã
ç°¡åãªäŸïŒPythonã䜿çšããŠããã€ã³ããå±ããŠãããã©ããã確èªããŸã
SECP256k1ã«ãŒã
>>> p = 115792089237316195423570985008687907853269984665640564039457584007908834671663 >>> x = 55066263022277343669578718895168534326250603453777594175500187360389116729240 >>> y = 32670510020758816978083085130507043184471273380659243275938904335757337482424 >>> (x ** 3 + 7) % p == y**2 % p True
ããžã¿ã«çœ²å
é»å眲åïŒEDSïŒãé»åããžã¿ã«çœ²åïŒEDSïŒ-ç§å¯çœ²åããŒã䜿çšããæ
å ±ã®æå·å€æã®çµæãšããŠååŸããã眲åãçæãããç¬éããé»åææžã«æ
å ±ã®æªã¿ããªãããšãæ€èšŒã§ããé»åææžã®è©³çŽ°ïŒæŽåæ§ïŒã眲åã¯éµèšŒææžã®ææè
ã«å±ããŸã眲åïŒèè
ïŒãããã³æ€èšŒã«æåããå Žåã¯ãé»åææžãžã®çœ²åïŒåŠèªé²æ¢ïŒã®äºå®ã確èªããŸã- ãŠã£ãããã£ã¢
äžè¬çãªèãæ¹ã¯æ¬¡ã®ãšããã§ããã¢ãªã¹ã¯1 BTCãããã«è»¢éããããšèããŠããŸãã ãããè¡ãããã«ãåœŒå¥³ã¯æ¬¡ã®ãããªã¡ãã»ãŒãžãäœæããŸãã
{ "from" : 1FXySbm7jpJfHEJRjSNPPUqnpRTcSuS8aN, // Alice's address "to" : 1Eqm3z1yu6D4Y1c1LXKqReqo1gvZNrmfvN, // Bob's address "amount" : 1 // Send 1 BTC }
次ã«ãã¢ãªã¹ã¯åœŒå¥³ã®ç§å¯éµïŒä»ã®ãšãããããã¯ã¢ãªã¹ã ããç¥ã£ãŠããæ°åã§ãããšä»®å®ã§ããŸãïŒãã¡ãã»ãŒãžããã·ã¥ãããã³æ¬¡ã®åœ¢åŒã®é¢æ°ãåãåããŸãã
)
ã åºåã§ã圌女ã¯ã¡ãã»ãŒãžã®
眲åãåãåããŸã-ECDSAã®å ŽåãæŽæ°ã®ãã¢ã«ãªããŸããä»ã®ã¢ã«ãŽãªãºã ã§ã¯ã眲åã¯ç°ãªã£ãŠèŠããå ŽåããããŸãã ãã®åŸã圌女ã¯ãã¹ãŠã®ãããã¯ãŒã¯åå è
ã«åæã¡ãã»ãŒãžã眲åãããã³å
¬ééµãéä¿¡ããŸãã
ãã®çµæãåVasyaã¯ãå¿
èŠã«å¿ããŠããã®äžäœäžäœããšãããšãã§ããŸãã
)
ç§å¯éµã®ææè
ãå®éã«ãã®ã¡ãã»ãŒãžã«çœ²åãããã©ããã確èªããŸãã ãããŠããããã¯ãŒã¯å
ã§èª°ããç¥ã£ãŠããå Žå

ã¢ãªã¹ãææããŠããã®ã§ã圌女ããéãéã£ãã®ãã誰ãã圌女ã«ä»£ãã£ãŠãããããããšããŠããã®ããããããŸãã

ããã«ãã¢ãªã¹ãšãããã¯ãŒã¯ã®ä»ã®éšåã®éã«äººãç«ã£ãŠãããšä»®å®ããŸãã 圌ã«ã¢ãªã¹ã®ã¡ãã»ãŒãžãååãããŠãæåéã10åã®ãã¡1ãããã倿ŽãããŸãã ãããããã®å Žåã§ãã眲åã®æ€èšŒ
)
ã¡ãã»ãŒãžã倿Žãããããšã瀺ããŸãã
ãããã¯ãŒã¯ã
忣ãããŠãããããããã¯ãããã³ã€ã³ã«ãšã£ãŠéåžžã«éèŠãªæ©èœã§ãã ç§ãã¡ã®ååŒã1000 BTCãè²æž¡ããèŠæ±ã§èª°ãåŸãããäºåã«ç¥ãããšã¯ã§ããŸããã ãã ãããã©ã³ã¶ã¯ã·ã§ã³ã¯ããªãã®ç§å¯éµã«ãã£ãŠçœ²åãããä»ã®ãããã¯ãŒã¯åå è
ã¯ããã§äœããééã£ãŠããããšãããã«çè§£ããããã圌ã¯ããã倿Žã§ããŸããïŒããšãã°ãåä¿¡è
ãšããŠèªåã®ã¢ãã¬ã¹ã瀺ããŸãïŒã
AHTUNGïŒ å®éãããã»ã¹ã¯äžèšãšã¯ãŸã£ããç°ãªããŸãã ããã§ã¯ãé»åããžã¿ã«çœ²åãšã¯äœãããªãå¿
èŠãªã®ããæã§ç€ºããŸããã å®éã®ã¢ã«ãŽãªãºã ã¯ã
ãBitcoin in a nutshell-Transactionsãã®ç« ã§èª¬æãããŠããŸãã
ç§å¯éµ
ç§å¯éµã¯ããªãäžè¬çãªçšèªã§ãããããŸããŸãªçš®é¡ã®ç§å¯éµãããŸããŸãªé»å眲åã¢ã«ãŽãªãºã ã§äœ¿çšã§ããŸãã
ãæ°ã¥ããããããŸãããããããã³ã€ã³ã¯ECDSAã¢ã«ãŽãªãºã ã䜿çšããŠããŸã-ãã®å Žåãç§å¯ããŒã¯256ãããã®èªç¶ãªæ°å€ãã€ãŸãã

åã«

ã æè¡çã«ã¯ã
123456ãšããæ°åã§ãæå¹ãªç§å¯ããŒã«ãªããŸãããæ»æè
ãç§å¯ããŒãæã«å
¥ãããŸã§ãã³ã€ã³ã¯ããã«ãæå±ããã
123456ã®ãããªå€
ã¯éåžžã«ç°¡åã«èŠã€ãããŸãã
仿¥ã§ã¯ããã¹ãŠã®ããŒãäžŠã¹æ¿ããããšã¯äžå¯èœã§ããããšã«æ³šæããããšãéèŠã§ã

-ããã¯é©ãã»ã©å€æ°ã§ãã
ç§ãã¡ã¯ãããæç€ºããããšããŸãïŒ
ãã®èšäºã«ãããšãå°çå
šäœã§ã¯å°ãå°ãªã

ç ç²ã ãšããäºå®ã掻çšããŠãã ãã

ããã¯

ç ç²ã ãããŠãç§ãã¡ã¯ãã¹ãŠã®ã¢ãã¬ã¹ãæã£ãŠããŸã

ããã

ã
ããã¯ãå°çäžã®ãã¹ãŠã®ç ãåãããã¹ãŠã®ç ç²ãæ°ããå°çã«ãçµæãšããŠçããææã®å±±ã§ãåææäžã®ãã¹ãŠã®ç ç²ãæ°ããå°çã«å€ããããšãã§ããç ç²ã®ç·æ°ãäŸç¶ãšããŠå¯èœãªç§å¯éµã®æ°ãããæ°æ¡å°ãªãããšãæå³ããŸãã
åãçç±ã§ãç§å¯éµãäœæãããšããã»ãšãã©ã®ãããã³ã€ã³ã¯ã©ã€ã¢ã³ãã¯åã«256ã®ã©ã³ãã ããããååŸããŸã-è¡çªã®å¯èœæ§ã¯éåžžã«å°ããã§ãã
Python
>>> import random >>> private_key = ''.join(['%x' % random.randrange(16) for x in range(0, 64)]) >>> private_key '9ceb87fc34ec40408fd8ab3fa81a93f7b4ebd40bba7811ebef7cbc80252a9815' >>>
>>> import binascii >>> import ecdsa
Bitcoin-cli
$ bitcoin-cli getnewaddress 14RVpC4su4PzSafjCKVWP2YBHv3f6zNf6U $ bitcoin-cli dumpprivkey 14RVpC4su4PzSafjCKVWP2YBHv3f6zNf6U L3SPdkFWMnFyDGyV3vkCjroGi4zfD59Wsc5CHdB1LirjN6s2vii9
å
¬ééµ
ããã

-ç§å¯éµã

-åºç¹ã次ã«å
¬éããŒ

ã ã€ãŸããå®éã«ã¯ã
å
¬ééµã¯æ²ç·SECP256k1äžã«ããç¹å®ã®ãã€ã³ãã§ãã
2ã€ã®éèŠãªãã¥ã¢ã³ã¹ã ãŸããå
¬ééµãååŸããæäœãäžæã«æ±ºå®ãããããšãã€ãŸããåäžã®ç§å¯éµãåžžã«åäžã®å
¬ééµã«å¯Ÿå¿ããããšã¯å®¹æã«ããããŸãã 第äºã«ãéã®æäœã¯èšç®äžå°é£ã§ãããäžè¬çãªå Žåãå
¬éããŒããç§å¯ããŒãååŸããããšã¯ãæåã®å®å
šãªæ€çŽ¢ã«ãã£ãŠã®ã¿å¯èœã§ãã
以äžã§ã¯ãå
¬ééµãšã¢ãã¬ã¹ã®éã«ãŸã£ããåãé¢ä¿ãååšããããšãããããŸããå
šäœã®ãã€ã³ãã¯ãããã·ã¥é¢æ°ãäžå¯éçã§ããããšã§ãã

PythonãECDSA
>>> import binascii >>> import ecdsa >>> private_key = ecdsa.SigningKey.generate(curve=ecdsa.SECP256k1) >>> public_key = private_key.get_verifying_key() >>> binascii.hexlify(public_key.to_string()).decode('ascii').upper() u'D5C08F1BFC9C26A5D18FE9254E7923DEBBD34AFB92AC23ABFC6388D2659446C1F04CCDEBB677EAABFED9294663EE79D71B57CA6A6B76BC47E6F8670FE759D746'
#include <bitcoin/bitcoin.hpp> #include <iostream> int main() { // Private key bc::ec_secret secret = bc::decode_hash( ); // Get public key bc::ec_point public_key = bc::secret_to_public_key(secret); std::cout << << bc::encode_hex(public_key) << std::endl; }
ã³ã³ãã€ã«ããŠå®è¡ããã«ã¯ãïŒlibbitcoinã®äºåã€ã³ã¹ããŒã«ïŒã䜿çšããŸãã
$ g++ -o public_key <filename> $$(pkg-config --cflags --libs libbitcoin) $ ./public_key Public key: 0202a406624211f2abbdc68da3df929f938c3399dd79fac1b51b0e4ad1d26a47aa
æåãš2çªç®ã®äŸã®å
¬éããŒã®åœ¢åŒãç°ãªãïŒå°ãªããšãé·ããïŒããšãããããŸããããã«ã€ããŠã¯ã以äžã§è©³ãã説æããŸãã
ãã©ãŒããããšäœæ
Base58Checkãšã³ã³ãŒãã£ã³ã°
ãã®ãšã³ã³ãŒãã£ã³ã°ã¯æ¬å
šäœã§çµ¶ããééãããããã©ã®ããã«æ©èœããã®ãããªãå¿
èŠãªã®ããçè§£ããå¿
èŠããããŸãã
ãã®æ¬è³ªã¯ããã€ãã·ãŒã±ã³ã¹ãæãèªã¿ããã圢åŒã§ã§ããã ãçãæžãçãããšåæã«ãã¿ã€ããã¹ã®å¯èœæ§ãããã«äœãããããšã§ãã Bitcoinã®å Žåãã»ãã¥ãªãã£ã¯æ±ºããŠäžèŠã§ã¯ãªãããšããçè§£ããã ããŠãããšæããŸãã 1ã€ã®ééã£ããã£ã©ã¯ã¿ãŒãšãéãããããã誰ãèŠã€ããããªãããŒã«ã¢ãã¬ã¹ã«è¡ããŸãã
base58.hããã®ãã®ãšã³ã³ãŒãã£ã³ã°ã«é¢ããã³ã¡ã³ãã¯
次ã®ãšããã§ãã
// Why base-58 instead of standard base-64 encoding? // - Don't want 0OIl characters that look the same in some fonts and // could be used to create visually identical looking account numbers. // - A string with non-alphanumeric characters is not as easily accepted as an account number. // - E-mail usually won't line-break if there's no punctuation to break at. // - Doubleclicking selects the whole number as one word if it's all alphanumeric.
èšé²ã®ç°¡æœãã¯ãããªãäžè¬çãª
Base64ãšã³ã³ãŒãã䜿çšããŠå®è£
ããã®ãæãç°¡åã§ããã€ãŸããæ°å
0,1,...,9
ãæå
az
ããã³
AZ
ãæžã蟌ã¿ã«äœ¿çšãããbase 64çªå·ã·ã¹ãã ã䜿çšããŸã-ããã¯62æåãäžããæ®ãã®2ã€ã¯å®è£
ã«ãã£ãŠç°ãªããŸãã
Base58Checkã®æåã®éãã¯ãæå
0,O,l,I
ã誰ããæ··åããããšã«ããå Žåã«åã
0,O,l,I
åé€ãããããšã§ãã 58æåã§ããããšãããããŸãã
b58 = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz' def base58encode(n): result = '' while n > 0: result = b58[n%58] + result n /= 58 return result
2çªç®ã®éãã¯åã
ãã§ãã¯ã§ãã è¡ã®æåŸã«ã
ãã§ãã¯ãµã ãåã³è¿œå ãããŸã
SHA256(SHA256(str))
æåã®4ãã€ã
SHA256(SHA256(str))
ã ãŸããbase58ã§ã®ãšã³ã³ãŒãã®åã«å
è¡ãŒãããã£ãã®ãšåãæ°ã®ãŠããããå
é ã«è¿œå ããå¿
èŠããããŸããããã¯ãã§ã«æè¡çãªåé¡ã§ãã
import hashlib def base58encode(n): b58 = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz' result = '' while n > 0: result = b58[n % 58] + result n /= 58 return result

ç§å¯éµã®åœ¢åŒ
ç§å¯éµãä¿åããæãæçœãªæ¹æ³ã¯ã256ãããããŒããš1ã®æãšããŠæžã蟌ãããšã§ãã ãããããããããæè¡çã«æèœãªäººãªããåãã·ãŒã±ã³ã¹ã32ãã€ãã®åœ¢åŒã§æç€ºããæ¹ãã¯ããã«ç°¡åã§ããããšãçè§£ããŠããŸããåãã€ãã¯16é²è¡šèšã®2æåã«å¯Ÿå¿ããŸãã ãã®å Žåãæ°å
0,1,...,9
ãšæå
A,B,C,D,E,F
ããããšãæãåºãããŠãã ããã äžèšã®äŸã§ã¯ãã®åœ¢åŒã䜿çšããŸããããçŸããã®ããã«ã¹ããŒã¹ã§åºåãããŠããå ŽåããããŸãã
E9 87 3D 79 C6 D8 7D C0 FB 6A 57 78 63 33 89 F4 45 32 13 30 3D A6 1F 20 BD 67 FC 23 3A A3 32 62
ãã1ã€ã®ããé«åºŠãªåœ¢åŒã¯ã
WIF ïŒ
Wallet Import Format ïŒã§ãã ããã¯éåžžã«ç°¡åã«æ§ç¯ãããŸãïŒ
0C28FCA386C7A227600B2FE50B7CAE11EC86D3BF1FBE471BE89827E19D72AA1D
ãªã©ã®ç§å¯éµãååŸããŸã- ãã¬ãã£ãã¯ã¹
0x80
ä»ããŠBase58Checkã«æžã蟌ã¿ãŸãã ããã ãã§ã
private_key = '0a56184c7a383d8bcce0c78e6e7a4b4b161b2f80a126caa48bde823a4625521f' def privateKeyToWif(key_hex): return base58CheckEncode(0x80, key_hex.decode('hex'))
å
¬ééµåœ¢åŒ
念ã®ãããå
¬éããŒã¯SECP256k1è¡ã®åãªããã€ã³ãã§ããããšãæãåºãããŠãã ããã ãããèšè¿°ããæåã§æãäžè¬çãªããªã¢ã³ãã¯ãXããã³Y座æš
ããšã«32ãã€ãã®
éå§çž®åœ¢åŒã§ãã æ··ä¹±ãé¿ããããã«ããã¬ãã£ãã¯ã¹
0x04
ãšãã®65ãã€ãã䜿çšãããŸãã
import ecdsa private_key = '0a56184c7a383d8bcce0c78e6e7a4b4b161b2f80a126caa48bde823a4625521f' def privateKeyToPublicKey(s): sk = ecdsa.SigningKey.from_string(s.decode('hex'), curve=ecdsa.SECP256k1) vk = sk.verifying_key return ('\04' + sk.verifying_key.to_string()).encode('hex') uncompressed_public_key = privateKeyToPublicKey(private_key)
ãã ããååã瀺ãããã«ãããã¯å
¬ééµãä¿åããæè¯ã®æ¹æ³ã§ã¯ãããŸããã
é©ãã§ããããã2çªç®ã®åœ¢åŒã¯
å§çž®ãšåŒã°
ããŸãã ãã®æ¬è³ªã¯æ¬¡ã®ãšããã§ããå
¬ééµã¯æ²ç·äžã®ç¹ãã€ãŸãåŒãæºããæ°å€ã®ãã¢ã§ã
)
ã ãããã£ãŠãX座æšã®ã¿ãèšè¿°ã§ããY座æšãå¿
èŠãªå Žåã¯æ¹çšåŒãè§£ãã ãã§ãã ãããã£ãŠãå
¬éããŒã®ãµã€ãºãã»ãŒ50ïŒ
åæžããŸãïŒ
å¯äžã®æ³šæç¹ã¯ããã€ã³ããæ²ç·äžã«ããå ŽåãX座æšã®ãã®æ¹çšåŒã«ã¯æããã«2ã€ã®è§£æ±ºçãããããšã§ãïŒçãããå Žåã¯äžã®ã°ã©ããèŠãŠãã ããïŒã éåžžãY座æšã®ç¬Šå·ãä¿æããŸãããæéäœäžã®é¢æ°ã«é¢ããŠã¯ã次ã®ããããã£ã䜿çšããå¿
èŠããããŸãïŒ
X座æšã®æ¹çšåŒã®è§£ãããå Žåããã€ã³ãã®1ã€ã¯å¶æ°ã®Y座æšãæã¡ã2çªç®ã®ãã€ã³ãã¯å¥æ°ã®åº§æš ïŒåã³ããªãèªèº«ã§èŠãããšãã§ããŸãïŒã
æåã®ã±ãŒã¹ã§ã¯ããã¬ãã£ãã¯ã¹
0x02
ãã2çªç®ã®ã±ãŒã¹ã§ã¯
0x03
0x02
ãŸãã ããã»ã¹ã®äŸã次ã«ç€ºããŸãã

äœæ
ãã§ã«è¿°ã¹ãããã«ãã¢ãã¬ã¹ã¯å
¬éããŒããç¬èªã®æ¹æ³ã§ååŸãããŸãã ããã«ãæå·çã«åŒ·åãªããã·ã¥é¢æ°
-RIPEMD160ããã³
SHA256ã
䜿çšãããŠãããããéã®æäœãå®è¡ããããšã¯ã§ããŸã
ã ã å
¬ééµãã¢ãã¬ã¹ã«å€æããã¢ã«ãŽãªãºã ã¯æ¬¡ã®ãšããã§ãã
45b0c38fa54766354cf3409d38b873255dfa9ed3407a542ba48eb9cab9dfca67
ãªã©ã®ç§å¯éµã45b0c38fa54766354cf3409d38b873255dfa9ed3407a542ba48eb9cab9dfca67
- éå§çž®åœ¢åŒã§å
¬ééµãååŸããŸãããã®å Žåã¯
04162ebcd38c90b56fbdb4b0390695afb471c944a6003cb334bbf030a89c42b584f089012beb4842483692bdff9fcab8676fed42c47bffb081001209079bbcb8db
ã§ãã RIPEMD160(SHA256(public_key))
ãèæ
®ãããšã RIPEMD160(SHA256(public_key))
ã§ããããšã5879DB1D96FC29B2A6BDC593E67EDD2C5876F64C
- çµæãæ¥é èŸ
17JdJpDyu3tB5GD3jwZP784W5KbRdfb84X
ãŸãã ããã¯äœæã§ãã
def pubKeyToAddr(s): ripemd160 = hashlib.new('ripemd160') ripemd160.update(hashlib.sha256(s.decode('hex')).digest()) return base58CheckEncode(0, ripemd160.digest()) def keyToAddr(s): return pubKeyToAddr(privateKeyToPublicKey(s))
眲åãšæ€èšŒ
ECDSAãã¡ãã»ãŒãžãã©ã®ããã«çœ²åããã³ãã§ãã¯ãããã«ã€ããŠã®æè¡çãªè©³çްãç¥ãå¿
èŠã¯ãªããšæããŸãããšã«ãããã©ãã§ãæ¢è£œã®ã©ã€ãã©ãªã䜿çšããŸãã äž»ãªããšã¯ããªããããå¿
èŠãªã®ãã«ã€ããŠå
±éã®çè§£ãæã£ãŠããããšã§ããããŸã èå³ãããå Žåã¯ã
æ¥åæ²ç·ããžã¿ã«çœ²åã®
ã¬ã€ãã³ã®ã¬ã€ããã芧ãã ããã以äžã®ããã»ã¹å
šäœã®çŸããèŠèŠåããããèªåã§è©ŠããŠã¿ãããšãã§ããŸãã
次ã®ç« ã
Bitcoin in a nutshell-Transactionã§ãã
ãªã³ã¯é