示例工程区块链【免费下载链接】Dapp-LearningDapp learning project for developers at all stages. Becoming and cultivating sovereign individuals. Nonprofit organization.项目地址https://gitcode.com/gh_mirrors/da/Dapp-Learning点击查看免费下载本文以 Dapp-Learning 仓库 basic/01-web3js-deploy 示例为蓝本完整讲解从 Solidity 源码编译、ABI 与字节码提取到通过 Infura 将合约部署到 Sepolia 测试网的全过程。读完本文你将掌握 web3.js v4 的核心接口solc标准 JSON 编译、web3.eth.Contract、deploy().send()以及用.env安全管理私钥的工程实践可直接迁移到其他测试网或主网部署场景。一、示例概览与项目文件构成该示例位于仓库 basic/01-web3js-deploy 目录通过一个最小化的自增计数合约让开发者理解合约编译 → 二进制/ABI 提取 → 交易构造 → 签名广播 → 回执解析的完整部署链路并掌握基本的 web3js 接口用法。目录包含以下关键文件文件作用Incrementer.sol待部署的 Solidity 智能合约Solidity ^0.8.0index.js主脚本读取配置、编译合约、部署上链package.json依赖声明web3、solc、dotenv.env.example环境变量模板说明需要填写的PRIVATE_KEY与INFURA_IDREADME.md英文版教程本项目同时提供后续进阶样例部署完成后可继续学习 02-web3js-transaction合约交互交易与 03-web3js-erc20ERC20 代币操作进一步巩固 web3js 的使用。二、前置准备在运行示例之前需要完成以下四项准备Infura 项目、MetaMask 私钥、Sepolia 测试币以及.env配置文件。2.1 创建 Infura Project 获取 PROJECT ID本示例通过 Infura 将交易发送到区块链网络因此需要先在 Infura 官网注册并创建一个 Project注册/登录 Infura 账户进入 Dashboard点击Create new API Key或类似入口新建一个 Project创建完成后将网络的ENDPOINT 切换为 Sepolia即可在项目详情页拿到对应的PROJECT ID即示例中的INFURA_ID。Infura 作为以太坊节点服务商为开发者提供了免自建节点的 RPC 访问入口其 URL 形如https://sepolia.infura.io/v3/PROJECT_ID下文构造 Web3 实例时会用到。2.2 生成私钥 PRIVATE_KEY本示例中私钥需要自己生成不能硬编码在代码里。最常见的方式是通过浏览器钱包 MetaMask安装 MetaMask 浏览器扩展并创建账户进入设置Settings→ 高级Advanced打开Show test networks选项即可在网络上看到 Sepolia 等测试网络选择Sepolia测试网络记录该账户地址点击账户详情 →导出私钥Export Private Key获得该测试账户的私钥PRIVATE_KEY。安全提示私钥代表账户的完全控制权导出后切勿提交到公共仓库或分享给他人本示例通过环境变量读取而非硬编码正是出于这一安全考虑。2.3 给 Sepolia 测试账户充值上一步创建的测试账户余额为 0无法支付部署所需的 Gas 费。需要通过水龙头faucet领取 Sepolia 测试币推荐使用 Chainlink Faucets 等公开水龙头服务输入账户地址后按提示领取每次约充入 0.1 ETH等待数分钟让交易确认后可在 MetaMask 中查看余额如果 Sepolia 水龙头不可用也可以切换到其他测试网络如 Goerli 等只需相应调整下文 RPC 地址与网络配置。2.4 配置 .env 环境变量为方便代码测试示例通过 .env.example 模板约定环境变量格式PRIVATE_KEYxxxxxxxxxxxxxxxx INFURA_IDyyyyyyyy复制模板为.env并填入实际值后index.js 会自动读取cp .env.example .env然后编辑.env将INFURA_ID与PRIVATE_KEY替换为真实值INFURA_ID即 2.1 节获取的 PROJECT ID。三、合约功能说明Incrementer.sol待部署的 Incrementer.sol 是一个极简的状态合约完整源码如下// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; contract Incrementer { uint256 public number; constructor(uint256 _initialNumber) { number _initialNumber; } function increment(uint256 _value) public { number number _value; } function reset() public { number 0; } function getNumber() public view returns (uint256) { return number; } }各成员的功能如下表成员类型说明numberuint256 public公共状态变量自动生成 getter可被外部读取constructor(uint256 _initialNumber)构造函数部署合约时调用将number初始化为_initialNumberincrement(uint256 _value)增值函数根据传入的_value对number执行number _valuereset()重置函数将number重置为 0getNumber()查询函数view类型返回number当前数值不消耗 Gas需要注意两个与部署直接相关的点构造函数带参数_initialNumber因此部署交易必须通过arguments传入初始值示例中传入[0]pragma solidity ^0.8.0声明了编译器版本下限package.json 中锁定solc: 0.8.0与源码要求匹配——这也是下文编译配置能直接使用solc.compile的原因。四、测试流程从安装依赖到首次部署4.1 安装依赖进入示例目录执行npm install本教程使用的 Node 版本为v20.11.0。示例依赖见 package.json为{ dependencies: { dotenv: ^16.3.1, solc: 0.8.0, web3: ^4.0.3 } }web3v4 系列以太坊 JavaScript API 库用于构造交易、签名与广播solcSolidity 编译器将.sol源码编译为二进制字节码与 ABIdotenv自动读取.env文件并加载为进程环境变量。4.2 配置 .envcp .env.example .env然后编辑.env填入实际值PRIVATE_KEYxxxxxxxxxxxxxxxx INFURA_IDyyyyyyyy4.3 执行部署脚本node index.js部署成功后控制台将打印部署进度、估算 Gas、合约地址与交易哈希具体输出格式见下文运行结果解读一节。五、index.js 代码逻辑逐段剖析index.js 是整个任务的核心包含从读取私钥到部署上链的完整逻辑共分为以下阶段。5.1 读取私钥dotenv 0x 前缀处理出于安全考虑私钥没有硬编码而是通过环境变量获取。启动时dotenv插件自动读取.env配置文件并加载为环境变量之后代码中通过process.env读取私钥及其他环境变量require(dotenv).config(); let privatekey process.env.PRIVATE_KEY; if (privatekey.slice(0, 2) ! 0x) privatekey 0x privatekey;相较于教程文档中的示例index.js 增加了一行前缀兼容处理如果私钥没有0x前缀如直接从 MetaMask 导出的十六进制字符串则自动补上保证后续wallet.add能正确解析。5.2 编译合约solc 标准 JSON 输入我们无法直接使用.sol文件与区块链交互需要先将其编译为二进制文件。第一步是把Incrementer.sol读取为source变量const source fs.readFileSync(Incrementer.sol, utf8);随后以 Solidity 编译器标准的 JSON 输入格式构造编译配置并执行编译const input { language: Solidity, sources: { Incrementer.sol: { content: source, }, }, settings: { outputSelection: { *: { *: [*], }, }, }, }; const compiledCode JSON.parse(solc.compile(JSON.stringify(input)));要点说明sources以文件名 → 源码内容的形式声明编译入口outputSelection的*: { *: [*] }表示输出所有合约的全部编译产物字节码、ABI、元数据等便于后续提取solc.compile接收 JSON 字符串、返回 JSON 字符串因此需要JSON.stringify序列化输入、JSON.parse反序列化输出不同 Solidity 源码版本编译方式可能稍有不同。本示例Incrementer.sol使用 0.8.0 版本且依赖中锁定了solc0.8.0因此上述标准 JSON 方式可直接生效若源码版本变化需同步调整编译器版本与编译参数。5.3 提取字节码与 ABI编译成功的 Solidity 对象中包含很多属性我们需要的是合约对象的二进制bytecode与 ABIconst contractFile compiledCode.contracts[Incrementer.sol][Incrementer]; // Get bin abi const bytecode contractFile.evm.bytecode.object; const abi contractFile.abi;bytecode合约的运行时创建字节码十六进制字符串部署时作为交易data携带abi合约接口的 JSON 描述用于构造web3.eth.Contract实例使代码能读懂合约的函数签名与参数类型。Solidity 对象中的其他属性如sourceMap、元数据等可以通过调试方式查看本示例不做展开。5.4 构造 Web3 实例Web3是 web3js 库的主 API通过它可向区块链网络发送交易并获取处理结果。构造Web3实例主要需要传入一个参数对应的区块链网络 RPC 地址包括 Sepolia 等测试网络或是 mainnet 主网const web3 new Web3(https://sepolia.infura.io/v3/ process.env.INFURA_ID);这里通过 Infura 的 Sepolia 节点发送交易INFURA_ID即 2.1 节获取的 PROJECT ID配置于.env注释提示可以将其中的sepolia替换为其他测试网络Goerli 等前提是账户在该网络上有测试币若部署到主网需将 RPC 地址替换为对应的主网端点并确保账户持有真实 ETH 支付 Gas。5.5 从私钥获取账户地址在区块链上每个用户都有对应的账户地址可通过私钥推导。示例调用web3.eth.accounts相关接口将私钥加载进钱包const accounts web3.eth.accounts.wallet.add(privatekey);教程文档中描述的是web3.eth.accounts.privateKeyToAccount(privatekey)方式——它可以返回包含address的账户对象而当前仓库的 index.js 实际采用wallet.add(privatekey)将私钥直接加入 web3 的本地钱包管理器之后即可通过accounts[0].address取得该账户的地址数组下标对应钱包中账户的添加顺序。两种方式都能实现私钥 → 地址的推导前者偏重单次转换后者偏重交易签名时的统一管理。5.6 构造合约实例在第 5.3 节取得 ABI 后即可用其构造合约实例后续通过该实例发起交易const deployContract new web3.eth.Contract(abi);由于尚未部署此处不传入合约地址仅传入 ABI。合约实例封装了deploy、methods、events等能力是后续一切合约交互的入口。5.7 创建部署交易调用deployContract.deploy创建部署合约的二进制交易。此时交易尚未发送到区块链网络即合约还没有被创建const deployTx deployContract.deploy({ data: 0x bytecode, arguments: [0], // Pass arguments to the contract constructor on deployment(_initialNumber in Incremental.sol) });data部署字节码需要手动拼接0x前缀arguments构造函数的入参数组[0]对应Incrementer构造函数中的_initialNumber 0。若初始值改为其他数字如[100]部署后number即为 100。5.8 估算 Gas 消耗仓库版脚本在发送交易前增加了 Gas 估算步骤并打印预估结果供开发调试const gas await deployTx.estimateGas({ from: accounts, }); console.log(estimated gas:, gas);estimateGas会在本地模拟执行部署返回预估的 Gas 消耗量。将其结果作为send时的gas参数可避免 Gas 不足导致的失败同时防止设置过高造成浪费。5.9 签名并广播部署交易、解析回执使用私钥对部署交易签名后发送到区块链网络并返回交易回执。从回执中可以得到此次部署的合约地址const tx await deployTx.send({ from: accounts[0].address, gas, // gasPrice: 10000000000, });from交易发起账户即 5.5 节钱包中的账户地址gas5.8 节估算出的 Gas 上限被注释掉的gasPrice行表示可手动指定 Gas 单价单位 wei不指定时由节点/钱包按当前网络情况自动填充send会完成签名、广播与回执等待的全过程tx.options.address为部署出的合约地址tx.transactionHash为交易哈希。5.10 部署后验证与统一错误处理仓库版脚本在部署完成后加入了日志与验证逻辑形成完整的最佳实践闭环console.log(Contract deployment started...); console.log(Network:, await web3.eth.net.getNetworkType()); console.log(Account:, accounts[0].address); // ...部署与回执打印... const code await web3.eth.getCode(tx.options.address); if (code 0x) { throw new Error(Contract deployment failed - no code at address); } return tx.options.address;web3.eth.net.getNetworkType()打印当前连接的网络类型如sepoliaweb3.eth.getCode(address)部署后读取目标地址上的合约代码若返回0x说明该地址没有代码即部署失败——这是部署后最直接的链上验证手段脚本开头还检查了INFURA_ID与PRIVATE_KEY环境变量是否存在缺失时抛出明确错误Missing INFURA_ID environment variable/Missing PRIVATE_KEY environment variable避免配置遗漏导致的费解报错整个部署逻辑包在async函数中主流程采用 Promise 链式调用并统一处理退出码Deploy() .then(() process.exit(0)) .catch((error) { console.error(error); process.exit(1); });六、运行结果解读与常见问题6.1 预期输出从 index.js 源码逻辑看部署成功的控制台输出大致为estimated gas: 估算值 Contract deployment started... Network: sepolia Account: 0x你的账户地址 Contract deployed successfully! Contract address: 0x新部署的合约地址 Transaction hash: 0x交易哈希之后可以在 MetaMask 或区块链浏览器输入合约地址中查看该合约并调用getNumber验证初始值确实为 0。6.2 常见问题排查Missing INFURA_ID environment variable/Missing PRIVATE_KEY environment variable.env未创建或未填写对应字段检查是否执行了cp .env.example .env并填入真实值账户余额不足Sepolia 测试币余额为 0 时无法支付 Gas需要先通过水龙头充值见 2.3 节Error: ... insufficient funds类报错Gas 估算与实际费用超出账户余额或from地址填错核对wallet.add后的账户地址编译结果与预期不符确认solc版本与合约pragma声明一致本示例固定为 0.8.0部署后getCode返回0x说明交易虽被接受但部署未成功检查 Gas 上限与构造函数参数必要时通过区块链浏览器查看交易回执的失败原因。七、延伸与参考完整英文版教程见 README.md中文原版见 README-cn.md其中保留了 Infura 创建指引、MetaMask 导出私钥教程、水龙头地址以及 Web3js 官方文档等原始参考链接本示例只涉及部署环节合约部署后如何发起交易调用increment、reset、getNumber可继续学习仓库内 02-web3js-transaction 示例该目录下的 README-cn.md 与 index.js 展示了同样的编译流程在合约交互场景中的应用若希望用 Truffle、Hardhat 等框架替代手工编译部署仓库 04-web3js-truffle 与 07-hardhat 提供了对应的工程化方案。赞分享示例工程区块链【免费下载链接】Dapp-LearningDapp learning project for developers at all stages. Becoming and cultivating sovereign individuals. Nonprofit organization.项目地址https://gitcode.com/gh_mirrors/da/Dapp-Learning点击查看免费下载相关推荐web3.js 智能合约实战从 Solidity 编译到部署与链上交互的完整指南web3.js 智能合约实战从 Solidity 编译到部署与链上交互的完整指南 本篇技术指南基于当前仓库 docs/docs/guides/05_smart区块链Web3FHEVM 合约的 Foundry 部署实战本地 Anvil 与 Sepolia 测试网完整指南FHEVM 合约的 Foundry 部署实战本地 Anvil 与 Sepolia 测试网完整指南 导读 本文基于 fhEVM 开源仓库的 Solidity 指密码学隐私计算区块链后端sway-farm智能合约部署教程从本地测试网到Fuel主网全流程sway farm智能合约部署教程从本地测试网到Fuel主网全流程 你是否正在寻找一份详尽的Fuel网络智能合约部署指南本文将以sway farm项目为例上一篇LINQ to GameObject源码分析InternalUnsafeRefStack实现细节下一篇如何在Obsidian中安装Advanced Slides3分钟快速上手教程创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
阅读完成 · 觉得有帮助?