def get_handler(**args): address = args.get('user_did').lstrip(forge_did.PREFIX) event_address = args.get('request').args.get('event_address') pk = forge_utils.multibase_b58decode(args.get('user_pk')) acquire_asset_tx, _ = forge.rpc.build_acquire_asset_tx( to=event_address, spec_datas=[{ "id": str(uuid.uuid4()) }], type_url='ec:s:general_ticket', proto_lib=protos) tx = forge_utils.build_unsigned_tx(itx=forge_utils.encode_to_any( 'fg:t:acquire_asset', acquire_asset_tx), chain_id=forge.config.chain_id, address=address, pk=pk) return { 'request_type': 'signature', 'workflow': 'buy-ticket', 'tx': tx, 'description': 'Confirm Purchase of Ticket', }
def to_state(self): event_info = protos.EventInfo( title=self.event_info.title, description=self.event_info.description, total=self.event_info.total, start_time=self.event_info.start_time, end_time=self.event_info.end_time, ticket_price=int(self.event_info.ticket_price), remaining=self.remaining, tickets=self.tickets, participants=self.participants, location=self.event_info.location, consume_tx=self.event_info.consume_tx, img_url=self.event_info.img_url, ) state = protos.AssetState( address=self.address, owner=self.owner, moniker=self.moniker, readonly=self.readonly, transferrable=self.transferrable, ttl=self.ttl, consumed_time=self.consumed_time, stake=self.stake, context=self.context, data=forge_utils.encode_to_any( 'ec:s:event_info', event_info, ), ) return state
def post_handler(**args): wallet_res = args.get('wallet_res') asset_address = wallet_res.get_asset_address() ticket = controllers.get_ticket_state(asset_address) new_tx = controllers.update_tx_multisig(tx=forge_utils.parse_to_proto( forge_utils.multibase_b58decode(ticket.consume_tx), forge_protos.Transaction), signer=wallet_res.get_address(), pk=wallet_res.get_user_pk(), data=forge_utils.encode_to_any( 'fg:x:address', asset_address, )) token = args.get('token') utils.mark_token_status(token, 'succeed') params = { 'tx': new_tx, 'url': utils.server_url( f'/api/did/consume_ticket/consume?_t_={token}&ticket_address={ticket.address}' ), 'description': 'Confirm to use the ticket.', 'workflow': 'use-ticket', 'user_did': wallet_res.get_address() } res = utils.send_did_request(request_type='signature', **params, **args.get('app_params')) logger.debug(f"POST Response: {res}") return json.loads(res)
def gen_consume_tx(wallet, token=None): consume_itx = forge_protos.ConsumeAssetTx(issuer=wallet.address) logger.debug(str(forge.rpc)) tx = forge.rpc.build_signed_tx(itx=forge_utils.encode_to_any( 'fg:t:consume_asset', consume_itx), wallet=wallet, token=token) return tx.SerializeToString()
def gen_ticket_holder(self, ticket_id): create_asset_ticket = create_asset_ticket_info( ticket_id, self.address, ) ticket__address = did.get_asset_address( did_address=self.wallet.address, itx=create_asset_ticket, ) ticket_create_tx = forge_rpc.create_tx( itx=forge_utils.encode_to_any( type_url='fg:t:create_asset', data=create_asset_ticket, ), from_address=self.wallet.address, token=self.token, ) exchange_tx = gen_exchange_tx( self.ticket_price, ticket__address, self.address, ) ticket_exchange_tx = forge_rpc.create_tx( itx=forge_utils.encode_to_any('fg:t:exchange', exchange_tx), from_address=self.wallet.address, wallet=self.wallet, token=self.token, ) ticket_holder = protos.TicketHolder( ticket_create=ticket_create_tx.tx, ticket_exchange=ticket_exchange_tx.tx, id=ticket_id, address=ticket__address, ) return ticket_holder
def create_asset_ticket_info(id, event_address): ticket_info = protos.TicketInfo( id=id, event_address=event_address, is_used=False, ) ticket_itx = protos.CreateAssetTx( data=forge_utils.encode_to_any( 'ec:s:ticket_info', ticket_info, ), readonly=True, ) return ticket_itx
def consume_mobile(self, consume_tx, address, signature, user_pk): multisig_data = forge_utils.encode_to_any( 'fg:x:address', self.address, ) tx = utils.update_tx_multisig( tx=consume_tx, signer=address, signature=signature, pk=user_pk, data=multisig_data, ) return forge_rpc.send_tx(tx)
def gen_poke_tx(address, pk): poke_itx = forge_protos.PokeTx( date=str( datetime.now().date()), address='zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz', ) itx = forge_utils.encode_to_any('fg:t:poke', poke_itx) params = { 'from': address, 'chain_id': config.chain_id, 'nonce': 0, 'pk': pk, 'itx': itx } return forge_protos.Transaction(**params)
def require_asset(event_address): try: event = models.get_event_factory(event_address) if request.method == 'GET': lib.parse_request_get(request, 'require-asset') params = { 'url': url_for('api_mobile.require_asset', event_address=event_address), 'target': event.title, } response = controllers.require_asset_consume(**params) return response if request.method == 'POST': wallet_res = lib.parse_request_post(request, 'require-asset') if not wallet_res: return lib.error("Error in parsing wallet data.") asset_address = wallet_res.get_asset_address() if not asset_address: return lib.error("Please provide an asset address.") new_tx = utils.update_tx_multisig(tx=event.consume_tx, signer=wallet_res.get_address(), pk=wallet_res.get_user_pk(), data=forge_utils.encode_to_any( 'fg:x:address', asset_address, )) params = { 'did': wallet_res.get_address(), 'tx': new_tx, 'url': url_for('api_mobile.consume', ticket_address=asset_address), } return controllers.require_sig_consume(**params) except Exception as e: logger.error(e, exc_info=True) return lib.error("Exception in requesting asset.")
def gen_consume_tx(self): consume_itx = protos.ConsumeAssetTx(issuer=self.wallet.address) res = forge_rpc.create_tx( itx=forge_utils.encode_to_any( 'fg:t:consume_asset', consume_itx, ), from_address=self.wallet.address, wallet=self.wallet, token=self.token, ) if res.code != 0 or res.tx is None: logger.error(u'Fail to generate consume tx for event.') return None else: logger.debug( u"Consume tx generated for event {}".format(self.title), ) return res.tx
def create(self): logger.debug(u"Creating event...") if not self.consume_tx: logger.error(u"Consume tx not generated!") event_info = protos.EventInfo( title=self.title, total=self.total, start_time=self.start_time, end_time=self.end_time, ticket_price=self.ticket_price, location=self.location, tickets=[], participants=[], remaining=self.total, consume_tx=self.consume_tx, img_url=self.img_url, ) create_asset_itx = protos.CreateAssetTx(data=forge_utils.encode_to_any( self.type_url, event_info), ) event_address = did.get_asset_address(did_address=self.wallet.address, itx=create_asset_itx) logger.debug( u"Event address has been calculated: {}".format(event_address), ) res = forge_rpc.create_asset( self.type_url, event_info, self.wallet, self.token, ) if res.code != 0 or not res.hash: logger.error(res) else: logger.info( u"Event '{0}' has been created successfully by tx {" "1}!".format( self.title, res.hash, ), ) return event_address
def to_state(self): ticket_info = protos.TicketInfo( id=self.id, event_address=self.event_address, is_used=self.is_used, ) state = protos.AssetState( address=self.address, owner=self.owner, moniker=self.moniker, readonly=self.readonly, transferrable=self.transferrable, ttl=self.ttl, consumed_time=self.consumed_time, stake=self.stake, context=self.context, data=forge_utils.encode_to_any( 'ec:s:ticket_info', ticket_info, ), ) logger.debug("ticket state about to update...") logger.debug("state: {}".format(state)) return state
print(f"operator's balance is {rpc.get_account_balance(op.wallet.address)}") print( f"manufacturer's balance is {rpc.get_account_balance(ma.wallet.address)}") print(f"supplier's balance is {rpc.get_account_balance(su.wallet.address)}") print(f"location's balance is {rpc.get_account_balance(lo.wallet.address)}") print("sending a tx...") # send a tx itx = AggregateTx(sku=sku, value=value, time=time, operator=op.wallet.address, manufacturer=ma.wallet.address, supplier=su.wallet.address, location=lo.wallet.address) itx2 = utils.encode_to_any(type_url="fg:t:aggregate", data=itx) print("itx2 is ", itx2) res = rpc.send_itx(tx=itx2, wallet=vm.wallet, token=vm.token, nonce=0) print("res is ", res) # check tx sleep(3) print(f"TX verify: {rpc.is_tx_ok(res.hash)}") print(f"operator's balance is {rpc.get_account_balance(op.wallet.address)}") print( f"manufacturer's balance is {rpc.get_account_balance(ma.wallet.address)}") print(f"supplier's balance is {rpc.get_account_balance(su.wallet.address)}") print(f"location's balance is {rpc.get_account_balance(lo.wallet.address)}")
def buy_ticket(event_address): try: if request.method == 'GET': wallet = lib.parse_request_get(request, 'buy-ticket') acquire_asset_tx, _ = forge_rpc.build_acquire_asset_tx( to=event_address, spec_datas=[{ "id": str(uuid.uuid4()) }], type_url='ec:s:general_ticket', proto_lib=protos) unsigned_tx = forge_rpc.build_unsigned_tx( forge_utils.encode_to_any('fg:t:acquire_asset', acquire_asset_tx), wallet, 2) did_request_params = { 'did': wallet.did, 'tx': unsigned_tx, 'url': url_for('api_mobile.buy_ticket', event_address=event_address), } response = controllers.require_sig_buy_ticket(**did_request_params) logger.debug(f'did auth response: {response}') return response elif request.method == 'POST': wallet_res = lib.parse_request_post(request, 'mobile-buy-ticket') if not wallet_res: return lib.error("Error in parsing wallet data.") participant_state = models.get_participant_state( wallet_res.get_address()) if not participant_state: return lib.error( f"user {wallet_res.get_address()} doesn't exist.") ticket_address, tx_hash = controllers.buy_ticket_mobile( wallet_res.get_origin_tx(), wallet_res.get_signature(), ) tx = wallet_res.get_origin_tx().__deepcopy__() tx.signature = wallet_res.get_signature() if ticket_address and tx_hash: logger.info(f"Ticket {ticket_address} is bought successfully.") return lib.ok({ 'ticket': ticket_address, 'hash': tx_hash, 'tx': utils.base58_encode_tx(tx) }) else: return lib.error('Whoops. Something is wrong :(') except Exception as e: logger.error(e, exc_info=True) return lib.error('Exception in buying ticket.')
async def send(context): ''' Get a ramdon element from each category, and current time to generate a bill for simulation. Send this bill on the chain through AggregateTx ------ Args: context(dict): all necessary info (items, vending_machines, batch) Output: send aggregate tx on the chain ''' # put random info together to generate a random bill item_unit = choice(context['items']) vm_unit = choice(context['vms']) op = vm_unit['operator'] ma = vm_unit['manufacturer'] su = item_unit['supplier'] lo = vm_unit['location'] # get current time curr_time = Timestamp() curr_time.GetCurrentTime() # get item's value value = utils.int_to_biguint(utils.to_unit(item_unit['value'])) logger.debug("before tx...") logger.debug( f"{op['moniker']}'s balance is {rpc.get_account_balance(op['address'])}" ) logger.debug( f"{ma['moniker']}'s balance is {rpc.get_account_balance(ma['address'])}" ) logger.debug( f"{su['moniker']}'s balance is {rpc.get_account_balance(su['address'])}" ) logger.debug( f"{lo['moniker']}'s balance is {rpc.get_account_balance(lo['address'])}" ) # group a wallet object for vending_machine vm_wallet = protos.WalletInfo(pk=utils.multibase_b64decode(vm_unit['pk']), sk=utils.multibase_b64decode(vm_unit['sk']), address=vm_unit['address']) # creat tx itx = AggregateTx(sku=item_unit['sku'], value=value, time=curr_time, operator=op['address'], manufacturer=ma['address'], supplier=su['address'], location=lo['address']) itx2 = utils.encode_to_any(type_url="fg:t:aggregate", data=itx) logger.info( f"batch {context['batch']} is sending tx... ---> value: {item_unit['value']}, from: {vm_unit['address']}, operator: {op['address']}, manufacturer: {ma['address']}, supplier: {su['address']}, location: {lo['address']}" ) res = rpc.send_itx(tx=itx2, wallet=vm_wallet, nonce=0) await asyncio.sleep(5) logger.info(f"verify tx: {rpc.is_tx_ok(res.hash)}") logger.debug( f"{op['moniker']}'s balance is {rpc.get_account_balance(op['address'])}" ) logger.debug( f"{ma['moniker']}'s balance is {rpc.get_account_balance(ma['address'])}" ) logger.debug( f"{su['moniker']}'s balance is {rpc.get_account_balance(su['address'])}" ) logger.debug( f"{lo['moniker']}'s balance is {rpc.get_account_balance(lo['address'])}" )