1. Installer node.js : https://nodejs.
org/en/download/
2. Pour vérifier si Nodejs est installé, exécutez cette commande sur votre terminal :
node -v
npm -v
3. Créer un dossier qui va contenir votre application ainsi que le fichier log
4. Installer les dépendances en utilisant npm :
npm i ethereumjs-tx
npm i fs
npm i log-timestamp
npm i react
npm i web3-eth
npm i web3
npm i eth-provider
npm i ipfs-http-client
5. Télécharger go-ipfs, l’extraire vers un dossier sur C:\Program Files\ et ajouter le chemin de ce
dossier aux variables d’environnement PATH
6. Installer L’extension Metamask sur Chrome : https://metamask.io/
7. Sélectionner le réseau de test Rinkebey et créer un nouveau compte sinon se connecter au
compte existant
8. Déployez le code Solidity suivant à l'aide de Remix sur le testnet Rinkeby :
https://remix.ethereum.org/
Créer un fichier Contract.sol avec le contenu :
pragma solidity >=0.7.0 <0.9.0;
contract Contract {
string ipfsHash;
function sendHash( string memory x) public {
ipfsHash = x;
}
function getHash() public view returns ( string memory x) {
return ipfsHash;
}
}
Compiler Contact.sol :
Déployer Contract.sol et confirmer à l’aide MetaMask pour associer un compte personnalisé
au contrat sur un environnement Injected Web3
Enregistrer l’adresse et l’Interface binaire d'application (ABI)
{
"inputs": [],
"name": "getHash",
"outputs": [
{
"internalType": "string",
"name": "x",
"type": "string"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "string",
"name": "x",
"type": "string"
}
],
"name": "sendHash",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
}
]
9. Pour chaque utilisateur créer un Wallet Ethereum (adresse publique, adresse privée) sur un
réseau rinkebey testnet : https://mycrypto.com/
10. Pour demander des fonds, coller votre adresse publique Ethereum et sélectionner 0.1 test
ETH sur le site : https://faucets.chain.link/rinkeby
11. Copier le fichier App.js dans un dossier contenant le fichier log.txt sur la machine ou serveur
dédié :
const args = process.argv;
const Tx = require('ethereumjs-tx').Transaction;
const fs = require('fs');
require('log-timestamp');
require('react');
var Eth = require('web3-eth');
var Web3 = require('web3');
const provider = require('eth-provider');
const IPFS = require('ipfs-http-client').create;
const ipfs = IPFS({ host: '127.0.0.1', port: 5001, protocol: 'http',apiPath: '/api/v0'}) ;
var web3 =new Web3(provider('wss://rinkeby.infura.io/ws/v3/5ee6459a6aac429c82eebb39d831f600'));
const private_key = '0x'+args[2];
const filepath = 'log.txt';
const privateKeyBuffer = Buffer.from(args[2], 'hex')
const abi = [
{
"inputs": [],
"name": "getHash",
"outputs": [
{
"internalType": "string",
"name": "x",
"type": "string"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "string",
"name": "x",
"type": "string"
}
],
"name": "sendHash",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
}
];
var addr = "0x006632ff840627BE612792Bb3B8d0F10B4F9a3aB";
var storehash = new web3.eth.Contract(abi, addr);
console.log(`Watching for file changes on ${filepath}`);
const getData = async () => {
let account = await web3.eth.accounts.privateKeyToAccount('0x'+args[2]);
const ethAddress= await storehash.options.address;
const buffer = fs.readFileSync(filepath);
try {
const uploadResult = await ipfs.add(Buffer.from(buffer));
const myData = storehash.methods.sendHash(
uploadResult.path).encodeABI()
.replace('dfb299350000000000000000000000000000000000000000000000'+
'000000000000000020000000000000000000000000000000000000000000000000000000000000002e','');
web3.eth.getTransactionCount(account.address , (err, txCount) => {
const txObject = {
nonce: web3.utils.toHex(txCount),
to: ethAddress,
value: web3.utils.toHex(web3.utils.toWei('0', 'ether')),
gasLimit: web3.utils.toHex(2100000),
gasPrice: web3.utils.toHex(web3.utils.toWei('6', 'gwei')),
data: myData
}
// Sign the transaction
const tx = new Tx(txObject,{'chain':'rinkeby'});
tx.sign(privateKeyBuffer);
const serializedTx = tx.serialize();
const raw = '0x' + serializedTx.toString('hex');
// Broadcast the transaction
const transaction = web3.eth.sendSignedTransaction(raw,
(err, tx) => {
console.log(tx)
});
});
} catch(e) {
console.log(e)
console.log(e.message)
return
}
};
getData();
fs.watchFile(filepath, (curr, prev) => {
console.log(`${filepath} file Changed`);
getData();
});
private_key : L’adresse privée de Wallet Ethereum de l’utilisateur rognée de 0X
filepath : Le chemin de fichier log
addr : Adresse publique de contrat
account : Wallet Ethereum de l’utilisateur
ethAddress : Adresse publique de contrat
buffer : Le fichier log converti en tampon
12. Lancer le démon IPFS
ipfs cat /ipfs/QmQPeNsJPyVWPFDVHb77w8G42Fvo15z4bG2X8D2GhfbSXc/readme
ipfs init
ipfs daemon
13. Pour vérifier que votre noeud ipfs au réseau public, consulter ce lien :
http://127.0.0.1:5001/webui
14. Lancer l’application via ligne de commande dans un autre terminal:
node App.js d931c9f18dc6f111e4a88fe758be4d3ce1c1cd300a2ab3f30032f126dd35e374
d931c9f18dc6f111e4a88fe758be4d3ce1c1cd300a2ab3f30032f126dd35e374 : L’adresse
privée de Wallet Ethereum de l’utilisateur rognée de 0X
Dans notre exemple : 0x15679D106919bd7bb6A761d9d2cd6DDc2c5F2D50 est l’adresse
publique de l’utilisateur
15.
Processus métier de l’exécution de l’application :
L’application est toujours en écoute de toute modification sur le fichier log
Une fois l’application est lancée :
o Le fichier est converti en tampon
o Le fichier mis en mémoire tampon est envoyé vers IPFS
o IPFS renvoie un hachage
o Le hachage d’IPFS est envoyé pour le stockage sur Ethereum de l’adresse de l’utilisateur vers
l’adresse de contrat
A chaque fois que le fichier est modifié par le système ou bien par un utilisateur de la chaine :
o Le fichier est converti en tampon
o Le fichier mis en mémoire tampon est envoyé vers IPFS
o IPFS renvoie un hachage
o Le hachage d’IPFS est envoyé pour le stockage sur Ethereum de l’adresse de l’utilisateur vers
l’adresse de contrat
o Le contrat Ethereum renvoie un numéro de hachage de la transaction
16. Historique des modifications sur le fichier log :
Vous pouvez accéder aux transactions vers l’adresse de contrat via :
https://rinkeby.etherscan.io/address/0x006632ff840627BE612792Bb3B8d0F10B4F9a3aB
avec 0x006632ff840627BE612792Bb3B8d0F10B4F9a3aB est l’adresse de contrat
En cliquant sur chaque transaction, puis sur le lien click to see more et le bouton decode
input data vous récupérer le nom de fichier modifié sur la passerelle IPFS, par exemple :
https://rinkeby.etherscan.io/tx/0x00d9404b67f82f4ad96f860536974601af01dc177953dd995
21235e25b4a00
On obtient le Hachage d’IPFS : QmYrYHtyuD2sXkqLj11qiRkBTcvVUFKi3xxz15Y89eb3pc
Le fichier modifié est obtenu en concaténant le hachage d’IPFS avec l’Url de gateway d’IPFS :
https://gateway.ipfs.io/ipfs/QmYrYHtyuD2sXkqLj11qiRkBTcvVUFKi3xxz15Y89eb3pc