概述Energy-FiProtocol是一个基于区块链的绿色能源交易与金融生态系统,通过智能合约实现能源资产的代币化、市场化交易、动态定价以及收益分配。本文将深入解析其核心合约架构、DAO治理机制以及质押分红系统。一、系统架构概览
Energy-Fi Protocol 是一个基于区块链的绿色能源交易与金融生态系统,通过智能合约实现能源资产的代币化、市场化交易、动态定价以及收益分配。本文将深入解析其核心合约架构、DAO治理机制以及质押分红系统。
| 层级 | 核心内容 |
|---|---|
| 资产层 | BoykaYuriToken (ERC20) + GreenCarbonNFT (ERC721) |
| 定价层 | AlgorithmicEnergyPricing (动态定价算法) |
| 市场层 | GreenEnergyMarket (P2P 能源交易) |
| 金融层 | EnergyStaking (质押挖矿与分红) |
| 治理层 | AccessControl (DAO 治理与权限管理) |
// SPDX-License-Identifier: MIT
// Compatible with OpenZeppelin Contracts ^5.5.0
pragma solidity ^0.8.24;
import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import {ERC20Burnable} from "@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol";
import {ERC20Permit} from "@openzeppelin/contracts/token/ERC20/extensions/ERC20Permit.sol";
import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";
contract BoykaYuriToken is ERC20, ERC20Burnable, Ownable, ERC20Permit {
constructor(address recipient, address initialOwner)
ERC20("MyToken", "MTK")
Ownable(initialOwner)
ERC20Permit("MyToken")
{
_mint(recipient, 1000000 * 10 ** decimals());
}
function mint(address to, uint256 amount) public onlyOwner {
_mint(to, amount);
}
}
技术亮点:
recipient 接收
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;import {ERC721} from "@openzeppelin/contracts/token/ERC721/ERC721.sol"; import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";
contract GreenCarbonNFT is ERC721, Ownable { error AlreadyOffset(uint256 tokenId);
struct CarbonData { uint256 amountKG; bool isOffset; }
mapping(uint256 => CarbonData) public carbonRegistry;
uint256 private _nextTokenId;
constructor(address initialOwner) ERC721("GreenCarbon", "GCC") Ownable(initialOwner) {}
function mintCarbonCredit(address to, uint256, uint256 kgAmount) external onlyOwner {
uint256 tokenId = _nextTokenId++;
_safeMint(to, tokenId);
carbonRegistry[tokenId] = CarbonData(kgAmount, false);
}
}
**应用场景:**
- 可再生能源项目方铸造碳信用NFT
- 企业购买NFT用于碳中和目标
- 链上透明记录,防止双重计算
### 2.3 AlgorithmicEnergyPricing - 算法定价引擎
采用 **AccessControl** 实现多角色治理的动态定价系统:
#### 核心公式
$$Price=BasePrice×(1+TargetMultiplier×(Load−Target)÷100)$$
// SPDX-License-Identifier: MIT pragma solidity ^0.8.24;
import {AccessControl} from "@openzeppelin/contracts/access/AccessControl.sol";
contract AlgorithmicEnergyPricing is AccessControl { bytes32 public constant GOVERNANCE_ROLE = keccak256("GOVERNANCE_ROLE"); bytes32 public constant ORACLE_ROLE = keccak256("ORACLE_ROLE");
uint256 public basePrice = 100; // 基础价
uint256 public loadMultiplier = 50; // 波动系数 (DAO治理)
uint256 public targetLoad = 1000; // 额定负荷 (MW)
uint256 public lastReportedLoad;
constructor(address admin, address dao) {
_grantRole(DEFAULT_ADMIN_ROLE, admin);
_grantRole(GOVERNANCE_ROLE, dao);
_grantRole(ORACLE_ROLE, admin); // 初始由管理员充当预言机
}
function updateLoadFromOracle(uint256 _load) external onlyRole(ORACLE_ROLE) {
lastReportedLoad = _load;
}
function setPricingParameters(uint256 _multiplier, uint256 _base) external onlyRole(GOVERNANCE_ROLE) {
loadMultiplier = _multiplier;
basePrice = _base;
}
function getCurrentPrice() public view returns (uint256) {
if (lastReportedLoad <= targetLoad) return basePrice;
uint256 excessLoad = lastReportedLoad - targetLoad;
uint256 dynamicPart = (loadMultiplier * excessLoad) / targetLoad;
return basePrice + (basePrice * dynamicPart / 100);
}
}
#### 角色权限设计
| 角色 | 权限 | 典型持有者 |
| :------------------- | :----- | :------ |
| `DEFAULT_ADMIN_ROLE` | 管理其他角色 | 协议部署者 |
| `GOVERNANCE_ROLE` | 修改定价参数 | DAO治理合约 |
| `ORACLE_ROLE` | 更新负荷数据 | 预言机节点 |
**治理优势:**
- 将定价权从单一所有者转移至DAO,实现去中心化治理
- 预言机角色独立,确保数据输入的可信度
- 参数调整需通过治理投票,防止恶意操纵
### 2.4 GreenEnergyMarket - 能源交易市场
```js
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {Pausable} from "@openzeppelin/contracts/utils/Pausable.sol";
import {AccessControl} from "@openzeppelin/contracts/access/AccessControl.sol";
contract GreenEnergyMarket is Pausable, AccessControl {
bytes32 public constant GOVERNANCE_ROLE = keccak256("GOVERNANCE_ROLE");
bytes32 public constant DEPIN_DEVICE_ROLE = keccak256("DEPIN_DEVICE_ROLE");
error UnauthorizedDevice(address device);
error PriceAnomalyDetected(uint256 price);
IERC20 public energyToken;
address public treasury;
struct Offer { address provider; uint256 amount; uint256 price; bool active; }
mapping(uint256 => Offer) public offers;
uint256 public nextOfferId;
constructor(address _token, address _admin, address _dao) {
energyToken = IERC20(_token);
_grantRole(DEFAULT_ADMIN_ROLE, _admin);
_grantRole(GOVERNANCE_ROLE, _dao);
}
function authorizeDevice(address _device) external onlyRole(DEFAULT_ADMIN_ROLE) {
_grantRole(DEPIN_DEVICE_ROLE, _device);
}
function recordProduction(address _provider, uint256 _amount) external onlyRole(DEPIN_DEVICE_ROLE) {
// 数据上链逻辑
}
function buyEnergy(uint256 _offerId) external whenNotPaused {
Offer storage offer = offers[_offerId];
uint256 totalCost = offer.amount * offer.price;
uint256 fee = totalCost / 100; // 1% 手续费
offer.active = false;
energyToken.transferFrom(msg.sender, offer.provider, totalCost - fee);
energyToken.transferFrom(msg.sender, treasury, fee);
}
function createOffer(uint256 _amount, uint256 _price, uint256) external whenNotPaused {
offers[nextOfferId++] = Offer(msg.sender, _amount, _price, true);
}
function updatePriceSafe(uint256 _newPrice) external onlyRole(DEFAULT_ADMIN_ROLE) {
if (_newPrice > 500) {
_pause();
revert PriceAnomalyDetected(_newPrice);
}
}
function setTreasury(address _treasury) external onlyRole(GOVERNANCE_ROLE) {
treasury = _treasury;
}
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import {ReentrancyGuard} from "@openzeppelin/contracts/utils/ReentrancyGuard.sol";
contract EnergyStaking is ReentrancyGuard { IERC20 public stakingToken; uint256 public totalStaked; mapping(address => uint256) public stakedBalance; mapping(address => uint256) public rewardMask; uint256 public accRewardPerShare;
constructor(address _token) { stakingToken = IERC20(_token); }
function stake(uint256 amount) external nonReentrant {
_updateReward(msg.sender);
stakingToken.transferFrom(msg.sender, address(this), amount);
stakedBalance[msg.sender] += amount;
totalStaked += amount;
}
// 接收国库转入的收益并更新全球每股收益
function notifyRewardAmount(uint256 reward) external {
if (totalStaked > 0) {
accRewardPerShare += (reward * 1e18) / totalStaked;
}
}
function _updateReward(address user) internal {
uint256 pending = (stakedBalance[user] * accRewardPerShare / 1e18) - rewardMask[user];
if (pending > 0) { stakingToken.transfer(user, pending); }
rewardMask[user] = stakedBalance[user] * accRewardPerShare / 1e18;
}
}
#### 分红闭环流程
```js
市场交易产生手续费
↓
手续费转入国库地址 (treasury)
↓
调用 notifyRewardAmount() 注入质押池
↓
更新 accRewardPerShare(全球每股收益)
↓
质押者调用 stake() / withdraw() 触发 _updateReward()
↓
自动计算并发放应得收益
Energy-Fi Protocol Full DAO & Yield Integration ✔ 逻辑一致性:电价算法应与脚本预期严格匹配 (1475ms) ✔ DAO 治理:只有治理角色可以修改定价参数 (680ms) ✔ 分红闭环:市场交易产生手续费并自动分发给质押者 (716ms)
import assert from "node:assert/strict";
import { describe, it } from "node:test";
import { parseEther, keccak256 } from "viem";
import { network } from "hardhat";
describe("Energy-Fi Protocol Full DAO & Yield Integration", function () {
async function deployFixture() {
const { viem } = await (network as any).connect();
const [admin, user, iotDevice, dao] = await viem.getWalletClients();
// 1. 部署全套合约
const energyToken = await viem.deployContract("BoykaYuriToken", [admin.account.address, admin.account.address]);
const carbonNFT = await viem.deployContract("GreenCarbonNFT", [admin.account.address]);
const pricingLogic = await viem.deployContract("AlgorithmicEnergyPricing", [admin.account.address, dao.account.address]);
const market = await viem.deployContract("GreenEnergyMarket", [energyToken.address, admin.account.address, dao.account.address]);
const staking = await viem.deployContract("EnergyStaking", [energyToken.address]);
// 2. 初始权限配置 (修复位置)
// 计算 DEPIN_DEVICE_ROLE 的哈希值 (keccak256("DEPIN_DEVICE_ROLE"))
const DEPIN_DEVICE_ROLE = keccak256(Buffer.from("DEPIN_DEVICE_ROLE"));
// 使用 AccessControl 标准的 grantRole 函数授予权限
await market.write.grantRole([DEPIN_DEVICE_ROLE, iotDevice.account.address], { account: admin.account });
// 设置国库地址 (此函数在 Market 合约中由 GOVERNANCE_ROLE 调用)
await market.write.setTreasury([staking.address], { account: dao.account });
return { energyToken, carbonNFT, pricingLogic, market, staking, admin, user, iotDevice, dao };
}
it("逻辑一致性:电价算法应与脚本预期严格匹配", async function () {
const { pricingLogic } = await deployFixture();
const currentLoad = 1200n;
const targetLoad = 1000n;
const basePrice = 100n;
const multiplier = 50n;
await pricingLogic.write.updateLoadFromOracle([currentLoad]);
const excessLoad = currentLoad - targetLoad;
const dynamicPart = (multiplier * excessLoad) / targetLoad;
const expectedPrice = basePrice + (basePrice * dynamicPart / 100n);
const currentPrice = await pricingLogic.read.getCurrentPrice();
assert.equal(currentPrice, expectedPrice, "定价算法不一致");
});
it("DAO 治理:只有治理角色可以修改定价参数", async function () {
const { pricingLogic, dao, user } = await deployFixture();
// 治理角色修改参数成功
await pricingLogic.write.setPricingParameters([80n, 110n], { account: dao.account });
// 普通用户尝试修改应失败 (AccessControl 抛出错误)
await assert.rejects(
async () => {
await pricingLogic.write.setPricingParameters([100n, 100n], { account: user.account });
},
/AccessControlUnauthorizedAccount/
);
});
it("分红闭环:市场交易产生手续费并自动分发给质押者", async function () {
const { energyToken, market, staking, admin, user } = await deployFixture();
const stakeAmount = parseEther("1000");
// 1. 用户质押代币
await energyToken.write.transfer([user.account.address, stakeAmount], { account: admin.account });
await energyToken.write.approve([staking.address, stakeAmount], { account: user.account });
await staking.write.stake([stakeAmount], { account: user.account });
// 2. 发生能源交易
const amount = 100n;
const price = parseEther("2");
const totalCost = amount * price;
await energyToken.write.approve([market.address, totalCost], { account: admin.account });
await market.write.createOffer([amount, price, 3600n], { account: admin.account });
await market.write.buyEnergy([0n], { account: admin.account });
// 3. 注入分红 (手动模拟国库转账并通知,实际可由合约自动触发)
const fee = totalCost / 100n;
await energyToken.write.approve([staking.address, fee], { account: admin.account });
await staking.write.notifyRewardAmount([fee], { account: admin.account });
// 4. 用户领取收益
const balanceBefore = await energyToken.read.balanceOf([user.account.address]);
await staking.write.stake([0n], { account: user.account }); // 触发更新
const balanceAfter = await energyToken.read.balanceOf([user.account.address]);
assert.ok(balanceAfter > balanceBefore, "质押分红未到账");
});
});
// scripts/deploy.js
import { network, artifacts } from "hardhat";
async function main() {
// 连接网络
const { viem } = await network.connect({ network: network.name });//指定网络进行链接
// 获取客户端
const [deployer,dao] = await viem.getWalletClients();
const publicClient = await viem.getPublicClient();
const deployerAddress = deployer.account.address;
console.log("部署者的地址:", deployerAddress);
// 加载合约
const BoykaYuriTokenArtifact = await artifacts.readArtifact("BoykaYuriToken");
const GreenCarbonNFTArtifact = await artifacts.readArtifact("GreenCarbonNFT");
const AlgorithmicEnergyPricingArtifact = await artifacts.readArtifact("AlgorithmicEnergyPricing");
const GreenEnergyMarketArtifact = await artifacts.readArtifact("GreenEnergyMarket");
const EnergyStakingArtifact = await artifacts.readArtifact("EnergyStaking");
// 部署(构造函数参数:recipient, initialOwner)
const BoykaYuriTokenHash = await deployer.deployContract({
abi: BoykaYuriTokenArtifact.abi,//获取abi
bytecode: BoykaYuriTokenArtifact.bytecode,//硬编码
args: [deployerAddress,deployerAddress],//部署者地址,初始所有者地址
});
const BoykaYuriTokenReceipt = await publicClient.waitForTransactionReceipt({ hash: BoykaYuriTokenHash });
console.log("代币合约地址:", BoykaYuriTokenReceipt.contractAddress);
//
const GreenCarbonNFTHash = await deployer.deployContract({
abi: GreenCarbonNFTArtifact.abi,//获取abi
bytecode: GreenCarbonNFTArtifact.bytecode,//硬编码
args: [deployerAddress],//部署者地址,初始所有者地址
});
// 等待确认并打印地址
const GreenCarbonNFTReceipt = await publicClient.waitForTransactionReceipt({ hash: GreenCarbonNFTHash });
console.log("绿色碳证合约地址:", GreenCarbonNFTReceipt.contractAddress);
const AlgorithmicEnergyPricingHash = await deployer.deployContract({
abi: AlgorithmicEnergyPricingArtifact.abi,//获取abi
bytecode: AlgorithmicEnergyPricingArtifact.bytecode,//硬编码
args: [deployerAddress,dao.account.address],//部署者地址,初始所有者地址
});
// 等待确认并打印地址
const AlgorithmicEnergyPricingReceipt = await publicClient.waitForTransactionReceipt({ hash: AlgorithmicEnergyPricingHash });
console.log("算法能源定价合约地址:", AlgorithmicEnergyPricingReceipt.contractAddress);
const GreenEnergyMarketHash = await deployer.deployContract({
abi: GreenEnergyMarketArtifact.abi,//获取abi
bytecode: GreenEnergyMarketArtifact.bytecode,//硬编码
args: [BoykaYuriTokenReceipt.contractAddress,deployerAddress,dao.account.address],//部署者地址,初始所有者地址
});
// 等待确认并打印地址
const GreenEnergyMarketReceipt = await publicClient.waitForTransactionReceipt({ hash: GreenEnergyMarketHash });
console.log("绿色能源市场合约地址:", GreenEnergyMarketReceipt.contractAddress);
const EnergyStakingHash = await deployer.deployContract({
abi: EnergyStakingArtifact.abi,//获取abi
bytecode: EnergyStakingArtifact.bytecode,//硬编码
args: [BoykaYuriTokenReceipt.contractAddress],//部署者地址,初始所有者地址
});
// 等待确认并打印地址
const EnergyStakingReceipt = await publicClient.waitForTransactionReceipt({ hash: EnergyStakingHash });
console.log("能源质押合约地址:", EnergyStakingReceipt.contractAddress);
}
main().catch(console.error);
GOVERNANCE_ROLE 逐步将控制权移交DAOEnergy-Fi Protocol 展示了区块链在能源金融领域的创新应用,通过智能合约实现了能源资产的数字化、交易的透明化以及收益分配的自动化。其DAO治理架构为传统能源市场向去中心化转型提供了可复用的技术范式。
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!