Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • blockchain/tsa2
  • renn_um/tsa2
2 results
Show changes
Commits on Source (15)
...@@ -26,6 +26,8 @@ npm install -g truffle ...@@ -26,6 +26,8 @@ npm install -g truffle
## Instalación de desarrollo ## Instalación de desarrollo
Para desarrollo se utilizó Ganache, una "one click blockchain". Se puede Para desarrollo se utilizó Ganache, una "one click blockchain". Se puede
descargar desde acá: https://truffleframework.com/ganache descargar desde acá: https://truffleframework.com/ganache
Utilizar esta herramienta para probar la TSA2 en localhost. Recordar **configurar** Ganache en modo Automine->False y establecer el parámetro **MINING BLOCK TIME (SECONDS)** en 5 segundos (qué es como está configurada la BFA).
Caso contrario, dará un error el endpoint de la API REST /wait1block
El proyecto está compuesto por tres componentes, los contratos, una api rest El proyecto está compuesto por tres componentes, los contratos, una api rest
y una interfaz gráfica. y una interfaz gráfica.
...@@ -41,6 +43,7 @@ contratos hay que correr dentro del directorio ```contract``` el siguiente coman ...@@ -41,6 +43,7 @@ contratos hay que correr dentro del directorio ```contract``` el siguiente coman
```bash ```bash
truffle migrate truffle migrate
``` ```
Ver la [incidencia #2](https://gitlab.bfa.ar/blockchain/tsa2/issues/2) para solucionar posibles errores al migrar el contrato.
Si se hacen modificaciones sobre el contrato se debe ejecutar lo siguiente: Si se hacen modificaciones sobre el contrato se debe ejecutar lo siguiente:
```bash ```bash
...@@ -80,12 +83,38 @@ Conectado exitosamente: ...@@ -80,12 +83,38 @@ Conectado exitosamente:
> netId: 5777 > netId: 5777
> account: 0x80C6C180d044d476437F9F5bCc824dF134A2c9B2 > account: 0x80C6C180d044d476437F9F5bCc824dF134A2c9B2
``` ```
Si estas probando en la red de TESTNET, deberás configurar el parámetro ```chainId``` que se encuentra en ```api/src/StamperWrapper.js``` con el valor ```99118822```
La api tiene dos endpoints: La api tiene dos endpoints:
* **/stamp**: Es un POST, recibe en el body un objeto json con sólo una clave * **/stamp**: Es un POST, recibe en el body un objeto json con sólo una clave
llamada ```hashes``` que es un array de strings que representan los hashes a llamada ```hashes``` que es un array de strings que representan los hashes a
stampear. stampear.
Devuelve 200 si la operación tuve exito, sino devuelve un error code > 400 Devuelve un objeto json con la siguiente estructura:
```json
{
"status": "ok",
"txHash": [
{
"hash": "0x0bd11b06abfd0d29295bada8aec7dda0c336d23856ac0a21b93d4be60d6388d5",
"block_number": "2540433",
"status": "already_stamped_by_this_TSA"
},
{
"hash": "0xca7ad1fc3c916e0f8956e997dd5f32072b17b381c9ea753295d387792499fcdc",
"block_number": "2540508",
"status": "already_stamped_by_this_TSA"
},
{
"hash": "0x589e0b25fe9e05ff319af24b9dd356a9228be8b1a46fe4bd4cca3567688c617b",
"block_number": "2540508",
"status": "stamped"
}
]
}
```
```status``` es ok si el resultado fue correcto. En ```txHash``` viene la
lista de hashes stampados (con sus metadatos). El campo ```status``` propio de cada elemento, se refiere
a que si el hash ya se encontraba previamente stampado ```already_stamped_by_this_TSA```, si fue stampado correctamente en el envío ```stamped```, o si tuvo algún error durante su proceso ```error```.
* **/verify/:hash**: Es un GET, se le pasa en vez de :hash el hash a verificar. * **/verify/:hash**: Es un GET, se le pasa en vez de :hash el hash a verificar.
Devuelve un objecto json con la siguiente estructura: Devuelve un objecto json con la siguiente estructura:
...@@ -96,7 +125,7 @@ La api tiene dos endpoints: ...@@ -96,7 +125,7 @@ La api tiene dos endpoints:
lista de stampers de ese objecto junto al nro de bloque en el que lo hizo. lista de stampers de ese objecto junto al nro de bloque en el que lo hizo.
### UI ### UI
La primera vez hay que ejecutar lo siguiente dentro del directorio ```ui``` Para el desarrollo de la UI, la primera vez hay que ejecutar lo siguiente dentro del directorio ```ui```
```bash ```bash
npm install npm install
``` ```
...@@ -105,6 +134,8 @@ La aplicación está escrita con Vue.js. Para correr el servicio hay que ejecuta ...@@ -105,6 +134,8 @@ La aplicación está escrita con Vue.js. Para correr el servicio hay que ejecuta
```bash ```bash
npm run serve npm run serve
``` ```
**Ver más detalles en el README dentro del directorio ```ui```**
## Instalación en producción ## Instalación en producción
Para correr en producción se deben compilar la UI y la API. Una vez hecho eso Para correr en producción se deben compilar la UI y la API. Una vez hecho eso
ya se está listo para correr la API y tirar los assets de UI donde se desee. ya se está listo para correr la API y tirar los assets de UI donde se desee.
...@@ -168,29 +199,37 @@ node dist/index.js ...@@ -168,29 +199,37 @@ node dist/index.js
### Deploy de la UI ### Deploy de la UI
Al buildear se crea el archivo ```ui/dist/index.html``` y todo el resto de los recursos Al buildear se crea el archivo ```ui/dist/index.html``` y todo el resto de los recursos
necesarios. Al acceder al index.html sólo se ve el componente de Stampeo. El html se ve así: necesarios. Al acceder al index.html sólo se ve el componente de Stampeo. El html se ve así:
```html ```html
<!DOCTYPE html> <div id="app" apiurl=https://tsa2.buenosaires.gob.ar
<html lang=en> lb_00=" El archivo "
<head> lb_01=" fue enviado con éxito para ser sellado"
<meta charset=utf-8> lb_02="Se ha producido un error al intentar sellar "
<meta http-equiv=X-UA-Compatible content="IE=edge"> lb_03=" se encuentra sellado por: "
<meta name=viewport content="width=device-width,initial-scale=1"> lb_04=" en el bloque "
<link rel=icon href=/favicon.ico> lb_05="No se ha podido verificar el archivo "
<title>ui</title> lb_06="Volver a Sellar o Verificar"
<link href=/css/app.47c5343e.css rel=preload as=style> lb_07="Cargando"
<link href=/js/app.fa8c25b5.js rel=preload as=script> lb_08="Arrastrá archivos aquí<br>ó"
<link href=/js/chunk-vendors.bbeb7c49.js rel=preload as=script> lb_09="Seleccioná archivos <span class='sr-only'>para Sellar o Verificar</span>"
<link href=/css/app.47c5343e.css rel=stylesheet> lb_10="Nombre del archivo: "
</head> lb_11="Hash del archivo: "
<body> lb_12="Sellar"
<noscript><strong>We're sorry but ui doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript> lb_13="Verificar"
<div id=app apiurl=http://localhost:3000></div> lb_14=" Agregar archivos"
<script src=/js/chunk-vendors.bbeb7c49.js></script><script src=/js/app.fa8c25b5.js></script> lb_15=" Copiar"
</body> lb_16="Enlace de verificación"
</html> lb_17="Remover archivo"
lb_18="Seleccionar otros archivos"
lb_19=" Solo se pueden agregar "
lb_20=" archivos por vez">
</div>
``` ```
Para embeberlo en otro contexto hay que copiar los ```<link />``` y el ```<div id=app>``` y ```<script />``` Para embeberlo en otro contexto hay que copiar el div ```<div id=app>```, los estilos ```link``` y el script ```tsa2.js``` del body.
del body.
También se puede cambiar los textos de la app modificando todos los labels (```lb_```) que figuran como atributos de ```<div id=app>``` según corresponda.
Es **importante** notar que la url de la api se configura en el atributo ***apiurl*** del div con id ```app```. Esto tiene que apuntar a la URL donde se eligió ejecutar la API. En este caso apunta a la API de producción hosteada por buenosaires.gob.ar
**Es importante notar que la url de la api se configura en el atributo ***apiurl*** del div con id ```app```. Esto tiene que apuntar a la URL donde se eligió ejecutar la API.** **Ver más detalles en el README dentro del directorio ```ui```**
...@@ -12,77 +12,121 @@ class Stamper { ...@@ -12,77 +12,121 @@ class Stamper {
// (o defaultAccount si no se especifica) // (o defaultAccount si no se especifica)
async stamp(objects, walletAccount) { async stamp(objects, walletAccount) {
console.log(`asked to stamp ${objects}`) console.log(`asked to stamp ${objects}`)
try {
// si walletAccount es undefined trata de usar la account de web3.eth.defaultAccount
let defaultAccount = (walletAccount) ? walletAccount.address : this.web3.eth.defaultAccount
let objectsToStamp = [] // Guardo los hashes que seran enviados a la BFA
let objectsStamped = [] // Guardo los objetos que ya fueron enviados a la BFA
for (let i=0; i < objects.length; i++) {
let blockNo = await this.contract.methods.getBlockNo(objects[i], defaultAccount).call()
if (blockNo == 0){
objectsToStamp.push(objects[i]);
} else {
console.log(`already stamped: ` + objects[i] + ' blockNro: ' + blockNo);
let new_object = {
hash: objects[i],
block_number: blockNo,
status: 'already_stamped_by_this_TSA',
}
objectsStamped.push(new_object);
}
}
// si walletAccount es undefined trata de usar la account de web3.eth.defaultAccount if (objectsToStamp.length == 0) return new Promise( (resolve) => {
let defaultAccount = (walletAccount) ? walletAccount.address : this.web3.eth.defaultAccount console.log(`Los objects enviados ya están stampeados`)
let objectsToStamp = [] resolve(objectsStamped)
})
for (let i=0; i < objects.length; i++) {
let blockNo = await this.contract.methods.getBlockNo(objects[i], defaultAccount).call() console.log(`stamping ` + objectsToStamp.join(', '));
if (blockNo == 0)
{ let txPromise
objectsToStamp.push(objects[i]) let gasLimit = 2000000
}
else if (walletAccount) {
{ let methodPut = this.contract.methods.put(objectsToStamp)
console.log(`already stamped: ` + objects[i] ); let encodedABI = methodPut.encodeABI()
}
} let tx = {
to: this.contractAddress,
if (objectsToStamp.length == 0) return new Promise( (resolve) => { // v: 47525974938 * 35 + 2,
console.log(`Los objects enviados ya están stampeados`) // v: 47525974938,
resolve() // Parece que sin chainId funciona igual - hasta a veces mejor. Pero en la red Testnet, hay que agregar el chainID 99118822
}) chainId: '99118822',
console.log(`stamping ` + objectsToStamp.join(', ') ); gas: gasLimit,
// gasLimit: gasLimit,
let txPromise data: encodedABI,
let gasLimit = 2000000 nonce: this.web3.bfa.txnonce++
}
if (walletAccount) { // tx.v = Buffer.from([47525974938])
let methodPut = this.contract.methods.put(objectsToStamp) // tx.nonce = this.web3.utils.toHex(await this.web3.eth.getTransactionCount(defaultAccount))
let encodedABI = methodPut.encodeABI()
let signedTx = await walletAccount.signTransaction(tx)
let tx = { // console.log(signedTx)
to: this.contractAddress, // txPromise = this.web3.eth.sendSignedTransaction(signedTx)
// v: 47525974938 * 35 + 2, // txPromise = this.web3.eth.sendSignedTransaction('0x' + signedTx.serialize().toString('hex'))
// v: 47525974938, txPromise = await this.web3.eth.sendSignedTransaction(signedTx.rawTransaction) // Apliqué el await para que espere a que finalice la operación
// Parece que sin chainId funciona igual - hasta a veces mejor.
//chainId: '200941592', let tx_result = []; // Objeto que contiene la info de la TX
gas: gasLimit,
// gasLimit: gasLimit, if(txPromise.status == true){
data: encodedABI, tx_result = {
nonce: this.web3.bfa.txnonce++ status: 'stamped',
block_number: txPromise.blockNumber,
hash: txPromise.transactionHash,
};
} else {
tx_result = {
status: 'error',
block_number: '-',
hash: '-',
};
}
for (let i=0; i < objectsToStamp.length; i++) {
// Creo un nuevo objeto con la info de la tx realizada
let new_object = {
hash: objectsToStamp[i],
block_number: tx_result.block_number,
status: tx_result.status,
tx_hash: tx_result.hash,
}
// Agrego el objeto al array de objetos stampados (incluye los que ya fueron stampados, si los hubiese, y los nuevos)
objectsStamped.push(new_object)
}
} else {
txPromise = await this.contract.methods.put(objectsToStamp).send({
from: defaultAccount,
gasLimit: gasLimit
})
} }
// tx.v = Buffer.from([47525974938])
// tx.nonce = this.web3.utils.toHex(await this.web3.eth.getTransactionCount(defaultAccount))
let signedTx = await walletAccount.signTransaction(tx)
// console.log(signedTx)
// txPromise = this.web3.eth.sendSignedTransaction(signedTx)
// txPromise = this.web3.eth.sendSignedTransaction('0x' + signedTx.serialize().toString('hex'))
txPromise = this.web3.eth.sendSignedTransaction(signedTx.rawTransaction)
} else {
txPromise = this.contract.methods.put(objectsToStamp).send({
from: defaultAccount,
gasLimit: gasLimit
})
}
txPromise.then((receipt) => { // Retorno un array con todos los objetos stampados
console.log(`> objects stampeados en bloque: ${receipt.blockNumber}`) return objectsStamped;
console.log(objectsToStamp) } catch (e) {
}).catch((error) => { console.error(e)
console.error(error) throw e
}) }
return new Promise((resolve, reject) => { // Código anterior, comentado a la espera de confirmar el cambio
txPromise.on('transactionHash', (txHash) => { /*txPromise.then((receipt) => {
resolve(txHash) console.log(`> objects stampeados en bloque: ${receipt.blockNumber}`)
}) console.log(`> Hash de la Tx: ${receipt.transactionHash}`)
txPromise.catch((error) => { console.log(`> Hash/es enviado/s:`)
reject(error) console.log(objectsToStamp)
}) }).catch((error) => {
}) console.error(error)
})*/
/*return new Promise((resolve, reject) => {
txPromise.on('transactionHash', (txHash) => {
resolve(objectsStamped)
})
txPromise.catch((error) => {
reject(error)
})
})*/
} }
async wait1block() { async wait1block() {
......
...@@ -150,15 +150,25 @@ app.post('/stamp', async (req, res) => { ...@@ -150,15 +150,25 @@ app.post('/stamp', async (req, res) => {
hashes[i] = hash hashes[i] = hash
} }
// Ahora retorno un JSON con el resultado de la operación
try try
{ {
let txHash = await ss.stamp(hashes, walletAccount) let txHash = await ss.stamp(hashes, walletAccount)
//let fullUrl = req.protocol + '://' + req.get('host') //let fullUrl = req.protocol + '://' + req.get('host')
res.status(200).send('success') console.log(">>>> Stamp OK <<<<");
res.json({
status: 'ok',
txHash
});
} catch (e) { } catch (e) {
console.log(">>>> Stamp ERROR <<<<");
console.error(e) console.error(e)
res.status(500) //res.status(500)
res.send('Error interno. Chequee el log de la aplicación para más detalles') //res.send('Error interno. Chequee el log de la aplicación para más detalles')
res.json({
status: 'error',
error: e,
})
} }
}) })
......
# ui # UI
## Project setup ## Producción
Si no se requieren cambios en la funcionalidad de la UI, se puede utilizar solamente la carpeta ```dist``` que ya se encuentra lista para su uso. No hace falta compilar nada, ni correr npm. Ahí mismo se pueden cambiar los estilos e imágenes de ser necesario.
### Cambios de Estilos
Modificar los estilos dentro del directorio ```dist/static/css/style.css``` y ```dist/static/css/tsa2.css```
También se puede cambiar los textos de la app modificando todos los labels (```lb_```) que figuran como atributos de ```<div id=app>``` según corresponda.
Es **importante** notar que la url de la api se configura en el atributo ***apiurl*** del div con id ```app```. Esto tiene que apuntar a la URL donde se eligió ejecutar la API. En este caso apunta a la API de producción hosteada por buenosaires.gob.ar
```html
<div id="app" apiurl=https://tsa2.buenosaires.gob.ar
lb_00=" El archivo "
lb_01=" fue enviado con éxito para ser sellado"
lb_02="Se ha producido un error al intentar sellar "
lb_03=" se encuentra sellado por: "
lb_04=" en el bloque "
lb_05="No se ha podido verificar el archivo "
lb_06="Volver a Sellar o Verificar"
lb_07="Cargando"
lb_08="Arrastrá archivos aquí<br>ó"
lb_09="Seleccioná archivos <span class='sr-only'>para Sellar o Verificar</span>"
lb_10="Nombre del archivo: "
lb_11="Hash del archivo: "
lb_12="Sellar"
lb_13="Verificar"
lb_14=" Agregar archivos"
lb_15=" Copiar"
lb_16="Enlace de verificación"
lb_17="Remover archivo"
lb_18="Seleccionar otros archivos"
lb_19=" Solo se pueden agregar "
lb_20=" archivos por vez">
</div>
```
Para embeberlo en otro contexto hay que copiar el div ```<div id=app>```, los estilos ```link``` y el script ```tsa2.js``` del body.
## Desarrollo
En caso de necesitar realizar cambios en la UI.
### 1. Setup del proyecto
``` ```
npm install npm install
``` ```
### Compiles and hot-reloads for development ### 2. Compila y tiene un live-reload para desarrollar
``` ```
npm run serve npm run serve
``` ```
### Compiles and minifies for production **Importante:** Siempre tratar de poner en el wording/texto de la app como atributo en el HTML para poder facilitar los cambios de texto/traducciones sin tener la necesidad de compilar.
### 3. Después de realizar los cambios es necesario hacer un build para compilar y minimizar en la carpeta ```dist```.
``` ```
npm run build npm run build
``` ```
### Run your tests ### 4. Corré el test para verificar que no haya errores
``` ```
npm run test npm run test
``` ```
### Lints and fixes files ### 5. Arreglo de lints
``` ```
npm run lint npm run lint
``` ```
### Customize configuration ### Si se requiere más configuración
See [Configuration Reference](https://cli.vuejs.org/config/). Ver [Configuration Reference](https://cli.vuejs.org/config/).
<!DOCTYPE html><html lang=es><head><meta charset=utf-8><meta http-equiv=X-UA-Compatible content="IE=edge"><meta name=viewport content="width=device-width,initial-scale=1"><link rel=icon href=favicon.ico><link href="https://fonts.googleapis.com/css?family=Raleway:400,400i,700,700i" rel=stylesheet><link rel=stylesheet href=static/css/bootstrap.min.css><link rel=stylesheet href=static/css/style.css><link rel=stylesheet href=static/css/tsa2.css><title>Sello de Tiempo - Blockchain Federal Argentina</title><link href=tsa2.js rel=preload as=script></head><body><noscript><b>Lo sentimos pero el sello de tiempo no funciona sin JavaScript. Por favor, habilitalo para continuar.</b></noscript><nav id=navbar role=banner class="navbar navbar-default"><div class=container><div class=navbar-header><a class="logo navbar-btn pull-left" href=/ rel=home><img id=logo src=static/images/logo.svg alt="Blockchain Federal Argentina"></a></div></div></nav><main><div class=container><div class=tsa2><h1>Sello de Tiempo</h1><p>El servicio de Sello de Tiempo de BFA permite demostrar que el contenido de cualquier documento digital existió en un momento y que desde entonces, no ha cambiado. Al sellar un archivo, cualquiera podrá verificar el día y la hora en que su hash fue almacenado en Blockchain Federal Argentina. Tené en cuenta que el documento seleccionado nunca se sube a la red, garantizando su privacidad.</p><p class=font_small><a href=https://bfa.ar/sello>Si tenés un archivo con Recibo Digital (.rd) verificalo aquí</a></p><div id=app apiurl=http://200.108.146.180:3000 lb_00=" El archivo " lb_01=" fue enviado con éxito para ser sellado" lb_02="Se ha producido un error al intentar sellar " lb_03=" se encuentra sellado por: " lb_04=" en el bloque " lb_05="No se ha podido verificar el archivo " lb_06="Volver a Sellar o Verificar" lb_07=Cargando lb_08="Arrastrá archivos aquí<br>ó" lb_09="Seleccioná archivos <span class='sr-only'>para Sellar o Verificar</span>" lb_10="Nombre del archivo: " lb_11="Hash del archivo: " lb_12=Sellar lb_13=Verificar lb_14=" Agregar archivos" lb_15=" Copiar" lb_16="Enlace de verificación" lb_17="Remover archivo" lb_18="Seleccionar otros archivos" lb_19=" Solo se pueden agregar " lb_20=" archivos por vez"></div></div></div><script src=tsa2.js></script></main></body></html> <!DOCTYPE html><html lang=es><head><meta charset=utf-8><meta http-equiv=X-UA-Compatible content="IE=edge"><meta name=viewport content="width=device-width,initial-scale=1"><link rel=icon href=favicon.ico><link href="https://fonts.googleapis.com/css?family=Raleway:400,400i,700,700i" rel=stylesheet><link rel=stylesheet href=static/css/bootstrap.min.css><link rel=stylesheet href=static/css/style.css><link rel=stylesheet href=static/css/tsa2.css><title>Sello de Tiempo 2.0 - Blockchain Federal Argentina</title><link href=tsa2.js rel=preload as=script></head><body><noscript><b>Lo sentimos pero el sello de tiempo no funciona sin JavaScript. Por favor, habilitalo para continuar.</b></noscript><nav id=navbar role=banner class="navbar navbar-default"><div class=container><div class=navbar-header><a class="logo navbar-btn pull-left" href=/ rel=home><img id=logo src=static/images/logo.svg alt="Blockchain Federal Argentina"></a></div></div></nav><main><div class=container><div class=tsa2><h1>Sello de Tiempo 2.0</h1><p>El servicio de Sello de Tiempo de BFA permite demostrar que el contenido de cualquier documento digital existió en un momento y que desde entonces, no ha cambiado. Al sellar un archivo, cualquiera podrá verificar el día y la hora en que su hash fue almacenado en Blockchain Federal Argentina. Tené en cuenta que el documento seleccionado nunca se sube a la red, garantizando su privacidad.</p><p class=font_small><a href=https://bfa.ar/sello>Si tenés un archivo con Recibo Digital (.rd) verificalo aquí</a></p><div id=app apiurl=https://tsa2.buenosaires.gob.ar lb_00=" El archivo " lb_01=" fue enviado con éxito para ser sellado" lb_02="Se ha producido un error al intentar sellar " lb_03=" se encuentra sellado por: " lb_04=" en el bloque " lb_05="No se ha podido verificar el archivo " lb_06="Volver a Sellar o Verificar" lb_07=Cargando lb_08="Arrastrá archivos aquí<br>ó" lb_09="Seleccioná archivos <span class='sr-only'>para Sellar o Verificar</span>" lb_10="Nombre del archivo: " lb_11="Hash del archivo: " lb_12=Sellar lb_13=Verificar lb_14=" Agregar archivos" lb_15=" Copiar" lb_16="Enlace de verificación" lb_17="Remover archivo" lb_18="Seleccionar otros archivos" lb_19=" Solo se pueden agregar " lb_20=" archivos por vez"></div></div></div><script src=tsa2.js></script></main></body></html>
\ No newline at end of file \ No newline at end of file
...@@ -40,12 +40,15 @@ ...@@ -40,12 +40,15 @@
} }
.tsa2 .btn-default{ .tsa2 .btn-default{
padding: 6px 12px; padding: 5px 12px;
color: #333; color: #333;
background-color: #fff; background-color: #fff;
border-color: #ccc; border-color: #ccc;
border-radius: 4px; border-radius: 4px;
border-width: 1px; border-width: 1px;
font-weight: normal;
margin-top: 0;
} }
.tsa2 .btn-default:hover { .tsa2 .btn-default:hover {
......
source diff could not be displayed: it is too large. Options to address this: view the blob.
This diff is collapsed.
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
<link rel="stylesheet" href="<%= BASE_URL %>static/css/bootstrap.min.css"> <link rel="stylesheet" href="<%= BASE_URL %>static/css/bootstrap.min.css">
<link rel="stylesheet" href="<%= BASE_URL %>static/css/style.css"> <link rel="stylesheet" href="<%= BASE_URL %>static/css/style.css">
<link rel="stylesheet" href="<%= BASE_URL %>static/css/tsa2.css"> <link rel="stylesheet" href="<%= BASE_URL %>static/css/tsa2.css">
<title>Sello de Tiempo - Blockchain Federal Argentina</title> <title>Sello de Tiempo 2.0 - Blockchain Federal Argentina</title>
</head> </head>
<body> <body>
...@@ -28,11 +28,11 @@ ...@@ -28,11 +28,11 @@
<main> <main>
<div class="container"> <div class="container">
<div class="tsa2"> <div class="tsa2">
<h1>Sello de Tiempo</h1> <h1>Sello de Tiempo 2.0</h1>
<p>El servicio de Sello de Tiempo de BFA permite demostrar que el contenido de cualquier documento digital existió en un momento y que desde entonces, no ha cambiado. Al sellar un archivo, cualquiera podrá verificar el día y la hora en que su hash fue almacenado en Blockchain Federal Argentina. Tené en cuenta que el documento seleccionado nunca se sube a la red, garantizando su privacidad.</p> <p>El servicio de Sello de Tiempo de BFA permite demostrar que el contenido de cualquier documento digital existió en un momento y que desde entonces, no ha cambiado. Al sellar un archivo, cualquiera podrá verificar el día y la hora en que su hash fue almacenado en Blockchain Federal Argentina. Tené en cuenta que el documento seleccionado nunca se sube a la red, garantizando su privacidad.</p>
<p class="font_small"><a href="https://bfa.ar/sello">Si tenés un archivo con Recibo Digital (.rd) verificalo aquí</a></p> <p class="font_small"><a href="https://bfa.ar/sello">Si tenés un archivo con Recibo Digital (.rd) verificalo aquí</a></p>
<div id="app" <div id="app"
apiurl="http://200.108.146.180:3000" apiurl="https://tsa2.buenosaires.gob.ar"
lb_00=" El archivo " lb_00=" El archivo "
lb_01=" fue enviado con éxito para ser sellado" lb_01=" fue enviado con éxito para ser sellado"
lb_02="Se ha producido un error al intentar sellar " lb_02="Se ha producido un error al intentar sellar "
...@@ -54,6 +54,8 @@ ...@@ -54,6 +54,8 @@
lb_18="Seleccionar otros archivos" lb_18="Seleccionar otros archivos"
lb_19=" Solo se pueden agregar " lb_19=" Solo se pueden agregar "
lb_20=" archivos por vez" lb_20=" archivos por vez"
lb_21=" ya se encuentra sellado en la BFA"
lb_22=" Hash de la TX:"
></div> ></div>
</div> </div>
......
...@@ -40,12 +40,15 @@ ...@@ -40,12 +40,15 @@
} }
.tsa2 .btn-default{ .tsa2 .btn-default{
padding: 6px 12px; padding: 5px 12px;
color: #333; color: #333;
background-color: #fff; background-color: #fff;
border-color: #ccc; border-color: #ccc;
border-radius: 4px; border-radius: 4px;
border-width: 1px; border-width: 1px;
font-weight: normal;
margin-top: 0;
} }
.tsa2 .btn-default:hover { .tsa2 .btn-default:hover {
......
...@@ -4,8 +4,34 @@ ...@@ -4,8 +4,34 @@
<p><span class="glyphicon glyphicon-remove" aria-hidden="true"></span> <span v-html="this.lb_19"></span> <span v-html="this.limite"></span><span v-html="this.lb_20"></span></p> <p><span class="glyphicon glyphicon-remove" aria-hidden="true"></span> <span v-html="this.lb_19"></span> <span v-html="this.limite"></span><span v-html="this.lb_20"></span></p>
</div> </div>
<div> <div>
<div v-if="state == 'stamped'" class="dropAreasuccess-stamp alert alert-success" role="alert"> <div v-if="state=='stamped'">
<p><span class="glyphicon glyphicon-ok" aria-hidden="true"></span> <span v-html="this.lb_00"></span> <b>{{archivo}}</b> <span v-html="this.lb_01"></span></p> <div v-for="(value, index) in allFiles" :key="index">
<div v-if="value.status == 'already_stamped_by_this_TSA'" class="success-verify alert alert-success" role="alert">
<p><span class="glyphicon glyphicon-ok" aria-hidden="true"></span> <span v-html="lb_00"></span> <b>{{value.fileName}}</b><span v-html="lb_21"></span> <span v-html="lb_04"></span> <b>{{ value.block }}</b></p>
<div class="copiar">
<label class="font_small" v-html="lb_16" :for="'id_'+index"></label>
<div class="input-group">
<input class="form-control input-sm" type="textfield" readonly :value="getHashURL(index)" :id="'id_'+index" >
<span class="input-group-btn">
<button class="btn btn-default btn-sm" v-on:click="copiarURL(index)"><span class="glyphicon glyphicon-copy text-success" aria-hidden="true"></span> <span v-html="lb_15"></span></button>
</span>
</div>
</div>
</div>
<div v-if="value.status == 'stamped'" class="success-verify alert alert-success" role="alert">
<p><span class="glyphicon glyphicon-ok" aria-hidden="true"></span> <span v-html="lb_00"></span> <b>{{value.fileName}}</b> <span v-html="lb_01"></span></p>
<p><span v-html="lb_22"> <b>{{value.tx_hash}}</b></span></p>
<div class="copiar">
<label class="font_small" v-html="lb_16" :for="'id_'+index"></label>
<div class="input-group">
<input class="form-control input-sm" type="textfield" readonly :value="getHashURL(index)" :id="'id_'+index" >
<span class="input-group-btn">
<button class="btn btn-default btn-sm" v-on:click="copiarURL(index)"><span class="glyphicon glyphicon-copy text-success" aria-hidden="true"></span> <span v-html="lb_15"></span></button>
</span>
</div>
</div>
</div>
</div>
</div> </div>
<div v-if="state=='failed-stamp'" class="fail-stamp alert alert-danger" role="alert"> <div v-if="state=='failed-stamp'" class="fail-stamp alert alert-danger" role="alert">
<p><span class="glyphicon glyphicon-remove" aria-hidden="true"></span> <span v-html="this.lb_02"></span> <b>{{archivo}}</b> <p><span class="glyphicon glyphicon-remove" aria-hidden="true"></span> <span v-html="this.lb_02"></span> <b>{{archivo}}</b>
...@@ -61,6 +87,7 @@ ...@@ -61,6 +87,7 @@
</div> </div>
</div> </div>
<DropFile <DropFile
ref="dropFile"
:apiurl="apiurl" :apiurl="apiurl"
:lb_07="lb_07" :lb_07="lb_07"
:lb_08="lb_08" :lb_08="lb_08"
...@@ -74,6 +101,8 @@ ...@@ -74,6 +101,8 @@
:lb_18="lb_18" :lb_18="lb_18"
:lb_19="lb_19" :lb_19="lb_19"
:lb_20="lb_20" :lb_20="lb_20"
:lb_21="lb_21"
:lb_22="lb_22"
v-if="state == 'visible-drop'" v-if="state == 'visible-drop'"
v-on:stamp="onStamp" v-on:stamp="onStamp"
v-on:failed-stamp="onFailedStamp()" v-on:failed-stamp="onFailedStamp()"
...@@ -112,7 +141,9 @@ ...@@ -112,7 +141,9 @@
'lb_17', 'lb_17',
'lb_18', 'lb_18',
'lb_19', 'lb_19',
'lb_20' 'lb_20',
'lb_21',
'lb_22',
], ],
computed: { computed: {
hash () { hash () {
...@@ -145,8 +176,8 @@ ...@@ -145,8 +176,8 @@
onFailedVerify() { onFailedVerify() {
this.state = 'failed-verification' this.state = 'failed-verification'
}, },
onStamp(hashStamped) { onStamp(allFiles) {
this.hashStamped = hashStamped; this.allFiles = allFiles
this.state = 'stamped' this.state = 'stamped'
}, },
onFailedStamp() { onFailedStamp() {
...@@ -154,7 +185,7 @@ ...@@ -154,7 +185,7 @@
}, },
onFilename (value) { onFilename (value) {
this.archivo = value this.archivo = value
}, },
onLimitSurpassed (value) { onLimitSurpassed (value) {
this.limite = value this.limite = value
}, },
......
...@@ -87,7 +87,7 @@ export default { ...@@ -87,7 +87,7 @@ export default {
'lb_17', 'lb_17',
'lb_18', 'lb_18',
'lb_19', 'lb_19',
'lb_20' 'lb_20',
], ],
data: function() { data: function() {
return { return {
...@@ -221,19 +221,51 @@ export default { ...@@ -221,19 +221,51 @@ export default {
hashes: self.allHashes hashes: self.allHashes
}).then(function(response) }).then(function(response)
{ {
if(response.data.status == 'ok'){
// Itero por los archivos que fueron enviados a sellar
for (var i = 0; i < self.uploadedFiles.length; i++) {
//Itero por los archivos que me retorno el metodo stamp de la api rest
for (var k = 0; k < response.data.txHash.length; k++) {
var hash = self.uploadedFiles[i].hash;
if ( ! hash.startsWith('0x') ) {
hash = '0x' + hash;
}
//Agrego nueva info para ser mostrada por pantalla, en cas
if(hash == response.data.txHash[k].hash){
self.uploadedFiles[i].block = response.data.txHash[k].block_number;
self.uploadedFiles[i].status = response.data.txHash[k].status;
if(response.data.txHash[k].status == 'stamped'){
self.uploadedFiles[i].tx_hash = response.data.txHash[k].tx_hash;
}
}
}
}
console.log(self.uploadedFiles);
self.$emit('stamp', self.uploadedFiles);
} else {
self.$emit('failed-stamp')
}
// console.log(response) // console.log(response)
axios.get(`${self.apiurl}/wait1block`).then(function(response){ // axios.get(`${self.apiurl}/wait1block`).then(function(response){
axios.get(`${self.apiurl}/wait1block`).then(() => { // axios.get(`${self.apiurl}/wait1block`).then(() => {
//console.log('Verificar:'+ self.allHashes) // //console.log('Verificar:'+ self.allHashes)
//self.$emit('stamp', self.uploadedFiles[0].hash); // self.verify(false);
self.verify(); // }).catch((e) => {
}) // // console.error(e)
}).catch((e) => { // self.$emit('stamp', self.uploadedFiles);
console.error(e) // })
self.$emit('stamp') // }).catch((e) => {
}) // // console.error(e)
} // self.$emit('stamp', self.uploadedFiles);
// })
}
).catch((e) => { ).catch((e) => {
console.error(e) console.error(e)
......
...@@ -44,6 +44,8 @@ new Vue({ ...@@ -44,6 +44,8 @@ new Vue({
lb_18: this.$el.attributes.lb_18.value, lb_18: this.$el.attributes.lb_18.value,
lb_19: this.$el.attributes.lb_19.value, lb_19: this.$el.attributes.lb_19.value,
lb_20: this.$el.attributes.lb_20.value, lb_20: this.$el.attributes.lb_20.value,
lb_21: this.$el.attributes.lb_21.value,
lb_22: this.$el.attributes.lb_22.value,
} }
}) })
} }
......