本文将引导您完成使用 Solidity 语言,通过 Neon EVM 在 Solana 区块链上部署智能合约的全过程。Neon EVM 是一个在 Solana 上运行的以太坊虚拟机(EVM)环境,让开发者能够利用 Solidity 开发并享受 Solana 的高性能与低费用。
为什么选择 Solana 和 Neon EVM?
在深入了解部署步骤之前,我们首先需要理解两个核心概念:Solana 的特性和 Neon EVM 的作用。
Solana 的核心特性
Solana 是一个高性能区块链平台,其设计采用了多项创新技术,具有以下特点:
- 账户无处不在:Solana 中的大多数元素,包括用户钱包、程序、数据日志和系统程序,都被表示为账户。这些账户类似于传统操作系统中的文件,可以被创建、修改和删除,既能保存数据也能处理数据。
- 程序而非智能合约:Solana 将智能合约称为“程序”。这些程序本质上是存储可执行代码的账户,负责处理交易和更新区块链状态。
- 无状态程序设计:与以太坊 EVM 的有状态合约不同,Solana 程序不在内部存储其状态。相反,它们利用独立的账户来存储和管理状态数据。
- 充裕的存储空间:Solana 账户最多可存储 10 MB 的数据,为各种应用场景提供了充足的存储容量。
Neon EVM 的工作原理
Neon EVM 是一个完整的以太坊虚拟机实现,它作为一个可执行账户集成在 Solana 中。这意味着:
- 开发者可以使用熟悉的 Solidity 和 Vyper 编写智能合约
- 兼容以太坊开发工具链,如 MetaMask、Hardhat、Truffle 和 Remix
- 享受 Solana 的低费用、快速交易处理和并行交易执行能力
- 无需学习新的编程语言或工具即可将以太坊应用迁移到 Solana
与二层解决方案或侧链不同,Neon EVM 是直接在 Solana 网络上运行的完整 EVM 实现。
开发环境准备
在开始编写和部署智能合约之前,我们需要设置适当的开发环境。
钱包配置
首先,您需要在钱包中添加 Neon EVM DevNet 网络。本指南以 MetaMask 为例:
- 访问 Neon 的 Chainlist 页面
- 点击 连接钱包 按钮
- 在 Neon EVM DevNet 下点击 添加到 MetaMask
- 按照提示完成网络添加
在 Neon EVM 上,代理运营商负责在 Solana 上结算 Neon 交易。虽然这是可更改的,但我们将使用 Chainlist 分配的默认代理运营商。
获取测试代币
接下来,您需要获取 NEON 测试代币用于开发和测试:
- 访问 Neon 水龙头
- 确保您的钱包已连接到 Neon EVM DevNet
- 选择 NEON 作为代币类型
- 输入您想要的数量(目前单次最大限额为 100 NEON)
- 点击 发送测试代币
稍等片刻,您的钱包就会收到 NEON 测试代币。
开发工具安装
我们将使用 Hardhat 作为开发环境,这是一个用于编译、部署、测试和调试以太坊软件的强大工具。
确保您的系统已安装以下依赖:
- Node.js(版本 > 8.9.4)
- 基本了解 Solidity 开发
- 基本了解 Solana 基础知识
- EVM 兼容的浏览器扩展钱包(如 MetaMask)
项目设置与配置
现在让我们开始创建项目并配置开发环境。
初始化项目
打开终端,在您选择的目录中运行以下命令:
mkdir neon-scoreboard && cd neon-scoreboard
npm init --yes
npm install --save-dev hardhat
npx hardhat init根据您的偏好选择 JavaScript 或 TypeScript,并按照提示完成初始化过程。
确保对最后一个问题输入 "y",因为我们需要安装特定版本的包。
安装完成后,安装额外的测试依赖:
npm install --save-dev chai@^4.3.6项目结构应该如下所示:
├── README.md // 项目文档和信息
├── contracts // Solidity 智能合约目录
├── hardhat.config.js // Hardhat 环境配置文件
├── node_modules // 项目依赖目录
├── package-lock.json // 依赖版本锁定文件
├── package.json // 项目元数据和依赖信息
├── scripts // 自定义脚本目录
└── test // 测试文件和测试相关代码目录配置 Hardhat
打开 hardhat.config.js 文件,修改为以下内容:
require("@nomicfoundation/hardhat-toolbox");
const proxy_url = "https://devnet.neonevm.org";
const network_id = 245022926;
// 测试账户的私钥
// 注意:替换为您自己的私钥,并确保有非零的 NEON 余额
const privateKeys = [
"PRIVATE_KEY",
];
module.exports = {
solidity: "0.8.4",
defaultNetwork: "hardhat",
networks: {
hardhat: {},
neonlabs: {
url: proxy_url,
accounts: privateKeys,
network_id: network_id,
chainId: network_id,
allowUnlimitedContractSize: false,
timeout: 1000000,
isFork: true,
},
},
};重要提示:将PRIVATE_KEY替换为您账户的私钥。如果您的私钥不以0x开头,请确保在私钥开头添加它。
编写智能合约
现在我们将创建一个简单的记分牌智能合约,允许用户管理和跟踪游戏分数。
创建合约文件
在 contracts 文件夹中创建 Solidity 文件:
echo > ./contracts/Scoreboard.sol将以下内容复制到 Scoreboard.sol 文件中:
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.4;
contract Scoreboard {
// 定义结构体表示用户分数数据
struct UserScore {
address player;
uint8 currentScore;
uint8 highestScore;
}
// 存储用户分数数据的数组
UserScore[] public accountData;
// 映射跟踪用户在数组中的索引
mapping(address => uint256) public userIndex;
// 记录分数更新的事件
event ScoreUpdated(
address indexed player,
uint8 currentScore,
uint8 highestScore
);
// 创建新用户的函数
function createUser() public {
// 确保用户不存在于数组中
require(userIndex[msg.sender] == 0, "User already exists");
// 创建并初始化新的 UserScore 结构体
UserScore memory newUser = UserScore({
player: msg.sender,
currentScore: 0,
highestScore: 0
});
// 添加新用户到数组并更新索引
accountData.push(newUser);
userIndex[msg.sender] = accountData.length;
}
// 向用户当前分数添加点数的函数
function addPoints(uint8 numPoints) public {
// 确保点数有效
require(numPoints > 0 && numPoints < 100, "Invalid points");
// 获取用户在数组中的索引
uint256 index = userIndex[msg.sender];
// 确保用户存在
require(index != 0, "User does not exist");
// 更新用户当前分数和最高分数
accountData[index - 1].currentScore += numPoints;
if (accountData[index - 1].currentScore > accountData[index - 1].highestScore) {
accountData[index - 1].highestScore = accountData[index - 1].currentScore;
}
// 发出分数更新事件
emit ScoreUpdated(
msg.sender,
accountData[index - 1].currentScore,
accountData[index - 1].highestScore
);
}
// 重置用户当前分数为零的函数
function resetScore() public {
uint256 index = userIndex[msg.sender];
require(index != 0, "User does not exist");
accountData[index - 1].currentScore = 0;
emit ScoreUpdated(
msg.sender,
accountData[index - 1].currentScore,
accountData[index - 1].highestScore
);
}
// 获取用户当前分数的函数
function getCurrentScore() public view returns (uint8) {
uint256 index = userIndex[msg.sender];
require(index != 0, "User does not exist");
return accountData[index - 1].currentScore;
}
// 获取用户最高分数的函数
function getHighScore() public view returns (uint8) {
uint256 index = userIndex[msg.sender];
require(index != 0, "User does not exist");
return accountData[index - 1].highestScore;
}
}这个智能合约提供了完整的功能来管理用户分数,包括创建用户、添加分数、重置分数和查询分数。
测试智能合约
在部署之前,我们需要确保智能合约按预期工作。
编写测试用例
在 test 文件夹中创建测试文件:
echo > ./test/Scoreboard.js添加以下测试代码:
const { expect } = require("chai");
const { ethers } = require("hardhat");
describe("Scoreboard Contract", function () {
let Scoreboard;
let scoreboard;
let owner;
beforeEach(async function () {
[owner] = await ethers.getSigners();
Scoreboard = await ethers.getContractFactory("Scoreboard");
scoreboard = await Scoreboard.deploy();
await scoreboard.waitForDeployment();
});
it("Should create a new user", async function () {
await scoreboard.createUser();
const userIndex = await scoreboard.userIndex(owner.address);
expect(userIndex).to.equal(1);
});
it("Should add points", async function () {
await scoreboard.createUser();
await scoreboard.addPoints(50);
const currentScore = await scoreboard.getCurrentScore();
const highestScore = await scoreboard.getHighScore();
expect(currentScore).to.equal(50);
expect(highestScore).to.equal(50);
});
it("Should reset the user's current score and maintain the high score", async function () {
await scoreboard.createUser();
await scoreboard.addPoints(50);
await scoreboard.resetScore();
const currentScore = await scoreboard.getCurrentScore();
const highestScore = await scoreboard.getHighScore();
expect(currentScore).to.equal(0);
expect(highestScore).to.equal(50);
});
});运行测试
执行以下命令运行测试:
npx hardhat test如果一切正常,您应该看到类似以下的输出:
Scoreboard Contract
✔ Should create a new user
✔ Should add points
✔ Should reset the user's current score and maintain the high score
3 passing (947ms)部署与验证
测试通过后,我们可以将智能合约部署到 Neon DevNet。
部署脚本
打开 scripts 文件夹中的 deploy.js 文件,修改为以下内容:
const hre = require("hardhat");
async function main() {
const [deployer] = await ethers.getSigners();
console.log("Deploying contracts with the account:", deployer.address);
const Scoreboard = await hre.ethers.getContractFactory("Scoreboard");
const scoreboard = await Scoreboard.deploy({ gasLimit: "0x10000000" });
await scoreboard.waitForDeployment();
console.log("Deployed contract address is: ", scoreboard.target);
}
main().catch((error) => {
console.error(error);
process.exitCode = 1;
});运行部署命令:
npx hardhat run scripts/deploy.js --network neonlabs部署成功后,您将看到类似以下的输出:
Deploying contracts with the account: 0x58D09ecd499A1d6F2a0269f361Ee6DbbaBa44eF8
Deployed contract address is: 0x244BDb09C3B6B4c9faF2a71D5E876c73085559d2您现在可以在 Neon 浏览器 中通过搜索智能合约地址来查看已部署的合约。
验证智能合约
为了透明和安全,您可以验证已部署的智能合约,让每个人都能查看代码。
更新 hardhat.config.js 文件,在 networks 对象后添加以下内容:
etherscan: {
apiKey: {
neonevm: "test",
},
customChains: [
{
network: "neonevm",
chainId: network_id,
urls: {
apiURL: "https://devnet-api.neonscan.org/hardhat/verify",
browserURL: "https://devnet.neonscan.org",
},
},
],
},运行验证命令(将 DEPLOYED_SMART_CONTRACT_ADDRESS 替换为您的合约地址):
npx hardhat verify DEPLOYED_SMART_CONTRACT_ADDRESS --network neonlabs验证成功后,您将收到一个浏览器链接,任何人都可以通过该链接查看和与您的智能合约交互。
常见问题
Neon EVM 与普通以太坊网络有什么区别?
Neon EVM 在 Solana 区块链上运行,这意味着它继承了 Solana 的高吞吐量和低交易成本特性。虽然开发体验与以太坊相似,但底层基础设施基于 Solana,提供了更好的扩展性和性能。
部署到 Neon EVM 需要多少费用?
费用以 NEON 代币支付,由于 Solana 的高效率,费用通常远低于以太坊主网。具体费用取决于合约复杂性和网络拥堵情况。
我能否将现有的以太坊合约部署到 Neon EVM?
是的,大多数为以太坊编写的 Solidity 合约可以直接部署到 Neon EVM,无需修改或只需 minimal 修改。这使开发者能够轻松地将现有项目迁移到 Solana。
如何获取主网 NEON 代币?
对于生产环境,您需要通过支持的加密货币交易所获取主网 NEON 代币。测试网代币只能用于开发和测试目的。
Neon EVM 支持哪些开发工具?
Neon EVM 支持所有标准的以太坊开发工具,包括 Hardhat、Truffle、Remix IDE、MetaMask 等,提供了熟悉的开发体验。
如何处理合约升级和迁移?
与以太坊类似,您可以使用代理模式或其他升级机制来管理合约升级。建议在部署前仔细规划合约架构以适应可能的未来变更。
总结
通过本指南,您已经学会了如何使用 Solidity 和 Neon EVM 在 Solana 区块链上部署智能合约。这个过程结合了以太坊的开发便利性和 Solana 的高性能优势,为构建去中心化应用提供了强大的基础。
关键要点包括:
- Neon EVM 使 Solidity 开发者能够利用 Solana 的高性能和低费用
- 开发环境设置与标准以太坊开发类似,降低了学习曲线
- 完整的测试和验证流程确保了合约的安全性和可靠性
- 部署后的合约可以通过区块链浏览器公开验证和交互
掌握了这些知识,您现在可以开始在其中一个最快、最高效的区块链平台上构建去中心化应用程序。祝您编码愉快!