以太坊,作为全球领先的智能合约平台,不仅仅是一种加密货币,更是一个去中心化的、可编程的区块链生态系统,它为开发者提供了构建去中心化应用(Dapps)的强大能力,本文将带你踏上一段以太坊编程入门实战的旅程,从基础概念到实际操作,一步步引导你构建你的第一个简单DApp,让你亲身感受区块链开发的魅力。
与比特币主要作为点对点的电子现金系统不同,以太坊的核心是“智能合约”,智能合约是运行在以太坊区块链上的自动执行程序,它们按照预设的规则和条件进行操作,无需第三方干预,这使得开发者可以构建各种复杂的应用,如去中心化金融(DeFi)、非同质化代币(NFT)、去中心化自治组织(DAO)等。
以太坊虚拟机(EVM)是智能合约的运行环境,它确保了所有合约在以太坊网络上的执行是确定性和安全的,Solidity是以太坊最主流的智能合约编程语言,其语法类似于JavaScript,易于上手。
在开始编写智能合约之前,我们需要搭建好开发环境。

npm install -g truffle
我们将构建一个简单的投票DApp,包含一个智能合约,用于管理候选人和投票。
voting-dapp,并进入该文件夹。truffle init
这会创建几个标准目录:
contracts/:存放智能合约代码。migrations/:存放部署脚本。test/:存放测试文件。truffle-config.js:Truffle配置文件。在contracts目录下创建一个新的文件Voting.sol,并编写以下代码:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract Voting {
// 候选人结构体
struct Candidate {
uint id;
string name;
uint voteCount;
}
// 存储候选人
Candidate[] public candidates;
// 存储投票者地址,防止重复投票
mapping(address => bool) public voters;
// 构造函数,初始化候选人
constructor() {
addCandidate("Candidate 1");
addCandidate("Candidate 2");
addCandidate("Candidate 3");
}
// 添加候选人函数(仅部署者可调用)
function addCandidate(string memory _name) private {
candidates.push(Candidate(candidates.length, _name, 0));
}
// 投票函数
function vote(uint _candidateId) public {
// 确保投票者尚未投票
require(!voters[msg.sender], "Already voted.");
// 确保候选人ID有效
require(_candidateId < candidates.length, "Invalid candidate ID.");
// 记录投票
voters[msg.sender] = true;
candidates[_candidateId].voteCount ;
}
// 获取候选人数量
function getCandidatesCount() public view returns (uint) {
return candidates.length;
}
// 获取候选人信息
function getCandidate(uint _id) public view returns (uint, string memory, uint) {
return (candidates[_id].id, candidates[_id].name, candidates[_id].voteCount);
}
}
代码解析:

SPDX-License-Identifier 和 pragma solidity 是Solidity合约的标准开头。Candidate结构体用于存储候选人的ID、姓名和票数。candidates数组存储所有候选人。voters映射记录哪些地址已经投过票,防止重复投票。constructor是合约的构造函数,在部署时执行,用于初始化候选人。vote函数是核心投票逻辑,它会检查投票资格并更新票数。getCandidatesCount和getCandidate是视图函数,用于查询候选人信息。在项目根目录的终端中运行:
truffle compile
如果成功,build/contracts目录下会生成Voting.json文件,这是编译后的合约字节码和ABI(应用程序二进制接口)。
在migrations目录下创建一个新的文件2_deploy_voting.js(数字2表示部署顺序):
const Voting = artifacts.require("Voting");
module.exports = function(deployer) {
deployer.deploy(Voting);
};
启动Ganache(确保它是运行状态,并记下一个账户地址,例如第一个账户)。

打开truffle-config.js文件,配置网络连接到Ganache,默认情况下,Truffle会连接到本地开发网络,端口通常是7545,如果Ganache配置不同,请相应修改:
module.exports = {
networks: {
development: {
host: "127.0.0.1", // Localhost (default: none)
port: 7545, // Standard Ethereum port (default: none)
network_id: "*", // Any network (default: none)
},
},
compilers: {
solc: {
version: "0.8.0", // A version string or the exact version of your compiler
settings: { // See the solidity docs for advice about optimization and evmVersion
optimizer: {
enabled: true,
runs: 200
}
}
}
}
}; 部署合约到Ganache:
truffle migrate --network development
如果成功,你会看到合约部署的详细信息,包括合约地址。
为了简单起见,我们使用一个基本的HTML文件和一些JavaScript来与部署的合约交互,在实际项目中,你会使用更复杂的前端框架(如React, Vue)。
在项目根目录下创建src文件夹,并在其中创建index.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Voting DApp</title>
<script src="https://cdn.ethers.io/lib/ethers-5.2.umd.min.js" type="application/javascript"></script>
</head>
<body>
<h1>以太坊投票DApp</h1>
<div id="candidates"></div>
<div id="votingSection">
<h3>投票</h3>
<label for="candidateSelect">选择候选人:</label>
<select id="candidateSelect"></select>
<button id="voteButton">投票</button>
</div>
<div id="message"></div>
<script src="app.js"></script>
</body>
</html> 在src文件夹下创建app.js:
let contract;
let accounts;
const contractAddress = "YOUR_DEPLOYED_CONTRACT_ADDRESS_HERE"; // 替换为你的合约地址
const contractABI = [/* 这里填入Voting.json中的ABI数组 */]; // 为了简便,这里直接从Voting.json复制ABI
// 初始化函数
async function init() {
if (typeof window.ethereum !== 'undefined') {
console.log("MetaMask is installed!");
// 请求账户访问
await window.ethereum.request({ method: 'eth_requestAccounts' });
const provider = new ethers.providers.Web3Provider(window.ethereum); 免责声明:本文为转载,非本网原创内容,不代表本网观点。其原创性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容、文字的真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
如有疑问请发送邮件至:bangqikeconnect@gmail.com