HTML页面通过Web3JS连接智能合约并调用其中接口

之前我们学习solidity 并用它编写了智能合约 登上区块链 然后也做了基本的测试
但是 其实在web3时代 前端依旧扮演者非常重要的角色
我们现在就来打通web3 从合约到页面的一个管理

首先 我们还是将自己的ganache环境起起来
在这里插入图片描述
然后 在我们之前智能合约的项目终端执行

truffle migrate

将我们的智能合约部署上去
在这里插入图片描述
然后 我们用MetaMask 导入我们ganache环境的第一个用户
在这里插入图片描述
然后 我们拿个html文件 编写代码如下

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src = "./js/web3.min.js"></script>
</head>
<body>
    <script type="module">
      var web3 = new Web3(Web3.givenProvider || "http://localhost:8545");
      let account = await web3.eth.requestAccounts();

    </script>
</body>
</html>

注意 他这里引入的web3.min.js 你们需要本地确实有这个文件
然后 我们运行

他这里就会需要我们选择链接授权用户 我们选择刚刚导入的ganache账号在这里插入图片描述
然后 我们在html中改一下代码 输出一下返回结果
在这里插入图片描述
再次运行 他就会将授权账号返回回来
在这里插入图片描述
那么 这样 就确认我们已经拿到它的一个授权了

但是 目前来讲 只是连到了我们的区块链 能拿到一些信息 但是 我们要拿区块链上的智能合约
web3.eth中有一个Contract函数
他接受两个参数
第一个参数 abi
可能很多人都熟悉API ABI的话差不多
也是基本的接口或者函数 只是 他是一种二进制的 JSON的交互智能合约 会比API更原始一点
然后 第二个参数是address
address的作用比较关键 就是 一个区块链上能部署很多智能合约 那么 它为什么就要连接你的呢?
我们每次部署智能合约都会输出这里一个contract address 就是填在里面 帮他找到你的合约的
在这里插入图片描述
那么 address知道怎么传了
但是 这个ABI估计大家还是有点懵
他其实就是让你传入 要用的这个合约上的接口
我们打开智能合约项目 找到 根目录下 编译生成的 build 下的 contracts下的 StudentStorage.json
在这里插入图片描述
这个文件 上来我们就会看到 ABI
在这里插入图片描述
我们直接点击 左侧 这个小箭头 将这个abi收起来
在这里插入图片描述
然后 将这里面的整个数组 复制 作为Contract的第一个参数 abi
在这里插入图片描述
在这个数组中 我们也能找到之前写的一些函数的信息
在这里插入图片描述
但是这里需要提醒 每次你改了智能合约 从小部署 他都会重新编译 这个json的内容也会改,所以你每次都要改这里的abi参数

可能很多人非常麻烦 之后呢确实我们可以处理到同一个文件夹 然后 我们web程序直接导入这个json 去取他里面的这个数据就好了
但是 目前来讲 我们还是快速建立功能

其实 address 也可以在build 下的 contracts下的 StudentStorage.json中找到
在这里插入图片描述
如图所见 如果编译过多次 那么 就会有很多个在这 直接取最后一个就好了
因为肯定是最新的
在这里插入图片描述
我们 HTML参考代码如下

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src = "./js/web3.min.js"></script>
</head>
<body>
    <script type="module">
      var web3 = new Web3(Web3.givenProvider || "http://localhost:8545");
      let account = await web3.eth.requestAccounts();
      console.log(account);
      const StudentStorage = await new web3.eth.Contract([
            {
            "inputs": [
                {
                "internalType": "uint256",
                "name": "",
                "type": "uint256"
                }
            ],
            "name": "userList",
            "outputs": [
                {
                "internalType": "uint256",
                "name": "id",
                "type": "uint256"
                },
                {
                "internalType": "string",
                "name": "name",
                "type": "string"
                },
                {
                "internalType": "uint256",
                "name": "age",
                "type": "uint256"
                }
            ],
            "stateMutability": "view",
            "type": "function",
            "constant": true
            },
            {
            "inputs": [
                {
                "internalType": "string",
                "name": "name",
                "type": "string"
                },
                {
                "internalType": "uint256",
                "name": "age",
                "type": "uint256"
                }
            ],
            "name": "addtList",
            "outputs": [
                {
                "internalType": "uint256",
                "name": "",
                "type": "uint256"
                }
            ],
            "stateMutability": "nonpayable",
            "type": "function"
            },
            {
            "inputs": [],
            "name": "queryList",
            "outputs": [
                {
                "components": [
                    {
                    "internalType": "uint256",
                    "name": "id",
                    "type": "uint256"
                    },
                    {
                    "internalType": "string",
                    "name": "name",
                    "type": "string"
                    },
                    {
                    "internalType": "uint256",
                    "name": "age",
                    "type": "uint256"
                    }
                ],
                "internalType": "struct StudentStorage.userData[]",
                "name": "",
                "type": "tuple[]"
                }
            ],
            "stateMutability": "view",
            "type": "function",
            "constant": true
            }
        ],
        "0x9d80C47da52731Df5649Ff81f8EAB664c0c80429"
    );
    console.log(StudentStorage);
    </script>
</body>
</html>

当然 Contract的函数 你们不能直接抄 但是什么 我已经说的够清楚了
我们页面控制台输出结果如下
在这里插入图片描述
能输出这个智能合约 我们就成功了

可能有人就会想 那么 既然我们用StudentStorage接了这个智能合约对象
是不是我们直接 StudentStorage.函数 就可以调用了呢?
其实不然
在这里插入图片描述
我们打开这个对象 发现 之前我们写的函数 并不在里面
不用急
我们里面必然会有一个 methods 打开你就会发现 我们的函数就都在里面了
在这里插入图片描述
然后 我们将html代码改写如下

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src = "./js/web3.min.js"></script>
</head>
<body>
    <input type="text" id="myname">
    <input type="number" id="myage">
    <button id="add">添加</button>
    <script type="module">
      var web3 = new Web3(Web3.givenProvider || "http://localhost:8545");
      let account = await web3.eth.requestAccounts();
      console.log(account);
      const StudentStorage = await new web3.eth.Contract([
            {
            "inputs": [
                {
                "internalType": "uint256",
                "name": "",
                "type": "uint256"
                }
            ],
            "name": "userList",
            "outputs": [
                {
                "internalType": "uint256",
                "name": "id",
                "type": "uint256"
                },
                {
                "internalType": "string",
                "name": "name",
                "type": "string"
                },
                {
                "internalType": "uint256",
                "name": "age",
                "type": "uint256"
                }
            ],
            "stateMutability": "view",
            "type": "function",
            "constant": true
            },
            {
            "inputs": [
                {
                "internalType": "string",
                "name": "name",
                "type": "string"
                },
                {
                "internalType": "uint256",
                "name": "age",
                "type": "uint256"
                }
            ],
            "name": "addtList",
            "outputs": [
                {
                "internalType": "uint256",
                "name": "",
                "type": "uint256"
                }
            ],
            "stateMutability": "nonpayable",
            "type": "function"
            },
            {
            "inputs": [],
            "name": "queryList",
            "outputs": [
                {
                "components": [
                    {
                    "internalType": "uint256",
                    "name": "id",
                    "type": "uint256"
                    },
                    {
                    "internalType": "string",
                    "name": "name",
                    "type": "string"
                    },
                    {
                    "internalType": "uint256",
                    "name": "age",
                    "type": "uint256"
                    }
                ],
                "internalType": "struct StudentStorage.userData[]",
                "name": "",
                "type": "tuple[]"
                }
            ],
            "stateMutability": "view",
            "type": "function",
            "constant": true
            }
        ],
        "0x9d80C47da52731Df5649Ff81f8EAB664c0c80429"
    );
    console.log(StudentStorage);

    async function getList() {
        let res = await StudentStorage.methods.queryList().call();
        console.log(res);
    }

    add.onclick = async function() {
        console.log(myname.value,myage.value)

        await StudentStorage.methods.addtList(myname.value,myage.value).send({from: account[0]})
        getList();
    }
    getList();
    </script>
</body>
</html>

这里 我们通过智能合约返回的StudentStorage对象做了一些操作
首先是 getList 这个方法异步调用了我们写在合约上的 queryList 函数 获取数组的长度
然后输出
因为我们之前合约上getList声明了一个 view 这样 表示 我们这个函数是不会改变合约上的内容 也不会改变区块链的
我们只是做个访问 所以 我们声明call 告诉它我们这个方法是不需要消耗燃料的
在这里插入图片描述
那么 我们的添加函数 调用了addtList 传入了 我们的 myname输入框 和 myage输入框的value
至于这个add.onclick 这里是一个基础 我们html中 调用id内容声明事件是直接可以通过id名去绑定的

然后 调用了addtList 将这些函数添加进去 但是 这个函数是改变了我们合约内容的 所以它会消耗燃料
那么 这个谁来承担呢?
我们web3.eth.requestAccounts()获取了MetaMask的账号授权列表 我们直接取0下标 然第一个用户去扣这个燃料

我们尝试输入内容 然后点击添加
在这里插入图片描述
然后 我们在控制台 console 中 输出的myname.value,myage.value在控制台上了 然后MetaMask弹出 让我们确认燃料
我们直接确定
在这里插入图片描述
我们知道 当我们执行成功 他会调用getList
这里 也成功展示出我们添加后的数组
在这里插入图片描述
但是 智能合约添加的操作 很多会要当前用户的信息 例如我们这里添加一个用户 他会需要知道 谁记录的这条信息 就是 在操作是顺带将操作的这个用户的信息传过来

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1. 引入web3.js库 需要先在HTML文件中引入web3.js库,可以从官方网站下载或者使用CDN链接。 ```html <script src="https://cdn.jsdelivr.net/npm/web3@1.3.0/dist/web3.min.js"></script> ``` 2. 连接到以太坊网络 在JavaScript代码中,创建一个`Web3`对象并连接到以太坊网络。 ```js // 连接到以太坊网络 const web3 = new Web3(Web3.givenProvider || "http://localhost:8545"); ``` 其中,`Web3.givenProvider`是指网页已经连接了以太坊网络,可以直接使用当前提供商,否则指定一个本地的以太坊节点地址。 3. 加载智能合约ABI和地址 需要加载智能合约的ABI和地址,以便使用web3.js调用智能合约的方法。 ```js // 加载合约ABI和地址 const contractABI = [...]; const contractAddress = '0x...'; const myContract = new web3.eth.Contract(contractABI, contractAddress); ``` 4. 调用智能合约方法 调用智能合约的方法可以使用`myContract.methods`属性,该属性包含了智能合约的所有方法。以调用`get()`方法为例: ```js // 调用合约get()方法 myContract.methods.get().call((error, result) => { if (!error) { console.log(result); } else { console.error(error); } }); ``` 其中,`call()`方法表示调用智能合约的读取方法(不改变区块链数据),如果是写入方法需要使用`send()`方法。回调函数返回结果或错误信息。 5. 监听智能合约事件 智能合约的事件可以通过`myContract.events`属性进行监听。以监听`Transfer`事件为例: ```js // 监听Transfer事件 const transferEvents = myContract.events.Transfer(); transferEvents.on('data', (event) => { console.log(event.returnValues); }); transferEvents.on('error', console.error); ``` 以上就是使用web3.js调用智能合约的基本流程。涉及到的概念比较复杂,需要深入学习区块链和以太坊相关知识。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值