使用以太坊区块链的方法

128 阅读6分钟

当谈到构建网络应用时,认证可能是一个主要的头痛问题。开发人员需要决定他们想要实现什么样的安全模式,并以正确的方式来实现。

Magic的前身是Fortmatic,它以快速、无缝、单向集成的网络认证而闻名,现在由于其Magic Auth产品,成为区块链生态系统的主要参与者。

在本教程中,我们将演示如何使用Magic与以太坊,讨论设置一个智能合约,并学习如何在以太坊区块链上使用Magic认证用户。

你可以在这篇文章中找到包含我们创建的项目的公共 repo 的链接

让我们开始吧!

什么是区块链?

区块链是近五年来搅动互联网的一个热门词汇,简单来说,它是一个分布式数据库,在计算机网络的各个节点之间共享,以数字格式的电子方式存储信息。区块链已被广泛采用,因为它保证了数据记录的真实性和安全性

区块链最出名的是其在加密货币系统中的关键作用,它维护着安全和去中心化的交易记录。

以太坊是一个流行的、去中心化的开源区块链,具有智能合约功能。在这篇文章中,我们将使用以太坊作为我们互动的区块链。

什么是Magic和Magic Auth?

Magic,最初是Fortmatic,因提供一种无缝的方式将认证整合到你的网络应用程序而广为人知。Magic是一个SDK,可以实现无密码认证,只需几行代码就可以集成到你的应用程序中。

我们在本文中使用的Magic Auth是一个SDK,当它集成到你的应用程序中时,可以使用魔法链接实现无密码的Web2和Web3的上机和认证。在撰写本文时,Magic Auth支持20多个区块链,只需几行代码就可以实现。

什么是web3.js?

web3.js是一个库的集合,允许你使用HTTP、IPC或WebSocket与本地或远程以太坊节点互动。总之,Web3.js是一个库,使我们能够使用JavaScript与以太坊区块链互动。

设置Magic和Web3.js

为了开始在以太坊区块链中使用Magic,我们需要添加一些配置和设置。

首先,创建一个新的目录来放置我们的项目:

 mkdir magic-blockchain && cd magic-blockchain

接下来,初始化一个Node.js项目:

npm init -y

现在,我们将安装web3.js库和Magic SDK:

npm install --save web3 magic-sdk@1.0.1 

编写我们的智能合约

我们需要创建一个智能合约,以后可以部署到Ethereum区块链上。智能合约是存储在区块链上的程序,在满足预定条件时运行。

我们将创建一个基本的 "你好,世界!"智能合约。创建一个名为helloworld.sol 的新文件,代码如下:

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.9;

contract helloworld {

  string public message = "Hello World";

  function update(string memory newMessage) public {
    message = newMessage;
  }

}

编译智能合约

如前所述,我们需要将我们的智能合约部署到Ethereum区块链上。为此,我们需要把它编译成我们可以在区块链上执行的形式。

我们将使用下面的代码,通过获取我们需要的Abi和字节码来帮助我们编译智能合约:

npm i solc@0.8.9

创建一个名为compile.js 的文件,并将下面的代码添加到其中:

const path  = require('path');
const fs = require('fs');
const  solc = require('solc')
const helloWorldPath = path.resolve(__dirname, '' , 'helloworld.sol');
const file = fs.readFileSync(helloWorldPath).toString();
// Input structure for solidity compiler
var input = {
    language: "Solidity",
    sources: {
      "helloworld.sol": {
        content: file,
      },
    },

    settings: {
      outputSelection: {
        "*": {
          "*": ["*"],
        },
      },
    },
  };
  const output = JSON.parse(solc.compile(JSON.stringify(input)));
  if(output.errors) {
      output.errors.forEach(err => {
          console.log(err.formattedMessage);
      });
  } else {
      const bytecode = output.contracts['helloworld.sol'].helloworld.evm.bytecode.object;
      const abi = output.contracts['helloworld.sol'].helloworld.abi;
      console.log(`bytecode: ${bytecode}`);
      console.log(`abi: ${JSON.stringify(abi, null, 2)}`);
  }

接下来,我们编译合约,得到我们需要的abibytecode 。运行node compile.js ,并将输出的bytecodeabi 复制到安全的地方存放。

对于合同的部署,我将使用我已经部署的合同的地址。

用Magic Auth认证用户

如前所述,Magic Auth为所有认证的用户创建了一个以太坊公共地址,然后我们可以用它来认证用户。

让我们创建一个index.html 文件,作为我们将要开发的应用程序的GUI。

为了验证用户进入我们的应用程序,我们将与Magic集成。一旦用户被认证,我们将能够看到Magic为该用户在以太坊区块链上自动创建的账户和公共地址。

在实现这个目标之前,我们首先需要创建一个Magic Auth应用程序,以获得我们在应用程序中需要的密钥。

前往你的Magic仪表板,点击新建应用程序按钮,并输入应用程序的名称。然后,复制PUBLISHABLE API KEY 的内容。

New App On Magic Dashboard

index.html 文件的内容可以实现登录和注销能力,以及与以太坊区块链的初始互动。

<!DOCTYPE html>
<html>
  <head>
    <title>Magic and Ethereum</title>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <link rel="stylesheet" type="text/css" href="styles.css" />
    <script src="https://auth.magic.link/sdk"></script>
    <script src="https://cdn.jsdelivr.net/npm/web3@1.2.11/dist/web3.min.js"></script>
    <script>
      /* Configure Ethereum provider */
      const magic = new Magic("pk_live_your_own_here", {
        network: "rinkeby"
      });
      const web3 = new Web3(magic.rpcProvider);
      const render = async () => {
        const isLoggedIn = await magic.user.isLoggedIn();

        let authHtml = `
          <div class="container">
            <h1>Please sign up or login</h1>
            <form onsubmit="login(event)">
              <input type="email" name="email" required="required" placeholder="Enter your email" />
              <button type="submit">Send</button>
            </form>
          </div>
        `;
        let userHtml = "";
        const target = document.querySelector("#app");
        if (isLoggedIn) {
          const userMetadata = await magic.user.getMetadata();
          const userAddress = (await web3.eth.getAccounts())[0];
          const userBalance = web3.utils.fromWei(
            await web3.eth.getBalance(userAddress)
          );
          authHtml = `
             <div class="container">
              <h1>Current user: ${userMetadata.email}</h1>
              <h1>User Address: ${userAddress}</h1>
              <h1>Current Balance: ${userBalance} ETH</h1>
              <button onclick="logout()">Logout</button>
            </div>
         `;

          userHtml = `
            <div class="container">
              <h1>Ethereum address</h1>
              <div class="info">
                <a href="https://rinkeby.etherscan.io/address/${userAddres                    s}" target="_blank">${userAddress}</a>
              </div>
              <h1>Balance</h1>
              <div class="info">${userBalance} ETH</div>
            </div>
          `;
        }
        target.innerHTML = authHtml + userHtml
      };
      const login = async e => {
        e.preventDefault();
        const email = new FormData(e.target).get("email");
        if (email) {
          await magic.auth.loginWithMagicLink({ email });
          render();
        }
      };

      const logout = async () => {
        await magic.user.logout();
        render();
      };
</script>
  </head>
  <body onload="render()">
    <div id="app">
      <div class="container">Loading...</div>
    </div>
  </body>
</html>

Login Screen Before User Authentication

在用户认证后,我们向他们展示一些细节,以确保一切运作良好:

Login Screen After User Authentication

写入区块链

在用户登录后,他们可以通过Magic与区块链互动。为了测试这一点,我们将通过写到区块链来更新合约中的消息属性。

我们将简单地调用合同中的update 方法并传入新的消息。让我们更新一下index.html 文件:

const contractABI = 'theabi';
let contractAddress = "0x83d2F577E2c4D056864543a62B8638bFA0ebaAD6";

let userHtml = "";
let contractHtml = "";
if (isLoggedIn) {
let contract = new web3.eth.Contract(
            JSON.parse(contractABI),
            contractAddress
          );
          const currentMessage = await contract.methods.message().call();
          contractHtml = `
            <div class="container">
              <h1>Smart Contract</h1>
              <div class="info">
                <a href="https://rinkeby.etherscan.io/address/${contractAddress}" target="_blank">${contractAddress}</a>
              </div>
              <h1>Message</h1>
              <div class="info">${currentMessage}</div>
              <form onsubmit="update(event)">
                <input type="text" name="new-message" class="full-width" required="required" placeholder="New Message" />
                <button id="btn-update-msg" type="submit">Update Message</button>
              </form>
            </div>
          `;
        }

target.innerHTML = authHtml + userHtml + contractHtml

接下来,我们添加update 方法,它只是使用Magic提供的第一个公共Ethereum账户来发送对合同的update 方法的调用:

const update = async e => {
        e.preventDefault();
        const newMessage = new FormData(e.target).get("new-message");
        if (newMessage) {
          const btnUpdateMsg = document.getElementById("btn-update-msg");
          btnUpdateMsg.disabled = true;
          btnUpdateMsg.innerText = "Updating...";
          const fromAddress = (await web3.eth.getAccounts())[0];
          const contract = new web3.eth.Contract(
            JSON.parse(contractABI),
            contractAddress
          );
          const receipt = await contract.methods
            .update(newMessage)
            .send({ from: fromAddress });
          console.log("Completed:", receipt);
          render();
        }
      };

我们现在有了一个新的界面,如下图所示:

Ethereum Interface

一旦用户输入一个新的消息,将启动一个新的交易来更新消息属性。

请记住,我们需要向用于与区块链互动的账户添加测试用的以太币。要做到这一点,请到Rinkeby Ether Faucet去。在账户中获得一些以太坊后,刷新页面,这样变化就会被反映出来。

Updated Ethereum Balance

接下来,用户通过插入一个新的信息来更新信息。这将需要一些时间,因为它需要与Rinkeby网络上运行的以太坊区块链互动。一旦完成,它应该重新渲染页面,新的合同信息将被显示:

Updated Smart Contract Message

通过点击部署的智能合约的链接,前往Rinkeby,以验证我们可以看到部署该合约的交易和更新消息的交易:

Rinkeby Transaction

这个更新从我们用来进行更新的账户中抽取一些气体费用。如果我们检查我们当前的余额,我们会看到所需的乙醚被扣除了:

Ethereum Balance After Update

总结

在这篇文章中,我们了解了Magic以及它如何使用web3.js JavaScript库与以太坊区块链整合。

希望你喜欢这篇文章,并对Magic给区块链开发者创造安全、去中心化的应用程序的机会感到兴奋。谢谢你的阅读!