当前位置: 首页 > news >正文

本地搭建一个简易版本的 Web3 服务

一、环境搭建与工具准备

(一)安装 Node.js 和 npm

Node.js 是一个基于 JavaScript 的运行时环境,npm 是其默认的包管理器。在 Web3 开发中,Node.js 和 npm 是必不可少的工具。

  1. 访问 Node.js 官网 并下载最新的 LTS 版本。

  2. 安装后,通过命令行检查安装是否成功

    node -v
    npm -v
(二)安装 Truffle 和 Ganache

Truffle 是一个开发、测试和部署智能合约的框架,Ganache 是一个本地的以太坊区块链模拟器,用于在本地测试智能合约。

  1. 安装 Truffle

    npm install -g truffle
  2. 安装 Ganache:

    • 可以通过 Ganache 官网 下载桌面版,或通过命令行安装 CLI 版

      npm install -g ganache-cli
(三)安装 MetaMask

MetaMask 是一个以太坊钱包,允许你在浏览器中与 dApp 交互。它充当你的数字钱包,并能连接到本地或远程的以太坊网络。

  1. 访问 MetaMask 官网,下载并安装适用于你浏览器的扩展插件。

  2. 安装后,创建一个新钱包并保存助记词。

二、创建和部署一个简单的智能合约

(一)初始化 Truffle 项目
  1. 创建项目文件夹

    mkdir my-first-web3-project
    cd my-first-web3-project
  2. 初始化 Truffle 项目

    truffle init
(二)编写智能合约

我们将编写一个简单的智能合约,用于存储和检索一条消息。

  1. 创建智能合约文件:

    • contracts 文件夹下创建一个名为 SimpleStorage.sol 的文件,内容如下

      // SPDX-License-Identifier: MIT
      pragma solidity ^0.8.0;contract SimpleStorage {string private message;// 设置消息function setMessage(string memory newMessage) public {message = newMessage;}// 获取消息function getMessage() public view returns (string memory) {return message;}
      }
  2. 编译智能合约:

    • 在项目根目录下运行以下命令来编译合约

      truffle compile
(三)部署智能合约

将智能合约部署到本地的以太坊区块链(Ganache)上。

  1. 配置网络:

    • truffle-config.js 文件中,配置本地的 Ganache 网络

      module.exports = {networks: {development: {host: "127.0.0.1",     // 本地主机地址port: 7545,            // Ganache 默认端口network_id: "*",       // 匹配任何网络 ID},},// 其他配置...
      };
  2. 编写部署脚本:

    • migrations 文件夹中创建一个名为 2_deploy_contracts.js 的文件,内容如下

      const SimpleStorage = artifacts.require("SimpleStorage");module.exports = function(deployer) {deployer.deploy(SimpleStorage);
      };
  3. 启动 Ganache:

    • 打开 Ganache 应用或通过命令行启动

      ganache-cli
  4. 部署智能合约:

    • 在项目根目录下运行以下命令,将合约部署到 Ganache

      truffle migrate
    • 成功部署后,Truffle 会显示智能合约的部署地址。

三、开发一个 dApp 并与智能合约交互

(一)设置前端开发环境

在项目中创建一个 client 文件夹,用于存放前端代码。

  1. 初始化前端项目

    mkdir client
    cd client
    npm init -y
  2. 安装依赖:

    • 安装 Web3.js 库和其他前端依赖

      npm install web3
      npm install lite-server --save-dev
  3. 创建前端文件:

    • client 文件夹中创建一个 index.html 文件,内容如下

      <!DOCTYPE html>
      <html lang="en">
      <head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>My First Web3 dApp</title>
      </head>
      <body><h1>Simple Storage dApp</h1><input type="text" id="messageInput" placeholder="Enter a message" /><button id="setMessageButton">Set Message</button><p>Stored Message: <span id="storedMessage"></span></p><script src="https://cdn.jsdelivr.net/npm/web3/dist/web3.min.js"></script><script src="app.js"></script>
      </body>
      </html>
    • 创建 app.js 文件,用于与智能合约进行交互,内容如下

      const web3 = new Web3(Web3.givenProvider || "http://localhost:7545");const contractAddress = "YOUR_CONTRACT_ADDRESS";  // 部署的合约地址
      const contractABI = [// ABI goes here...
      ];const contract = new web3.eth.Contract(contractABI, contractAddress);document.getElementById('setMessageButton').onclick = async () => {const message = document.getElementById('messageInput').value;const accounts = await web3.eth.getAccounts();await contract.methods.setMessage(message).send({ from: accounts[0] });alert('Message stored successfully');
      };const loadMessage = async () => {const message = await contract.methods.getMessage().call();document.getElementById('storedMessage').innerText = message;
      };loadMessage();
    • 将部署时生成的智能合约 ABI 复制到 app.js 中的 contractABI 变量中,并替换 contractAddress 为实际的合约地址。

(二)运行 dApp
  1. 启动开发服务器:

    • client 文件夹中,运行以下命令启动轻量级开发服务器

      npx lite-server
  2. 在浏览器中访问 dApp:

    • 浏览器将自动打开并显示你的 dApp。你可以在输入框中输入消息并点击“Set Message”按钮,将消息存储到智能合约中。

  3. 与智能合约交互:

    • 输入消息并提交后,dApp 会与智能合约进行交互,将消息存储到区块链中。页面将自动显示存储的消息。

四、C++ 智能合约开发

(一)环境依赖
  • 操作系统:目前仅支持 Linux 和 MAC 系统。

  • 软件依赖

    • GCC:7.3+,C 编译器。

      • Mac:brew install gcc

      • Linux:

        • Ubuntu/Debian:apt-get install gcc

        • CentOS/Redhat:yum install gcc

(二)编写 C++ 智能合约
1. 搭建开发环境
  • 开发者可根据 ChainMaker 提供的 SDK 开发 C++ 合约,C++ 合约的 SDK 工程下载地址为:chainmaker-contract-sdk-cpp。

  • SDK 下载完成后,开发者可根据自身习惯选择熟悉的 C++ 编辑器或 IDE。推荐使用 CLion,CLion 下载和安装请参见官网:JetBrains CLion。

  • 安装完成后,使用 CLion 打开 SDK 工程,通过编辑 main.cc 文件即可编辑自己的 C++ 合约。

2. 代码编写规则
  • 外部方法声明:只有声明为外部方法的函数,才可以(被用户或其他合约)从外部调用,否则,只能用于合约内部调用。外部方法声明规则如下:

    • WASM_EXPORT:必须,暴露声明。

    • void:必须,无返回值。

    • method_name():必须,暴露方法名称

      // 示例
      WASM_EXPORT void init_contract() {
      }
  • 强制声明外部方法:强制声明外部方法为合约必须提供且必须对外暴露的方法,有以下两个:

    • init_contract:创建合约会自动执行该方法,无需指定方法名。

    • upgrade:升级合约会自动执行该方法,无需指定方法名

      // 在创建本合约时,调用一次init方法。ChainMaker不允许用户直接调用该方法。
      WASM_EXPORT void init_contract() {// 安装时的业务逻辑,可为空
      }// 在升级本合约时,对于每一个升级的版本调用一次upgrade方法。ChainMaker不允许用户直接调用该方法。
      WASM_EXPORT void upgrade() {// 升级时的业务逻辑,可为空
      }
  • 获取 SDK 接口上下文:C++ 合约通过 SDK 接口上下文与链进行交互,具体信息可参考文章末尾 C++ SDK API描述

    // 获取 SDK 接口上下文
    Context* ctx = context();
3. 合约示例源码展示
  • 下文代码框内为一个 C++ 编写的存证合约示例,该合约示例实现以下功能:

    1. 存储文件哈希、文件名称和该交易的 ID。

    2. 通过文件哈希查询该条记录。

    #include "chainmaker/chainmaker.h"using namespace chainmaker;class Counter : public Contract {
    public:void init_contract() {}void upgrade() {}// 保存void save() {// 获取 SDK 接口上下文Context* ctx = context();// 定义变量std::string time;std::string file_hash;std::string file_name;std::string tx_id;// 获取参数ctx->arg("time", time);ctx->arg("file_hash", file_hash);ctx->arg("file_name", file_name);ctx->arg("tx_id", tx_id);// 发送合约事件// 向 topic:"topic_vx" 发送 2 个 event 数据,file_hash,file_namectx->emit_event("topic_vx", 2, file_hash.c_str(), file_name.c_str());// 存储数据ctx->put_object("fact" + file_hash, tx_id + " " + time + " " + file_hash + " " + file_name);// 记录日志ctx->log("call save() result:" + tx_id + " " + time + " " + file_hash + " " + file_name);// 返回结果ctx->success(tx_id + " " + time + " " + file_hash + " " + file_name);}// 查询void find_by_file_hash() {// 获取 SDK 接口上下文Context* ctx = context();// 获取参数std::string file_hash;ctx->arg("file_hash", file_hash);// 查询数据std::string value;ctx->get_object("fact" + file_hash, &value);// 记录日志ctx->log("call find_by_file_hash()-" + file_hash + ",result:" + value);// 返回结果ctx->success(value);}
    };// 在创建本合约时,调用一次 init 方法。ChainMaker 不允许用户直接调用该方法。
    WASM_EXPORT void init_contract() {Counter counter;counter.init_contract();
    }// 在升级本合约时,对于每一个升级的版本调用一次 upgrade 方法。ChainMaker 不允许用户直接调用该方法。
    WASM_EXPORT void upgrade() {Counter counter;counter.upgrade();
    }WASM_EXPORT void save() {Counter counter;counter.save();
    }WASM_EXPORT void find_by_file_hash() {Counter counter;counter.find_by_file_hash();
    }
4. 编译合约
  • 搭建编译环境:开发者可使用 ChainMaker 已经打包好的 Docker 镜像编译 C++ 合约代码,ChainMaker 官方已经将容器发布至 docker hub。

    • 拉取镜像

      docker pull chainmakerofficial/chainmaker-cpp-contract:2.1.0
    • 启动镜像:启动镜像前,需要指定本地开发目录,用于映射为 docker 镜像的 home 目录。用于映射的本地开发目录一般为 SDK 工程目录,例如 /data/workspace/chainmaker-contract-sdk-cpp,这样编辑开发的 C++ 合约就可以在 docker 容器内的 home 目录直接编译了

      # 启动并进入容器,$WORK_DIR 即本地工作目录
      docker run -it --name chainmaker-cpp-contract -v $WORK_DIR:/home chainmakerofficial/chainmaker-cpp-contract:2.1.0 bash
      # 或者先后台启动
      docker run -d --name chainmaker-cpp-contract -v $WORK_DIR:/home chainmakerofficial/chainmaker-cpp-contract:2.1.0 bash -c "while true; do echo hello world; sleep 5;done"
      # 再进入容器
      docker exec -it chainmaker-cpp-contract bash
  • 编译示例合约:进入编译容器后,切换到 home 目录,这个 home 目录对应启动编译容器时映射的本地开发目录,进入后执行以下命令

    cd /home/
    make clean
    emmake make
    • 编译完成后,将生成合约的字节码文件 main.wasm

5. SDK 工程框架描述
  • chainmaker-contract-sdk-cpp 工程的结构和文件描述如下:

    • chainmaker

      • basic_iterator.cc:迭代器实现。

      • basic_iterator.h:迭代器头文件声明。

      • chainmaker.h:SDK 主要接口头文件声明,详情见 C++ SDK API描述。

      • context_impl.cc:与链交互接口实现。

      • context_impl.h:与链交互头文件声明。

      • contract.cc:合约基础工具类。

      • error.h:异常处理类。

      • exports.js:编译合约导出函数。

      • safemath.hassert 异常处理。

      • syscall.cc:与链交互入口。

      • syscall.h:与链交互头文件声明。

    • pb

      • contract.pb.cc:与链交互数据协议。

      • contract.pb.h:与链交互数据协议头文件声明。

    • main.cc:用户写合约入口。

    • Makefile:常用 build 命令。

6. 编译说明
  • 在 ChainMaker 提供的 Docker 容器中,已经预装了 Emscripten SDK 和相关的编译工具链,用户无需手动安装。

  • 编译过程中,make clean 命令用于清理之前的编译产物,emmake make 命令用于启动编译流程。

  • 如果在编译过程中遇到错误,可以根据错误信息检查合约代码是否存在语法错误、依赖库是否正确链接等问题。

  • 编译生成的 .wasm 文件是智能合约的可执行文件,需要通过 ChainMaker 的合约管理工具进行部署和发布,才能在区块链网络中运行。

相关文章:

  • 2025年世界职业院校技能大赛实施方案(意见稿)
  • 讯联桌面TV版apk下载-讯联桌面安卓电视版免费下载安装教程
  • 【25软考网工笔记】第三章 局域网(1)CSMA/CD、二进制指数退避算法、最小帧长计算
  • C语言学习记录(16)文件操作7
  • VScode-py环境
  • 用全新发布的ChatGPT-o3搜文献写综述、专业审稿、降重润色,四个步骤轻松搞定全部论文难题!
  • element-plus中,Steps 步骤条组件的使用
  • 从“堆料竞赛”到“体验深耕”,X200 Ultra和X200s打响手机价值升维战
  • 第 7 篇:总结与展望 - 时间序列学习的下一步
  • ubuntu--汉字、中文输入
  • 1-1 什么是数据结构
  • Python 金融量化分析
  • pytest基础-new
  • 泰迪智能科技大模型应用平台功能特色优势
  • 代码随想录第21天: 回溯算法3
  • HAL库(STM32CubeMX)——高级ADC学习、HRTIM(STM32G474RBT6)
  • 策略模式:思考与解读
  • 版本控制利器——SVN简介
  • 浙江大学DeepSeek 公开课 第三季 第1期讲座 - 马东方教授 (附PPT下载) by突破信息差
  • 多线程出bug不知道如何调试?java线程几种常见状态
  • 王毅同印尼外长苏吉约诺会谈
  • 言短意长|把水搅浑的京东和美团
  • 吕治国执掌全国唯一的热带海洋大学,曾从教育部“空降”海南
  • 独家专访|苏童:《好天气》是一部献给中国郊区的作品
  • 观察丨微短剧盛行“拿来主义”,版权保护迫在眉睫
  • 礼来公布口服降糖药积极结果,或年底前提交用于体重管理上市申请