基于区块链的去中心化电力市场【含实现代码】

区块链最擅长处理去中心化市场这一类问题,随着能源市场中可再生能源的发展, 显然区块链有可能颠覆目前能源产业的中心化格局。在这片文章中,我们将 介绍基于以太坊区块链的区中心化电力市场解决方案并提供实现代码。

1、电力网络的运行机制

简单来讲,电力网络负责匹配电力的生产与消费。如果我的笔记本电脑在 两小时内需要200瓦的电力,那么就需要有人在同一时间段向同一电力网络中提供 200瓦的电力。如果1万人同时使用笔记本电脑,那就意味着在同一时刻需要 向电力网络中提供200万瓦的电力。在电力的生产和消费之间由于传输距离 的影响,存在着一定的电力损耗,而且绝大多数电力网络会有几套电路来 路由电力供应,不过基本上其工作原理就是上面所述。

在这一场景中通常有4种参与的角色:

  • 电力生产商:负责发电并以此获利
  • 电力分销商:负责维护电力网络,以便将电力从发电企业输送到消费者
  • 电力零售商:从发电企业批量购买电力并出售给消费者
  • 电力消费者:从零售商购买电力

这一买卖电力的行为并不是说电力零售商可以从某个风力发电企业购买电力 并将其出售给特定的消费者,零售商买入和卖出的其实是一种认证。

每个发电企业要将其电力进入网络都需要先有认证。消费者要从网络 中获得电力也需要有足够的认证。显然不允许使用同样的认证进行电力 的买入或卖出。这一模式已经运行了近100年。

中心化的发电意味着大型电站为大量消费者供应电力。传统的电力 流向是通过电力分配网络从发电企业到消费者,而资金流向是从消费者 通过零售商到电力生产企业,这工厂也会借助于电表来匹配消费者的用电量。

最近这一场景已经开始向生产性消费变化。现在在一些国家有大量家庭 使用太阳能板发电,这些生产性消费者有时从网络中获取电力,有时又 可以将自己用不完的电力输入网络。

这使得电力市场更加复杂。这些生产性消费者如何认证?谁来决定其供电 价格?谁来买这些电?电力分销商现在不仅对网络的平衡问题头疼,而且 这还是一个复杂的去中心化市场。

可能你已经大概明白应该干点什么了,我相信一定有办法利用区块链技术为这些生产性 消费者打造一个有效的去中心化市场。

2、区块链去中心化电力市场业务用例

我们的业务用例是一个可再生能源交易方面的生产性消费者场景。我们 假设电力分销商运行着电力能源市场并使用货币化激励机制来平衡电力的 生产与消费。

这类似于真实世界中的能源市场,但并不完全一致。我尽可能保持用例的 通用,因为基于区块链的能源市场还存在一些计算方面的约束。

在现实的电力能源市场中,电力生产商在一定时间区间内会下注一个其愿意 发电的价格,零售商通常会以最低价格从生产商处买电。这其实和股票交易 市场的运作模式一样,但是对于当前的区块链平台而言计算量太大了。

3、基于以太坊的电力市场DApp设计

我们将使用以太坊区块链的ERC20通证作为货币来实现这个简化的能源市场,使用两个变量 来表示市场中的生产与消费负载。我们将时间拆分为不同单位,目的是在每个 时间单位里尽可能实现电力生产和消费负载的平衡。

我将从去中心化金融中的uniswap市场找到了一些灵感,并使用一个简单的价格公式:当指定 时间区间内电力生产商多于消费者时,就降低电力价格。这样,便宜的电力 就可以激励消费者多用电,而生产商就会尽可能少发电,从而实现网络的 平衡。反而言之,当网络中的电力生产商少于消费者时电力价格就上涨。

简而言之,电力网络负责匹配电力供求关系,供不应求时,电价上涨,供过于求 时,电价下降。

在所有的交易中,电力分配网络都是一个参与者。电力分配网络将设定电价。 供电企业向分配网络出售电力,消费者从分配网络购买电力。 物理的电力分配网络保持不变,但是在生产性消费者之间的金融分配网络 现在变成了区块链上去中心化的智能合约。

我移除了很多复杂的特性以便聚焦于市场机制。我详细有可能基于区块链 实现一个全国性的能源市场,但是为了完成本文,我们必须简化场景。我 将在本文的结束部分探讨这些被忽略的特性。

现在让我们看看这个基于以太坊区块链的去中心化电力市场的智能合约的实现代码, 合约使用Solidity实现,相关教程可以参考:以太坊去中心化电商DApp开发教程

4、电力市场Solidity智能合约实现

以太坊教程链接: Dapp入门 | 电商Dapp实战 | Token实战 | Php对接 | Java对接 | Python对接 | C#对接 | Dart对接

Uniswap方式的去中心化市场,最大的优点就是非常简单。在我们的用例中,整个 电力能源交易市场只需要不到100行Solidity代码就可以实现,这还包含了注释:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
pragma solidity ^0.5.10;import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@hq20/contracts/contracts/access/Whitelist.sol";/**
* @title Energy Market
* @notice Implements a simple energy market, using ERC20 and
* Whitelist. ERC20 is used to enable payments from the consumers to
* the distribution network, represented by this contract, and from
* the distribution network to the producers. Whitelist is used to
* keep a list of compliant smart meters that communicate the
* production and consumption of energy.
*/
contract EnergyMarket is ERC20, Whitelist {
event EnergyProduced(address producer, uint256 time);
// uint128 is used here to facilitate the price formula
event EnergyConsumed(address consumer, uint256 time);
// Casting between uint128 and int256 never overflows
// int256(uint128) - int256(uint128) never overflows
mapping(uint256 => uint128) public consumption;
mapping(uint256 => uint128) public production;
uint128 public basePrice; /**
* @dev The constructor initializes the underlying currency token
* and the smart meter whitelist. The constructor also mints the
* requested amount of the underlying currency token to fund the
* network load. Also sets the base energy price, used for
* calculating prices.
*/
constructor (uint256 _initialSupply, uint128 _basePrice)
public
ERC20()
Whitelist()
{
_mint(address(this), _initialSupply);
basePrice = _basePrice;
} /**
* @dev The production price for each time slot.
*/
function getProductionPrice(uint256 _time)
public
view
returns(uint256)
{
return uint256(
max(
0,
int256(basePrice) *
(3 + safeSub(production[_time], consumption[_time]))
)
);
} /**
* @dev The consumption price for each time slot
*/
function getConsumptionPrice(uint256 _time)
public
view
returns(uint256)
{
return uint256(
max(
0,
int256(basePrice) *
(3 + safeSub(consumption[_time], production[_time]))
)
);
} /**
* @dev Add one energy unit to the distribution network at the
* specified time and be paid the production price. Only
* whitelisted smart meters can call this function.
*/
function produce(uint256 _time)
public
{
require(isMember(msg.sender), "Unknown meter.");
this.transfer(
msg.sender,
getProductionPrice(_time)
);
production[_time] = production[_time] + 1;
emit EnergyProduced(msg.sender, _time);
} /**
* @dev Take one energy unit from the distribution network at the
* specified time by paying the consumption price. Only
* whitelisted smart meters can call this function.
*/
function consume(uint256 _time)
public
{
require(isMember(msg.sender), "Unknown meter.");
this.transferFrom(
msg.sender,
address(this),
getConsumptionPrice(_time)
);
consumption[_time] = consumption[_time] + 1;
emit EnergyConsumed(msg.sender, _time);
} /**
* @dev Returns the largest of two numbers.
*/
function max(int256 a, int256 b)
internal
pure
returns(int256)
{
return a >= b ? a : b;
} /**
* @dev Substracts b from a using types safely casting from
* uint128 to int256.
*/
function safeSub(uint128 a, uint128 b)
internal
pure
returns(int256)
{
return int256(a) - int256(b);
}
}

我们的实现将继承以太坊区块链的ERC20和Whitelist合约。ERC20为我们提供了支付工具, 白名单则允许我们只允许得到认证的消费者和供电企业进入市场。

uniswap市场需要用一些资金来初始化,这是因为电力生产者可能 多于消费者,而市场需要从消费者收钱,并付款给生产者。因此需要一点 价差资金。

价格是基于生产和消费复杂的差异,使用两个简单的公式计算得到的。 当电力生产和消费负载一致时就得到基准价格。请忽略合约代码中的所有 类型转换,那只是为了进行计算方面的溢出保护。

这个机制非常简单,因此可以应用在算力有限的区块链上,而同时它 也鼓励电力生产和消费的平衡,在任何一个方向上的不稳定都会造成 资金的损失。

重要的一点,是要注意现在是区块链智能合约在控制着资金的流向,生产和 消费委托单通常填写未来的时间。物理配电网络会对所建议的消费和 生产负载有所了解并能在需要平衡电力网络时采取措施。

只有在白名单中的电力生产者可以为电力网络供电,他们只需要声明其发电目的 即可立即收到款。显然这是现实场景的一个超级简化,在真实的生产 环境中资金应当被托管并直至生产者真正供电才向其释放资金。

能源的消费机制也是一样的。消费者声明其用电目的并以电力网络确定的 价格支付。在现实生活中,有可能会根据消费者的实际用电量有一些资金返还。


原文链接:How to Build an Energy Market on a Blockchain

汇智网翻译整理,转载请标明出处