4.1. Proposed Scheme
The scheme that is studied in this work follows the leader–follower strategy. The leader (only) can register (or delete) drones in the swarm based on their addresses (Listing 1). If drones have not been registered by the leader, they cannot use any of the smart contract’s functionality. Drone registration is a method of authorization in order to enhance the security of the proposed system.
Listing 1. Drone registration function. |
1 function addDrone(address drone) public onlyLeader { |
2 drones[drone] = true; |
3 droneCount++; |
4 emit DroneAdded(drone); |
5 } |
This specific function can be called only by the swarm’s leader; therefore, the onlyLeader modifier is used to prevent access from the other members. All drone addresses are stored in the drones[drone] mapping, along with a Boolean variable that is set to true if the drones have been successfully registered in the swarm. This function also has an opposite function called removeDrone, with the main difference being that the Boolean value is changed to false. The opposite function can be called by the leader, for instance, if a voting procedure is conducted and the majority of the swarm members decide that a specific drone has been compromised. In this way, the malicious drone can be stopped from using the smart contract’s features. Therefore, the hacker will not be able to obstruct the task that the rest of the drones have to finish. The challenge of creating such a mechanism still needs to be addressed in future research.
Subsequently, a new transaction can be started by the leader utilizing the submitData function to submit data along with its location (Listing 2). The swarm’s followers can also utilize this specific function. For instance, location or other information that their sensors may have gathered can be submitted to the blockchain by the members of the swarm using this method.
Listing 2. Data submission function. |
1 function submitData(string memory _location, string memory_data) public { |
2 require(drones[msg.sender], "Error: A drone must be in the |
3 swarm in order to submit data."); |
4 droneData.push(DataCollectedByDrone(block.timestamp, _location, _data, msg.sender)); |
5 } |
Once these tasks are finished, the leader can submit the mission information to the blockchain to generate a new transaction. The mission is identified by its name, a distinctive identifier (id) that sets it apart from other missions; its type (missionType); suitable formation (formationType); and a Boolean parameter that indicates whether the particular mission is operational (Listing 3). A specific type of mission (dive and attack, search and rescue, city surveillance) can be selected by the leader in the proposed smart contract. These missions are illustrative, though it would not be difficult to add to or modify the list. A mission can be created by the leader using the following method:
Listing 3. Mission creation function. |
1 function createMission(string memory name, MissionType missionType, FormationType formationType) public onlyLeader { |
2 uint16 missionId = missionCount; |
3 missions[missionId] = Mission(missionId, name, |
4 missionType, formationType, false); |
5 missionCount++; |
6 emit MissionCreated(missionId); |
7 } |
A mapping missions[missionId] is used, which takes as a key the ID of each mission in order to identify it. One can see that initially, the mission is declared inactive (a false Boolean) during its definition. This is so it can be activated or deactivated whenever needed by the leader (Listing 4). In this way, there is better synchronization in cases where several missions have been declared. The formation that the swarm must follow depends on the type of mission assigned by the leader (Search, DiveAttack, CitySurveillance) and is determined automatically (Ring, V, and Line, respectively). Activation of the declared mission is carried out using the following function:
Listing 4. Mission activation function. |
1 function activateMission(uint16 missionId) public onlyLeader { |
2 require(missions[missionId].id == missionId, "No such mission"); |
3 missions[missionId].active = true; |
4 emit MissionActivated(missionId); |
5 } |
In the suggested smart contract, a mechanism for confirming that the leader is alive has also been included. For the followers to be certain that their leader is still active, the leader must send a heartbeat message that can be read by them. An indicative threshold of 180 s has been used, even though this can be easily modified. If the leader does not report his status, a new leader-election process will follow. The outcome of this process will favor the drone with the highest battery life. Leader’s functionality flowchart can be seen below (
Figure 5).
As for the followers, the first thing they do is make sure their leader is still active.
Followers can inspect whether a heartbeat message has been sent by the leader by invoking the smart contract’s checkLeaderStatus method (Listing 5). If not, they go through a process of choosing a new leader. The drone with the highest battery life is chosen as the new leader of the swarm, presuming that all of the drones in the swarm are of the same type (so there are no connectivity, design, or other issues). Drones can use the following function to periodically report their battery levels (Listing 6):
Listing 5. Checking the leader’s status. |
1 function checkLeaderStatus() public { |
2 if (block.timestamp - lastHeartbeat > heartbeatTimeout){ |
3 leaderIsAlive = false; |
4 if (msg.sender != leader) { |
5 electNewLeader(); |
6 } |
7 } |
8 } |
Listing 6. Battery level submission for followers. |
1 function submitBatteryLevel(uint8 batteryLevel) public { |
2 require(drones[msg.sender], "Only drones can submit battery level."); |
3 batteryLevels[msg.sender] = batteryLevel; |
4 } |
The aforementioned procedure does not take place when the leader is active. The mission and the declared formation can now be checked by followers by reading the data that their leader has submitted. Knowing the position of their leader, they can select the location of the formation that is closest to them. A formula is required to translate angles and distances into coordinates in order to create a formation scheme. The Haversine equation is the ideal solution for this problem. If the coordinates of two points are
(latitude, longitude), the central angle
between the two points can be determined using the equation:
where
is the Haversine function
.
Subsequently, the distance between the two points along the geodesic can be calculated using the formula , where r is the earth’s radius. The desired coordinates for the formation can be determined by following the same approach in reverse. For example, if the desired formation is V, for angles and distances m between drones, the inverse Haversine formula calculates the desired coordinates.
This information can be used by the drones to determine the location that is closest to them (through a loop). Assume that they are located at
. If the coordinates determined using the Haversine formula are
, by using the Euclidean distance equation
for all of them, the position nearest to them can be calculated. First, the available positions in the formation are examined by the drones through the blockchain. If the position is free, a submission process will occur through which the position will be submitted to the blockchain. Next, this exact location will be occupied by the swarm member who selects it. Otherwise, if the desired position is not available, the next nearest position is selected, and so on.
In the illustration above (
Figure 6), the leader’s coordinates are (
). In the V formation, the leader will, therefore, be in position 0. Consider a follower (
i) with the coordinates (
) = (
). Based on Equations (
1) and (
2), the follower determines all
Euclidean distances for positions 1, 2, 3, 4, 5, and 6. From these, he selects the position that is nearest to him, in this case, position 4, and moves there. Repeating this procedure allows each follower in the swarm to communicate its position to the blockchain, where it is visible to all other followers. If this position is already taken, the next one closest to it is chosen (in this case, position 5). This strategy (submitting chosen positions to the blockchain and determining their availability) avoids situations where the same position is chosen by two (or more) separate drones, which may result in collisions.
One can see the position submission utilized by the drones to disclose their positions through the smart contract in the aforementioned function (Listing 7). Also, as previously stated, specific measures have been taken in order to ensure that the position submitted to the blockchain is valid and not occupied. In any other case, the transaction will be reverted. A typical flowchart for follower functionalities is shown below (
Figure 7).
Listing 7. Position-selection function. |
1 function assignPosition(uint8 position) public { |
2 require(drones[msg.sender], "Only drones can assign positions"); |
3 require(position > 0 && position < droneCount, "Invalid position"); |
4 require(positions[msg.sender] == 0, "Position already assigned"); |
5 require(positionsTaken[position] == address(0), "Position taken"); |
6 positions[msg.sender] = position; |
7 positionsTaken[position] = msg.sender; |
8 emit PositionAssigned(msg.sender, position); |
9 } |
Although the suggested smart contract is only defined for use in the military domain, it can still be updated and applied to other sectors as well. The basic concept behind this model is that each smart contract will only be effective for a set amount of time before becoming obsolete and needing to be reprogrammed in accordance with the new task that the drones must complete. In the matter of unplanned situations during a mission where the drones must operate differently, the deactivateMission function can be used in order to abort the pre-defined mission.