当前位置: 首页 > 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 的合约管理工具进行部署和发布,才能在区块链网络中运行。

博主争取到官网产品9折优惠券,有需要的可以通过以下链接领取。创作不易,感谢支持。

  • 云小站_专享特惠_云产品推荐-阿里云上云优惠聚集地,新人专享优惠价格,可叠加专享代金券购买价格更低。https://www.aliyun.com/minisite/goods?userCode=fvjl5o6e


http://www.mrgr.cn/news/99272.html

相关文章:

  • 可穿戴设备待机功耗需降至μA级但需保持实时响应(2万字长文深度解析)
  • python测试框架之pytest
  • Cypress EZ-USB CX3 适配输出imx586相机
  • 【全网最全】23种设计模式思维导图详解 | 含React/Vue/Spring实战案例
  • 数据结构--并查集-高效处理连通性问题
  • python——函数
  • 【C++篇】string类的终章:深浅拷贝 + 模拟实现string类的深度解析(附源码)
  • SQL Server基础
  • Python+Word实现周报自动化的完整流程
  • 【22】Strongswan sa ——IKE_SA task_manager_v1
  • 计算机组成与体系结构:内存接口(Memory Interface)
  • (五)机器学习---决策树和随机森林
  • Kubernetes集群超配节点容量
  • el-select+vue-virtual-scroller解决数据量大卡顿问题
  • 深度学习3.5 图像分类数据集
  • Ubuntu下展锐刷机工具spd_dump使用说明
  • Transformer中Post-Norm和Pre-Norm如何选择?
  • 机器学习-08-推荐算法-案例
  • 《相对论中相对性原理的实验验证与分析》
  • 开源脚本分享:用matlab处理ltspice生成的.raw双脉冲数据