Aplicaciones construidas en Lisk : proyecto Lisk Ride
Introducción
LiskRide es una plataforma comunitaria que conecta a los conductores con asientos libres con los pasajeros que buscan un viaje en la misma dirección. Nuestro objetivo es eliminar a los intermediarios y permitir transacciones directas.
Este proyecto es parte de la economía colaborativa y aprovecha la plataforma de aplicaciones Lisk blockchain, y se ha desarrollado como una aplicación web progresiva basada en Reactjs.
¿Como funciona?
En nuestro ecosistema hay dos tipos de participantes:
En primer lugar, se explican los requisitos previos para el conductor, seguido por el pasajero.
Requisitos previos comunes para pasajeros y conductores
Autenticación
Para usar la aplicación LiskRide, el conductor y el pasajero deberán crear sus cuentas a través de la página de autenticación y mantener la contraseña segura. La contraseña y la dirección se generan automáticamente en la página "Registrarse".
Si los usuarios ya tienen una cuenta, deberán iniciar sesión a través de la página de inicio de sesión.
Transferir
Una vez que haya iniciado sesión, en la página de Transferencia, los usuarios podrán recolectar tokens para usar la plataforma. Cabe señalar que esta transferencia se realiza para el POC.
Aclaración: Pa:ra ver completos los codigos se recomeienda verlos desde una PC
| handleTransfert = ( evento ) => { |
| esto . setState ( { isLoading : true } ) |
| dejar usuario = JSON . parse ( getUser ( ) ) ; |
|
|
| prueba { |
| const fundTransaction = new TransferTransaction ( { |
| activo : { |
| destinatarioId : usuario . dirección , |
| cantidad : utils . convertLSKToBeddows ( "200" ) , |
| } , |
| networkIdentifier : networkIdentifier , |
| } ) ; |
|
|
| fundTransaction . signo ( "XXXX XXXX XXXX XXXX" ) ; |
| |
| api . transacciones . broadcast ( fundTransaction . toJSON ( ) ) . entonces ( respuesta => { |
| esto . setState ( { isLoading : false } ) |
| } ) . catch ( err => { |
| esto . setState ( { isLoading : false } ) |
| consola . log ( JSON . stringify ( err . errores , nulo , 2 ) ) ; |
| } ) ; |
|
|
| } captura ( error ) { |
| esto . setState ( { isLoading : false } ) |
| consola . log ( error ) |
| } |
| } ; |
Los requisitos previos del controlador
El conductor requiere los siguientes pasos:
Publicación del plan de viaje
El conductor puede agregar su plan de viaje eligiendo la ciudad de destino, la ciudad de salida, la fecha de salida, la tarifa por asiento y la cantidad de asientos disponibles.
| applyAsset ( tienda ) { |
| errores constantes = [ ] ; |
| |
| viaje constante = tienda . cuenta . getOrDefault ( este . activo . travelId ) ; |
| conductor constante = tienda . cuenta . obtener ( este . senderId ) |
| const driverTravels = conductor . activo . driverTravels || [ ] |
|
|
| if ( ! travel . asset . pickUpDate ) { |
|
|
| const driverTravel = { |
| carId : esto . activo . carId , |
| travelId : esto . activo . travelId , |
| senderId : esto . senderId , |
| driverAdress : esto . activo . driverAdress , |
| pickUpLocation : este . activo . pickUpLocation , |
| pickUpDate : esto . activo . pickUpDate , |
| availableSeatCount : esto . activo . availableSeatCount , |
| pricePerSeat : este . activo . pricePerSeat , |
| destino : este . activo . destino |
| } |
|
|
| driverTravels . empujar ( conductor de viaje ) |
| |
| const updatedTravelAccount = { |
| ... viajar , |
| activo : { |
| carId : esto . activo . carId , |
| travelId : esto . activo . travelId , |
| senderId : esto . senderId , |
| driverAdress : esto . activo . driverAdress , |
| pickUpLocation : este . activo . pickUpLocation , |
| pickUpDate : esto . activo . pickUpDate , |
| availableSeatCount : esto . activo . availableSeatCount , |
| pricePerSeat : este . activo . pricePerSeat , |
| destino : este . activo . destino |
| } |
| } ; |
|
|
| const updatedDriverAccount = { |
| ... conductor , |
| activo : { |
| ... conductor . activo , |
| driverTravels : driverTravels , |
| } |
| } ; |
|
|
| tienda . cuenta . conjunto ( viajes . dirección , updatedTravelAccount ) ; |
| tienda . cuenta . set ( este . senderId , updatedDriverAccount ) ; |
| } más { |
| errores . empujar ( |
| new TransactionError ( |
| 'el viaje ya ha sido registrado' , |
| productor . activo . nombre |
| ) |
| ) ; |
| } |
| |
| devolver errores ; |
| } |
Reserva de pasajeros y aseguramiento de fondos
Cuando un pasajero reserva el viaje, la información de contacto se envía al conductor. Además, los fondos se retiran del pasajero y se depositan en la cuenta de viaje para garantizar que el pasajero pueda pagar el viaje.
| applyAsset ( tienda ) { |
| errores constantes = [ ] ; |
| viaje constante = tienda . cuenta . obtener ( este . activo . travelId ) ; |
| const pasajero = tienda . cuenta . obtener ( este . activo . Id . de pasajero ) ; |
| conductor constante = tienda . cuenta . get ( viaje . asset . carId ) ; |
| const pasajeroViajes = pasajero . activo . viajes de pasajeros || [ ] |
|
|
| const foundDriverTravelIndex = controlador . activo . driverTravels . findIndex ( element => element . travelId === this . asset . travelId ) ; |
|
|
| const amountTravel = nuevos utils . BigNum ( viaje . Activo . PricePerSeat ) . mul ( |
| utilidades nuevas . BigNum ( this . Asset . SeatCount ) |
| ) ; |
|
|
| const newTravelBalance = nuevos utils . BigNum ( viaje . Saldo ) . añadir ( |
| utilidades nuevas . BigNum ( amountTravel ) |
| ) ; |
| const newPassengerBalance = nuevos utils . BigNum ( pasajero . Saldo ) . sub ( |
| newTravelBalance |
| ) ; |
|
|
| si ( |
| ! utils . BigNum ( pasajero . Saldo ) . gt ( "0" ) || |
| ! utils . BigNum ( pasajero . Saldo ) . gte ( newTravelBalance ) |
| ) { |
| errores . empujar ( |
| new TransactionError ( |
| "cantidad insuficiente para este viaje" , |
| esto . activo . travelId |
| ) |
| ) ; |
| } |
| si ( |
| ! utils . Bignum ( viajes . Activo . AvailableSeatCount ) . gte ( este . activo . seatCount ) |
| ) { |
| errores . empujar ( |
| new TransactionError ( |
| "no hay suficiente asiento para este viaje" , |
| esto . activo . travelId |
| ) |
| ) ; |
| } |
| si ( |
| pasajero . dirección == conductor . habla a |
| ) { |
| errores . empujar ( |
| new TransactionError ( |
| "El conductor no puede reservar asiento en su coche" , |
| esto . activo . travelId |
| ) |
| ) ; |
| } |
|
|
| if ( errores . longitud <= 0 ) { |
|
|
| const travelPassengerBalances = viaje . activo . travelPassengerBalances || [ ] |
| |
| const foundTravelPassengerBalanceIndex = travelPassengerBalances . FindIndex ( elemento => elemento . passengerAddress === pasajero . dirección ) ; |
| const foundTravelPassengerBalance = travelPassengerBalances [ foundTravelPassengerBalanceIndex ] ; |
|
|
| if ( ! foundTravelPassengerBalance ) { |
| travelPassengerBalances . empujar ( { pasajeroAddress : pasajero . dirección , seatCount : this . asset . seatCount , amountTravel : amountTravel . toString ( ) } ) |
| } más { |
| travelPassengerBalances [ foundTravelPassengerBalanceIndex ] = { ... foundTravelPassengerBalance , seatCount : utils . BigNum ( foundTravelPassengerBalance . SeatCount ) . añadir ( this . asset . seatCount ) . toString ( ) , amountTravel : utils . BigNum ( foundTravelPassengerBalance . AmountTravel ) . añadir ( utilidades nuevas . BigNum ( amountTravel ) ) . toString ( ) } |
| } |
|
|
| const restSeatCount = nuevos utils . BigNum ( |
| viajar . activo . availableSeatCount |
| ) . sub ( este . activo . seatCount ) ; |
|
|
| const updatedTravel = { |
| ... viajar , |
| activo : { |
| ... viajar . activo , |
| travelPassengerBalances : travelPassengerBalances , |
| availableSeatCount : restSeatCount . toString ( ) , |
| } , |
| balance : newTravelBalance . toString ( ) , |
| } ; |
|
|
| tienda . cuenta . conjunto ( viajes . dirección , updatedTravel ) ; |
|
|
| viajes de pasajeros . empujar ( viajar ) |
|
|
| const updatedPassenger = { |
| ... pasajero , |
| activo : { |
| ... pasajero . activo , |
| viajes de pasajeros : viajes de pasajeros , |
| } , |
| balance : newPassengerBalance . toString ( ) , |
| } ; |
|
|
| tienda . cuenta . set ( pasajero . dirección , updatedPassenger ) ; |
|
|
|
|
| conductor . activo . driverTravels [ foundDriverTravelIndex ] = viaje actualizado . activo |
|
|
| const updatedDriver = { |
| ... conductor , |
| activo : { |
| ... conductor . activo , |
| driverTravels : conductor . activo . driverTravels , |
| } |
| } ; |
|
|
| tienda . cuenta . conjunto ( conductor . dirección , updatedDriver ) ; |
|
|
| } |
|
|
| devolver errores ; |
| } |
Viaje
Cuando el conductor se encuentra con el pasajero, debe aceptar comenzar el viaje juntos. Esta acción debe realizarse en presencia de ambas partes. Esto desbloqueará la transferencia de fondos a la cuenta del conductor.
| applyAsset ( tienda ) { |
| errores constantes = [ ] ; |
|
|
| viaje constante = tienda . cuenta . obtener ( este . activo . travelId ) ; |
| const pasajero = tienda . cuenta . obtener ( este . activo . Id . de pasajero ) ; |
|
|
| const travelDriverBalance = viaje . activo . travelDriverBalance || [ ] |
| const travelPassengerBalances = viaje . activo . travelPassengerBalances || [ ] |
| |
| const foundTravelPassengerBalance = travelPassengerBalances . encontrar ( elemento => elemento . passengerAddress === pasajeros . dirección ) ; |
| const foundTravelDriverBalance = travelDriverBalance . encontrar ( elemento => elemento . passengerAddress === pasajeros . dirección ) ; |
|
|
| if ( ! foundTravelDriverBalance ) { |
| if ( foundTravelPassengerBalance ) { |
| travelDriverBalance . empujar ( foundTravelPassengerBalance ) |
| } |
| } más { |
| errores . empujar ( |
| new TransactionError ( |
| 'travelDriverBalance ya se ha configurado para el conductor' , |
| esto . activo . travelId |
| ) |
| ) ; |
| } |
| |
| const updatedTravelAccount = { |
| ... viajar , |
| activo : { |
| ... viajar . activo , |
| travelDriverBalance : travelDriverBalance , |
| } |
| } ; |
|
|
| if ( errores . longitud === 0 ) { |
| tienda . cuenta . conjunto ( viajes . dirección , updatedTravelAccount ) ; |
| } |
|
|
| |
| devolver errores ; |
| } |
Recibo de pago
El conductor podrá recuperar los fondos y evaluar al pasajero a través de una interfaz de retiro accesible a través de su lista de viajes. En el futuro, el retiro será posible después de un período de 24 horas.
| applyAsset ( tienda ) { |
| errores constantes = [ ] ; |
| viaje constante = tienda . cuenta . obtener ( este . activo . travelId ) ; |
| const pasajero = tienda . cuenta . obtener ( este . activo . Id . de pasajero ) ; |
| conductor constante = tienda . cuenta . get ( this . asset . carId ) ; |
|
|
| const travelDriverBalance = viaje . activo . travelDriverBalance || [ ] ; |
| const foundTravelDriverBalanceIndex = travelDriverBalance . findIndex ( |
| ( elemento ) => elemento . passAddress === esto . activo . pasajerosId |
| ) ; |
|
|
| si ( |
| ! travelDriverBalance [ foundTravelDriverBalanceIndex ] . calificación && |
| utilidades nuevas . BigNum ( |
| travelDriverBalance [ foundTravelDriverBalanceIndex ] . cantidad de viaje |
| ) . gt ( 0 ) |
| ) { |
| const amountToWidthdraw = nuevos utils . BigNum ( |
| travelDriverBalance [ foundTravelDriverBalanceIndex ] . cantidad de viaje |
| ) ; |
|
|
| travelDriverBalance [ foundTravelDriverBalanceIndex ] = { |
| ... travelDriverBalance [ foundTravelDriverBalanceIndex ] , |
| calificación : esto . activo . calificación , |
| amountTravel : "0" , |
| } ; |
|
|
| const newTravelBalance = nuevos utils . BigNum ( viaje . Saldo ) . sub ( |
| utilidades nuevas . BigNum ( amountToWidthdraw ) |
| ) ; |
|
|
| const newDriverBalance = nuevos utils . BigNum ( conductor . Saldo ) . añadir ( |
| amountToWidthdraw |
| ) ; |
|
|
| const ratings = pasajero . activo . calificaciones || [ ] ; |
|
|
| calificaciones . empujar ( { |
| calificación : esto . activo . calificación , |
| notado por : esto . senderId , |
| marca de tiempo : esto . marca de tiempo , |
| } ) ; |
|
|
| const updatedTravelAccount = { |
| ... viajar , |
| balance : newTravelBalance . toString ( ) , |
| activo : { |
| ... viajar . activo , |
| travelDriverBalance : travelDriverBalance , |
| } , |
| } ; |
|
|
| const updatedPassengerAccount = { |
| ... pasajero , |
| activo : { |
| ... pasajero . activo , |
| calificaciones : calificaciones , |
| } , |
| } ; |
|
|
| const updatedDriverAccount = { |
| ... conductor , |
| balance : newDriverBalance . toString ( ) , |
| } ; |
|
|
| tienda . cuenta . conjunto ( viajes . dirección , updatedTravelAccount ) ; |
| tienda . cuenta . conjunto ( pasajero . dirección , updatedPassengerAccount ) ; |
| tienda . cuenta . conjunto ( conductor . dirección , updatedDriverAccount ) ; |
| } |
|
|
| devolver errores ; |
| } |
Los requisitos previos de los requisitos de los pasajeros
El pasajero requiere los siguientes pasos:
Encontrar un viaje al destino deseado
Para buscar un viaje planificado, el pasajero simplemente tiene que ingresar su destino, su ciudad de salida y la fecha correspondiente. Entonces será posible elegir una ruta a partir de los resultados obtenidos. Si se requiere más información, pueden contactar con el conductor antes de reservar.
La búsqueda fue posible gracias al uso de la API extendida de Moosty: @ moosty / lisk-extended-api.
| estado = { |
| salida : indefinida , |
| pickUpLocation : undefined , |
| pickUpDate : nueva fecha ( ) , |
| availableSeatCount : 0 , |
| pricePerSeat : 0 , |
| viajes : [ ] , |
| showCalendarModal : falso , |
| isLoading : falso |
| } ; |
| handleForm = ( ) => { |
| const { |
| destino , |
| pickUpLocation , |
| pickUpDate , |
| availableSeatCount , |
| } = esto . estado ; |
|
|
| viajes constantes = [ ] ; |
|
|
| esto . setState ( { isLoading : true } ) |
| dejar destinoP = buscar ( |
| `http: // localhost: 2020 / extended-api / accounts? asset = destination & contains = $ { destination } ` |
| ) ; |
| dejar pickUpLocationP = fetch ( |
| `http: // localhost: 2020 / extended-api / accounts? asset = pickUpLocation & contains = $ { pickUpLocation } ` |
| ) ; |
| dejar pickUpDateP = fetch ( |
| `http: // localhost: 2020 / extended-api / accounts? asset = pickUpDate & contains = $ { pickUpDate } ` |
| ) ; |
|
|
| var search = { |
| availableSeatCount , |
| pickUpDate , |
| pickUpLocation , |
| destino |
| } ; |
|
|
| Promesa . todos ( [ |
| destinoP , |
| pickUpLocationP , |
| pickUpDateP , |
| ] ) |
| . entonces ( ( valores ) => { |
| dejar promesas = [ ] ; |
| valores . forEach ( ( valor ) => { |
| promesas . empujar ( valor . json ( ) ) ; |
| } ) ; |
| Promesa . todas ( promesas ) . entonces ( ( valores ) => { |
| valores . forEach ( ( valor ) => { |
| consola . log ( valor ) ; |
| |
| valor . datos . forEach ( ( v ) => viaja . empujar ( { travelId : v . id , carId : v . carId , ... v . asset } ) ) ; |
| } ) ; |
| |
| filtro constante = { pickUpDate , pickUpLocation , destino } |
|
|
| deja resultados = viajes . filtro ( función ( elemento ) { |
| para ( clave var en filtro ) { |
| if ( elemento [ clave ] === indefinido || elemento [ clave ] ! == filtro [ clave ] ) |
| devolver falso ; |
| } |
| devuelve verdadero ; |
| } ) ; |
| esto . setState ( { isLoading : false } ) |
| |
| deje uniquResult = _ . uniqBy ( resultados , 'travelId' ) ; |
| esto . apoyos . updateTravels ( { viajes : uniquResult , buscar } ) |
| esto . apoyos . historia . empujar ( "/ inicio / resultados" ) ; |
| } ) ; |
| } ) |
| . atrapar ( ( razón ) => { |
| esto . setState ( { isLoading : false } ) |
| consola . log ( razón ) ; |
| } ) ; |
Pago y aseguramiento de fondos
El pasajero reserva su viaje y se le debitará automáticamente el importe correspondiente. Estos fondos se depositarán en la cuenta de viajes.
| applyAsset ( tienda ) { |
| errores constantes = [ ] ; |
| viaje constante = tienda . cuenta . obtener ( este . activo . travelId ) ; |
| const pasajero = tienda . cuenta . obtener ( este . activo . Id . de pasajero ) ; |
| conductor constante = tienda . cuenta . get ( viaje . asset . carId ) ; |
| const pasajeroViajes = pasajero . activo . viajes de pasajeros || [ ] |
|
|
| const foundDriverTravelIndex = controlador . activo . driverTravels . findIndex ( element => element . travelId === this . asset . travelId ) ; |
|
|
| const amountTravel = nuevos utils . BigNum ( viaje . Activo . PricePerSeat ) . mul ( |
| utilidades nuevas . BigNum ( this . Asset . SeatCount ) |
| ) ; |
|
|
| const newTravelBalance = nuevos utils . BigNum ( viaje . Saldo ) . añadir ( |
| utilidades nuevas . BigNum ( amountTravel ) |
| ) ; |
| const newPassengerBalance = nuevos utils . BigNum ( pasajero . Saldo ) . sub ( |
| newTravelBalance |
| ) ; |
|
|
| si ( |
| ! utils . BigNum ( pasajero . Saldo ) . gt ( "0" ) || |
| ! utils . BigNum ( pasajero . Saldo ) . gte ( newTravelBalance ) |
| ) { |
| errores . empujar ( |
| new TransactionError ( |
| "cantidad insuficiente para este viaje" , |
| esto . activo . travelId |
| ) |
| ) ; |
| } |
| si ( |
| ! utils . Bignum ( viajes . Activo . AvailableSeatCount ) . gte ( este . activo . seatCount ) |
| ) { |
| errores . empujar ( |
| new TransactionError ( |
| "no hay suficiente asiento para este viaje" , |
| esto . activo . travelId |
| ) |
| ) ; |
| } |
| si ( |
| pasajero . dirección == conductor . habla a |
| ) { |
| errores . empujar ( |
| new TransactionError ( |
| "El conductor no puede reservar asiento en su coche" , |
| esto . activo . travelId |
| ) |
| ) ; |
| } |
|
|
| if ( errores . longitud <= 0 ) { |
|
|
| const travelPassengerBalances = viaje . activo . travelPassengerBalances || [ ] |
| |
| const foundTravelPassengerBalanceIndex = travelPassengerBalances . FindIndex ( elemento => elemento . passengerAddress === pasajero . dirección ) ; |
| const foundTravelPassengerBalance = travelPassengerBalances [ foundTravelPassengerBalanceIndex ] ; |
|
|
| if ( ! foundTravelPassengerBalance ) { |
| travelPassengerBalances . empujar ( { pasajeroAddress : pasajero . dirección , seatCount : this . asset . seatCount , amountTravel : amountTravel . toString ( ) } ) |
| } más { |
| travelPassengerBalances [ foundTravelPassengerBalanceIndex ] = { ... foundTravelPassengerBalance , seatCount : utils . BigNum ( foundTravelPassengerBalance . SeatCount ) . añadir ( this . asset . seatCount ) . toString ( ) , amountTravel : utils . BigNum ( foundTravelPassengerBalance . AmountTravel ) . añadir ( utilidades nuevas . BigNum ( amountTravel ) ) . toString ( ) } |
| } |
|
|
| const restSeatCount = nuevos utils . BigNum ( |
| viajar . activo . availableSeatCount |
| ) . sub ( este . activo . seatCount ) ; |
|
|
| const updatedTravel = { |
| ... viajar , |
| activo : { |
| ... viajar . activo , |
| travelPassengerBalances : travelPassengerBalances , |
| availableSeatCount : restSeatCount . toString ( ) , |
| } , |
| balance : newTravelBalance . toString ( ) , |
| } ; |
|
|
| tienda . cuenta . conjunto ( viajes . dirección , updatedTravel ) ; |
|
|
| viajes de pasajeros . empujar ( viajar ) |
|
|
| const updatedPassenger = { |
| ... pasajero , |
| activo : { |
| ... pasajero . activo , |
| viajes de pasajeros : viajes de pasajeros , |
| } , |
| balance : newPassengerBalance . toString ( ) , |
| } ; |
|
|
| tienda . cuenta . set ( pasajero . dirección , updatedPassenger ) ; |
|
|
|
|
| conductor . activo . driverTravels [ foundDriverTravelIndex ] = viaje actualizado . activo |
|
|
| const updatedDriver = { |
| ... conductor , |
| activo : { |
| ... conductor . activo , |
| driverTravels : conductor . activo . driverTravels , |
| } |
| } ; |
|
|
| tienda . cuenta . conjunto ( conductor . dirección , updatedDriver ) ; |
|
|
| } |
|
|
| devolver errores ; |
|