# BPET: A Unified Blockchain-Based Framework for Peer-to-Peer Energy Trading
## 5 System Implementation
### Smart Contracts  
We leverage the price mechanism in the Alberta electricity wholesale market to design smart contracts. In the pool market smart contract, the core business logic determines the market clearance price, called the pool price in Alberta. According to the official guidance documentation [34] on the AESO website, the pool price is determined in the following way. First, the market collects all near-future electricity supplies and demands in terms of price, amount, etc. Pool market participants regularly submit offers and bids to the market for each hour on a day-ahead basis. These supply offers and demand bids are sorted into merit order for each hour of the day. In this way, the AESO ensures that the most competitively priced electricity meets Alberta's overall electricity needs. Then, the pool price rate, i.e., the dollar cost of a megawatt hour of electricity at the end of a given hour that retailers pay to electricity generators, is calculated from the merit order. Setting the pool price is highly detailed and can be summarized into two steps. The first step is to calculate the system marginal price (SMP), as described in Algorithm 1. The algorithm obtains the latest total demand and energy supply offers as inputs every minute, and it obtains a merit order of all valid offers at this minute. Then, the highest-priced supply offer is calculated by comparing the aggregated supply with the total demand in a loop, where the algorithm automatically dispatches all lower-priced offers. The highest-priced offer submitted to the market, and dispatched by the algorithm, is designated as the system marginal offer (SMO) for this minute, with its price designated as the SMP. All SMOs are stored on-chain and are indexed by their timestamps in minutes. ```
1:\(\mathit{bidUpdated}\), \(\mathit{energyOffers}\)\(\triangleright\) read from states
2:\(\mathrm{smp}\) at a particular minute timestamp \(\triangleright\) update to states
3:if\(\mathit{bidsNotEmpty}\) & \(\mathit{offersNotEmpty}\)then
4:\(\mathit{totalDispatched}\gets 0\)\(\triangleright\) initiate total dispatched
5:\(\mathit{latestTotalDemand}\gets\mathit{getLatestTotalDemand}()\)\(\triangleright\) get total demand
6:\(\mathit{meritOrderOfers}\gets\mathit{getMeritOrderSnapshot}()\)\(\triangleright\) get a merit order snapshot
7:\(\mathit{currHour}\leftarrow\mathit{block.timestamp}\) in hour
8:\(N\leftarrow\mathit{meritOrderOffers.length}\)
9:for\(k\gets 0\) to \(N\)do
10:\(\mathit{id}\leftarrow\mathit{meritOrderOffers}_{k}\)
11:\(\mathit{offer}\leftarrow\mathit{energyOffers}[id]\)\(\triangleright\) get an offer
12:\(\mathit{amount}\leftarrow\mathit{offer.amount}\)
13:\(\mathit{account}\gets\mathit{offer.supplierAccount}\)
14:\(\mathit{totalDispatched}\gets\mathit{totalDispatched}+\mathit{amount}\)
15:\(\mathit{dispatchedOffer}\gets\mathit{DispatchedOffer}(account,\mathit{amount}, \mathit{time})\)
16:\(\mathit{dispatchedOffers}[\mathit{currHour}].add(\mathit{dispatchedOffer})\)
17:if\(\mathit{totalDispatched}\geq\mathit{latestTotalDemand}\)then\(\triangleright\) meet total demand
18:\(\mathit{currMinute}\leftarrow\mathit{block.timestamp}\) in minute
19:\(\mathit{smpOferIDs}[\mathit{currMinute}]\gets id\)\(\triangleright\) store system marginal offer
20:\(\mathit{smMinutes.add}(\mathit{currMinute})\)\(\triangleright\) store current minute as index
21:break
22:break
23:end if
24:end for
25:end if
26:end for
```  
**Algorithm 1** System Marginal Price Calculation AlgorithmThe second step is to leverage the SMPs from the first step to calculate the pool price, as described in Algorithm 2. At the beginning of each hour, this algorithm calculates the SMP for the following market clearance hour, i.e., the first SMP to calculate the next pool price at the beginning of the next hour. Then, it calculates the pool price as the average of these one-minute SMPs in a loop. For instance, if there is an SMP calculated for each minute in an hour, the pool price will be the average of all the 60 SMPs.