Sempre più spesso sentiamo l’esigenza di “notarizzare” o inserire dati in blockchain, questo può sembrare un task parecchio complicato, soprattutto se non siamo ferrati sui vari tipi di blockchain e le varie caratteristiche. In questo articolo affronteremo un caso di notarizzazione all’interno di una blockchain italiana: Scrypta Blockchain.
Se non conosci la blockchain di Scrypta ti invito a farti due passi qui: https://scryptachain.org e qui https://scrypta.wiki così da avere un’idea generica, ma non preoccuparti non serve andare così a fondo con la comprensione di quanto è stato effetivamente fatto dalla fondazione. Possiamo paragonare Scrypta ad una versione un po’ più evoluta di Bitcoin essendo un fork di PIVX. Dal punto di vista della programmazione e dello sviluppatore è importante sapere che è decentralizzata, permissionless e puoi inserire fino a 50KB di dati arbitrari per ogni transazione pagando una flat-fee di 0.001 LYRA.
All’interno di questo tutorial non affronteremo la parte di installazione nodi, sincronizzazione etc, ma utilizzeremo alcuni dei tool che Scrypta Foundation ha realizzato per creare, in pochi passi, un servizio managed di notarizzazione.
La cosa importante da capire, quando si parla di notarizzazione, è chi scrive dati in blockchain, ovvero l’indirizzo che effettivamente andrà a scrivere il dato. Questo dato è molto importante in quanto in alcuni casi i dati inseriti in blockchain possono essere usati come prova quindi la questione dell’identità diventa assolutamente importante.
Nel caso di un servizio managed, ovvero gestito da voi che lo create, l’utente può avere a disposizione la chiave privata dell’indirizzo, ma questa deve inevitabilmente essere condivisa con il servizio stesso, in quanto permetterà all’utente di notarizzare i dati in modo “semplice”.
Questo tutorial parte appunto da questo assunto ovvero che abbiamo bisogno di una chiave (BIP39/39) da cui derivare il resto delle chiavi degli utenti e che queste verranno usate per scrivere effettivamente dei dati.
Scaffolding del progetto
Cloniamo il progetto pubblico ed installiamo tutte le dipendenze, è fondamentale che abbiate NodeJS installato.
git clone https://github.com/turinglabsorg/simple-notarization-service
cd simple-notarization-service
npm install
Il progetto che abbiamo appena clonato è realizzato con NestJS ed espone degli endpoint che ci permetteranno già di realizzare delle notarizzazioni.
La prima cosa che dobbiamo controllare è se il file .env, contenente la nostra chiave principale, esiste ed abbia il parametro.
Per farlo aggiungiamo questo codice all’interno dell’ app.module.ts :
const scrypta = new ScryptaCore
scrypta.staticnodes = true
scrypta.generateMnemonic().then(mnemonic => {
fs.writeFileSync('.env', "MAIN_WALLET=" + mnemonic)
console.log('Mnemonic generated successfully, please restart the process now.')
process.exit(1);
})
Questo permetterà di creare una nuova seed phrase ed agganciarla al file .env, fatto questo saremo già pronti a partire e derivare chiavi private.
Definizione metodi principali
I metodi principali saranno 3: – Derivazione di identità: servirà per ottenere le chiavi private relative ad un determinato hash. – Notarizzazione: servirà per inserire dati in blockchain. – Lettura dati: servirà per leggere i dati precedentemente scritti in blockchain dallo stesso indirizzo.
Implementazione del codice
Inseriamo ora i metodi relativi al controller all’interno di app.controller.ts:
Questi tre metodi richiameranno quelli di app.service.ts:
async getIdentity(hash): Promise<any> {
const scrypta = new ScryptaCore
scrypta.staticnodes = true
if (process.env.MAIN_WALLET !== undefined) {
try {
/**
* Deriving path from requested hash using Core method:
* https://scrypta.wiki/en/#/core/advanced-management#hashtopathhash-hardened--false
*/
let hashtopath = await scrypta.hashtopath(hash)
/**
* Deriving key from mnemonic using Core method:
* https://scrypta.wiki/en/#/core/advanced-management#derivekeyfrommnemonic-menmonic-index
*/
let identity = await scrypta.deriveKeyFromMnemonic(process.env.MAIN_WALLET, hashtopath)
identity.path = hashtopath
return identity;
} catch (e) {
return { message: "Service errored, retry.", error: true }
}
} else {
return { message: "Identity passphrase not found", error: true }
}
}
async returnData(hash): Promise<any> {
const scrypta = new ScryptaCore
scrypta.debug = true
scrypta.staticnodes = true
try {
/**
* Returning identity using previous method
*/
const identity = await this.getIdentity(hash)
/**
* Reading data from IdaNode using post endpoint:
* https://scrypta.wiki/en/#/idanode/pdm#post-read
*/
const data = await scrypta.post('/read', { address: identity.pub })
if (data.data !== undefined) {
return data.data;
} else {
return { message: "IdANode errored, retry.", error: true }
}
} catch (e) {
return { message: "Service errored, retry.", error: true }
}
}
async notarizeData(hash, data): Promise<any> {
const scrypta = new ScryptaCore
scrypta.debug = true
try {
let canWrite = true
/**
* Returning identity using previous method.
*/
const identity = await this.getIdentity(hash)
/**
* Returning address balance using get endpoint:
* https://scrypta.wiki/en/#/idanode/block-explorer#get-balanceaddress
*/
const balance = await scrypta.get('/balance/' + identity.pub)
/**
* Checking if balance is enough, if not funding balance with master key.
*/
if (balance.balance < 0.001) {
/**
* Deriving key with Core method:
* https://scrypta.wiki/en/#/core/advanced-management#derivekeyfrommnemonic-menmonic-index
*/
var master = await scrypta.deriveKeyFromMnemonic(process.env.MAIN_WALLET, 'm/0')
/**
* Funding address using Core method:
* https://scrypta.wiki/en/#/core/addresses-management#fundaddressprivatekey-to-amount
*/
canWrite = await scrypta.fundAddress(master.prv, identity.pub, 0.001)
await scrypta.sleep(1500)
}
if (canWrite) {
/**
* Importing private key because we always need encrypted wallets by default:
* https://scrypta.wiki/en/#/core/addresses-management#importprivatekeykey-password
*/
let temporaryKey = await scrypta.importPrivateKey(identity.prv, '-', false)
/**
* Checking if data can be stringified because we must pass a string into write method.
*/
try {
data = JSON.stringify(data)
} catch (e) {
console.log('Data is a string.')
}
/**
* Finally write the data using Core method:
* https://scrypta.wiki/en/#/core/pdm#writepassword-metadata-collection---refid---protocol---key---uuid--
*/
return await scrypta.write(temporaryKey.walletstore, '-', data)
} else {
return { message: "This address can't write right now, seems master address can't fund it.", master: master.pub, error: true }
}
} catch (e) {
console.log(e)
return { message: "Service errored, retry.", error: true }
}
}
Scrypta Core
Il tool che abbiamo utilizzato è principalmente @scrypta/core (https://www.npmjs.com/package/@scrypta/core) e che permette l’interfacciamento alla rete pubblica di IdANode e, in definitiva, alla blockchain.
Le tre funzionalità principali riguardano:
– derivazione delle chiavi private grazie al metodo deriveKeyFromMnemonic.
– invio di fondi o scrittura grazie ai metodi fundAddress e write.
– interrogazione della rete degli idanode grazie ai metodi post e get.
Mettiamo in moto il tutto
Dopo aver sistemato tutto il codice siamo pronti per far partire il progetto con npm start o npm run start:dev se vogliamo andare in modalità sviluppo.
Al primo avvio l’applicativo vi creerà una nuova seed phrase e vi chiederà di riavviarlo. Diamo nuovamente `npm start` e saremo definitivamente pronti a partire.
Per l’interrogazione del servizio consigliamo l’utilizzo di Postman, di cui abbiamo già creato una collezione importabile qui: https://github.com/turinglabsorg/simple-notarization-service/blob/master/postman.json
Mi raccomando ad inviare il quantitativo di LYRA necessario per far partire le transazioni all’indirizzo master. Per ottenere il vostro indirizzo master basterà provare a fa partire una transazione richiamando l’endpoint notarize.
La prima risposta sarà quindi del tipo: { "message": "This address can't write right now, seems master address can't fund it.", "master": "LKjvThy4EsJYhqui1QHQzKoT7TjEYnqd3U", "error": true}
Il valore corrispondende a master sarà il vostro indirizzo.
Conclusioni
Non vi resta quindi che provare voi stessi a notarizzare delle stringhe o degli oggetti, mi raccomando.. questi rimarranno per sempre all’interno di una blockchain pubblica e permissionless!
Tutti i riferimenti agli endpoint sono presenti all’interno del README.md del repository https://github.com/turinglabsorg/simple-notarization-service.
Questo in effetti non è che un solo passo verso gli applicativi decentralizzati. Dopo aver effettivamente messo le mani nel mondo dell’archiviazione decentralizzata non potrete altro che domandarvi cosa notarizzare in blockchain!
Se aveste bisogno di una mano no esitate ad aggiungere issue su GitHub o contattarmi direttamente via e-mail a info@scrypta.foundation
Scrypta è un'infrastruttura digitale decentralizzata che semplifica e rende più efficienti i processi di gestione, archiviazione e certificazione dei dati che caratterizzano i settori economico, produttivo e sociale. Il sistema flessibile di Scrypta consente di creare architetture complete per progetti illimitati e nuovi casi d'uso
Abbiamo chiesto alla community italiana i principali dubbi sulla dichiarazione delle criptovalute e il pagamento delle imposte. Abbiamo le risposte! C...
Shiba Inu è il token del momento. Il potenziale di guadagno è impressionante. Basta pensare al ROI avuto dal lancio, che ad oggi supera il 2600000%....
Utilizziamo i cookie sul nostro sito Web per offrirti l'esperienza più pertinente ricordando le tue preferenze. Facendo clic su "Accetta", acconsenti all'uso di TUTTI i cookie.
This website uses cookies to improve your experience while you navigate through the website. Out of these, the cookies that are categorized as necessary are stored on your browser as they are essential for the working of basic functionalities of the website. We also use third-party cookies that help us analyze and understand how you use this website. These cookies will be stored in your browser only with your consent. You also have the option to opt-out of these cookies. But opting out of some of these cookies may affect your browsing experience.
Necessary cookies are absolutely essential for the website to function properly. This category only includes cookies that ensures basic functionalities and security features of the website. These cookies do not store any personal information.
Any cookies that may not be particularly necessary for the website to function and is used specifically to collect user personal data via analytics, ads, other embedded contents are termed as non-necessary cookies. It is mandatory to procure user consent prior to running these cookies on your website.