Web3与智能合约交互实战

2023-11-08


写在前面

在最初学习以太坊的时候,很多人都是自己创建以太坊节点后,使用geth与之交互。这种使用命令行交互的方法虽然让很多程序员感到兴奋(黑客帝国的既视感?),但不可能指望普通用户通过命令行使用Dapp。因此,我们需要一种友好的方式(比如一个web页面)来与智能合约交互,于是问题的答案就是web3.js

Web3.js

Web3.js是以太坊官方的Javascript API,可以帮助智能合约开发者使用HTTP或者IPC与本地的或者远程的以太坊节点交互。实际上就是一个库的集合,主要包括下面几个库:

  • web3-eth用来与以太坊区块链和智能合约交互
  • web3-shh用来控制whisper协议与p2p通信以及广播
  • web3-bzz用来与swarm协议交互
  • web3-utils包含了一些Dapp开发有用的功能

Web3与geth通信使用的是 JSON-RPC ,这是一种轻量级的RPC(Remote Procedure Call)协议,整个通信的模型可以抽象为下图。

Web3 Communication Model

搭建测试链

在开发初期,我们并没有必要使用真实的公链,为了开发效率,一般选择在本地搭建测试链。在本文我们选择的Ganache(在此之前使用的是testrpc,Ganache属于它的升级版),一个图形化测试软件(也有命令行版本),可以一键在本地搭建以太坊区块链测试环境,并且将区块链的状态通过图形界面显示出来,Ganache的运行界面如下图所示。

Ganache

从图中可以看到Ganache会默认创建10个账户,监听地址是http://127.0.0.1:7545,可以实时看到Current BlockGas PriceGas Limit等信息。

创建智能合约

目前以太坊官方全力支持的智能合约开发环境是Remix IDE,我们在合约编辑页面编写如下代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
pragma solidity ^0.4.21;

contract InfoContract {
    
   string fName;
   uint age;
   
   function setInfo(string _fName, uint _age) public {
       fName = _fName;
       age = _age;
   }
   
   function getInfo() public constant returns (string, uint) {
       return (fName, age);
   }   
}

代码很简单,就是简单的给nameage变量赋值与读取,接下来切换到 run 的 tab 下,将Environment切换成Web3 Provider,并输入我们的测试链的地址http://127.0.0.1:7545,这里对这三个选项做一简单说明:

  • Javascript VM:简单的Javascript虚拟机环境,纯粹练习智能合约编写的时候可以选择
  • Injected Web3:连接到嵌入到页面的Web3,比如连接到MetaMask
  • Web3 Provider:连接到自定义的节点,如私有的测试网络。

如果连接成功,那么在下面的Account的选项会默认选择 Ganache 创建的第一个账户地址。接下来我们点击Create就会将我们的智能合约部署到我们的测试网中。接下来 Remix 的页面不要关闭,在后面编写前端代码时还要用到合约的地址以及ABI信息。

安装Web3

在这之前,先在终端创建我们的项目:

1
2
> mkdir info
> cd info

接下来使用 node.js 的包管理工具 npm 初始化项目,创建package.json 文件,其中保存了项目需要的相关依赖环境。

1
> npm init

一路按回车直到项目创建完成。最后,运行下面命令安装web.js:

1
> npm install web3

注意: 在实际安装过程中我发现web3在安装完成后并没有 /node_modules/web3/dist/we3.min.js 文件,这个问题在 issue#1041中有体现,但官方好像一直没解决。不过可以在这里下载所需的文件,解压后将dist文件夹的内容拷贝到 /node_modules/web3路径下。

创建 UI

在项目目录下创建index.html,在这里我们将创建基础的 UI,功能包括nameage的输入框,以及一个按钮,这些将通过 jQuery 实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>

    <link rel="stylesheet" type="text/css" href="main.css">

    <script src="./node_modules/web3/dist/web3.min.js"></script>

</head>
<body>
    <div class="container">

        <h1>Info Contract</h1>

        <h2 id="info"></h2>

        <label for="name" class="col-lg-2 control-label">Name</label>
        <input id="name" type="text">

        <label for="name" class="col-lg-2 control-label">Age</label>
        <input id="age" type="text">

        <button id="button">Update Info</button>


    </div>

    <script src="https://code.jquery.com/jquery-3.2.1.slim.min.js"></script>

    <script>
       // Our future code here..
    </script>

</body>
</html>

接下来需要编写main.css文件设定基本的样式:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
body {
    background-color:#F0F0F0;
    padding: 2em;
    font-family: 'Raleway','Source Sans Pro', 'Arial';
}
.container {
    width: 50%;
    margin: 0 auto;
}
label {
    display:block;
    margin-bottom:10px;
}
input {
    padding:10px;
    width: 50%;
    margin-bottom: 1em;
}
button {
    margin: 2em 0;
    padding: 1em 4em;
    display:block;
}

#info {
    padding:1em;
    background-color:#fff;
    margin: 1em 0;
}

##使用Web3与智能合约交互
UI 创建好之后,在<script>标签中间编写web.js的代码与智能合约交互。首先创建web3实例,并与我们的测试环境连接:

1
2
3
4
5
6
7
8
<script>
    if (typeof web3 !== 'undefined') {
        web3 = new Web3(web3.currentProvider);
    } else {
        // set the provider you want from Web3.providers
        web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:7545"));
    }
</script>

这段代码是web3.js Github提供的样例,意思是如果web3已经被定义,那么就可以直接当作我们的 provider 使用。如果没有定义,则我们手动指定 provider。

这里可能会存在疑问:为什么 web3 会被事先定义呢?实际上,如果你使用类似 MetaMask(一个 Chrome 上的插件,迷你型以太坊钱包)这样的软件,provider 就会被自动植入。

在上面代码的基础上,接下来设置默认的以太坊账户:

1
web3.eth.defaultAccount = web3.eth.accounts[0];

在上文中我们使用 Ganache 已经创建了 10 个账户了,这里我们选择第一个账户当作默认账户。

接下来需要让我们的web3知道我们的合约是什么样的,这里需要用到合约的 ABI(Application Binary Interface)ABI可以使我们调用合约的函数,并且从合约中获取数据。

在上文中我们已经在 Remix 中创建了我们的合约,这时重新回到 Remix,在 Compile 的 tab 下我们点击Details 出现的页面中我们可以拷贝合约的ABI,如下图所示。

将其复制到代码中:

1
var infoContract = web3.eth.contract(PASTE ABI HERE!);

接下来转到 run 的tab,拷贝合约的地址,将其复制到下面的代码中:

1
var info = InfoContract.at('PASTE CONTRACT ADDRESS HERE');

完成这些我们就可以调用合约中的函数了,下面我们使用 jQuery 与我们的合约进行交互:

1
2
3
4
5
6
7
8
9
10
11
12
13
info.getInfo(function(error, result){
    if(!error)
        {
            $("#info").html(result[0]+' ('+result[1]+' years old)');
            console.log(result);
        }
    else
        console.error(error);
});

$("#button").click(function() {
    info.setInfo($("#name").val(), $("#age").val());
});

以上的代码就简单地实现了对合约中两个函数的调用,分别读取和显示nameage变量。

到此我们就完成了全部的代码,完整代码可以在 InfoContract 中找到。在浏览器中打开index.html测试效果如下图(输入名字和年龄后刷新)。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Web3与智能合约交互实战 的相关文章

  • 智能合约(一)————智能合约入门

    1 智能合约的基本组成 1 1 程序版本 1 2 合约声明 1 3 状态变量 1 4 合约方法 在这里constant相当于他声明这个局部变量不能更改 但是他并没有实际作用 实际就只是警示作用 2 地址adress address bala
  • 使用web3 部署智能合约

    CentOS 7 环境 web3安装 及 对象的创建 m0 47233175的博客 CSDN博客https blog csdn net m0 47233175 article details 121960931还未安装web3环境 请参照以
  • 元宇宙不是Web3

    个人对元宇宙的定义为 大规模 可互操作的网络 能够实时渲湘3D虚拟世界 借助大量连使性数据 如身份 历史 权利 对象 通信和支付等 可以让无限数量的用户体脸实时同步和持续有效的在场感 现在 你应该能理解我为何会给出这样的定义了 许多人可能会
  • 理解不同加密币的要点(一)—— 共识机制

    一 加密货币分类 一 价值层面 与实体资产绑定的代币 为了因应市场需求而生 与实体资产做挂钩的代币 也就是我们说的稳定币 例如与美元做挂钩的USDT TUSD PAX与USDC等 仰赖网络共识的代币 代币价值仰赖网路上市场共识的代币 基本上
  • Web3与智能合约交互实战

    写在前面 在最初学习以太坊的时候 很多人都是自己创建以太坊节点后 使用geth与之交互 这种使用命令行交互的方法虽然让很多程序员感到兴奋 黑客帝国的既视感 但不可能指望普通用户通过命令行使用Dapp 因此 我们需要一种友好的方式 比如一个w
  • 智能合约(二)————智能合约进阶

    1 保留关键字 abstract after alias apply auto case catch copyof default define final immutable implements in inline let macro
  • Moonbeam路由流动性

    Moonbeam路由流动性 Moonbeam Routed Liquidity MRL 使加密资产流动性能够从其他生态系统 如以太坊 Solana Polygon或Avalanche 进入波卡生态系统 借助MRL 用户可以通过简洁的用户体验
  • 智能合约之短地址攻击

    在了解以太坊智能合约短地址攻击之前 先要简单了解一下以太坊代币ERC 20 TOKEN 的一些基础知识 ERC EthereumRequest for Comment 即以太坊通用征求意见协议 开发者可以通过提交EIP Ethereum I
  • 以太坊开发者工具的最新清单

    以太坊开发者工具的最新终极清单 用于在以太坊上开发应用程序的可用工具 组件 框架和平台的指南 对于任何开发者 无论你是一个睁大眼睛的Web3新手还是一个头发灰白的OG加密无政府主义技术霸主 Github都是你的朋友 特别是ConsenSys
  • 以太坊智能合约开发:Solidity 语言中的数据类型

    本文我们介绍Solidity语言的数据类型 重点是值类型 包括布尔类型 整型 地址类型 字节类型 字符串类型和枚举类型 并且通过两个智能合约例子 用于演示这些数据类型的声明与使用方法 访问 Github 仓库 获取更多资料 基本概念 Sol
  • 如何通过Geth、Node.js和UNIX/PHP访问以太坊节点

    本文旨在说明通过Geth Node js如何访问以太坊节点和UNIX下PHP如何访问以太坊节点 说明如何通过RPC使用此 A 以太坊节点 对于以太坊主网络使用RPC url http 85 214 51 53 8545 对于Ropsten测
  • 014.Solidity入门——01数据类型

    数据类型是编写智能合约的基础 Solidity支持多种数据类型 包括基本数据类型 数组 结构体 枚举 映射等 基本数据类型包括 bool 布尔型 true或false int uint 整型 可以表示正负整数 int 或非负整数 uint
  • 用Go构建一个简单的区块链

    在本教程中 我将尝试通过帮助你在Go中编写简单的区块链来揭开区块链的广义概念 在本教程中 你应该能够 理解区块链术语 创建自己的简单区块链 了解什么是区块以及如何创建块 了解如何维护区块链的完整性 区块链 一种数字分类帐 以较小的集合排列
  • Solidity API

    这是Solidity教程系列文章第8篇介绍Solidity API 它们主要表现为内置的特殊的变量及函数 存在于全局命名空间里 Solidity 系列完整的文章列表请查看分类 Solidity 写在前面 Solidity 是以太坊智能合约编
  • 智能合约漏洞案例,DEI 漏洞复现

    智能合约漏洞案例 DEI 漏洞复现 1 漏洞简介 https twitter com eugenioclrc status 1654576296507088906 2 相关地址或交易 https explorer phalcon xyz t
  • 如何在opensea批量发布NFT(Goerli测试网)

    一 生成NFT图象 hashlips art engine HashLips Art Engine 是一种用于根据提供的图层创建多个不同的艺术作品实例的工具 1 安装 npm install or yarn install 2 使用 在 l
  • 以太坊(ethereum)技术开发相关资料

    收集所有以太坊 ethereum 技术开发相关资料 INTRO 介绍 Started 入门 区块链技术指南 区块链领域比较系统的入门资料 什么是以太坊 什么是智能合约 以太坊智能合约入门概念 理解区块链 区块链关键要点讲解 一 简单易懂地介
  • java和android程序员使用web3j进行区块链以太坊开发详解

    如何使用web3j为Java应用或Android App增加以太坊区块链支持 教程内容即涉及以太坊中的核心概念 例如账户管理包括账户的创建 钱包创建 交易转账 交易与状态 智能合约开发与交互 过滤器和事件等 同时也详细说明如何使用web3j
  • 【0基础】学习solidity开发智能合约-初识solidity

    本篇课程开始 我们来学习一下如何使用solidity开发智能合约 由于博主对于solidity的学习 也是自学的 所以一些不足或有纰漏之处还望指出 大家共同进步 本系列课程会分很多节课讲述 从入门到进阶 实战 在课程最后 我们会通过所学知识
  • 区块链应用开发(智能合约的开发和WeBASE合约IDE的使用)

    文章目录 四 智能合约的开发和WeBASE合约IDE的使用 一 实验概述 二 实验目标 三 实验环境及建议 四 实验步骤 4 1 启动Webase 4 2 智能合约开发 4 2 1 合约功能设计 4 2 2 存证合约开发 4 2 3 工厂合

随机推荐

  • 【实际开发17】- 静态测试

    静态测试技术 不运行被测试程序 对代码通过检查 阅读进行分析 目录 1 静态测试 1 静态测试三步曲 走查 审查 评审 2 编码的标准和规范 3 代码评审 1 代码走查 Walk Through 2 正式会议审查 Inspection 3
  • MySQL 主从复制(实时热备)原理与配置

    MySQL是现在普遍使用的数据库 但是如果宕机了必然会造成数据丢失 为了保证MySQL数据库的可靠性 就要会一些提高可靠性的技术 MySQL主从复制可以做到实时热备数据 本文介绍MySQL主从复制原理及其配置过程 术语 主从复制 maste
  • Android中文API最新中文版

    http www eoeandroid com thread 58597 1 1 html 转载于 https www cnblogs com lost in code archive 2013 03 13 2956940 html
  • import “cv2“ could not be resolved pylance(reportMissingImports)

    openCV系列文章目录 文章目录 openCV系列文章目录 前言 一 错误原因 二 解决方法 1 在vscode Python Select Interpreter 2 依然报错 cv2 error OpenCV 4 7 0 D a op
  • Vagrant Note

    Vagrant Note 1 vagrant 命令 vagrant init hashicorp precise64 需要先删除Vagrantfile文件 vagrant up 启动虚拟机 根据Vagrantfile文件启动 vagrant
  • 【Linux命令详解

    文章标题 简介 一 参数列表 二 使用介绍 1 基本用法 2 显示所有进程 3 显示进程详细信息 4 根据CPU使用率排序 5 查找特定进程 6 显示特定用户的进程 7 显示进程内存占用 8 查看进程树 9 实时监控进程 10 查看特定进程
  • 一行代码实现安慰剂检验

    1 什么是安慰剂检验 随着 因果推断方法 在实证研究中的使用比例不断提升 越来越多的文章也会进行安慰剂检验 其检验基本原理与医学中的安慰剂类似 即使用 假的政策发生时间或实验组 进行分析 以检验能否得到政策效应 如果依然得到了政策效应 则表
  • echarts tooltip显示其他字段

    这是上面的数据 let data nodes 公司名称 name 浏览器有限公司 category 0 0代表公司 1代表自然人股东 value 100 capi 持股数1200 股东列表 name 操作系统集团 category 0 va
  • -----关于Onvif链接成功但运行报错/usr/bin/ld: warning:xxx,needed by xxx,may conflict with libssl.so.1.0.0

    1 错误分析 看图 原因是openssl系统中的版本与mysql或者libevent这些库里面的openssl的版本不一致 导致链接出了问题 解决方法 重新下载与项目中mysql和libevent中openssl一样的版本 即 由于我项目中
  • Python毕业设计 机器学习新闻算法研究与实现

    文章目录 0 前言 简介 本文章博主将介绍 参与及比较算法 先说结论 实现过程 数据爬取 数据预处理 CNN文本分类 其他分类方法更新中 最后 0 前言 这两年开始毕业设计和毕业答辩的要求和难度不断提升 传统的毕设题目缺少创新和亮点 往往达
  • C/C++实现协程及原理(详细完整版)-架构师篇

    一 协程 Coroutine 简介 协程 又称微线程 纤程 英文名Coroutine 协程的概念很早就提出来了 但直到最近几年才在某些语言 如Lua 中得到广泛应用 子程序 或者称为函数 在所有语言中都是层级调用 比如A调用B B在执行过程
  • drools 7.x 加载指定的决策表

    git https github com lccbiluox2 drools test git 1 决策表 位置 Users lcc IdeaProjects drools test src main resources com drool
  • Python异步请求:处理并发任务的结果

    Python异步请求 处理并发任务的结果 处理并发任务的结果 在异步编程中 处理并发任务的结果可能会有所不同 以下是几种常见的处理方式 使用asyncio as completed asyncio as completed 函数返回一个迭代
  • 场景题之最快返回结果

    场景题之最快返回结果 问题描述 输入中文 最快从百度翻译 谷歌翻译 有道翻译获取结果返回 代码实现 思路 采用CompletableFuture实现 多个CompletableFuture可以串行执行 也可以并行执行 其中anyOf 方法只
  • 插入排序(Insertion-Sort)-- 初级排序算法

    1 插入排序 Insertion Sort 插入排序 Insertion Sort 的算法描述是一种简单直观的排序算法 它的工作原理是通过构建有序序列 对于未排序数据 在已排序序列中从后向前扫描 找到相应位置并插入 算法描述 一般来说 插入
  • doGet和doPost、Cookie和Session的原理及区别、Spring框架

    一 doGet和doPost 1 doGet GET调用用于获取服务器信息 并将其做为响应返回给客户端 当经由Web浏览器或通过HTML JSP直接访问Servlet的URL时 一般用GET调用 public class doGet ser
  • 为分类数据添加计数表(R语言实现)

    为分类数据添加计数表 R语言实现 在数据分析和统计学中 我们经常需要对分类变量进行计数 并以表格的形式展示分类的频数 R语言是一种功能强大的数据分析工具 提供了各种函数和包来处理和可视化数据 在本文中 我将向您展示如何使用R语言为划分后的分
  • Android Studio相关知识

    一 如何更新android studio 打开Help gt Check For Updates 或 打开Settings gt 搜索Updates 找到按钮Check Now 二 如何更新android studio的adb 方案一 直接
  • 【SMD & NSMD】

    正确的PCB焊盘设计对于有效地将元件焊接到电路板至关重要 对于裸焊盘组装 有两种常见的焊接方法 阻焊层定义 SMD 与非阻焊层定义 NSMD 每种方法都有自己的特点和优势 SMD Solder Mask Defined Pad 是由阻焊层来
  • Web3与智能合约交互实战

    写在前面 在最初学习以太坊的时候 很多人都是自己创建以太坊节点后 使用geth与之交互 这种使用命令行交互的方法虽然让很多程序员感到兴奋 黑客帝国的既视感 但不可能指望普通用户通过命令行使用Dapp 因此 我们需要一种友好的方式 比如一个w