Pages:
Author

Topic: Python Bitcoin ECC library, supports signing, transactions, determinstic wallets - page 3. (Read 11455 times)

sr. member
Activity: 330
Merit: 397
Nice, congratulations. Though I would've suggested a different language cause simply Python ain't all that fast when it comes to these expensive operations there.

If you want fast I strongly recommend you look at the C++ -based libbitcoin and sx: http://bitcoinmagazine.com/what-libbitcoin-and-sx-are-and-why-they-matter/ sx doesn't support elliptic curve arithmetic or ECDSA message signing, but it's great for the actual Bitcoin stuff!

And I realize there are plenty of inefficiencies in my code as used above with converting between numbers and hex and back. I'm deliberately targeting developer ease of use. No dependency-chasing, no ./configure, make, sudo make install, just a Python file that you can even copy+paste single functions from.
legendary
Activity: 1862
Merit: 1011
Reverse engineer from time to time
Nice, congratulations. Though I would've suggested a different language cause simply Python ain't all that fast when it comes to these expensive operations there.
sr. member
Activity: 330
Merit: 397
I've been writing my own Python library for handling Bitcoin elliptic curve arithmetic for a while now, and just yesterday I made a serious push to have it include many more features. It now supports compressed keys, RFC6979 deterministic ECDSA message signatures (compatible with Electrum; see tests.py), transaction construction and signing and even Electrum-style wallets.

Here's the repo: https://github.com/vbuterin/pybitcointools

I deliberately designed the library to be simple and no-nonsense. No hundred-line monolithic functions, no classes, no wrapper objects, just hex/binary/numbers in and hex/binary/numbers out. You don't need to spend a lot of time "learning" it; no matter what format your data uses, there's some way of handling it in there somewhere. Note that this is NOT a fully functional wallet; it does not support transaction generation or verification, networking or anything to do with blocks. You still need *coind or *coin-qt along with the importprivkey command to do that. It's not a full node, but does have the basic features for constructing Bitcoin transactions and includes two functions for fetching history and pushing transactions with blockchain.info.

Here are some basic usage scenarios:

> from pybitcointools import *
> priv = sha256('some big long brainwallet password')
> priv
'57c617d9b4e1f7af6ec97ca2ff57e94a28279a7eedd4d12a99fa11170e94f5a4'
> pub = privtopub(priv)
> pub
'0420f34c2786b4bae593e22596631b025f3ff46e200fc1d4b52ef49bbdc2ed00b26c584b7e32523 fb01be2294a1f8a5eb0cf71a203cc034ced46ea92a8df16c6e9'
> addr = pubtoaddr(pub)
> addr
'1CQLd3bhw4EzaURHbKCwM5YZbUQfA4ReY6'


Transaction stuff:


> h = history(addr)
> h
[{'output': u'97f7c7d8ac85e40c255f8a763b6cd9a68f3a94d2e93e8bfa08f977b92e55465e:0', 'value': 50000, 'address': u'1CQLd3bhw4EzaURHbKCwM5YZbUQfA4ReY6'}, {'output': u'4cc806bb04f730c445c60b3e0f4f44b54769a1c196ca37d8d4002135e4abd171:1', 'value': 50000, 'address': u'1CQLd3bhw4EzaURHbKCwM5YZbUQfA4ReY6'}]
> outs = [{'value': 90000, 'address': '16iw1MQ1sy1DtRPYw3ao1bCamoyBJtRB4t'}]
> tx = mktx(h,outs)
> tx
'01000000025e46552eb977f908fa8b3ee9d2943a8fa6d96c3b768a5f250ce485acd8c7f79700000 00000ffffffff71d1abe4352100d4d837ca96c1a16947b5444f0f3e0bc645c430f704bb06c84c01 00000000ffffffff01905f0100000000001976a9143ec6c3ed8dfc3ceabcc1cbdb0c5aef4e2d028 73c88ac00000000'
> tx2 = sign(tx,0,priv)
> tx2
'01000000025e46552eb977f908fa8b3ee9d2943a8fa6d96c3b768a5f250ce485acd8c7f79700000 0008b483045022100fc9ec3f6c66f630604e76309092ae00b48d39a83f8683bbf9d6310084e70ea bd022058333d7a1d2158529ce39f9b48dea23dedefbe85028cdceab34e1ee9b1518c3201410420f 34c2786b4bae593e22596631b025f3ff46e200fc1d4b52ef49bbdc2ed00b26c584b7e32523fb01b e2294a1f8a5eb0cf71a203cc034ced46ea92a8df16c6e9ffffffff71d1abe4352100d4d837ca96c 1a16947b5444f0f3e0bc645c430f704bb06c84c0100000000ffffffff01905f0100000000001976 a9143ec6c3ed8dfc3ceabcc1cbdb0c5aef4e2d02873c88ac00000000'
> tx3 = sign(tx2,1,priv)
> tx3
'01000000025e46552eb977f908fa8b3ee9d2943a8fa6d96c3b768a5f250ce485acd8c7f79700000 0008b483045022100fc9ec3f6c66f630604e76309092ae00b48d39a83f8683bbf9d6310084e70ea bd022058333d7a1d2158529ce39f9b48dea23dedefbe85028cdceab34e1ee9b1518c3201410420f 34c2786b4bae593e22596631b025f3ff46e200fc1d4b52ef49bbdc2ed00b26c584b7e32523fb01b e2294a1f8a5eb0cf71a203cc034ced46ea92a8df16c6e9ffffffff71d1abe4352100d4d837ca96c 1a16947b5444f0f3e0bc645c430f704bb06c84c010000008c493046022100da7fa563ce34af5a4c 8167a2978cb5517ded494e52a29ea4103ff2c67bce77c102210094a18bda1109591a82d5cf5e444 6b12b3c399401c0f668755ac7f614eb3baa7701410420f34c2786b4bae593e22596631b025f3ff4 6e200fc1d4b52ef49bbdc2ed00b26c584b7e32523fb01be2294a1f8a5eb0cf71a203cc034ced46e a92a8df16c6e9ffffffff01905f0100000000001976a9143ec6c3ed8dfc3ceabcc1cbdb0c5aef4e 2d02873c88ac00000000'
> pushtx(tx3)
'Transaction Submitted'


ECDSA (Electrum-compatible):

> sig = ecdsa_sign("Hallo world",sha256("123"))
> sig
'G9vmnqdlS9hmP7qT6ReRJEqldYn7f6xc47ado3zg7g4LKpLgVmpmSttDNAAPSizww7zzKDamsyD7bhh fAqaAJ0s='
> ecdsa_verify("Hallo world",sig,privtopub(sha256("123")))
True
> ecdsa_verify("Hallo world!",sig,privtopub(sha256("123")))
False
> ecdsa_recover("Hallo world",sig)
'04be686ed7f0539affbaf634f3bcc2b235e8e220e7be57e9397ab1c14c39137eb43705125aac75a 865268ef33c53897c141bd092cf4d1a306b2a57e37e1386826d'
> privtopub(sha256("123"))
'04be686ed7f0539affbaf634f3bcc2b235e8e220e7be57e9397ab1c14c39137eb43705125aac75a 865268ef33c53897c141bd092cf4d1a306b2a57e37e1386826d'


Electrum:

> seed = sha256("cow")[:32]
> mpk = electrum_mpk(seed)
> for i in range(5): print electrum_privkey(seed,i,0), pubkey_to_address(privtopub(electrum_privkey(seed,i,0)))
daa19f768ea1a7bc8e33d83f9401ef237f5164ce39bf8000ec9630d088cec028 1GG9cGb7KW6qNBCxcU7Y3NH3mPRz9YSxgG
c45ad49da1ccb0ba30258902ed3de66af571de7421f9c73ffc0a8c2bde9ca596 19zxmnE4hmTwPFxhoDAxjtfnKQcRES4Sm2
c31100a56692314248a73f29b767ca252c3847eae15ce5d06e7e7f67a63ee5df 17mJpsyEVykxuf5H4YWsyhatXFyuJmkuoh
302362a97a2db566c5c65b875388db7cce246355faa72f15b486111c2f380bf3 16PGWQwcXM37iY7dPHqqVFit4GXsifRuAM
869424a50260cca7a7fa475c85e48ddf0e47abb0474df59ee45e72e6b95c8333 15QgAJmroGtExvVqVd8MGs1ZZvwYsk39i7
> for i in range(5): print pubkey_to_address(electrum_pubkey(mpk,i,0))
1GG9cGb7KW6qNBCxcU7Y3NH3mPRz9YSxgG
19zxmnE4hmTwPFxhoDAxjtfnKQcRES4Sm2
17mJpsyEVykxuf5H4YWsyhatXFyuJmkuoh
16PGWQwcXM37iY7dPHqqVFit4GXsifRuAM
15QgAJmroGtExvVqVd8MGs1ZZvwYsk39i7


Much faster Electrum by precomputing the secret exponent:

> seed = sha256("cow")[:32]
> secexp = electrum_stretch(seed)
> for i in range(5): print electrum_privkey(secexp,i,0), pubkey_to_address(privtopub(electrum_privkey(secexp,i,0)))
daa19f768ea1a7bc8e33d83f9401ef237f5164ce39bf8000ec9630d088cec028 1GG9cGb7KW6qNBCxcU7Y3NH3mPRz9YSxgG
c45ad49da1ccb0ba30258902ed3de66af571de7421f9c73ffc0a8c2bde9ca596 19zxmnE4hmTwPFxhoDAxjtfnKQcRES4Sm2
c31100a56692314248a73f29b767ca252c3847eae15ce5d06e7e7f67a63ee5df 17mJpsyEVykxuf5H4YWsyhatXFyuJmkuoh
302362a97a2db566c5c65b875388db7cce246355faa72f15b486111c2f380bf3 16PGWQwcXM37iY7dPHqqVFit4GXsifRuAM
869424a50260cca7a7fa475c85e48ddf0e47abb0474df59ee45e72e6b95c8333 15QgAJmroGtExvVqVd8MGs1ZZvwYsk39i7


BIP32:

> bip32_master_key('123456789')
'xprv9s21ZrQH143K2zm1WhDFQqHVdgzoyBWfghiTfgdVJDSjZtTupL9eeg7391hLNjHQNAbd1qLobce ZcaYvrKZ81E3SwtiZ2UbPsP2zm9HeDJo'
> bip32_ckd(bip32_master_key('123456789'),0)
'xprv9ujNqB68cg8G1owbyxEwLHMBYbB1RCyrcra4i8BciNhBrsWeQaEj8FBPNnRmGedK1Q9A5DD3vLe c8me5pBPSwdhckMPQPTWBMtiesu688LN'
> bip32_extract_key(bip32_ckd(bip32_privtopub(bip32_master_key('123456789')),0))
'02e7f3eb95c70480f3f850198017644a84654325b2a4b038268546ea60c1814f6f'
> bip32_extract_key(bip32_privtopub(bip32_ckd(bip32_master_key('123456789'),0)))
'02e7f3eb95c70480f3f850198017644a84654325b2a4b038268546ea60c1814f6f'
> privtopub(bip32_extract_key(bip32_ckd(bip32_master_key('123456789'),0)))
'02e7f3eb95c70480f3f850198017644a84654325b2a4b038268546ea60c1814f6f'


(Those are compressed public keys, which BIP0032 makes standard)

This is still an early work in progress; ideally, with help from others, I'd like to this extended to handle more networking options than just blockchain.info, and serve as a universal altcoin light client. That's a far-off goal though; better have the more basic features ironed out first. Feel free to provide any suggestions!
Pages:
Jump to: