def create_transfer(p_num): print(p_num, ":create_transfer start") while True: alice, bob = generate_keypair(), generate_keypair() asset = Asset(data={'money': 'RMB'}, data_id='20170628150000', divisible=True) metadata = {'planet': 'earth'} tx_create = Transaction.create([alice.public_key], [([alice.public_key], 1)], metadata=metadata, asset=asset) tx_create = tx_create.sign([alice.private_key]) try: create_queue.put(tx_create, False) except Full: print(p_num, ":create_queue full", create_queue.qsize()) break cid = 0 condition = tx_create.to_dict()['transaction']['conditions'][cid] inputs = Fulfillment.from_dict({ 'fulfillment': condition['condition']['details'], 'input': { 'cid': cid, 'txid': tx_create.to_dict()['id'], }, 'owners_before': condition['owners_after'], }) asset = Asset.from_dict(tx_create.to_dict()['transaction']['asset']) tx_transfer = Transaction.transfer([inputs], [([bob.public_key], 1)], asset) tx_transfer = tx_transfer.sign([alice.private_key]) try: transfer_queue.put(tx_transfer, False) except Full: print(p_num, ":transfer_queue full") break
def _normalize_asset(asset, is_transfer=False): """ Normalizes the given asset dictionary. For now, this means converting the given asset dictionary to a :class:`~.bigchaindb.common.transaction.Asset` class. Args: asset (dict): The asset to normalize. is_transfer (boal, optional): Flag used to indicate whether the asset is to be used as part of a `'TRANSFER'` operation or not. Defaults to ``False``. Returns: The :class:`~.bigchaindb.common.transaction.Asset` class, instantiated from the given asset dictionary. .. important:: If the instantiation step fails, ``None`` may be returned. .. danger:: For specific internal usage only. The behavior is tricky, and is subject to change. """ if is_transfer: asset = Asset.from_dict(asset) else: try: asset = Asset(**asset) except (AttributeError, TypeError): if not asset: asset = None return asset
def create(): # Cryptographic Identities Generation alice, bob = generate_keypair(), generate_keypair() # Digital Asset Definition (e.g. bicycle) asset = Asset(data={ "bicycle": { "manufacturer": "bkfab", "serial_number": "abcd1234" } }) # Metadata Definition metadata = {'planet': 'earth'} # create trnsaction TODO : owners_before might be node_pubkey in v0.8.0 tx = Transaction.create([alice.public_key], [([alice.public_key], 1)], metadata=metadata, asset=asset) # sign with private key tx = tx.sign([alice.private_key]) tx_id = tx.to_dict()['id'] # write to backlog b = Bigchain() b.write_transaction(tx) # wait 2 sec sleep(2) # get tx by id tx = b.get_transaction(tx_id) return tx.to_dict()
def create_duplicate_tx(): ##################################################### 1.CREATE # Cryptographic Identities Generation alice, bob = generate_keypair(), generate_keypair() # Digital Asset Definition (e.g. bicycle) asset = Asset(data={"bicycle": {"manufacturer": "bkfab", "serial_number": "abcd1234"}}) # Metadata Definition metadata = {'planet': 'earth1'} # create trnsaction TODO : owners_before might be node_pubkey in v0.8.0 tx = Transaction.create([alice.public_key], [([alice.public_key], 1)], metadata=metadata, asset=asset) print(" ") print("1.tx_create asset id : alice-----bicycle(", tx.to_dict()['transaction']['asset']['id'], ")----->alice") print("1.tx_create tx id : ", tx.to_dict()['id']) # sign with alice's private key tx = tx.sign([alice.private_key]) tx_id = tx.to_dict()['id'] # write to backlog b = Bigchain() print("1.tx_create db response : ", b.write_transaction(tx)) # wait 2 sec sleep(delay) # get tx by id tx = b.get_transaction(tx_id) print("1.tx_create query : ", tx) print(" ") ##################################################### print("2.write dulpicate tx: ", b.write_transaction(tx))
def transfer(self, transaction, *owners_after, asset, signing_key=None): """Issue a transaction to transfer an asset. Args: transaction (dict): The transaction to transfer. owners_after (str): Zero or more public keys of the new owners. asset (dict): Asset to transfer. signing_key (str): Private key used to sign transactions. Returns: dict: The transaction pushed to the Federation. Raises: :class:`~bigchaindb_driver.exceptions.InvalidSigningKey`: If neither ``signing_key`` nor ``self.signing_key`` have been set. """ signing_key = signing_key if signing_key else self.signing_key if not signing_key: raise InvalidSigningKey transaction_obj = Transaction.from_dict(transaction) signed_transfer_transaction = Transaction.transfer( transaction_obj.to_inputs(), list(owners_after), asset=Asset.from_dict(asset), ).sign([signing_key]).to_dict() return self._push(signed_transfer_transaction)
def get(): # Cryptographic Identities Generation alice, bob = generate_keypair(), generate_keypair() print(" ") # Digital Asset Definition (e.g. bicycle) asset = Asset(data={ "bicycle": { "manufacturer": "bkfab", "serial_number": "abcd1234" } }) # Metadata Definition metadata = {'planet': 'earth'} # create trnsaction TODO : owners_before might be node_pubkey in v0.8.0 tx = Transaction.create([alice.public_key], [alice.public_key], metadata=metadata, asset=asset) # sign with private key tx = tx.sign([alice.private_key]) # get tx by id b = Bigchain() block = b.create_block([tx]) block_voters = block.to_dict()['block']['voters'] print(block_voters) tx_id = '2cb004cad29c0b79872646558f8c867a4c0aecbc4997f0917' tx = b.get_transaction(tx_id) print( "block status : ", b.block_election_status( '2257384a0cee8cf98bd82c3142dd38eee5c268c124b5b357b773b8c6c1fa1221', block_voters))
def bft(): # Cryptographic Identities Generation alice, bob = generate_keypair(), generate_keypair() print(" ") # Digital Asset Definition (e.g. bicycle) asset = Asset(data={ "bicycle": { "manufacturer": "bkfab", "serial_number": "abcd1234" } }) # Metadata Definition metadata = {'planet': 'earth'} # create trnsaction TODO : owners_before might be node_pubkey in v0.8.0 tx = Transaction.create([alice.public_key], [([alice.public_key], 1)], metadata=metadata, asset=asset) # sign with private key tx = tx.sign([alice.private_key]) tx_id = tx.to_dict()['id'] print("tx_id : ", tx_id) # create block b = Bigchain() block = b.create_block([tx]) print("valid block timestamp : ", block.to_dict()['block']['timestamp']) # tamper block block.timestamp = '1' print("tamper block.timestamp to 1 : ") block_id = block.to_dict()['id'] block_voters = block.to_dict()['block']['voters'] print("invalid block timestamp : ", block.to_dict()['block']['timestamp']) print("tamper_block_id : ", block_id) print("db response of block : ", b.write_block(block)) sleep(0) last_voted_id = b.get_last_voted_block().id vote = b.vote(block_id, last_voted_id, True) print("crate vote 'True' : ", vote) print("db response of vote : ", b.write_vote(vote)) print("tamper_block status : ", b.block_election_status(block_id, block_voters)) print("blocks_status_containing_tx : ", b.get_blocks_status_containing_tx(tx_id)) print("wait for 20 sec : ") sleep(20) print("blocks_status_containing_tx : ", b.get_blocks_status_containing_tx(tx_id)) print(" ")
def merge_utxo(alicepub, alicepriv, include_spent): asset = Asset(data={ "bicycle": { "manufacturer": "bkfab", "serial_number": "abcd1234" } }, data_id="334cd061-846b-4213-bd25-588e951def5f") metadata = {'planet': 'earth'} b = Bigchain() utxo = b.get_outputs_filtered_not_include_freeze(alicepub, include_spent) for u in utxo: # print(u) u.pop('details') print('userA unspent asset:') print(json.dumps(utxo, indent=4)) inputs = [] balance = 0 utxo = b.get_outputs_filtered_not_include_freeze(alicepub, include_spent) for i in utxo: f = Fulfillment.from_dict({ 'fulfillment': i['details'], 'input': { 'cid': i['cid'], 'txid': i['txid'], }, 'owners_before': [alicepub], }) inputs.append(f) balance += i['amount'] length = len(utxo) if balance <= 0: print('No need to merge, because of lack of balance') elif length <= 1: print('No need to merge, because utxo len = 1') else: tx = Transaction.transfer(inputs, [([alicepub], balance)], metadata=metadata, asset=asset) tx = tx.sign([alicepriv]) tx_id = tx.to_dict()['id'] # write to backlog b.write_transaction(tx) # wait 2 sec print("========userA merge multi-asset========") print("========wait for block and vote...========") sleep(5) # get tx by id tx = b.get_transaction(tx_id) print("merge txid:" + tx.to_dict()['id']) utxo = b.get_outputs_filtered_not_include_freeze(alicepub, include_spent) for u in utxo: # print(u) u.pop('details') print('userA unspent asset:') print(json.dumps(utxo, indent=4))
def alice_transaction_obj(alice_pubkey): serial_number = b64encode(urandom(10), altchars=b'-_').decode() return Transaction.create( owners_before=[alice_pubkey], owners_after=[alice_pubkey], asset=Asset(data={'data': { 'serial_number': serial_number }}), )
def transactions(): priv, pub = generate_key_pair() tx = Transaction.create([pub], [([pub], 1)]) while True: i = yield tx.to_dict() tx.asset = Asset(data={'n': i}, data_id='20170628150000', divisible=True) tx.sign([priv])
def get_asset_by_id(self, asset_id): """Returns the asset associated with an asset_id. Args: asset_id (str): The asset id. Returns: :class:`~bigchaindb.common.transaction.Asset` if the asset exists else None. """ cursor = backend.query.get_asset_by_id(self.connection, asset_id) cursor = list(cursor) if cursor: return Asset.from_dict(cursor[0]['asset'])
def create(self, asset=None, verifying_key=None, signing_key=None): """Issue a transaction to create an asset. Args: asset (dict): Fungible unit to spend and lock with the transaction being created. signing_key (str): Private key used to sign transactions. verifying_key (str): Public key associated with the :attr:`signing_key`. Returns: dict: The transaction pushed to the Federation. Raises: :class:`~bigchaindb_driver.exceptions.InvalidSigningKey`: If neither ``signing_key`` nor ``self.signing_key`` have been set. :class:`~bigchaindb_driver.exceptions.InvalidVerifyingKey`: If neither ``verifying_key`` nor ``self.verifying_key`` have been set. """ signing_key = signing_key if signing_key else self.signing_key if not signing_key: raise InvalidSigningKey verifying_key = verifying_key if verifying_key else self.verifying_key if not verifying_key: raise InvalidVerifyingKey asset = Asset(**asset) if asset else Asset() # TODO: In the future, we should adjust this to let the user of the # driver define both `owners_before` and `owners_after`. transaction = Transaction.create( owners_before=[verifying_key], owners_after=[verifying_key], asset=asset, ) signed_transaction = transaction.sign([signing_key]) return self._push(signed_transaction.to_dict())
def tamper_block(): # Cryptographic Identities Generation alice, bob = generate_keypair(), generate_keypair() print(" ") # Digital Asset Definition (e.g. bicycle) asset = Asset(data={ "bicycle": { "manufacturer": "bkfab", "serial_number": "abcd1234" } }) # Metadata Definition metadata = {'planet': 'earth'} # create trnsaction TODO : owners_before might be node_pubkey in v0.8.0 tx = Transaction.create([alice.public_key], [([alice.public_key], 1)], metadata=metadata, asset=asset) # sign with private key tx = tx.sign([alice.private_key]) tx_id = tx.to_dict()['id'] print("tx_id : ", tx_id) # create block b = Bigchain() block = b.create_block([tx]) block_id = block.to_dict()['id'] block_voters = block.to_dict()['block']['voters'] print("last_block_id sig : ", block_id, block.signature) print(block.to_dict()) # tamper block sig block.sign(alice.private_key) block_dict = block.to_dict() print("tamper_block_id sig : ", block_dict['id'], block_dict['signature']) print(block_dict) print("db response : ", b.backend.write_block(serialize(block_dict))) sleep(delay) print("tamper_block status : ", b.block_election_status(block_dict['id'], block_voters)) print("blocks_status_containing_tx : ", b.get_blocks_status_containing_tx(tx_id)) print(" ")
def create_transfer(public_key, private_key, include_spent): asset = Asset(data={ "bicycle": { "manufacturer": "bkfab", "serial_number": "abcd1234" } }, data_id="334cd061-846b-4213-bd25-588e951def5f") ##################################################### 1.getfreeze b = Bigchain() utxo_freeze = b.get_freeze_outputs_only(public_key) # for u in utxo_freeze: # # print(u) # u.pop('details') print('userA frozen asset:') print(json.dumps(utxo_freeze, indent=4)) # print(json.load(utxo)) # # ##################################################### 2.Unfreeze inputs = [] balance = 0 for i in utxo_freeze: f = Fulfillment.from_dict({ 'fulfillment': i['details'], 'input': { 'cid': i['cid'], 'txid': i['txid'], }, 'owners_before': [public_key], }) inputs.append(f) balance += i['amount'] # create trnsaction tx = Transaction.freeze_asset(inputs, [([public_key], balance, False)], asset) # # inputs and asset # sign with alice's private key tx = tx.sign([private_key]) tx_id = tx.to_dict()['id'] # write to backlog b = Bigchain() b.write_transaction(tx) print("unfreeze asset for userA") print("========wait for block and vote...========") # wait 2 sec sleep(5) # get tx by id tx = b.get_transaction(tx_id) print("unfreeze asset tx1_id:" + tx.to_dict()['id']) ##################################################### 3.UTXO # inputs and asset utxo = b.get_outputs_filtered_not_include_freeze(public_key, include_spent) for u in utxo: # print(u) u.pop('details') print('userA unspent asset:') print(json.dumps(utxo, indent=4))
def validate(self, bigchain): """Validate a transaction. Args: bigchain (Bigchain): an instantiated bigchaindb.Bigchain object. Returns: The transaction (Transaction) if the transaction is valid else it raises an exception describing the reason why the transaction is invalid. Raises: OperationError: if the transaction operation is not supported TransactionDoesNotExist: if the input of the transaction is not found TransactionNotInValidBlock: if the input of the transaction is not in a valid block TransactionOwnerError: if the new transaction is using an input it doesn't own DoubleSpend: if the transaction is a double spend InvalidHash: if the hash of the transaction is wrong InvalidSignature: if the signature of the transaction is wrong """ if len(self.fulfillments) == 0: raise ValueError('Transaction contains no fulfillments') input_conditions = [] inputs_defined = all([ffill.tx_input for ffill in self.fulfillments]) if self.operation in (Transaction.CREATE, Transaction.GENESIS): # validate inputs if inputs_defined: raise ValueError('A CREATE operation has no inputs') # validate asset amount = sum([condition.amount for condition in self.conditions]) self.asset.validate_asset(amount=amount) elif self.operation == Transaction.TRANSFER: if not inputs_defined: raise ValueError('Only `CREATE` transactions can have null ' 'inputs') # check inputs # store the inputs so that we can check if the asset ids match input_txs = [] input_amount = 0 for ffill in self.fulfillments: input_txid = ffill.tx_input.txid input_cid = ffill.tx_input.cid input_tx, status = bigchain.\ get_transaction(input_txid, include_status=True) if input_tx is None: raise TransactionDoesNotExist("input `{}` doesn't exist" .format(input_txid)) if status != bigchain.TX_VALID: raise TransactionNotInValidBlock( 'input `{}` does not exist in a valid block'.format( input_txid)) spent = bigchain.get_spent(input_txid, ffill.tx_input.cid) if spent and spent.id != self.id: raise DoubleSpend('input `{}` was already spent' .format(input_txid)) input_conditions.append(input_tx.conditions[input_cid]) input_txs.append(input_tx) if input_tx.conditions[input_cid].amount < 1: raise AmountError('`amount` needs to be greater than zero') input_amount += input_tx.conditions[input_cid].amount # validate asset id asset_id = Asset.get_asset_id(input_txs) if asset_id != self.asset.data_id: raise AssetIdMismatch(('The asset id of the input does not' ' match the asset id of the' ' transaction')) # get the asset creation to see if its divisible or not asset = bigchain.get_asset_by_id(asset_id) # validate the asset asset.validate_asset(amount=input_amount) # validate the amounts output_amount = 0 for condition in self.conditions: if condition.amount < 1: raise AmountError('`amount` needs to be greater than zero') output_amount += condition.amount if output_amount != input_amount: raise AmountError(('The amount used in the inputs `{}`' ' needs to be same as the amount used' ' in the outputs `{}`') .format(input_amount, output_amount)) else: allowed_operations = ', '.join(Transaction.ALLOWED_OPERATIONS) raise TypeError('`operation`: `{}` must be either {}.' .format(self.operation, allowed_operations)) if not self.fulfillments_valid(input_conditions): raise InvalidSignature() else: return self
def validate(self, bigchain): """Validate a transaction. Args: bigchain (Bigchain): an instantiated bigchaindb.Bigchain object. Returns: The transaction (Transaction) if the transaction is valid else it raises an exception describing the reason why the transaction is invalid. Raises: OperationError: if the transaction operation is not supported TransactionDoesNotExist: if the input of the transaction is not found TransactionOwnerError: if the new transaction is using an input it doesn't own DoubleSpend: if the transaction is a double spend InvalidHash: if the hash of the transaction is wrong InvalidSignature: if the signature of the transaction is wrong """ # print(self.operation) if self.operation == Transaction.METADATA: return self if len( self.fulfillments ) == 0 and self.operation != Transaction.CONTRACT and self.operation != Transaction.INTERIM: # print(self.id) print('Transaction contains no fulfillments') raise ValueError('Transaction contains no fulfillments') # print("3") # print("self::",self) if len( self.conditions ) == 0 and self.operation != Transaction.CONTRACT and self.operation != Transaction.INTERIM: print('Transaction contains no conditions') raise ValueError('Transaction contains no conditions') input_conditions = [] inputs_defined = all([ffill.tx_input for ffill in self.fulfillments]) # print("4",inputs_defined) if self.operation in (Transaction.CREATE, Transaction.GENESIS): # print("5") # validate inputs if inputs_defined: raise ValueError('A CREATE operation has no inputs') # validate asset self.asset._validate_asset() elif self.operation in (Transaction.CONTRACT, Transaction.INTERIM): pass elif self.operation == Transaction.TRANSFER: if not inputs_defined: raise ValueError('Only `CREATE` transactions can have null ' 'inputs') # print("6") # check inputs # store the inputs so that we can check if the asset ids match input_txs = [] for ffill in self.fulfillments: input_txid = ffill.tx_input.txid input_cid = ffill.tx_input.cid input_tx, status = bigchain.\ get_transaction(input_txid, include_status=True) if input_tx is None: raise TransactionDoesNotExist( "input `{}` doesn't exist".format(input_txid)) if status != bigchain.TX_VALID: raise FulfillmentNotInValidBlock( 'input `{}` does not exist in a valid block'.format( input_txid)) spent = bigchain.get_spent(input_txid, ffill.tx_input.cid) if spent and spent.id != self.id: raise DoubleSpend( 'input `{}` was already spent'.format(input_txid)) input_conditions.append(input_tx.conditions[input_cid]) input_txs.append(input_tx) # validate asset id asset_id = Asset.get_asset_id(input_txs) if asset_id != self.asset.data_id: raise AssetIdMismatch( 'The asset id of the input does not match the asset id of the transaction' ) else: allowed_operations = ', '.join(Transaction.ALLOWED_OPERATIONS) raise TypeError('`operation`: `{}` must be either {}.'.format( self.operation, allowed_operations)) # print("validate in=2========",self.operation) if self.operation in (Transaction.CONTRACT): # validate contract signature # 1.validate the contract users signture # print("7") ContractBody = deepcopy(self.Contract["ContractBody"]) contract_owners = ContractBody["ContractOwners"] contract_signatures = ContractBody["ContractSignatures"] ContractBody["ContractSignatures"] = None detail_serialized = serialize(ContractBody) if contract_owners != None and contract_signatures != None: if len(contract_owners) < len(contract_signatures): raise MutilContractOwner for index, contract_sign in enumerate(contract_signatures): owner_pubkey = contract_owners[index] signature = contract_sign["Signature"] if not self.is_signature_valid(detail_serialized, owner_pubkey, signature): print("Invalid contract Signature") raise InvalidSignature() return self else: # TODO 2.validate the contract votes? return self # print("validate in=3========",self.operation,"==",self.version) if self.version == 2: # 1.validate the nodes signature voters = self.Relation["Voters"] votes = self.Relation["Votes"] # print("taskid 146 --- ",self.Relation["TaskId"]) # tx_dict = deepcopy(self.to_dict()) # tx_dict["transaction"].pop('Relation') # tx_dict["transaction"].pop('Contract') # detail_serialized = serialize(tx_dict) if len(voters) < len(votes): raise MutilcontractNode for index, vote in enumerate(votes): # print(index) owner_pubkey = voters[index] signature = vote["Signature"] detail_serialized = self.id print(detail_serialized) # print(owner_pubkey) # print(signature) if not self.is_signature_valid(detail_serialized, owner_pubkey, signature): print("Invalid vote Signature") raise InvalidSignature() return self if not self.fulfillments_valid(input_conditions): raise InvalidSignature() else: return self
def create_transfer(): ##################################################### 1.CREATE # Cryptographic Identities Generation alice, bob = generate_keypair(), generate_keypair() # Digital Asset Definition (e.g. bicycle) asset = Asset(data={"bicycle": {"manufacturer": "bkfab", "serial_number": "abcd1234"}}) # Metadata Definition metadata = {'planet': 'earth'} # create trnsaction TODO : owners_before might be node_pubkey in v0.8.0 tx = Transaction.create([alice.public_key], [([alice.public_key], 1)], metadata=metadata, asset=asset) print(" ") print("1.tx_create asset id : alice-----bicycle(", tx.to_dict()['transaction']['asset']['id'], ")----->alice") print("1.tx_create tx id : ", tx.to_dict()['id']) # sign with alice's private key tx = tx.sign([alice.private_key]) tx_id = tx.to_dict()['id'] # write to backlog b = Bigchain() print("1.tx_create db response : ", b.write_transaction(tx)) # wait 2 sec sleep(delay) # get tx by id tx = b.get_transaction(tx_id) print("1.tx_create query : ", tx) # print("tx1_id:"+tx.to_dict()['id']) print(" ") ##################################################### 2.TRANSFER # inputs and asset [fake] cid = 0 condition = tx.to_dict()['transaction']['conditions'][cid] inputs = Fulfillment.from_dict({ 'fulfillment': condition['condition']['details'], 'input': { 'cid': cid, 'txid': tx.to_dict()['id'], }, 'owners_before': [bob.public_key], }) asset = Asset.from_dict(tx.to_dict()['transaction']['asset']) # transfer tx = Transaction.transfer([inputs], [([bob.public_key], 1)], asset) print("2.tx_fake asset id : bob-----bicycle(", tx.to_dict()['transaction']['asset']['id'], ")----->bob") print("2.tx_fake tx id : ", tx.to_dict()['id']) # sign with bob's private key [fake] tx = tx.sign([bob.private_key]) tx_id = tx.to_dict()['id'] # write to backlog b = Bigchain() print("2.tx_fake db response : ", b.write_transaction(tx)) # wait 2 sec sleep(delay) # get tx by id tx = b.get_transaction(tx_id) print("2.tx_fake query : ", tx) # print("tx2_id:"+tx.to_dict()['id']) print(" ")
def create_transfer(alicepub, alicepriv, include_spent): ##################################################### 1.CREATE # Cryptographic Identities Generation # alice, bob = generate_keypair(), generate_keypair() # Digital Asset Definition (e.g. bicycle) asset = Asset(data={ "bicycle": { "manufacturer": "bkfab", "serial_number": "abcd1234" } }, data_id="334cd061-846b-4213-bd25-588e951def5f") # Metadata Definition metadata = {'planet': 'earth'} # create trnsaction TODO : owners_before might be node_pubkey in v0.8.0 tx = Transaction.create([alicepub], [([alicepub], 100)], metadata=metadata, asset=asset) # sign with alice's private key tx = tx.sign([alicepriv]) tx_id = tx.to_dict()['id'] # write to backlog b = Bigchain() b.write_transaction(tx) print("========create 100 asset for userA========") print("========wait for block and vote...========") # wait 2 sec sleep(5) # get tx by id tx = b.get_transaction(tx_id) print("create 100 asset tx1_id:" + tx.to_dict()['id']) ##################################################### 3.UTXO # inputs and asset utxo = b.get_outputs_filtered_not_include_freeze(alicepub, include_spent) for u in utxo: # print(u) u.pop('details') print('userA unspent asset:') print(json.dumps(utxo, indent=4)) # print(json.load(utxo)) ##################################################### 2.Freeze # inputs and asset cid = 0 condition = tx.to_dict()['transaction']['conditions'][cid] inputs = Fulfillment.from_dict({ 'fulfillment': condition['condition']['details'], 'input': { 'cid': cid, 'txid': tx.to_dict()['id'], }, 'owners_before': condition['owners_after'], }) asset = Asset.from_dict(tx.to_dict()['transaction']['asset']) # transfer tx = Transaction.freeze_asset([inputs], [([alicepub], 90, True), ([alicepub], 10, False)], asset) # sign with alice's private key tx = tx.sign([alicepriv]) tx_id = tx.to_dict()['id'] # write to backlog b = Bigchain() b.write_transaction(tx) print("========freeze 90 asset for userA ========") print("========wait for block and vote...========") # wait 2 sec sleep(5) # get tx by id tx = b.get_transaction(tx_id) print("freeze 90 asset tx2_id:" + tx.to_dict()['id']) ##################################################### 3.UTXO # inputs and asset utxo = b.get_outputs_filtered_not_include_freeze(alicepub, include_spent) for u in utxo: # print(u) u.pop('details') print('userA unspent asset:') print(json.dumps(utxo, indent=4))
def create_transfer(): ##################################################### 1.CREATE # Cryptographic Identities Generation alice, bob, tom = generate_keypair(), generate_keypair(), generate_keypair( ) asset = Asset(data={'money': 'RMB'}, data_id='20170628150000', divisible=True) metadata = {'planet': 'earth'} tx = Transaction.create([alice.public_key], [([alice.public_key], 1000)], metadata=metadata, asset=asset) print(" ") print("1.tx_create asset id : alice-----money 1000(", tx.to_dict()['transaction']['asset']['id'], ")----->alice") print("1.tx_create tx id : ", tx.to_dict()['id']) # sign with alice's private key tx = tx.sign([alice.private_key]) tx_id = tx.to_dict()['id'] # write to backlog b = Bigchain() print("1.tx_create db response : ", b.write_transaction(tx)) # wait 4 sec sleep(delay) # get tx by id tx = b.get_transaction(tx_id) print("1.tx_create query : ", tx) # print("tx1_id:"+tx.to_dict()['id']) print(" ") ##################################################### 2.TRANSFER # inputs and asset cid = 0 condition = tx.to_dict()['transaction']['conditions'][cid] inputs = Fulfillment.from_dict({ 'fulfillment': condition['condition']['details'], 'input': { 'cid': cid, 'txid': tx.to_dict()['id'], }, 'owners_before': condition['owners_after'], }) asset = Asset.from_dict(tx.to_dict()['transaction']['asset']) # transfer tx = Transaction.transfer([inputs], [([bob.public_key], 300), ([alice.public_key], 700)], asset) print("2.tx_transfer asset id : alice-----money 300(", tx.to_dict()['transaction']['asset']['id'], ")----->bob") print("2.tx_transfer tx id : ", tx.to_dict()['id']) print("2.tx_transfer tx : ", tx.to_dict()) print(" ") # sign with alice's private key tx = tx.sign([alice.private_key]) # man in the middle attack, then write to backlog tx.conditions[0].amount = 600 tx.conditions[1].amount = 400 print("3.tx_attack asset id : alice-----money 600(", tx.to_dict()['transaction']['asset']['id'], ")----->tom") print("3.tx_attack tx id : ", tx.to_dict()['id']) print("3.tx_attack tx : ", tx.to_dict()) tx_id = tx.to_dict()['id'] b = Bigchain() print("3.tx_attack db response : ", b.write_transaction(tx)) # wait 4 sec sleep(delay) # get tx by id tx = b.get_transaction(tx_id) print("3.tx_attack query : ", tx) print(" ")
def validate(self, bigchain): """Validate a transaction. Args: bigchain (Bigchain): an instantiated bigchaindb.Bigchain object. Returns: The transaction (Transaction) if the transaction is valid else it raises an exception describing the reason why the transaction is invalid. Raises: OperationError: if the transaction operation is not supported TransactionDoesNotExist: if the input of the transaction is not found TransactionOwnerError: if the new transaction is using an input it doesn't own DoubleSpend: if the transaction is a double spend InvalidHash: if the hash of the transaction is wrong InvalidSignature: if the signature of the transaction is wrong """ if len(self.fulfillments) == 0: raise ValueError('Transaction contains no fulfillments') input_conditions = [] inputs_defined = all([ffill.tx_input for ffill in self.fulfillments]) if self.operation in (Transaction.CREATE, Transaction.GENESIS): # validate inputs if inputs_defined: raise ValueError('A CREATE operation has no inputs') # validate asset self.asset._validate_asset() elif self.operation == Transaction.TRANSFER: if not inputs_defined: raise ValueError('Only `CREATE` transactions can have null ' 'inputs') # check inputs # store the inputs so that we can check if the asset ids match input_txs = [] for ffill in self.fulfillments: input_txid = ffill.tx_input.txid input_cid = ffill.tx_input.cid input_tx, status = bigchain.\ get_transaction(input_txid, include_status=True) if input_tx is None: raise TransactionDoesNotExist( "input `{}` doesn't exist".format(input_txid)) if status != bigchain.TX_VALID: raise FulfillmentNotInValidBlock( 'input `{}` does not exist in a valid block'.format( input_txid)) spent = bigchain.get_spent(input_txid, ffill.tx_input.cid) if spent and spent.id != self.id: raise DoubleSpend( 'input `{}` was already spent'.format(input_txid)) input_conditions.append(input_tx.conditions[input_cid]) input_txs.append(input_tx) # validate asset id asset_id = Asset.get_asset_id(input_txs) if asset_id != self.asset.data_id: raise AssetIdMismatch( 'The asset id of the input does not match the asset id of the transaction' ) else: allowed_operations = ', '.join(Transaction.ALLOWED_OPERATIONS) raise TypeError('`operation`: `{}` must be either {}.'.format( self.operation, allowed_operations)) if not self.fulfillments_valid(input_conditions): raise InvalidSignature() else: return self
def create_double(): ##################################################### 1.CREATE # Cryptographic Identities Generation alice, bob = generate_keypair(), generate_keypair() # Digital Asset Definition (e.g. money) asset = Asset(data={'money': 'RMB'}, data_id='20170628150000', divisible=True) # Metadata Definition metadata = {'planet': 'earth'} # create trnsaction TODO : owners_before might be node_pubkey in v0.8.0 tx = Transaction.create([alice.public_key], [([alice.public_key], 100), ([alice.public_key], 100)], metadata=metadata, asset=asset) print(" ") print("1.tx_create asset id : alice-----money(", tx.to_dict()['transaction']['asset']['id'], ")----->alice") print("1.tx_create tx id : ", tx.to_dict()['id']) # sign with alice's private key tx = tx.sign([alice.private_key]) tx_id = tx.to_dict()['id'] # write to backlog b = Bigchain() print("1.tx_create db response : ", b.write_transaction(tx)) # wait 2 sec sleep(delay) # get tx by id tx = b.get_transaction(tx_id) unspent = b.get_outputs_filtered_not_include_freeze( alice.public_key, False) print("1.tx_create query : ", tx) print("1.tx_create unspent : ", unspent) print(" ") ##################################################### 2.TRANSFER # inputs and asset cid = 0 condition = tx.to_dict()['transaction']['conditions'][cid] inputs = Fulfillment.from_dict({ 'fulfillment': condition['condition']['details'], 'input': { 'cid': cid, 'txid': tx.to_dict()['id'], }, 'owners_before': [alice.public_key], }) asset = Asset.from_dict(tx.to_dict()['transaction']['asset']) # transfer tx1 = Transaction.transfer([inputs], [([bob.public_key], 100)], asset) print("2.tx_transfer asset id : alice-----money(", tx1.to_dict()['transaction']['asset']['id'], ")----->bob") print("2.tx_transfer tx id : ", tx1.to_dict()['id']) # sign with alice's private key tx1 = tx1.sign([alice.private_key]) tx1_id = tx1.to_dict()['id'] # write to backlog b = Bigchain() print("2.tx_transfer db response : ", b.write_transaction(tx1)) # wait 2 sec sleep(delay) # get tx by id tx1 = b.get_transaction(tx1_id) block = list(b.get_blocks_status_containing_tx(tx1_id).keys())[0] votes = list(b.backend.get_votes_by_block_id(block)) votes_cast = [vote['vote']['is_block_valid'] for vote in votes] election = b.get_blocks_status_containing_tx(tx1_id) print("2.tx_transfer query : ", tx1) print("2.tx_transfer block : ", block) print("2. votes : ", votes) print("2. votes_cast : ", votes_cast) print("2. election : ", election) print(" ") ##################################################### 3.INTERVAL # Cryptographic Identities Generation alice, bob = generate_keypair(), generate_keypair() # Digital Asset Definition (e.g. money) asset = Asset(data={'money': 'RMB'}, data_id='20170628150000', divisible=True) # Metadata Definition metadata = {'planet': 'earth'} # create trnsaction TODO : owners_before might be node_pubkey in v0.8.0 txi = Transaction.create([alice.public_key], [([alice.public_key], 100), ([alice.public_key], 100)], metadata=metadata, asset=asset) print(" ") print("1.tx_create asset id : alice-----money(", tx.to_dict()['transaction']['asset']['id'], ")----->alice") print("1.tx_create tx id : ", txi.to_dict()['id']) # sign with alice's private key txi = txi.sign([alice.private_key]) tx_id = txi.to_dict()['id'] # write to backlog b = Bigchain() print("1.tx_create db response : ", b.write_transaction(tx)) # wait 2 sec sleep(delay) ##################################################### 3.TRANSFER # inputs and asset [double spend] cid = 1 condition = tx.to_dict()['transaction']['conditions'][cid] inputs = Fulfillment.from_dict({ 'fulfillment': condition['condition']['details'], 'input': { 'cid': cid, 'txid': tx.to_dict()['id'], }, 'owners_before': [alice.public_key], }) asset = Asset.from_dict(tx.to_dict()['transaction']['asset']) # transfer tx1 = Transaction.transfer([inputs], [([bob.public_key], 100)], asset) print("3.tx_double asset id : alice-----money(", tx1.to_dict()['transaction']['asset']['id'], ")----->bob") print("3.tx_double tx id : ", tx1.to_dict()['id']) # sign with alice's private key tx1 = tx1.sign([alice.private_key]) tx1_id = tx1.to_dict()['id'] # write to backlog b = Bigchain() print("3.tx_double db response : ", b.write_transaction(tx1)) # wait 2 sec sleep(delay) # get tx by id tx1 = b.get_transaction(tx1_id) block = list(b.get_blocks_status_containing_tx(tx1_id).keys())[0] votes = list(b.backend.get_votes_by_block_id(block)) votes_cast = [vote['vote']['is_block_valid'] for vote in votes] election = b.get_blocks_status_containing_tx(tx1_id) print("3.tx_transfer query : ", tx1) print("3.tx_transfer block : ", block) print("3. votes : ", votes) print("3. votes_cast : ", votes_cast) print("3. election : ", election) print(" ")
import requests import time from bigchaindb.common.transaction import Transaction, Asset, Fulfillment from bigchaindb.common.crypto import generate_key_pair # 一对多转账,生成1+3个公钥 pri_1, pub_1 = generate_key_pair() pri_n1, pub_n1 = generate_key_pair() pri_n2, pub_n2 = generate_key_pair() pri_n3, pub_n3 = generate_key_pair() delay = 4 # 发送交易后,等待建块投票延迟 msg = "1_to_n" asset = Asset(data={'money': 'RMB'}, data_id='20170628150000', divisible=True) metadata = {'raw': msg} # pub_1先创建10000,再转给n1,n2,n3各2000/3000/5000 amount = 10000 amount_n1 = 2000 amount_n2 = 3000 amount_n3 = 5000 # pub_1创建交易 tx = Transaction.create([pub_1], [([pub_1], amount)], metadata=metadata, asset=asset) tx = tx.sign([pri_1]).to_dict() print("========create tx======") # 发送给区块链节点 with requests.Session() as session: res = session.post('http://localhost:9984/uniledger/v1/transaction/createOrTransferTx', json=tx)
def create_transfer(): ##################################################### 1.CREATE # Cryptographic Identities Generation alice, bob, tom = generate_keypair(), generate_keypair(), generate_keypair() asset = Asset(data={"bicycle": {"manufacturer": "bkfab", "serial_number": "abcd1234"}}) metadata = {'planet': 'earth'} tx = Transaction.create([alice.public_key], [([alice.public_key], 1)], metadata=metadata, asset=asset) print(" ") print("1.tx_create asset id : alice-----bicycle(", tx.to_dict()['transaction']['asset']['id'], ")----->alice") print("1.tx_create tx id : ", tx.to_dict()['id']) # sign with alice's private key tx = tx.sign([alice.private_key]) tx_id = tx.to_dict()['id'] # write to backlog b = Bigchain() print("1.tx_create db response : ", b.write_transaction(tx)) # wait 4 sec sleep(delay) # get tx by id tx = b.get_transaction(tx_id) print("1.tx_create query : ", tx) # print("tx1_id:"+tx.to_dict()['id']) print(" ") ##################################################### 2.TRANSFER # inputs and asset cid = 0 condition = tx.to_dict()['transaction']['conditions'][cid] inputs = Fulfillment.from_dict({ 'fulfillment': condition['condition']['details'], 'input': { 'cid': cid, 'txid': tx.to_dict()['id'], }, 'owners_before': condition['owners_after'], }) asset = Asset.from_dict(tx.to_dict()['transaction']['asset']) # transfer tx = Transaction.transfer([inputs], [([bob.public_key], 1)], asset) print("2.tx_transfer asset id : alice-----bicycle(", tx.to_dict()['transaction']['asset']['id'], ")----->bob") print("2.tx_transfer tx id : ", tx.to_dict()['id']) print("2.tx_transfer tx : ", tx.to_dict()) print(" ") # sign with alice's private key tx = tx.sign([alice.private_key]) # man in the middle attack, then write to backlog tx.conditions[0].owners_after = [tom.public_key] print("3.tx_attack asset id : alice-----bicycle(", tx.to_dict()['transaction']['asset']['id'], ")----->tom") print("3.tx_attack tx id : ", tx.to_dict()['id']) print("3.tx_attack tx : ", tx.to_dict()) tx_id = tx.to_dict()['id'] b = Bigchain() print("3.tx_attack db response : ", b.write_transaction(tx)) # wait 4 sec sleep(delay) # get tx by id tx = b.get_transaction(tx_id) print("3.tx_attack query : ", tx) print(" ")