0

I made a login page with metamask for my Dapp, but now I need to link my login button to the profile page which will have student details like name, phonenumber, certificates (pdf) etc. where these data must be stored in a smart contract (solidity). I've also written the smart contract code. But the problem is I have no idea how to fetch the code in frontend written in typescript. Please give me a idea to code which does the job. I'll link my login.tsx file and solidity code.

Login.tsx:

import './Login.css';
import React, { useState } from 'react';
import Web3 from 'web3';

import { Auth } from '../types';

interface Props {
    onLoggedIn: (auth: Auth) => void;
}

let web3: Web3 | undefined = undefined; // Will hold the web3 instance

export const Login = ({ onLoggedIn }: Props): JSX.Element => {
    const [loading, setLoading] = useState(false); // Loading button state

    const handleAuthenticate = ({
        publicAddress,
        signature,
    }: {
        publicAddress: string;
        signature: string;
    }) =>
        fetch(`${process.env.REACT_APP_BACKEND_URL}/auth`, {
            body: JSON.stringify({ publicAddress, signature }),
            headers: {
                'Content-Type': 'application/json',
            },
            method: 'POST',
        }).then((response) => response.json());

    const handleSignMessage = async ({
        publicAddress,
        nonce,
    }: {
        publicAddress: string;
        nonce: string;
    }) => {
        try {
            const signature = await web3!.eth.personal.sign(
                `I am signing my one-time nonce: ${nonce}`,
                publicAddress,
                '' // MetaMask will ignore the password argument here
            );

            return { publicAddress, signature };
        } catch (err) {
            throw new Error(
                'You need to sign the message to be able to log in.'
            );
        }
    };

    const handleSignup = (publicAddress: string) =>
        fetch(`${process.env.REACT_APP_BACKEND_URL}/users`, {
            body: JSON.stringify({ publicAddress }),
            headers: {
                'Content-Type': 'application/json',
            },
            method: 'POST',
        }).then((response) => response.json());

    const handleClick = async () => {
        // Check if MetaMask is installed
        if (!(window as any).ethereum) {
            window.alert('Please install MetaMask first.');
            return;
        }

        if (!web3) {
            try {
                // Request account access if needed
                await (window as any).ethereum.enable();

                // We don't know window.web3 version, so we use our own instance of Web3
                // with the injected provider given by MetaMask
                web3 = new Web3((window as any).ethereum);
            } catch (error) {
                window.alert('You need to allow MetaMask.');
                return;
            }
        }

        const coinbase = await web3.eth.getCoinbase();
        if (!coinbase) {
            window.alert('Please activate MetaMask first.');
            return;
        }

        const publicAddress = coinbase.toLowerCase();
        setLoading(true);

        // Look if user with current publicAddress is already present on backend
        fetch(
            `${process.env.REACT_APP_BACKEND_URL}/users?publicAddress=${publicAddress}`
        )
            .then((response) => response.json())
            // If yes, retrieve it. If no, create it.
            .then((users) =>
                users.length ? users[0] : handleSignup(publicAddress)
            )
            // Popup MetaMask confirmation modal to sign message
            .then(handleSignMessage)
            // Send signature to backend on the /auth route
            .then(handleAuthenticate)
            // Pass accessToken back to parent component (to save it in localStorage)
            .then(onLoggedIn)
            .catch((err) => {
                window.alert(err);
                setLoading(false);
            });
    };

    return (
        <div>
            <p>Please Signup with MetaMask and Login</p>
            <button className="Login-button Login-mm" onClick={handleClick}>
                {loading ? 'Loading...' : 'Login with MetaMask'}
            </button>
        </div>
    );
};

In the handleClick function I need to link my profile.tsx page,which is connected to solidity code.

Please someone help me to write the code for profile.tsx

Solidity code:

    pragma solidity ^0.6.0;
    
    contract register{
        string name;
        string dept;
        uint phonenumber;
        string addresshome;
        string emailid;
        uint aadhar;
        string ipfshash1;
        string ipfshash2;
        string ipfshash3;
        string ipfshash4;
        constructor() public {
            phonenumber=0;
            aadhar=0;
            
        }
        
        function getname(string memory _name) public pure returns(string memory){
            return _name;
        }
        
        function getdept(string memory _dept) public pure returns(string memory){
            return _dept;
        }
        
        function getphonenumber(uint _phonenumber) public pure returns(uint){
            return _phonenumber;
        }
        
        function getaddresshome(string memory _addresshome) public pure returns(string memory){
            return _addresshome;
        }
function getemailid(string memory _emailid) public pure returns(string memory){
        return _emailid;
    }
    
    function getaadhar(uint _aadhar) public pure returns(uint){
        return _aadhar;
    }
    
    function sendhash1(string memory x) public {
        ipfshash1=x;
    }
     function gethash1() public view returns(string memory x) {
        return ipfshash1;
    }
    
    function sendhash2(string memory x) public {
        ipfshash2=x;
    }
     function gethash2() public view returns(string memory x) {
        return ipfshash2;
    }
    
    function sendhash3(string memory x) public {
        ipfshash3=x;
    }
     function gethash3() public view returns(string memory x) {
        return ipfshash3;
    }
    
    function sendhash4(string memory x) public {
        ipfshash4=x;
    }
     function gethash4() public view returns(string memory x) {
        return ipfshash4;
    }
    
}
5
  • Please be aware that all information on a blockchain is public and readable by anyone. You might want to reconsider if this data is required to be (immutably) on chain. If so, I'd recommend encrypting the data first, so you don't store any personal information in plain text.
    – wslyvh
    Commented Jun 4, 2021 at 7:16
  • Can I use IPFS for this? Can I get the hash of text from IPFS and Store it. IF so how it's done
    – Shru
    Commented Jun 4, 2021 at 12:03
  • Yes you could, but with similar concerns. Make sure to properly encrypt/decrypt data on-chain, IPFS or any other decentralized, public infrastructure. Alternatively, store it in a regular database and store a hash, or reference on-chain.
    – wslyvh
    Commented Jun 8, 2021 at 14:46
  • But my concept is moving decentralized! If I store them in local DB then store only the hash of it in Blockchain, the main motto of the project is changed!
    – Shru
    Commented Jun 12, 2021 at 12:28
  • If you need this kind of information, you should have a look at some of Self-Sovereign Identity (SSI), Decentralized Identifier (DID) and Verifiable Claims (VC) projects that are working on it (e.g. Sovrin, 3Box, IDX). They can help you with some of these privacy concerns, without giving up decentralization. But please, do not store any of that information unencrypted on-chain. You're likely violating privacy/data protection laws as well
    – wslyvh
    Commented Jun 13, 2021 at 13:39

1 Answer 1

0

Are you sure to write this data on your smart contract ? They will be accessible for anyone in the world with no restrictions. And you will pay like 100 000gas for it so it's quite expansive for a user.

Why not store them on a local database, then ask user to sign it with EIP712 so they can log in ?

5
  • I'm not sure about EIP712, I'll have a look at it. Is that also way of storing in decentralized manner?
    – Shru
    Commented Jun 4, 2021 at 5:06
  • I actually need to make a Student Management System, where data is received from the frontend(data like name, dept, address, pdf files) and store them in a smart contract and view it whenever necessary.How EI{712 works in this case.As I'm a beginner in this,I'm not able to understand it!
    – Shru
    Commented Jun 4, 2021 at 5:57
  • In Ethereum network everyone is pseudonymous, begin an ethereum address. I do not advice you to upload personnal data in the blockchain, the cost will be enormous and it will not be compliant with privacy law I think. And everyone can read it. Instead what you can do is : 1) Get personnal info from your student in a local database (like every site in the world) 2) encrypt/secure them 3) add an ethereum address that is linked to this data 4) If you want your student to log in with his ethereum data, they can sign a message for free to log in with EIP712.
    – GrindCode
    Commented Jun 5, 2021 at 9:45
  • Thanks a lot for the info.It would be great if you can share some docs related to it. I'll start my work soon.
    – Shru
    Commented Jun 5, 2021 at 15:37
  • medium.com/metamask/…
    – GrindCode
    Commented Jun 5, 2021 at 16:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.