def test_register_piece_no_editions(self): # create piece piece, editions = self.create_piece(self.user1, self.digitalwork_user1, self.thumbnail_user1, num_editions=0) # check piece address self.assertTrue( self._check_address(piece.bitcoin_path, self.user1, self.password)) # retrieve transaction btc_tx = BitcoinTransaction.objects.get(ownership__piece=piece) self.assertEqual(btc_tx.from_address, BitcoinWallet.mainAdminBtcAddress()) self.assertEqual( btc_tx.outputs[0], (BitcoinService.minDustSize, piece.hash_as_address_no_metada())) self.assertEqual(btc_tx.outputs[1], (BitcoinService.minDustSize, piece.hash_as_address())) self.assertEqual(btc_tx.outputs[2], (BitcoinService.minDustSize, piece.bitcoin_id)) self.assertEqual(btc_tx.spoolverb, 'ASCRIBESPOOL01PIECE') self.assertEqual(btc_tx.status, TX_PENDING)
def test_consigned_registration(self): piece, editions = self.create_consigned_registration( self.user1, self.digitalwork_user1, self.thumbnail_user1, num_editions=10) btc_txs = BitcoinTransaction.objects.filter(ownership__piece=piece) btc_tx = BitcoinTransaction.objects.get( ownership__type='ConsignedRegistration') # consigned registration + editions self.assertEqual(len(btc_txs), 2) for edition in editions: self.assertTrue( self._check_address(edition.bitcoin_path, self.user1, self.password)) self.assertEqual(btc_tx.from_address, BitcoinWallet.mainAdminBtcAddress()) self.assertEqual( btc_tx.outputs, [(BitcoinService.minDustSize, piece.hash_as_address_no_metada()), (BitcoinService.minDustSize, piece.hash_as_address()), (BitcoinService.minDustSize, piece.bitcoin_id)]) self.assertEqual(btc_tx.spoolverb, 'ASCRIBESPOOL01CONSIGNEDREGISTRATION') self.assertEqual(btc_tx.status, TX_PENDING)
def test_register_number_editions(self): # create piece piece, editions = self.create_piece(self.user1, self.digitalwork_user1, self.thumbnail_user1, num_editions=0) self.assertFalse( BitcoinTransaction.objects.filter( ownership__type='OwnershipEditions').exists()) # create editions edition_task = self.create_editions(self.user1, piece, 10) btc_tx = BitcoinTransaction.objects.get( ownership__type='OwnershipEditions') self.assertEqual(btc_tx.from_address, BitcoinWallet.mainAdminBtcAddress()) self.assertEqual( btc_tx.outputs, [(BitcoinService.minDustSize, piece.hash_as_address_no_metada()), (BitcoinService.minDustSize, piece.hash_as_address()), (BitcoinService.minDustSize, piece.bitcoin_id)]) self.assertEqual(btc_tx.spoolverb, 'ASCRIBESPOOL01EDITIONS10') self.assertEqual(btc_tx.status, TX_PENDING)
def init_edition(address, piece_id, edition_number, user_id): root_piece = Piece.objects.get(pk=piece_id) user = get_user_model().objects.get(pk=user_id) address = BitcoinWallet.walletForUser(user).create_new_address() return Edition(parent=root_piece, edition_number=edition_number, bitcoin_path=address, owner=user)
def testUpdateBitcoinWallet(self): save_wallet = BitcoinWallet.create(self.user1, password=self.password) save_wallet.save() save_wallet.public_key = "nonsense" save_wallet.save() find_wallet = BitcoinWallet.objects.get(user=self.user1.id) self.assertTrue(save_wallet == find_wallet) self.assertEqual(find_wallet.public_key, "nonsense")
def refill_main_wallet(): inputs = refill_main_wallet.select_chunk() outputs = [{ 'address': BitcoinWallet.mainAdminBtcAddress(), 'value': settings.BTC_FEE }] * 50 outputs += [{ 'address': BitcoinWallet.mainAdminBtcAddress(), 'value': settings.BTC_TOKEN }] * 150 unsigned_tx = refill_main_wallet.transactions.build_transaction( inputs, outputs) signed_tx = refill_main_wallet.transactions.sign_transaction( unsigned_tx, settings.BTC_REFILL_PASSWORD) txid = refill_main_wallet.transactions.push(signed_tx) logger.info('Refilling main wallet {}'.format(txid)) return txid
def test_migration_transfer(self): piece, editions = self.create_piece(self.user1, self.digitalwork_user1, self.thumbnail_user1, num_editions=10) edition = editions[0] self.request_reset_password(self.user1) self.reset_password(self.user1, self.new_password) self.create_transfer(self.user1, self.user2.email, edition.bitcoin_id, self.new_password) btc_txs = BitcoinTransaction.objects.filter(ownership__piece=piece) btc_tx_migrate = BitcoinTransaction.objects.get( ownership__type='OwnershipMigration') btc_tx_transfer = BitcoinTransaction.objects.get( ownership__type='OwnershipTransfer') ownership_migration = OwnershipMigration.objects.get(edition=edition) ownership_transfer = OwnershipTransfer.objects.get(edition=edition) # piece, editions, register, migration, transfer self.assertEqual(len(btc_txs), 5) # check migration new_btc_path_migration = ownership_migration.new_btc_address _, new_address_migration = new_btc_path_migration.split(':') self.assertTrue( self._check_address(new_btc_path_migration, self.user1, self.new_password)) self.assertEqual(btc_tx_migrate.from_address, BitcoinWallet.mainAdminBtcAddress()) self.assertEqual( btc_tx_migrate.outputs, [(BitcoinService.minDustSize, edition.hash_as_address_no_metada()), (BitcoinService.minDustSize, edition.bitcoin_id), (BitcoinService.minDustSize, new_address_migration)]) self.assertEqual( btc_tx_migrate.spoolverb, 'ASCRIBESPOOL01MIGRATE{}'.format(edition.edition_number)) self.assertEqual(btc_tx_migrate.status, TX_PENDING) # check transfer new_btc_path_transfer = ownership_transfer.new_btc_address _, new_address_transfer = new_btc_path_transfer.split(':') self.assertEqual(btc_tx_transfer.from_address, new_btc_path_migration) self.assertEqual( btc_tx_transfer.outputs, [(BitcoinService.minDustSize, edition.hash_as_address_no_metada()), (BitcoinService.minDustSize, new_address_transfer)]) self.assertEqual( btc_tx_transfer.spoolverb, 'ASCRIBESPOOL01TRANSFER{}'.format(edition.edition_number)) self.assertEqual(btc_tx_transfer.status, TX_PENDING)
def _alice_bitcoin_wallet(): from bitcoin.models import BitcoinWallet alice = _alice() try: alice_wallet = BitcoinWallet.objects.get(user=alice) except BitcoinWallet.DoesNotExist: alice_wallet = BitcoinWallet.create(alice, password='******') alice_wallet.save() return alice_wallet
def testPycoinWallet(self): save_wallet = BitcoinWallet.create( self.user_admin, password=settings.DJANGO_PYCOIN_ADMIN_PASS) save_wallet.save() find_wallet = BitcoinWallet.objects.get(user=self.user_admin.id) self.assertEqual( find_wallet.rootAddress, find_wallet.pycoinWallet( public_key=find_wallet.public_key).bitcoin_address())
def on_loan_piece_create(sender, instance, password, *args, **kwargs): # upon loan created we need to check if: # 1. If it requires a migration # check migration migration = check_migration(instance) if migration: instance.prev_btc_address = migration.new_btc_address instance.ciphertext_wif = BitcoinWallet.encoded_wif_for_path(instance, password) instance.save()
def alice_bitcoin_wallet(alice, alice_password): from bitcoin.models import BitcoinWallet # TODO remove the try/except clause, and make the creation more explicit, # i.e.: via Bitcoin.objects.create() with required parameters try: alice_wallet = BitcoinWallet.objects.get(user=alice) except BitcoinWallet.DoesNotExist: alice_wallet = BitcoinWallet.create(alice, password=alice_password) alice_wallet.save() return alice_wallet
def _djroot_bitcoin_wallet(): from pycoin.key.BIP32Node import BIP32Node from bitcoin.models import BitcoinWallet djroot = _djroot_user() netcode = 'XTN' if settings.BTC_TESTNET else 'BTC' private_wallet = BIP32Node.from_master_secret('secret-djroot', netcode=netcode) public_key = private_wallet.wallet_key(as_private=False) djroot_wallet = BitcoinWallet.create(djroot, public_key=public_key) djroot_wallet.save() return djroot_wallet
def invited_erin_bitcoin_wallet(invited_erin, invited_erin_password): from bitcoin.models import BitcoinWallet # TODO remove the try/except clause, and make the creation more explicit, # i.e.: via Bitcoin.objects.create() with required parameters try: invited_erin_wallet = BitcoinWallet.objects.get(user=invited_erin) except BitcoinWallet.DoesNotExist: invited_erin_wallet = BitcoinWallet.create( invited_erin, password=invited_erin_password) invited_erin_wallet.save() return invited_erin_wallet
def djroot_bitcoin_wallet(djroot_user, monkeypatch): from pycoin.key.BIP32Node import BIP32Node from bitcoin.models import BitcoinWallet netcode = 'XTN' if settings.BTC_TESTNET else 'BTC' private_wallet = BIP32Node.from_master_secret('secret-djroot', netcode=netcode) public_key = private_wallet.wallet_key(as_private=False) djroot_wallet = BitcoinWallet.create(djroot_user, public_key=public_key) djroot_wallet.save() monkeypatch.setattr('django.conf.settings.BTC_MAIN_WALLET', djroot_wallet.address) return djroot_wallet
def rescan(): print 'Rescanning the blockchain. This may take several minutes...' transactions = Transactions(service=settings.BTC_SERVICE, testnet=settings.BTC_TESTNET, username=settings.BTC_USERNAME, password=settings.BTC_PASSWORD, host=settings.BTC_HOST, port=settings.BTC_PORT) main_address = BitcoinWallet.mainAdminBtcAddress() print 'Sending rescan command to {} main address {}'.format( settings.BTC_HOST, main_address) transactions.import_address(main_address, 'mainaddress', rescan=True)
def test_import_address(self): t = Transactions(service=settings.BTC_SERVICE, testnet=settings.BTC_TESTNET, username=settings.BTC_USERNAME, password=settings.BTC_PASSWORD, host=settings.BTC_HOST, port=settings.BTC_PORT) with self.settings(BTC_ENABLED=False): address = BitcoinWallet.walletForUser( self.user1).create_new_address() BitcoinWallet.import_address(address, self.user1).delay() address = address.split(':')[1] # with btc disabled the address should not be imported response = t._service.make_request('getaddressesbyaccount', [self.user1.email]) self.assertIsNone(response['error']) self.assertFalse(address in response['result']) # lets import it import_address(address, self.user1.email) response = t._service.make_request('getaddressesbyaccount', [self.user1.email]) self.assertIsNone(response['error']) self.assertTrue(address in response['result']) # lets create a new address with btc enabled address = BitcoinWallet.walletForUser(self.user1).create_new_address() BitcoinWallet.import_address(address, self.user1).delay() address = address.split(':')[1] response = t._service.make_request('getaddressesbyaccount', [self.user1.email]) self.assertIsNone(response['error']) self.assertTrue(address in response['result'])
def reset_password(user, password): UserResetPasswordRole.create(user=user).save() user.set_password(password) user.save() request_role = UserRequestResetPasswordRole.objects.filter( user=user).order_by("-datetime")[0] request_role.confirm() request_role.save() # update bitcoin wallet wallet = BitcoinWallet.objects.get(user=user) pubkey = BitcoinWallet.pubkeyFromPassword(user, password) wallet.public_key = pubkey wallet.save()
def forwards_func(apps, schema_editor): # We need to convert the encoded passwords to encoded wif Ownership = apps.get_model("ownership", "Ownership") Edition = apps.get_model("piece", "Edition") for o in Ownership.objects.filter(ciphertext_password__isnull=False): if o.prev_btc_address: path, prev_address = o.prev_btc_address.split(':') else: edition = Edition.objects.get(id=o.edition_id) path, prev_address = btc_owner_address(apps, edition).split(':') password = crypto.decode(settings.SECRET_KEY, o.ciphertext_password) wallet = BitcoinWallet.pycoinWallet( password=BitcoinWallet.pycoinPassword(o.prev_owner, password), public=False) wif = wallet.subkey_for_path(path).wif() encoded_wif = crypto.encode(settings.SECRET_KEY, wif) o.ciphertext_password = encoded_wif o.save()
def check_migration(instance): # Check to see if an edition needs to be migrated role = UserResetPasswordRole.objects.filter(user=instance.prev_owner).order_by('-datetime') role = role[0] if role else None # if user reset its password if role: # set the prev_btc_address if instance.prev_btc_address: prev_btc_address = instance.prev_btc_address else: prev_btc_address = instance.edition.btc_owner_address # get registration previous_ownership = ownership_models.Ownership.objects.filter(new_owner=instance.prev_owner, new_btc_address=prev_btc_address ).order_by("-datetime") # There is always at least a registration previous_ownership = previous_ownership[0] # if the previous ownership action was done before the change of password # or the previous ownership is a registration if role.datetime >= previous_ownership.datetime or previous_ownership.type == 'OwnershipRegistration': new_btc_address = BitcoinWallet.walletForUser(instance.prev_owner).create_new_address() BitcoinWallet.import_address(new_btc_address, instance.prev_owner).delay() if instance.edition: migration = ownership_models.OwnershipMigration.create(edition=instance.edition, new_owner=instance.prev_owner) else: migration = ownership_models.OwnershipMigration.create(edition=None, piece=instance.piece, new_owner=instance.piece.user_registered) migration.new_btc_address = new_btc_address migration.prev_btc_address = prev_btc_address migration.save() return migration return None
def wallet_settings(self, request): wallet = BitcoinWallet.walletForUser(request.user) btc_public_key = wallet.public_key btc_root_address = wallet.rootAddress json_data = { 'btc_public_key': btc_public_key, 'btc_root_address': btc_root_address } return Response({ 'success': True, 'wallet_settings': json_data }, status=status.HTTP_200_OK)
def testCreateBitcoinTransaction(self): user = self.user1 from_wallet = BitcoinWallet.create(self.user1, password=self.password) from_wallet.save() save_bitcointransaction = BitcoinTransaction.create( user=user, from_address=from_wallet.address, outputs=[(int(1 * BitcoinService.minTransactionSize), BTC_TEST_ADDRESS)], spoolverb='ascribespoolverbtest') save_bitcointransaction.save() find_bitcointransaction = BitcoinTransaction.objects.get( id=save_bitcointransaction.id) self.assertTrue(save_bitcointransaction == find_bitcointransaction)
def wallet_status(): print 'Checking Federation wallet status...' transactions = Transactions(service=settings.BTC_SERVICE, testnet=settings.BTC_TESTNET, username=settings.BTC_USERNAME, password=settings.BTC_PASSWORD, host=settings.BTC_HOST, port=settings.BTC_PORT) main_address = BitcoinWallet.mainAdminBtcAddress() unspents = transactions.get(main_address, min_confirmations=1)['unspents'] fees = 0 tokens = 0 for u in unspents: if u['amount'] == settings.BTC_TOKEN: tokens += 1 elif u['amount'] == settings.BTC_FEE: fees += 1 print "Wallet {} has {} tokens and {} fees".format(main_address, tokens, fees)
def test_transfer_edition(self): piece, editions = self.create_piece(self.user1, self.digitalwork_user1, self.thumbnail_user1, num_editions=10) edition = editions[0] self.create_transfer(self.user1, self.user2.email, edition.bitcoin_id, self.password) btc_txs = BitcoinTransaction.objects.filter(ownership__piece=piece) btc_tx_transfer = BitcoinTransaction.objects.get( ownership__type='OwnershipTransfer') btc_tx_register = BitcoinTransaction.objects.get( ownership__type='OwnershipRegistration') # piece + editions + register + transfer self.assertEqual(len(btc_txs), 4) # check registration self.assertEqual(btc_tx_register.from_address, BitcoinWallet.mainAdminBtcAddress()) self.assertEqual( btc_tx_register.outputs, [(BitcoinService.minDustSize, edition.hash_as_address_no_metada()), (BitcoinService.minDustSize, edition.hash_as_address()), (BitcoinService.minDustSize, edition.bitcoin_id)]) self.assertEqual( btc_tx_register.spoolverb, 'ASCRIBESPOOL01REGISTER{}'.format(edition.edition_number)) self.assertEqual(btc_tx_register.status, TX_PENDING) # check transfer self.assertTrue( self._check_address(edition.btc_owner_address, self.user2, self.password2)) self.assertEqual(btc_tx_transfer.from_address, edition.bitcoin_path) self.assertEqual( btc_tx_transfer.outputs, [(BitcoinService.minDustSize, edition.hash_as_address_no_metada()), (BitcoinService.minDustSize, edition.btc_owner_address_noprefix)]) self.assertEqual( btc_tx_transfer.spoolverb, 'ASCRIBESPOOL01TRANSFER{}'.format(edition.edition_number)) self.assertEqual(btc_tx_transfer.status, TX_PENDING)
def on_loan_edition_create(sender, instance, password, *args, **kwargs): # upon loan created we need to check if: # 1. An edition is registered # 2. If it requires a migration # check if edition is registered registration = ownership_models.OwnershipRegistration.objects.filter(edition=instance.edition) if not registration: registration = ownership_models.OwnershipRegistration.create(edition=instance.edition, new_owner=instance.edition.owner) registration.save() # check migration migration = check_migration(instance) if migration: instance.prev_btc_address = migration.new_btc_address instance.ciphertext_wif = BitcoinWallet.encoded_wif_for_path(instance, password) instance.save()
def on_ownership_transfer_create(sender, instance, password, *args, **kwargs): # Create bitcoin transfer transaction transfer = BitcoinTransaction.transfer(instance) # if a user needs to register and there is no wallet yet no transaction will be created if transfer: # before pushing the transaction we need to check: # 1. the edition is already registered (because of lazy editions) # 2. check if an edition needs migration (due to a password change) # 3. the edition address is refilled # check if edition is registered registration = ownership_models.OwnershipRegistration.objects.filter(edition=instance.edition) if not registration: registration = ownership_models.OwnershipRegistration.create(edition=instance.edition, new_owner=instance.edition.owner) registration.save() # check if edition needs migration migration = check_migration(instance) if migration: instance.prev_btc_address = migration.new_btc_address instance.btc_tx = None instance.ciphertext_wif = BitcoinWallet.encoded_wif_for_path(instance, password) instance.save() # delete old btc_tx which has the wrong addresses and create a new one transfer.delete() transfer = BitcoinTransaction.transfer(instance) # refill the edition address # create the transaction refill = BitcoinTransaction.refill(instance) # set the transfer as the dependent transaction so that it is sent after the refill by the # transaction_monitor refill.dependent_tx = transfer refill.save() tasks.refill.delay(refill.id, util.mainAdminPassword())
def select_inputs(self, address, nfees, ntokens, min_confirmations=6): # select inputs from the federation wallet if address == BitcoinWallet.mainAdminBtcAddress(): cursor = connection.cursor() cursor.execute(query_sql_main % (ntokens, nfees)) desc = cursor.description unspents = [ dict(zip([col[0] for col in desc], row)) for row in cursor.fetchall() ] fees = filter(lambda d: d['amount'] == settings.BTC_FEE, unspents) tokens = filter(lambda d: d['amount'] == settings.BTC_TOKEN, unspents) if len(fees) != nfees or len(tokens) != ntokens: raise SpoolFundsError('Not enough unspents for transaction') return fees + tokens else: # select inputs from the user HD wallet return super(BackendSpool, self).select_inputs(address, nfees, ntokens, min_confirmations=1)
def _bob_bitcoin_wallet(): from bitcoin.models import BitcoinWallet bob = _bob() bob_wallet = BitcoinWallet.create(bob, password='******') bob_wallet.save() return bob_wallet
def testCreateBitcoinWallet(self): save_wallet = BitcoinWallet.create(self.user1, password=self.password) save_wallet.save() find_wallet = BitcoinWallet.objects.get(user=self.user1.id) self.assertTrue(save_wallet == find_wallet)
def test_register_editions(registered_piece_alice): from bitcoin.bitcoin_service import BitcoinService from bitcoin.models import BitcoinTransaction, BitcoinWallet, TX_PENDING from ownership.models import OwnershipEditions from acl.models import ActionControl from ..models import Edition from ..tasks import register_editions # Test can be used with any number of editions. # We use 1 for speed reasons. num_editions = 1 alice = registered_piece_alice.user_registered piece_alice = registered_piece_alice editions_tasks = register_editions(piece_alice, alice, num_editions).delay() assert editions_tasks.failed() is False # We test if the editions returned # were correctly inserted into the database editions = editions_tasks.get() assert all( Edition.objects.filter(parent=piece_alice, bitcoin_path__icontains=e.bitcoin_id).exists() for e in editions) assert piece_alice.num_editions == num_editions assert len(editions) == num_editions # We test if the ACLs for the respective user # and their editions have been set appropriately acls = ActionControl.objects.filter(user=alice, piece=piece_alice, edition__in=editions) for acl in acls: assert acl.acl_view is True assert acl.acl_edit is True assert acl.acl_download is True assert acl.acl_delete is True assert acl.acl_create_editions is False assert acl.acl_share is True assert acl.acl_unshare is False assert acl.acl_transfer is True assert acl.acl_withdraw_transfer is False assert acl.acl_consign is True assert acl.acl_withdraw_consign is False assert acl.acl_unconsign is False assert acl.acl_request_unconsign is False assert acl.acl_loan is True assert acl.acl_coa is True # We test if an OwnershipEditions object and # a related BitcoinTransaction were created editions_ownership = OwnershipEditions.objects.get(piece=piece_alice, new_owner=alice) assert editions_ownership.piece == piece_alice btc_tx = BitcoinTransaction.objects.get(pk=editions_ownership.btc_tx.id) assert btc_tx.from_address == BitcoinWallet.mainAdminBtcAddress() assert btc_tx.outputs == [ (BitcoinService.minDustSize, piece_alice.hash_as_address_no_metada()), (BitcoinService.minDustSize, piece_alice.hash_as_address()), (BitcoinService.minDustSize, piece_alice.bitcoin_id) ] assert btc_tx.spoolverb == 'ASCRIBESPOOL01EDITIONS{}'.format(num_editions) assert btc_tx.status == TX_PENDING
def _createNewUser(email, password, username=None, application=None, invited=False, lang=settings.LANGUAGE_CODE, subdomain="www", token=None): pending_actions = False if not username: username = createUsername(email.split('@')[0][:30]) user = userNeedsRegistration(email) # user exists in DB. Was it created by an invite? if user is not None: user.set_password(password) user.save() # BitcoinWallet.objects.get(user=user).delete() UserNeedsToRegisterRole.objects.get( user=user, type="UserNeedsToRegisterRole").delete() pending_actions = True else: user = User.objects.create_user(username, email, password) if invited: UserNeedsToRegisterRole.create(user=user, role=None).save() return user try: user_profile = UserProfile.objects.get(user=user) except ObjectDoesNotExist: user_profile = UserProfile.objects.create(user=user, created_by=application) user_profile.save() # create bitcoin account # there should only be one wallet. but just in case old_wallet = BitcoinWallet.objects.filter(user=user) if len(old_wallet) > 0: for w in old_wallet: w.delete() BitcoinWallet.create(user, password=password).save() # after the wallet is created we can check the pending actions if pending_actions: check_pending_actions.send(sender=UserEndpoint, user=user) if not token: validate_email_role = UserValidateEmailRole.create(user) validate_email_role.save() # TODO put this logic somewhere else if subdomain == 'cc': msg_cls = messages.WelcomeEmailMessageCreativeCommons elif subdomain == '23vivi': msg_cls = messages.WelcomeEmailMessage23vivi elif subdomain == 'lumenus': msg_cls = messages.WelcomeEmailMessageLumenus elif subdomain == 'polline': msg_cls = messages.WelcomeEmailMessagePolline elif subdomain == 'artcity': msg_cls = messages.WelcomeEmailMessageArtcity elif subdomain == 'demo': msg_cls = messages.WelcomeEmailMessageDemo elif subdomain == 'liquidgallery': msg_cls = messages.WelcomeEmailMessageLiquidGallery else: msg_cls = messages.WelcomeEmailMessage send_ascribe_email.delay( msg_cls=msg_cls, to=user.email, token=validate_email_role.token, subdomain=subdomain, lang=lang, ) else: validate_email_role = UserValidateEmailRole.objects.filter( user=user).order_by("-datetime")[0] assert validate_email_role.token == token validate_email_role.confirm() validate_email_role.save() return user