Steps to including DID into VehicleRegistry.sol (Already implemented, this is just explanation)
-
Implement a DID smart contract, based on IoTeX's implementation here: https://github.com/iotexproject/iotex-did/blob/master/smartcontracts/contracts/IoTeXDID.sol
- In addition to ALL of the above DID methods, add a method getDocumentUriFromIMEI(string IMEI) to get the location of the DID document based only on the IMEI of the device
- For this to work it means we also have an additional mapping(string => string) where string1 is an IMEI and string2 is a DID id string e.g. did:io:0x2323....4039
- Note, we should store the DID document on Arweave, for the sake of the challenge prize.
-
Add an additional field to the DID document called "creator", which is a DID string pointing to the owner of the device, so that we can slash them when needed.
- This means that one owner can have multiple devices pointing to it, e.g. in the case where a person has multiple cars, or multiple ships in his/her fleet
-
How to slash?
- When we receive data from a device (either through streaming, or through pinging the S3 bucket), we get the GPS coordinates, and convert them to a turfJS point
- We then query the JurisdictionRegistry.sol to get the polygon boundaries
- We pass the point, and the polygon boundaries into the enclave which checks whether the point is in the polygon
- If it isn't we don't need to do anything. If it is, we get the device's IMEI (it would be passed to us in the data), then we use that IMEI to get the DID document as described by the getDocumentUriFromIMEI() smart contract method described in point number 1. We read creator field from the DID document (which is stored on Arweave), and then make a slash() smart contract call with that creator's DID.
-
To begin with, the DID document should be in the format:
{ "@context": "https://w3id.org/did/v1", "created": "2018-02-08T16:02:20Z", "entity": "Individual" "creator": "did:io:0x5576E95935366Ebd2637D9171E4C92e60598be10", "imei": "3489075349087539087894" }
-
What does each field mean?:
* "@context": always the same as above. * "created": timestamp of when the DID is created. * "entity": can be "device", "company:company name", or "individual". * "creator": optional, only used if its a device DID. * "imei": optional, only use if its a pebble tracker
How does VehicleRegistry.sol work?
- The contract method names are self explanatory. The main things to note about the contract:
- One "owner" can have multiple vehicles assigned to them. Each vehicle has its own stake amount and expiry date, which means each vehicle can be penalised individually.
- The contract does not really care about addresses, it works with DIDs. DIDs should be passed in as a string in the format, for example, did:io:0x5576E95935366Ebd2637D9171E4C92e60598be10
- Right now for testing purposes the
lockTime
input variable during registration is in minutes as its easy to test that staking works correctly then. Once the web forms are complete we can easily extend to support multiple units e.g. seconds, minutes and days
02/02/2020: We need a web form to register a PERSON to give them a DID and store the DID document on Arweave (Leo). 02/02/2020: We need a web form to register a DEVICE to give it a DID and store the DID document on Arweave (Leo). 02/02/2020: We need a web form to register VEHICLES using VehicleRegistry.sol (Tony?).
Governments register MPA boundaries
- Upload file with Geojson FeatureCollection - polygons of MPA boundaries.
- Arweave deploy (+ IPFS?) (https://medium.com/@arweave/arweave-ipfs-persistence-for-the-interplanetary-file-system-9f12981c36c3)
- Register IPFS address and / or arweave reference within smart contract (
JurisdictionRegistry.sol?
). - Graphical interface - form fill / file drop basically
WHO? Runs Cloud Node program (or within enclave?)
-
Fetch current boundaries (query smart contract)
-
Check for new data into S3 cloud bucket every minute
-
Check to see if points are within MPA boundaries (eventually trusted script)
- If TRUE:
- Submit transaction slashing that vessel's stake
- Set
bool CleanCatch = False
(?). This means that the Node service has private keys to sign tx. Who is administering this? Etc?
- If TRUE:
-
Note: This requires trust in a centralized authority. This process could be executed inside a secure enclave - and potentially replicated so each jurisdiction
- Constructs
Jurisdiction
contracts- Registers boundaries
- Registers and deregisters border officials
✅ Hard code registration
✅ Human interface
- View complete list of shipments in country
- View appropriate container metadata
✅ Human interface
- Submit verification that shipment is ok
✅ Human interface
- Submit verification that shipment was received ok
✅ Machine interface
- Register ownership of device?
// on tracker ping:
// fetch data from Redis - or stream
// Check which jurisdiction the tracker is in
// Check which jurisdiction tracker is registered in on-chain
// if different:
// Revoke access to prior jurisdiction
// Grant access to current jurisdiction
// AND execute enter(jurisdiction);
// Check if tracker is still in that jurisdiction
// If yes:
// Else:
// Check if tracker is inside another jurisdiction
contract Tracker {
address currentJurisdiction; // < contract address
construction () {
// register DID on iotex registry with msg.sender as owner
}
crossBorder(_departingJurisdiction, _enteringJurisdiction) {
// revoke _departingJurisdiction officers access to location information
// pay _enteringJurisdiction money.
// grant _enteringJurisdiction officers access to location information
// update currentJurisdiction
}
}
contract Jurisdiction {
boundaries;
uint importTaxPct;
did; // did:io:_contractaddress_
struct Officer {
address,
}
mapping (address => Officer) officers;
constructor (_boundaries) {
// register DID with boundaries
//
}
// list of border officers
function registerOfficer () {
}
function removeOfficer () {
}
function updateBoundaries (_newBoundaries) {
// replace boundaries with new boundaries
}
function enterJurisdiction (_trackerId) payable {
// confirm signatures
// accept payment ...
}
function departJurisdiction (_trackerId) {
}
}
contract JurisdictionRegistry {
}
// Tracker
// Jurisdiction
{
"@context": "https://w3id.org/did/v1",
"id": "did:io:<<Government's wallet address>>",
"publicKey": [{
"id": "did:io:<<public key>>#keys-1",
"type": "RsaVerificationKey2018",
"controller": "did:io:0x56d0B5eD3D525332F00C9BC938f93598ab16AAA7",
"publicKeyPem": "-----BEGIN PUBLIC KEY...END PUBLIC KEY-----\r\n" }],
"authentication": [{
"type": "RsaSignatureAuthentication2018",
"publicKey": "did:io:0x5576E95935366Ebd2637D9171E4C92e60598be10#keys-1" }],
"service": [{
"id": "did:io:0x88C36867cffB66197812a9385A038cc6Dd75244b;fetch_boundaries",
"type": "FetchBoundaries",
"serviceEndpoint": "https://gateway.ipfs.io/ipfs/QmTeW79w7QQ6Npa3b1d5tANreCDxF2iDaAPsDvW6KtLmfB/" }],
// a signed hash of the boundaries for verification in SGX enclave.
"created": "2018-02-08T16:03:00Z",
"proof": {
"type": "LinkedDataSignature2015",
"created": "2018-02-08T16:02:20Z",
"creator": "did:io:0x5576E95935366Ebd2637D9171E4C92e60598be10#keys-1",
"signatureValue": "QNB13Y7Q9...1tzjn4w=="
}
}
//
// In SGX enclave on the cloud:
// point in polygon {
// confirm validity of jurisdictional boundaries (verify signed hash)\
// confirm validity of tracker location (verify signed coordinates)
// calculate if point in polygon
}
// Obvs not rust but ...
function toBeChecked (_trackerId, _jurisdiction)
returns (bool performCheck_) {
// If temperature has stayed below max
// and
// trackers[_trackerId].Value > x
// and
// No controlled ingredients
return False;
} Else {
return True;
}
}