天天看點

電力市場鍊改方案及源碼【以太坊應用】

區塊鍊最擅長處理去中心化市場這一類問題,随着能源市場中可再生能源的發展,顯然區塊鍊有可能颠覆目前能源産業的中心化格局。在這片文章中,我們将介紹基于以太坊區塊鍊的區中心化電力市場解決方案并提供智能合約的實作代碼。

1、電力網絡的運作機制

以太坊教程連結: Dapp入門 | 電商Dapp實戰 Token實戰 Php對接 Java對接 Python對接 C#對接 Dart對接

簡單來講,電力網絡負責比對電力的生産與消費。如果我的筆記本電腦在兩小時内需要200瓦的電力,那麼就需要有人在同一時間段向同一電力網絡中提供200瓦的電力。如果1萬人同時使用筆記本電腦,那就意味着在同一時刻需要向電力網絡中提供200萬瓦的電力。在電力的生産和消費之間由于傳輸距離

的影響,存在着一定的電力損耗,而且絕大多數電力網絡會有幾套電路來路由電力供應,不過基本上其工作原理就是上面所述。

電力市場鍊改方案及源碼【以太坊應用】

在這一場景中通常有4種參與的角色:

  • 電力生産商:負責發電并以此獲利
  • 電力分銷商:負責維護電力網絡,以便将電力從發電企業輸送到消費者
  • 電力零售商:從發電企業批量購買電力并出售給消費者
  • 電力消費者:從零售商購買電力

這一買賣電力的行為并不是說電力零售商可以從某個風力發電企業購買電力并将其出售給特定的消費者,零售商買入和賣出的其實是一種認證。

每個發電企業要将其電力進入網絡都需要先有認證。消費者要從網絡中獲得電力也需要有足夠的認證。顯然不允許使用同樣的認證進行電力的買入或賣出。這一模式已經運作了近100年。

中心化的發電意味着大型電站為大量消費者供應電力。傳統的電力流向是通過電力配置設定網絡從發電企業到消費者,而資金流向是從消費者通過零售商到電力生産企業,這工廠也會借助于電表來比對消費者的用電量。

最近這一場景已經開始向生産性消費變化。現在在一些國家有大量家庭使用太陽能闆發電,這些生産性消費者有時從網絡中擷取電力,有時又可以将自己用不完的電力輸入網絡。

這使得電力市場更加複雜。這些生産性消費者如何認證?誰來決定其供電價格?誰來買這些電?電力分銷商現在不僅對網絡的平衡問題頭疼,而且這還是一個複雜的去中心化市場。

可能你已經大概明白應該幹點什麼了,我相信一定有辦法利用區塊鍊技術為這些生産性消費者打造一個有效的去中心化市場。

2、區塊鍊去中心化電力市場業務用例

我們的業務用例是一個可再生能源交易方面的生産性消費者場景。我們假設電力分銷商運作着電力能源市場并使用貨币化激勵機制來平衡電力的生産與消費。

這類似于真實世界中的能源市場,但并不完全一緻。我盡可能保持用例的通用,因為基于區塊鍊的能源市場還存在一些計算方面的限制。

在現實的電力能源市場中,電力生産商在一定時間區間内會下注一個其願意發電的價格,零售商通常會以最低價格從生産商處買電。這其實和股票交易市場的運作模式一樣,但是對于目前的區塊鍊平台而言計算量太大了。

3、基于以太坊的電力市場DApp設計

我們将使用以太坊區塊鍊的ERC20通證作為貨币來實作這個簡化的能源市場,使用兩個變量來表示市場中的生産與消費負載。我們将時間拆分為不同機關,目的是在每個時間機關裡盡可能實作電力生産和消費負載的平衡。

我将從去中心化金融中的uniswap市場找到了一些靈感,并使用一個簡單的價格公式:當指定時間區間内電力生産商多于消費者時,就降低電力價格。這樣,便宜的電力就可以激勵消費者多用電,而生産商就會盡可能少發電,進而實作網絡的平衡。反而言之,當網絡中的電力生産商少于消費者時電力價格就上漲。

簡而言之,電力網絡負責比對電力供求關系,供不應求時,電價上漲,供過于求時,電價下降。

在所有的交易中,電力配置設定網絡都是一個參與者。電力配置設定網絡将設定電價。供電企業向配置設定網絡出售電力,消費者從配置設定網絡購買電力。實體的電力配置設定網絡保持不變,但是在生産性消費者之間的金融配置設定網絡現在變成了區塊鍊上去中心化的智能合約。

我移除了很多複雜的特性以便聚焦于市場機制。我相信有可能基于區塊鍊實作一個全國性的能源市場,但是為了完成本文,我們必須簡化場景。我将在本文的結束部分探讨這些被忽略的特性。

現在讓我們看看這個基于以太坊區塊鍊的去中心化電力市場的智能合約的實作代碼,合約使用Solidity實作,相關教程可以參考:

以太坊去中心化電商DApp開發教程

4、電力市場Solidity智能合約實作

Uniswap方式的去中心化市場,最大的優點就是非常簡單。在我們的用例中,整個

電力能源交易市場隻需要不到100行Solidity代碼就可以實作,這還包含了注釋:

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市場需要用一些資金來初始化,這是因為電力生産者可能多于消費者,而市場需要從消費者收錢,并付款給生産者。是以需要一點價差資金。

價格是基于生産和消費複雜的差異,使用兩個簡單的公式計算得到的。當電力生産和消費負載一緻時就得到基準價格。請忽略合約代碼中的所有類型轉換,那隻是為了進行計算方面的溢出保護。

這個機制非常簡單,是以可以應用在算力有限的區塊鍊上,而同時它也鼓勵電力生産和消費的平衡,在任何一個方向上的不穩定都會造成資金的損失。

重要的一點,是要注意現在是區塊鍊智能合約在控制着資金的流向,生産和消費委托單通常填寫未來的時間。實體配電網絡會對所建議的消費和生産負載有所了解并能在需要平衡電力網絡時采取措施。

隻有在白名單中的電力生産者可以為電力網絡供電,他們隻需要聲明其發電目的即可立即收到款。顯然這是現實場景的一個超級簡化,在真實的生産環境中資金應當被托管并直至生産者真正供電才向其釋放資金。

能源的消費機制也是一樣的。消費者聲明其用電目的并以電力網絡确定的價格支付。在現實生活中,有可能會根據消費者的實際用電量有一些資金返還。

原文連結:

基于區塊鍊的去中心化電力市場 — 彙智網