def getnewsubaccount(self): key = CKey() key.generate() private_key = key.get_privkey() public_key = key.get_pubkey() address = pubkey_to_address(public_key) return {"address": address, "public_key": public_key, "private_key": private_key, "balance": 0.0, 'height' : 0, 'received' : []}
def encode_pw(key, pw): key = CKey() decode_string = __decode_b58(key)[1:-4] key.generate(decode_string) key.set_compressed(False) bt = Bip38(key, pw) return str(CBase58Data(bt.get_encrypted(), 0x01))
def getnewsubaccount(self): key = CKey() key.generate() private_key = key.get_privkey() public_key = key.get_pubkey() address = pubkey_to_address(public_key) print "Address: ", address print "Private key: ", type(private_key), private_key print "Public key: ", type(public_key), public_key return {"address": address, "public_key": public_key, "private_key": private_key, "balance": 0.0, 'height' : 0, 'received' : []}
def _decrypt_ec_multiply(k_buffer, passphrase): if passphrase is None or passphrase == '': raise ValueError("Passphrase must not be empty.") prefix = k_buffer[0:1] flagbyte = k_buffer[1:2] ls_numbers = False if ''.join(chr(ord(c)&ord(k)) for c,k in izip(flagbyte, '\x04')) == '\x04': ls_numbers = True ls, = unpack('>I', k_buffer[10:14]) lot = ls / 4096 sequence = ls - (lot*4096) salt = k_buffer[6:10] else: salt = k_buffer[6:14] address_hash = k_buffer[2:6] ownerentropy = k_buffer[6:14] prefactor = scrypt.hash(passphrase, salt, N=16384, r=8, p=8, buflen=32) if ls_numbers is True: passfactor = SHA256.new(SHA256.new(prefactor+ownerentropy).digest()).digest() else: passfactor = prefactor passpoint = Bip38._compute_passpoint(passfactor) derived = scrypt.hash(passpoint, address_hash + ownerentropy, N=1024, r=1, p=1, buflen=64) derived_half1 = derived[:32] derived_half2 = derived[32:64] cipher = AES.new(derived_half2) decrypted_half2 = Bip38.xor_zip(cipher.decrypt(k_buffer[22:22+16]), derived_half1[16:32]) ep12 = decrypted_half2[0:8] decrypted_half1 = Bip38.xor_zip(cipher.decrypt(k_buffer[14:14+8] + ep12), derived_half1[:16]) seedb = decrypted_half1[0:16] + decrypted_half2[8:16] factorb = SHA256.new(SHA256.new(seedb).digest()).digest() r = ssl.BN_new() pf = ssl.BN_bin2bn(passfactor, 32, ssl.BN_new()) fb = ssl.BN_bin2bn(factorb, 32, ssl.BN_new()) NID_secp256k1 = 714 k = ssl.EC_KEY_new_by_curve_name(NID_secp256k1) group = ssl.EC_KEY_get0_group(k) ctx = ssl.BN_CTX_new() ssl.BN_CTX_start(ctx) order = ssl.BN_CTX_get(ctx) if ssl.EC_GROUP_get_order(group, order, ctx) == 0: raise Exception('Error in EC_GROUP_get_order()') ssl.BN_mod_mul(r, pf, fb, order, ctx) ssl.BN_CTX_free(ctx) pkey = CKey() final = ctypes.create_string_buffer(32) ssl.BN_bn2bin(r, final) pkey.generate(secret=final) return pkey.get_secret()
def encryptBIP0038(pubkey, privkey, secret): k = CKey() #decode the wallet import format by base58 decoding then dropping the last 4 bytes and the first byte decoded = b58decode(privkey) decoded = decoded[:-4] decoded = decoded[1:] k.generate(decoded) k.set_compressed(False) b = Bip38(k, secret) res = b.encrypt_no_ec_multiply() return res
def gen_eckey(passphrase=None, secret=None, pkey=None, compressed=False, rounds=1, version=0): k = CKey() if passphrase: secret = passphrase.encode('utf8') for i in xrange(rounds): secret = hashlib.sha256(secret).digest() if pkey: secret = base58_check_decode(pkey, 128+version) compressed = len(secret) == 33 secret = secret[0:32] k.generate(secret) k.set_compressed(compressed) return k
def CheckSig(sig, pubkey, script, txTo, inIdx, hashtype): key = CKey() key.set_pubkey(pubkey) if len(sig) == 0: return False if hashtype == 0: hashtype = ord(sig[-1]) elif hashtype != ord(sig[-1]): return False sig = sig[:-1] tup = SignatureHash(script, txTo, inIdx, hashtype) return key.verify(ser_uint256(tup[0]), sig)
def _get_confirmation_code(flagbyte, ownerentropy, factorb, derived_half1, derived_half2, addresshash): k = CKey() k.set_compressed(True) k.generate(secret=factorb) pointb = k.get_pubkey() if len(pointb) != 33: return AssertionError('pointb (' + hexlify(pointb) + ') is ' + str(len(pointb)) + ' bytes. It should be 33 bytes.') if pointb[:1] != '\x02' and pointb[:1] != '\x03': return ValueError('pointb is not correct.') pointbprefix = Bip38.xor_zip( pointb[:1], chr(ord(derived_half2[31:32]) & ord('\x01'))) cipher = AES.new(derived_half2) pointbx1 = cipher.encrypt( Bip38.xor_zip(pointb[1:17], derived_half1[:16])) pointbx2 = cipher.encrypt( Bip38.xor_zip(pointb[17:33], derived_half1[16:32])) encryptedpointb = pointbprefix + pointbx1 + pointbx2 if len(encryptedpointb) != 33: return AssertionError('encryptedpointb is not 33 bytes long.') magic = '\x3b\xf6\xa8\x9a' return str( CBase58Data( magic + flagbyte.tostring() + addresshash + ownerentropy + encryptedpointb, 0x64))
def withdrawfromvault(self, fromvaultaddress, toaddress, amount): vault = self.getvault(fromvaultaddress) received = self.chaindb.listreceivedbyvault(fromvaultaddress) received = received.values()[0] if received['value'] < amount + 2 * utils.calculate_fees(None): self.logger.warning("Insufficient funds in vault, exiting, return") return # create transaction tx = CTransaction() # to the receiver txout = CTxOut() txout.nValue = amount txout.scriptPubKey = utils.address_to_pay_to_pubkey_hash(toaddress) tx.vout.append(txout) # from the sender nValueIn = 0 nValueOut = amount txin = CTxIn() txin.prevout = COutPoint() txin.prevout.hash = received['txhash'] txin.prevout.n = received['n'] txin.scriptSig = received['scriptPubKey'] tx.vin.append(txin) # calculate nValueIn nValueIn = received['value'] # calculate the total excess amount excessAmount = nValueIn - nValueOut # calculate the fees fees = 2 * utils.calculate_fees(tx) # create change transaction, if there is any change left if excessAmount > fees: change_txout = CTxOut() change_txout.nValue = excessAmount - fees account = self.getaccount() changeaddress = fromvaultaddress self.logger.debug("Change address: %s" % changeaddress) change_txout.scriptPubKey = \ utils.vault_address_to_pay_to_vault_script(changeaddress) tx.vout.append(change_txout) # calculate txhash tx.calc_sha256() txhash = str(tx.sha256) key = CKey() key.set_pubkey(vault['public_key']) key.set_privkey(vault['private_key']) signature = key.sign(txhash) vaultscript = utils.create_vault_script(vault['address'], \ vault['master_address'], vault['timeout'], vault['maxfees']) scriptSig = chr(OP_VAULT_WITHDRAW) + chr(len(signature)) + signature + \ chr(len(vaultscript)) + vaultscript self.logger.debug("Adding signature: %s" % binascii.hexlify(scriptSig)) txin.scriptSig = scriptSig return tx
def sign(jsonbuf, privkey, role, extra_keys=[]): ''' :type jsonbuf: str. :param privkey: private key in DER form :type privkey: str. :type role: str. :type extra_keys: list. :returns: dict - JSON with signature appended. :raises: BadJSONError ''' jsondoc = json.loads(jsonbuf) signed_keys = jsondoc.get('signed_keys', []) sigdict = {} for key in signed_keys + extra_keys: # FIXME:в ключе допустимы только [a-zA-Z0-9_.\-] # FIXME:можно исключить числа с плавающей точкой value = jsondoc.get(key, None) if not value: raise BadJSONError('Missing attribute: %s' % (repr(key),)) sigdict[key] = value if not len(sigdict): raise BadJSONError('No attributes to sign') instr = json.dumps(sigdict, separators=(',',':'), sort_keys=True) hash = hashlib.sha256(hashlib.sha256(instr).digest()).digest() ckey = CKey() ckey.set_privkey(privkey) signed = ckey.sign(hash) sigentry = { 'role': role, 'signature_type': 'secp256k1', 'pubkey': binascii.hexlify(ckey.get_pubkey()), 'signature': binascii.hexlify(signed) } if extra_keys: sigentry['extra_signed_keys'] = extra_keys jsondoc.setdefault('signatures', []).append(sigentry) return jsondoc
def overridevaulttx(self, fromvaultaddress, toaddress): vault = self.getvault(fromvaultaddress) # select the input addresses received = self.chaindb.listallreceivedbyvault(fromvaultaddress) if not received: self.logger.warning("Empty vault, exiting, return") return None, None received = received.values()[0] if received['value'] < 2 * utils.calculate_fees(None): self.logger.warning("Insufficient funds in vault, exiting, return") return None, None # calculate remaining amount amount = received['value'] - 2 * utils.calculate_fees(None) # create transaction tx = CTransaction() # to the receiver txout = CTxOut() txout.nValue = amount txout.scriptPubKey = utils.address_to_pay_to_pubkey_hash(toaddress) tx.vout.append(txout) # from the sender nValueIn = 0 nValueOut = amount txin = CTxIn() txin.prevout = COutPoint() txin.prevout.hash = received['txhash'] txin.prevout.n = received['n'] txin.scriptSig = received['scriptPubKey'] tx.vin.append(txin) # calculate nValueIn nValueIn = received['value'] # calculate the total excess amount excessAmount = nValueIn - nValueOut # calculate the fees fees = utils.calculate_fees(tx) # calculate txhash tx.calc_sha256() txhash = str(tx.sha256) key = CKey() key.set_pubkey(vault['public_key']) key.set_privkey(vault['private_key']) signature = key.sign(txhash) # get the script vaultscript = utils.create_vault_script(vault['address'], \ vault['master_address'], vault['timeout'], vault['maxfees']) scriptSig = chr(OP_VAULT_OVERRIDE) + chr(len(vault['master_public_key'])) + \ vault['master_public_key'] + chr(len(signature)) + signature + \ chr(len(vaultscript)) + vaultscript self.logger.debug("Adding signature: %s" % binascii.hexlify(scriptSig)) txin.scriptSig = scriptSig return amount, tx
def verify(jsonbuf): ''' :param jsondoc: str with JSON :type jsondoc: str returns: bool - True if signature verification succeeds :raises: BadJSONError ''' basedict = {} jsondoc = json.loads(jsonbuf) signatures = jsondoc.get('signatures', []) if not len(signatures): raise BadJSONError('Signatures not found') for key in jsondoc.get('signed_keys', []): value = jsondoc.get(key, None) if not value: raise BadJSONError('Missing attribute: %s' % (repr(key),)) basedict[key] = value ckey = CKey() sigchecks = [] for signature_dict in signatures: if 'secp256k1' != signature_dict.get('signature_type', ''): continue sig = binascii.unhexlify(signature_dict.get('signature', '')) pubkey = binascii.unhexlify(signature_dict.get('pubkey', '')) sigdict = {} for key in signature_dict.get('extra_signed_keys', []): value = jsondoc.get(key, None) if not value: raise BadJSONError('Missing attribute: %s' % (repr(key),)) sigdict[key] = value sigdict.update(basedict) ckey.set_pubkey(pubkey) instr = json.dumps(sigdict, separators=(',',':'), sort_keys=True) hash = hashlib.sha256(hashlib.sha256(instr).digest()).digest() sigchecks.append(ckey.verify(hash, sig)) return (sigchecks and 0 not in sigchecks and -1 not in sigchecks)
def verify(jsonbuf): ''' :param jsondoc: str with JSON :type jsondoc: str returns: bool - True if signature verification succeeds :raises: BadJSONError ''' basedict = {} jsondoc = json.loads(jsonbuf) signatures = jsondoc.get('signatures', []) if not len(signatures): raise BadJSONError('Signatures not found') for key in jsondoc.get('signed_keys', []): value = jsondoc.get(key, None) if not value: raise BadJSONError('Missing attribute: %s' % (repr(key), )) basedict[key] = value ckey = CKey() sigchecks = [] for signature_dict in signatures: if 'secp256k1' != signature_dict.get('signature_type', ''): continue sig = binascii.unhexlify(signature_dict.get('signature', '')) pubkey = binascii.unhexlify(signature_dict.get('pubkey', '')) sigdict = {} for key in signature_dict.get('extra_signed_keys', []): value = jsondoc.get(key, None) if not value: raise BadJSONError('Missing attribute: %s' % (repr(key), )) sigdict[key] = value sigdict.update(basedict) ckey.set_pubkey(pubkey) instr = json.dumps(sigdict, separators=(',', ':'), sort_keys=True) hash = hashlib.sha256(hashlib.sha256(instr).digest()).digest() sigchecks.append(ckey.verify(hash, sig)) return (sigchecks and 0 not in sigchecks and -1 not in sigchecks)
def no_ec_multiply(self, v, compressed=False): k = CKey() k.generate(unhexlify(v['unencrypted_hex'])) k.set_compressed(compressed) # Test get_secret() self.assertEqual(unhexlify(v['unencrypted_hex']), k.get_secret()) self.assertEqual(v['unencrypted_wif'], k.get_secret(form=CKeyForm.BASE58)) # Test encryption b = Bip38(k, v['passphrase']) self.assertEqual(v['encrypted'], b.encrypt_no_ec_multiply()) # Test decryption self.assertEqual(unhexlify(v['unencrypted_hex']), Bip38.decrypt(v['encrypted'], v['passphrase']))
def encryptBIP0038(pubkey, privkey, secret): k = CKey() #decode the wallet import format by base58 decoding then dropping the last 4 bytes and the first byte decoded = b58decode(privkey) decoded = decoded[:-4] decoded = decoded[1:] k.generate(decoded) k.set_compressed(False) b = Bip38(k, secret) return str(CBase58Data(b.get_encrypted(), 0x01))
def generate_address(): # def get_addr(k,version = 0): k = CKey() version = 0 k.generate() k.set_compressed(True) pubkey = k.get_pubkey() secret = k.get_secret() hash160 = rhash(pubkey) addr = base58_check_encode(hash160, version) # payload = secret # if k.compressed: # payload = secret + chr(1) pkey = base58_check_encode(payload, 128+version) return addr, pkey
def no_ec_multiply(self, v, compressed = False): k = CKey() k.generate(unhexlify(v['unencrypted_hex'])) k.set_compressed(compressed) # Test get_secret() self.assertEqual(unhexlify(v['unencrypted_hex']), k.get_secret()) self.assertEqual(v['unencrypted_wif'], k.get_secret(form=CKeyForm.BASE58)) # Test encryption b = Bip38(k, v['passphrase']) self.assertEqual(v['encrypted'], b.encrypt_no_ec_multiply()) # Test decryption self.assertEqual(unhexlify(v['unencrypted_hex']), Bip38.decrypt(v['encrypted'], v['passphrase']))
def getnewsubaccount(self): key = CKey() key.generate() private_key = key.get_privkey() public_key = key.get_pubkey() address = pubkey_to_address(public_key) return { "address": address, "public_key": public_key, "private_key": private_key, "balance": 0.0, 'height': 0, 'received': [] }
def test_no_compression_ec_multiply_lot_sequence_numbers(self): vec = [ {'passphrase': 'MOLON LABE', 'passphrase_code': 'passphraseaB8feaLQDENqCgr4gKZpmf4VoaT6qdjJNJiv7fsKvjqavcJxvuR1hy25aTu5sX', 'encrypted': '6PgNBNNzDkKdhkT6uJntUXwwzQV8Rr2tZcbkDcuC9DZRsS6AtHts4Ypo1j', 'salt': '\x4f\xca\x5a\x97', 'seedb': '\x87\xa1\x3b\x07\x85\x8f\xa7\x53\xcd\x3a\xb3\xf1\xc5\xea\xfb\x5f\x12\x57\x9b\x6c\x33\xc9\xa5\x3f', 'bitcoin_address': '1Jscj8ALrYu2y9TD8NrpvDBugPedmbj4Yh', 'unencrypted_wif': '5JLdxTtcTHcfYcmJsNVy1v2PMDx432JPoYcBTVVRHpPaxUrdtf8', 'unencrypted_hex': '44EA95AFBF138356A05EA32110DFD627232D0F2991AD221187BE356F19FA8190', 'confirmation_code': 'cfrm38V8aXBn7JWA1ESmFMUn6erxeBGZGAxJPY4e36S9QWkzZKtaVqLNMgnifETYw7BPwWC9aPD', 'lot': 263183, 'sequence': 1, }, {'passphrase': 'ΜΟΛΩΝ ΛΑΒΕ', 'passphrase_code': 'passphrased3z9rQJHSyBkNBwTRPkUGNVEVrUAcfAXDyRU1V28ie6hNFbqDwbFBvsTK7yWVK', 'encrypted': '6PgGWtx25kUg8QWvwuJAgorN6k9FbE25rv5dMRwu5SKMnfpfVe5mar2ngH', 'salt': '\xc4\x0e\xa7\x6f', 'seedb': '\x03\xb0\x6a\x1e\xa7\xf9\x21\x9a\xe3\x64\x56\x0d\x7b\x98\x5a\xb1\xfa\x27\x02\x5a\xaa\x7e\x42\x7a', 'bitcoin_address': '1Lurmih3KruL4xDB5FmHof38yawNtP9oGf', 'unencrypted_wif': '5KMKKuUmAkiNbA3DazMQiLfDq47qs8MAEThm4yL8R2PhV1ov33D', 'unencrypted_hex': 'CA2759AA4ADB0F96C414F36ABEB8DB59342985BE9FA50FAAC228C8E7D90E3006', 'confirmation_code': 'cfrm38V8G4qq2ywYEFfWLD5Cc6msj9UwsG2Mj4Z6QdGJAFQpdatZLavkgRd1i4iBMdRngDqDs51', 'lot': 806938, 'sequence': 1, } ] for v in vec: k = CKey() k.generate(unhexlify(v['unencrypted_hex'])) k.set_compressed(False) # Test get_secret() self.assertEqual(unhexlify(v['unencrypted_hex']), k.get_secret()) self.assertEqual(v['unencrypted_wif'], k.get_secret(form=CKeyForm.BASE58)) # Test get_intermediate b = Bip38(k, v['passphrase'], ec_multiply = True, ls_numbers = True) self.assertEqual(v['passphrase_code'], b.get_intermediate(salt = v['salt'], lot=v['lot'], sequence=v['sequence'])) # Test encryption self.assertEqual(v['encrypted'], b.encrypt_ec_multiply(v['passphrase_code'], seedb=v['seedb'])) # Test decryption self.assertEqual(unhexlify(v['unencrypted_hex']), Bip38.decrypt(v['encrypted'], v['passphrase']))
def gen_eckey(passphrase=None, secret=None, pkey=None, compressed=False, rounds=1, version=0): k = CKey() if passphrase: secret = passphrase.encode('utf8') for i in xrange(rounds): secret = hashlib.sha256(secret).digest() if pkey: secret = base58_check_decode(pkey, 128 + version) compressed = len(secret) == 33 secret = secret[0:32] k.generate(secret) k.set_compressed(compressed) return k
def test_no_compression_ec_multiply_no_lot_sequence_numbers(self): vec = [ {'passphrase': 'TestingOneTwoThree', 'passphrase_code': 'passphrasepxFy57B9v8HtUsszJYKReoNDV6VHjUSGt8EVJmux9n1J3Ltf1gRxyDGXqnf9qm', 'encrypted': '6PfQu77ygVyJLZjfvMLyhLMQbYnu5uguoJJ4kMCLqWwPEdfpwANVS76gTX', 'salt': '\xa5\x0d\xba\x67\x72\xcb\x93\x83', 'seedb': '\x99\x24\x1d\x58\x24\x5c\x88\x38\x96\xf8\x08\x43\xd2\x84\x66\x72\xd7\x31\x2e\x61\x95\xca\x1a\x6c', 'bitboin_address': '1PE6TQi6HTVNz5DLwB1LcpMBALubfuN2z2', 'unencrypted_wif': '5K4caxezwjGCGfnoPTZ8tMcJBLB7Jvyjv4xxeacadhq8nLisLR2', 'unencrypted_hex': 'A43A940577F4E97F5C4D39EB14FF083A98187C64EA7C99EF7CE460833959A519', }, {'passphrase': 'Satoshi', 'passphrase_code': 'passphraseoRDGAXTWzbp72eVbtUDdn1rwpgPUGjNZEc6CGBo8i5EC1FPW8wcnLdq4ThKzAS', 'encrypted': '6PfLGnQs6VZnrNpmVKfjotbnQuaJK4KZoPFrAjx1JMJUa1Ft8gnf5WxfKd', 'salt': '\x67\x01\x0a\x95\x73\x41\x89\x06', 'seedb': '\x49\x11\x1e\x30\x1d\x94\xea\xb3\x39\xff\x9f\x68\x22\xee\x99\xd9\xf4\x96\x06\xdb\x3b\x47\xa4\x97', 'bitcoin_address': '1CqzrtZC6mXSAhoxtFwVjz8LtwLJjDYU3V', 'unencrypted_wif': '5KJ51SgxWaAYR13zd9ReMhJpwrcX47xTJh2D3fGPG9CM8vkv5sH', 'unencrypted_hex': 'C2C8036DF268F498099350718C4A3EF3984D2BE84618C2650F5171DCC5EB660A', } ] for v in vec: k = CKey() k.generate(unhexlify(v['unencrypted_hex'])) k.set_compressed(False) # Test get_secret() self.assertEqual(unhexlify(v['unencrypted_hex']), k.get_secret()) self.assertEqual(v['unencrypted_wif'], k.get_secret(form=CKeyForm.BASE58)) # Test get_intermediate b = Bip38(k, v['passphrase'], ec_multiply = True) self.assertEqual(v['passphrase_code'], b.get_intermediate(salt = v['salt'])) # Test encryption self.assertEqual(v['encrypted'], Bip38.encrypt_ec_multiply(v['passphrase_code'], seedb=v['seedb'])) # Test decryption self.assertEqual(unhexlify(v['unencrypted_hex']), Bip38.decrypt(v['encrypted'], v['passphrase']))
def sign(jsonbuf, privkey, role, extra_keys=[]): ''' :type jsonbuf: str. :param privkey: private key in DER form :type privkey: str. :type role: str. :type extra_keys: list. :returns: dict - JSON with signature appended. :raises: BadJSONError ''' jsondoc = json.loads(jsonbuf) signed_keys = jsondoc.get('signed_keys', []) sigdict = {} for key in signed_keys + extra_keys: # FIXME:в ключе допустимы только [a-zA-Z0-9_.\-] # FIXME:можно исключить числа с плавающей точкой value = jsondoc.get(key, None) if not value: raise BadJSONError('Missing attribute: %s' % (repr(key), )) sigdict[key] = value if not len(sigdict): raise BadJSONError('No attributes to sign') instr = json.dumps(sigdict, separators=(',', ':'), sort_keys=True) hash = hashlib.sha256(hashlib.sha256(instr).digest()).digest() ckey = CKey() ckey.set_privkey(privkey) signed = ckey.sign(hash) sigentry = { 'role': role, 'signature_type': 'secp256k1', 'pubkey': binascii.hexlify(ckey.get_pubkey()), 'signature': binascii.hexlify(signed) } if extra_keys: sigentry['extra_signed_keys'] = extra_keys jsondoc.setdefault('signatures', []).append(sigentry) return jsondoc
def getnewaddress(): # Generate public and private keys key = Key() key.generate() key.set_compressed(True) private_key = key.get_privkey() public_key = key.get_pubkey() private_key_hex = private_key.encode('hex') public_key_hex = public_key.encode('hex') public_key_bytearray = bytearray.fromhex(public_key_hex) # Perform SHA-256 and RIPEMD-160 hashing on public key hash160_address = myhash160(public_key_bytearray) # add version byte: 0x00 for Main Network extended_address = '\x00' + hash160_address # generate double SHA-256 hash of extended address hash_address = myhash(extended_address) # Take the first 4 bytes of the second SHA-256 hash. This is the address checksum checksum = hash_address[:4] # Add the 4 checksum bytes from point 7 at the end of extended RIPEMD-160 hash from point 4. This is the 25-byte binary Bitcoin Address. binary_address = extended_address + checksum # Convert the result from a byte string into a base58 string using Base58Check encoding. address = encode(binary_address) return public_key, private_key, address
def _get_confirmation_code(flagbyte, ownerentropy, factorb, derived_half1, derived_half2, addresshash): k = CKey() k.set_compressed(True) k.generate(secret=factorb) pointb = k.get_pubkey() if len(pointb) != 33: return AssertionError('pointb (' + hexlify(pointb) + ') is ' + str(len(pointb)) + ' bytes. It should be 33 bytes.') if pointb[:1] != '\x02' and pointb[:1] != '\x03': return ValueError('pointb is not correct.') pointbprefix = Bip38.xor_zip(pointb[:1], chr(ord(derived_half2[31:32])&ord('\x01'))) cipher = AES.new(derived_half2) pointbx1 = cipher.encrypt(Bip38.xor_zip(pointb[1:17], derived_half1[:16])) pointbx2 = cipher.encrypt(Bip38.xor_zip(pointb[17:33], derived_half1[16:32])) encryptedpointb = pointbprefix + pointbx1 + pointbx2 if len(encryptedpointb) != 33: return AssertionError('encryptedpointb is not 33 bytes long.') magic = '\x3b\xf6\xa8\x9a' return str(CBase58Data(magic + flagbyte.tostring() + addresshash + ownerentropy + encryptedpointb, 0x64))
def test_no_compression_ec_multiply_lot_sequence_numbers(self): vec = [{ 'passphrase': 'MOLON LABE', 'passphrase_code': 'passphraseaB8feaLQDENqCgr4gKZpmf4VoaT6qdjJNJiv7fsKvjqavcJxvuR1hy25aTu5sX', 'encrypted': '6PgNBNNzDkKdhkT6uJntUXwwzQV8Rr2tZcbkDcuC9DZRsS6AtHts4Ypo1j', 'salt': '\x4f\xca\x5a\x97', 'seedb': '\x87\xa1\x3b\x07\x85\x8f\xa7\x53\xcd\x3a\xb3\xf1\xc5\xea\xfb\x5f\x12\x57\x9b\x6c\x33\xc9\xa5\x3f', 'bitcoin_address': '1Jscj8ALrYu2y9TD8NrpvDBugPedmbj4Yh', 'unencrypted_wif': '5JLdxTtcTHcfYcmJsNVy1v2PMDx432JPoYcBTVVRHpPaxUrdtf8', 'unencrypted_hex': '44EA95AFBF138356A05EA32110DFD627232D0F2991AD221187BE356F19FA8190', 'confirmation_code': 'cfrm38V8aXBn7JWA1ESmFMUn6erxeBGZGAxJPY4e36S9QWkzZKtaVqLNMgnifETYw7BPwWC9aPD', 'lot': 263183, 'sequence': 1, }, { 'passphrase': 'ΜΟΛΩΝ ΛΑΒΕ', 'passphrase_code': 'passphrased3z9rQJHSyBkNBwTRPkUGNVEVrUAcfAXDyRU1V28ie6hNFbqDwbFBvsTK7yWVK', 'encrypted': '6PgGWtx25kUg8QWvwuJAgorN6k9FbE25rv5dMRwu5SKMnfpfVe5mar2ngH', 'salt': '\xc4\x0e\xa7\x6f', 'seedb': '\x03\xb0\x6a\x1e\xa7\xf9\x21\x9a\xe3\x64\x56\x0d\x7b\x98\x5a\xb1\xfa\x27\x02\x5a\xaa\x7e\x42\x7a', 'bitcoin_address': '1Lurmih3KruL4xDB5FmHof38yawNtP9oGf', 'unencrypted_wif': '5KMKKuUmAkiNbA3DazMQiLfDq47qs8MAEThm4yL8R2PhV1ov33D', 'unencrypted_hex': 'CA2759AA4ADB0F96C414F36ABEB8DB59342985BE9FA50FAAC228C8E7D90E3006', 'confirmation_code': 'cfrm38V8G4qq2ywYEFfWLD5Cc6msj9UwsG2Mj4Z6QdGJAFQpdatZLavkgRd1i4iBMdRngDqDs51', 'lot': 806938, 'sequence': 1, }] for v in vec: k = CKey() k.generate(unhexlify(v['unencrypted_hex'])) k.set_compressed(False) # Test get_secret() self.assertEqual(unhexlify(v['unencrypted_hex']), k.get_secret()) self.assertEqual(v['unencrypted_wif'], k.get_secret(form=CKeyForm.BASE58)) # Test get_intermediate b = Bip38(k, v['passphrase'], ec_multiply=True, ls_numbers=True) self.assertEqual( v['passphrase_code'], b.get_intermediate(salt=v['salt'], lot=v['lot'], sequence=v['sequence'])) # Test encryption self.assertEqual( v['encrypted'], b.encrypt_ec_multiply(v['passphrase_code'], seedb=v['seedb'])) # Test decryption self.assertEqual(unhexlify(v['unencrypted_hex']), Bip38.decrypt(v['encrypted'], v['passphrase']))
def sendtovault(self, vault_address, amount): # select the input addresses funds = 0 subaccounts = [] accounts = self.getaccounts() for account in accounts: for address, subaccount in account.iteritems(): if subaccount['balance'] == 0: continue else: subaccounts.append(subaccount) funds = funds + subaccount['balance'] if funds >= amount + utils.calculate_fees(None): break # incase of insufficient funds, return if funds < amount + utils.calculate_fees(None): self.logger.warning("Insufficient funds, exiting, return") raise exceptions.InsufficientBalanceException # create transaction tx = CTransaction() # to the receiver txout = CTxOut() txout.nValue = amount txout.scriptPubKey = utils.vault_address_to_pay_to_vault_script(vault_address) tx.vout.append(txout) # from the sender nValueIn = 0 nValueOut = amount public_keys = [] private_keys = [] for subaccount in subaccounts: # get received by from address previous_txouts = subaccount['received'] for received in previous_txouts: txin = CTxIn() txin.prevout = COutPoint() txin.prevout.hash = received['txhash'] txin.prevout.n = received['n'] txin.scriptSig = received['scriptPubKey'] tx.vin.append(txin) nValueIn = nValueIn + received['value'] public_keys.append(subaccount['public_key']) private_keys.append(subaccount['private_key']) if nValueIn >= amount + utils.calculate_fees(tx): break if nValueIn >= amount + utils.calculate_fees(tx): break # calculate the total excess amount excessAmount = nValueIn - nValueOut # calculate the fees fees = utils.calculate_fees(tx) # create change transaction, if there is any change left if excessAmount > fees: change_txout = CTxOut() change_txout.nValue = excessAmount - fees changeaddress = self.getnewaddress()[1] change_txout.scriptPubKey = utils.address_to_pay_to_pubkey_hash(changeaddress) tx.vout.append(change_txout) # calculate txhash tx.calc_sha256() txhash = str(tx.sha256) self.logger.debug("Sending to vault %064x" % tx.sha256) # sign the transaction for public_key, private_key, txin in zip(public_keys, private_keys, tx.vin): key = CKey() key.set_pubkey(public_key) key.set_privkey(private_key) signature = key.sign(txhash) # scriptSig = chr(len(signature)) + hash_type + signature + chr(len(public_key)) + public_key scriptSig = chr(len(signature)) + signature + chr(len(public_key)) + public_key self.logger.debug("Adding signature: %s" % binascii.hexlify(scriptSig)) txin.scriptSig = scriptSig self.logger.debug("Tx Validity: %064x" % tx.is_valid()) # push data to vault tx.calc_sha256() self.set(str("vault:" + vault_address), {'txhash': tx.sha256}) return (vault_address, tx)
from bitcoin.key import CKey as Key from bitcoin.base58 import encode, decode # bitcoin addresses testing: http://gobittest.appspot.com/ # validate: https://en.bitcoin.it/wiki/Technical_background_of_Bitcoin_addresses def MyHash(s): return hashlib.sha256(hashlib.sha256(s).digest()).digest() def MyHash160(s): h = hashlib.new('ripemd160') h.update(hashlib.sha256(s).digest()) return h.digest() # Generate public and private keys key = Key() # key.set_privkey(0x18E14A7B6A307F426A94F8114701E7C8E774E7F9A47E2C2035DB29A206321725) # key.set_pubkey(bytearray.fromhex("0450863AD64A87AE8A2FE83C1AF1A8403CB53F53E486D8511DAD8A04887E5B23522CD470243453A299FA9E77237716103ABC11A1DF38855ED6F2EE187E9C582BA6")) key.generate() key.set_compressed(True) private_key = key.get_privkey() public_key = key.get_pubkey() secret = key.get_secret() private_key_hex = private_key.encode('hex') public_key_hex = public_key.encode('hex') secret_hex = binascii.hexlify(secret) print "Private key: ", private_key_hex print "Public key: ", public_key_hex print "secret : ", secret_hex public_key = bytearray.fromhex(public_key_hex)
# sign the transaction now print "\n\n" x = """ 0100000001eccf7e3034189b851985d871f91384b8ee357cd47c3024736e5676eb2debb3f201 0000001976a914010966776006953d5567439e5e39f86a0d273bee88acffffffff01605af405 000000001976a914097072524438d003d23a2f23edb65aae1bb3e46988ac0000000001000000""" # print x dhash = binascii.unhexlify( "9302bda273a887cb40c13e02a50b4071a31fd3aae3ae04021b0b843dd61ad18e") PRIVATE_KEY = 0x18E14A7B6A307F426A94F8114701E7C8E774E7F9A47E2C2035DB29A206321725 HEX_TRANSACTION = "010000000126c07ece0bce7cda0ccd14d99e205f118cde27e83dd75da7b141fe487b5528fb000000008b48304502202b7e37831273d74c8b5b1956c23e79acd660635a8d1063d413c50b218eb6bc8a022100a10a3a7b5aaa0f07827207daf81f718f51eeac96695cf1ef9f2020f21a0de02f01410452684bce6797a0a50d028e9632be0c2a7e5031b710972c2a3285520fb29fcd4ecfb5fc2bf86a1e7578e4f8a305eeb341d1c6fc0173e5837e2d3c7b178aade078ffffffff02b06c191e010000001976a9143564a74f9ddb4372301c49154605573d7d1a88fe88ac00e1f505000000001976a914010966776006953d5567439e5e39f86a0d273bee88ac00000000" #output to redeem. must exist in HEX_TRANSACTION k = CKey() k.generate(('%064x' % PRIVATE_KEY).decode('hex')) #here we retrieve the public key data generated from the supplied private key pubkey_data = k.get_pubkey() #then we create a signature over the hash of the signature-less transaction signed_data = k.sign(dhash) print binascii.hexlify(signed_data) """ # Add four-byte version field: 01000000 # One-byte varint specifying the number of inputs: 01 # 32-byte hash of the transaction from which we want to redeem an output: eccf7e3034189b851985d871f91384b8ee357cd47c3024736e5676eb2debb3f2 # Four-byte field denoting the output index we want to redeem from the transaction with the above hash (output number 2 = output index 1): 01000000 Now comes the scriptSig. For the purpose of signing the transaction, this is temporarily filled with the scriptPubKey of the output we want to redeem. First we write a one-byte varint which denotes the length of the scriptSig (0x19 = 25 bytes): 19 Then we write the actual scriptSig (which is the scriptPubKey of the output we want to redeem): 76a914010966776006953d5567439e5e39f86a0d273bee88ac Then we write a four-byte field denoting the sequence. This is currently always set to 0xffffffff: ffffffff
def _compute_passpoint(passfactor): k = CKey() k.set_compressed(True) k.generate(secret=passfactor) return k.get_pubkey()
#!/usr/bin/python # -*- coding: utf-8 -*- import sys import paperwallet import paperwallet.util from bitcoin.key import CKey k = CKey() k.generate() k.set_compressed(False) public_key = paperwallet.util.public_key_to_bc_address(k.get_pubkey()) private_key = \ paperwallet.util.private_key_to_wallet_import_format(k.get_privkey()) pw = paperwallet.PaperWallet(sys.argv[1], sys.argv[2], public_key, private_key) pw.save('bar.png')
def test_no_compression_ec_multiply_no_lot_sequence_numbers(self): vec = [{ 'passphrase': 'TestingOneTwoThree', 'passphrase_code': 'passphrasepxFy57B9v8HtUsszJYKReoNDV6VHjUSGt8EVJmux9n1J3Ltf1gRxyDGXqnf9qm', 'encrypted': '6PfQu77ygVyJLZjfvMLyhLMQbYnu5uguoJJ4kMCLqWwPEdfpwANVS76gTX', 'salt': '\xa5\x0d\xba\x67\x72\xcb\x93\x83', 'seedb': '\x99\x24\x1d\x58\x24\x5c\x88\x38\x96\xf8\x08\x43\xd2\x84\x66\x72\xd7\x31\x2e\x61\x95\xca\x1a\x6c', 'bitboin_address': '1PE6TQi6HTVNz5DLwB1LcpMBALubfuN2z2', 'unencrypted_wif': '5K4caxezwjGCGfnoPTZ8tMcJBLB7Jvyjv4xxeacadhq8nLisLR2', 'unencrypted_hex': 'A43A940577F4E97F5C4D39EB14FF083A98187C64EA7C99EF7CE460833959A519', }, { 'passphrase': 'Satoshi', 'passphrase_code': 'passphraseoRDGAXTWzbp72eVbtUDdn1rwpgPUGjNZEc6CGBo8i5EC1FPW8wcnLdq4ThKzAS', 'encrypted': '6PfLGnQs6VZnrNpmVKfjotbnQuaJK4KZoPFrAjx1JMJUa1Ft8gnf5WxfKd', 'salt': '\x67\x01\x0a\x95\x73\x41\x89\x06', 'seedb': '\x49\x11\x1e\x30\x1d\x94\xea\xb3\x39\xff\x9f\x68\x22\xee\x99\xd9\xf4\x96\x06\xdb\x3b\x47\xa4\x97', 'bitcoin_address': '1CqzrtZC6mXSAhoxtFwVjz8LtwLJjDYU3V', 'unencrypted_wif': '5KJ51SgxWaAYR13zd9ReMhJpwrcX47xTJh2D3fGPG9CM8vkv5sH', 'unencrypted_hex': 'C2C8036DF268F498099350718C4A3EF3984D2BE84618C2650F5171DCC5EB660A', }] for v in vec: k = CKey() k.generate(unhexlify(v['unencrypted_hex'])) k.set_compressed(False) # Test get_secret() self.assertEqual(unhexlify(v['unencrypted_hex']), k.get_secret()) self.assertEqual(v['unencrypted_wif'], k.get_secret(form=CKeyForm.BASE58)) # Test get_intermediate b = Bip38(k, v['passphrase'], ec_multiply=True) self.assertEqual(v['passphrase_code'], b.get_intermediate(salt=v['salt'])) # Test encryption self.assertEqual( v['encrypted'], Bip38.encrypt_ec_multiply(v['passphrase_code'], seedb=v['seedb'])) # Test decryption self.assertEqual(unhexlify(v['unencrypted_hex']), Bip38.decrypt(v['encrypted'], v['passphrase']))
def sendtoaddress(self, toaddress, amount): # select the input addresses funds = 0 subaccounts = [] accounts = self.getaccounts() for account in accounts: for address, subaccount in account.iteritems(): if subaccount['balance'] == 0: continue else: subaccounts.append(subaccount) funds = funds + subaccount['balance'] if funds >= amount + utils.calculate_fees(None): break # incase of insufficient funds, return if funds < amount + utils.calculate_fees(None): self.logger.warning("Insufficient funds, exiting, return") return None, None # create transaction tx = CTransaction() # to the receiver txout = CTxOut() txout.nValue = amount txout.scriptPubKey = utils.address_to_pay_to_pubkey_hash(toaddress) tx.vout.append(txout) # from the sender nValueIn = 0 nValueOut = amount public_keys = [] private_keys = [] # secrets = [] for subaccount in subaccounts: # get received by from address previous_txouts = subaccount['received'] for received in previous_txouts: txin = CTxIn() txin.prevout = COutPoint() txin.prevout.hash = received['txhash'] txin.prevout.n = received['n'] txin.scriptSig = received['scriptPubKey'] tx.vin.append(txin) nValueIn = nValueIn + received['value'] public_keys.append(subaccount['public_key']) private_keys.append(subaccount['private_key']) # secrets.append(subaccount['secret']) if nValueIn >= amount + utils.calculate_fees(tx): break if nValueIn >= amount + utils.calculate_fees(tx): break # calculate the total excess amount excessAmount = nValueIn - nValueOut # calculate the fees fees = utils.calculate_fees(tx) # create change transaction, if there is any change left if excessAmount > fees: change_txout = CTxOut() change_txout.nValue = excessAmount - fees changeaddress = subaccounts[0]['address'] change_txout.scriptPubKey = utils.address_to_pay_to_pubkey_hash( changeaddress) tx.vout.append(change_txout) # calculate txhash tx.calc_sha256() txhash = str(tx.sha256) # sign the transaction for public_key, private_key, txin in zip(public_keys, private_keys, tx.vin): key = CKey() key.set_pubkey(public_key) key.set_privkey(private_key) signature = key.sign(txhash) # scriptSig = chr(len(signature)) + hash_type + signature + chr(len(public_key)) + public_key scriptSig = chr(len(signature)) + signature + chr( len(public_key)) + public_key txin.scriptSig = scriptSig return amount, tx
# bitcoin addresses testing: http://gobittest.appspot.com/ # validate: https://en.bitcoin.it/wiki/Technical_background_of_Bitcoin_addresses def MyHash(s): return hashlib.sha256(hashlib.sha256(s).digest()).digest() def MyHash160(s): h = hashlib.new('ripemd160') h.update(hashlib.sha256(s).digest()) return h.digest() # Generate public and private keys key = Key() # key.set_privkey(0x18E14A7B6A307F426A94F8114701E7C8E774E7F9A47E2C2035DB29A206321725) # key.set_pubkey(bytearray.fromhex("0450863AD64A87AE8A2FE83C1AF1A8403CB53F53E486D8511DAD8A04887E5B23522CD470243453A299FA9E77237716103ABC11A1DF38855ED6F2EE187E9C582BA6")) key.generate() key.set_compressed(True) private_key = key.get_privkey() public_key = key.get_pubkey() secret = key.get_secret() private_key_hex = private_key.encode('hex') public_key_hex = public_key.encode('hex') secret_hex = binascii.hexlify(secret) print "Private key: ", private_key_hex print "Public key: ", public_key_hex print "secret : ", secret_hex public_key = bytearray.fromhex(public_key_hex)
# sign the transaction now print "\n\n" x = """ 0100000001eccf7e3034189b851985d871f91384b8ee357cd47c3024736e5676eb2debb3f201 0000001976a914010966776006953d5567439e5e39f86a0d273bee88acffffffff01605af405 000000001976a914097072524438d003d23a2f23edb65aae1bb3e46988ac0000000001000000""" # print x dhash = binascii.unhexlify("9302bda273a887cb40c13e02a50b4071a31fd3aae3ae04021b0b843dd61ad18e") PRIVATE_KEY=0x18E14A7B6A307F426A94F8114701E7C8E774E7F9A47E2C2035DB29A206321725 HEX_TRANSACTION="010000000126c07ece0bce7cda0ccd14d99e205f118cde27e83dd75da7b141fe487b5528fb000000008b48304502202b7e37831273d74c8b5b1956c23e79acd660635a8d1063d413c50b218eb6bc8a022100a10a3a7b5aaa0f07827207daf81f718f51eeac96695cf1ef9f2020f21a0de02f01410452684bce6797a0a50d028e9632be0c2a7e5031b710972c2a3285520fb29fcd4ecfb5fc2bf86a1e7578e4f8a305eeb341d1c6fc0173e5837e2d3c7b178aade078ffffffff02b06c191e010000001976a9143564a74f9ddb4372301c49154605573d7d1a88fe88ac00e1f505000000001976a914010966776006953d5567439e5e39f86a0d273bee88ac00000000" #output to redeem. must exist in HEX_TRANSACTION k = CKey() k.generate(('%064x' % PRIVATE_KEY).decode('hex')) #here we retrieve the public key data generated from the supplied private key pubkey_data = k.get_pubkey() #then we create a signature over the hash of the signature-less transaction signed_data = k.sign(dhash) print binascii.hexlify(signed_data) """ # Add four-byte version field: 01000000 # One-byte varint specifying the number of inputs: 01 # 32-byte hash of the transaction from which we want to redeem an output: eccf7e3034189b851985d871f91384b8ee357cd47c3024736e5676eb2debb3f2 # Four-byte field denoting the output index we want to redeem from the transaction with the above hash (output number 2 = output index 1): 01000000 Now comes the scriptSig. For the purpose of signing the transaction, this is temporarily filled with the scriptPubKey of the output we want to redeem. First we write a one-byte varint which denotes the length of the scriptSig (0x19 = 25 bytes): 19 Then we write the actual scriptSig (which is the scriptPubKey of the output we want to redeem): 76a914010966776006953d5567439e5e39f86a0d273bee88ac
def _decrypt_ec_multiply(k_buffer, passphrase): if passphrase is None or passphrase == '': raise ValueError("Passphrase must not be empty.") prefix = k_buffer[0:1] flagbyte = k_buffer[1:2] ls_numbers = False if ''.join(chr(ord(c) & ord(k)) for c, k in izip(flagbyte, '\x04')) == '\x04': ls_numbers = True ls, = unpack('>I', k_buffer[10:14]) lot = ls / 4096 sequence = ls - (lot * 4096) salt = k_buffer[6:10] else: salt = k_buffer[6:14] address_hash = k_buffer[2:6] ownerentropy = k_buffer[6:14] prefactor = scrypt.hash(passphrase, salt, N=16384, r=8, p=8, buflen=32) if ls_numbers is True: passfactor = SHA256.new( SHA256.new(prefactor + ownerentropy).digest()).digest() else: passfactor = prefactor passpoint = Bip38._compute_passpoint(passfactor) derived = scrypt.hash(passpoint, address_hash + ownerentropy, N=1024, r=1, p=1, buflen=64) derived_half1 = derived[:32] derived_half2 = derived[32:64] cipher = AES.new(derived_half2) decrypted_half2 = Bip38.xor_zip(cipher.decrypt(k_buffer[22:22 + 16]), derived_half1[16:32]) ep12 = decrypted_half2[0:8] decrypted_half1 = Bip38.xor_zip( cipher.decrypt(k_buffer[14:14 + 8] + ep12), derived_half1[:16]) seedb = decrypted_half1[0:16] + decrypted_half2[8:16] factorb = SHA256.new(SHA256.new(seedb).digest()).digest() r = ssl.BN_new() pf = ssl.BN_bin2bn(passfactor, 32, ssl.BN_new()) fb = ssl.BN_bin2bn(factorb, 32, ssl.BN_new()) NID_secp256k1 = 714 k = ssl.EC_KEY_new_by_curve_name(NID_secp256k1) group = ssl.EC_KEY_get0_group(k) ctx = ssl.BN_CTX_new() ssl.BN_CTX_start(ctx) order = ssl.BN_CTX_get(ctx) if ssl.EC_GROUP_get_order(group, order, ctx) == 0: raise Exception('Error in EC_GROUP_get_order()') ssl.BN_mod_mul(r, pf, fb, order, ctx) ssl.BN_CTX_free(ctx) pkey = CKey() final = ctypes.create_string_buffer(32) ssl.BN_bn2bin(r, final) pkey.generate(secret=final) return pkey.get_secret()
def sendtovault(self, vault_address, amount): # select the input addresses funds = 0 subaccounts = [] accounts = self.getaccounts() for account in accounts: for address, subaccount in account.iteritems(): if subaccount['balance'] == 0: continue else: subaccounts.append(subaccount) funds = funds + subaccount['balance'] if funds >= amount + utils.calculate_fees(None): break # incase of insufficient funds, return if funds < amount + utils.calculate_fees(None): self.logger.warning("Insufficient funds, exiting, return") raise exceptions.InsufficientBalanceException # create transaction tx = CTransaction() # to the receiver txout = CTxOut() txout.nValue = amount txout.scriptPubKey = utils.vault_address_to_pay_to_vault_script( vault_address) tx.vout.append(txout) # from the sender nValueIn = 0 nValueOut = amount public_keys = [] private_keys = [] for subaccount in subaccounts: # get received by from address previous_txouts = subaccount['received'] for received in previous_txouts: txin = CTxIn() txin.prevout = COutPoint() txin.prevout.hash = received['txhash'] txin.prevout.n = received['n'] txin.scriptSig = received['scriptPubKey'] tx.vin.append(txin) nValueIn = nValueIn + received['value'] public_keys.append(subaccount['public_key']) private_keys.append(subaccount['private_key']) if nValueIn >= amount + utils.calculate_fees(tx): break if nValueIn >= amount + utils.calculate_fees(tx): break # calculate the total excess amount excessAmount = nValueIn - nValueOut # calculate the fees fees = utils.calculate_fees(tx) # create change transaction, if there is any change left if excessAmount > fees: change_txout = CTxOut() change_txout.nValue = excessAmount - fees changeaddress = self.getnewaddress()[1] change_txout.scriptPubKey = utils.address_to_pay_to_pubkey_hash( changeaddress) tx.vout.append(change_txout) # calculate txhash tx.calc_sha256() txhash = str(tx.sha256) self.logger.debug("Sending to vault %064x" % tx.sha256) # sign the transaction for public_key, private_key, txin in zip(public_keys, private_keys, tx.vin): key = CKey() key.set_pubkey(public_key) key.set_privkey(private_key) signature = key.sign(txhash) # scriptSig = chr(len(signature)) + hash_type + signature + chr(len(public_key)) + public_key scriptSig = chr(len(signature)) + signature + chr( len(public_key)) + public_key self.logger.debug("Adding signature: %s" % binascii.hexlify(scriptSig)) txin.scriptSig = scriptSig self.logger.debug("Tx Validity: %064x" % tx.is_valid()) # push data to vault tx.calc_sha256() self.set(str("vault:" + vault_address), {'txhash': tx.sha256}) return (vault_address, tx)
def sendtoaddress(self, toaddress, amount): # select the input addresses funds = 0 subaccounts = [] accounts = self.getaccounts() for account in accounts: for address, subaccount in account.iteritems(): if subaccount['balance'] == 0: continue else: subaccounts.append(subaccount) # print "got one subaccount", subaccount # print "subaccounts: ", subaccounts funds = funds + subaccount['balance'] if funds >= amount + utils.calculate_fees(None): break # print "subaccounts 2: ", subaccounts # incase of insufficient funds, return if funds < amount + utils.calculate_fees(None): print "In sufficient funds, exiting, return" return # create transaction tx = CTransaction() # print "subaccounts 3: ", subaccounts # to the receiver txout = CTxOut() txout.nValue = amount txout.scriptPubKey = utils.address_to_pay_to_pubkey_hash(toaddress) tx.vout.append(txout) # from the sender nValueIn = 0 nValueOut = amount public_keys = [] private_keys = [] # secrets = [] # print "subaccounts 4: ", subaccounts for subaccount in subaccounts: # print "subaccount: ", subaccount # get received by from address previous_txouts = subaccount['received'] # print "Previous txouts", previous_txouts for received in previous_txouts: txin = CTxIn() txin.prevout = COutPoint() txin.prevout.hash = received['txhash'] txin.prevout.n = received['n'] txin.scriptSig = binascii.unhexlify(received['scriptPubKey']) tx.vin.append(txin) nValueIn = nValueIn + received['value'] public_keys.append(subaccount['public_key']) private_keys.append(subaccount['private_key']) # secrets.append(subaccount['secret']) if nValueIn >= amount + utils.calculate_fees(tx): break if nValueIn >= amount + utils.calculate_fees(tx): break # calculate the total excess amount excessAmount = nValueIn - nValueOut # calculate the fees fees = utils.calculate_fees(tx) # create change transaction, if there is any change left if excessAmount > fees: change_txout = CTxOut() change_txout.nValue = excessAmount - fees changeaddress = subaccounts[0]['address'] change_txout.scriptPubKey = utils.address_to_pay_to_pubkey_hash(changeaddress) tx.vout.append(change_txout) # calculate txhash tx.calc_sha256() txhash = str(tx.sha256) # sign the transaction for public_key, private_key, txin in zip(public_keys, private_keys, tx.vin): key = CKey() key.set_pubkey(public_key) key.set_privkey(private_key) signature = key.sign(txhash) # scriptSig = chr(len(signature)) + hash_type + signature + chr(len(public_key)) + public_key scriptSig = chr(len(signature)) + signature + chr(len(public_key)) + public_key print "Adding signature: ", binascii.hexlify(scriptSig) txin.scriptSig = scriptSig print "Tx Validity: ", tx.is_valid() return tx