flintlang / flint

The Flint Programming Language for Smart Contracts
MIT License
245 stars 18 forks source link

☂️ Flint Package Manager #237

Open DJRHails opened 6 years ago

DJRHails commented 6 years ago

Most languages have package managers, i.e. a tool which allows developers to easily use third-party code to augment the functionality of theirs.

For example, JavaScript’s Node Package Manager allows programmers to easily use other people’s code, such as cryptography libraries.

Package managers usually store different versions of a code base’s source code, and clients decide which version they would like to use. Flint’s package manager aims to help programmers discover and assess the quality of thirdparty Flint packages.

In addition to storing the source code, a Flint package also records gas cost upper-bounds for each of its functions, and highlights potential security warnings. This information will be produced automatically by the Flint Static Analyzer.

Plausible Implementation

The goal is to separate the implementation package manager into two components. The first is a smart contract recording information about all the Flint packages. Writing the package manager as a decentralized application on Ethereum’s blockchain reduces the need of using a third-party server. This is advantageous in this situation, as it ensures, for instance, that critical information such as security warnings about contracts cannot be tampered with by hacking into a central server.

Storing the source code of every package on the blockchain would, however, be quite expensive.

Instead, we use a secondary, traditional NoSQL database to store source code. The blockchain then stores an integrity hash of the code, allowing the compiler to ensure what the imported code reflects what was expected.

Smart Contract

// Represents a Flint package .
struct Package {
  // Name of the package .
  var name: String

  // Creator and owner of the package .
  var owner: Address

  // Latest version of the package .
  var version: Int

  // Hash of the package ’s source code .
  var hash: String

  // Hash of the package ’s interface
  var interfaceHash: String

  // Security information relating to this package .
  var securityInformation: SecurityInformation

   // The gas cost upper - bounds for each function in the package .
  var gasCosts: [String: Int]
}

contract PackageManager {
  var admin: Address
  var packages: [String: Package]
}

PackageManager :: caller <- (any) {
  mutating func createPackage ( name : String , version : Int , hash : String )
  mutating func updatePackage ( package : String , version : Int , hash : String )
  mutating func addSecurityWarning ( package : String , warning : String )
  mutating func addGasCost ( package : String , function : String , gasCost : Int )
  func getGasCost ( package : String , function : String ) -> Int
  func getPackageHash ( name : String ) -> String
  func getPackageVersion ( name : String ) -> Int
  func getPackageNumSecurityWarnings ( name : String ) -> Int
  func getPackageSecurityWarnings ( name : String , index : Int ) -> String
  func packageExists ( name : String ) -> Bool
}

PackageManager :: (admin) {
  public mutating func deletePackage(name: String)
}
DJRHails commented 6 years ago