epm 0.3.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +19 -0
- data/.travis.yml +15 -0
- data/Gemfile +3 -0
- data/LICENSE.md +23 -0
- data/README.md +166 -0
- data/Rakefile +2 -0
- data/bin/epm +90 -0
- data/epm.gemspec +28 -0
- data/lib/epm.rb +81 -0
- data/lib/epm/compile.rb +41 -0
- data/lib/epm/create.rb +35 -0
- data/lib/epm/deploy.rb +126 -0
- data/lib/epm/query.rb +29 -0
- data/lib/epm/transact.rb +36 -0
- data/lib/epm/utils.rb +154 -0
- data/lib/epm/version.rb +1 -0
- data/settings/epm-rpc.json +17 -0
- data/spec/fixtures/test.lll +15 -0
- data/spec/fixtures/test.package-definition +16 -0
- data/spec/fixtures/test2.lll +3 -0
- metadata +81 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 71968fbf0b3c65f40ed5f98a9340c3de0b6c9f57
|
4
|
+
data.tar.gz: d8be28a9138e03c27ade4091e79aa6c4558ef3a3
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: b63fc02ea393ff5a9d09590231193b41daa16756e792c627936a27375996e4692df19b807e50dc3e783adf17386c0ee72cb30ea0b0161772c08861f6b1113438
|
7
|
+
data.tar.gz: c7cff450ec22cc08ea6a98e509127ffdf8b4313f8c129a292a3f0422f5b858fdbb52c18769054ce8a22a233f77d45fc22cce12bf02464bfa4d4f5ed519dcc40d
|
data/.gitignore
ADDED
data/.travis.yml
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
language: ruby
|
2
|
+
rvm:
|
3
|
+
- "1.9.3"
|
4
|
+
- "2.0.0"
|
5
|
+
- "2.1.1"
|
6
|
+
- jruby-19mode
|
7
|
+
- jruby-20mode
|
8
|
+
|
9
|
+
notifications:
|
10
|
+
email:
|
11
|
+
on_failure: change
|
12
|
+
slack:
|
13
|
+
rooms:
|
14
|
+
- douglas:CkaMdC9JhYYG1NVbRXnu6xLc#general
|
15
|
+
- douglas:CkaMdC9JhYYG1NVbRXnu6xLc#infrastructure
|
data/Gemfile
ADDED
data/LICENSE.md
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2014 Watershed Legal Service, PLLC
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
22
|
+
|
23
|
+
In other words, don't be a jerk.
|
data/README.md
ADDED
@@ -0,0 +1,166 @@
|
|
1
|
+
# Introduction
|
2
|
+
|
3
|
+
EPM is a package (provision?) manager. It is meant to simplify the management of git hosted repositories which contain Ethereum standard or customized contracts. This package manager should work in the way which most package managers operate -- with the addition that it will be able to interact with the Ethereum BlockChain.
|
4
|
+
|
5
|
+
In addition to installing, uninstalling, updating, and upgrading your packages for you, the Gem will also act as a hub for different Ethereum contract building, testing, simulating, and deploying mechanisms.
|
6
|
+
|
7
|
+
The package manager builds in a standard tipping system which is -- by convention -- built to allow tipping of the EPM system as well as the other tools which developers use to build, test, and deploy their contracts onto the Ethereum BlockChain. The tipping system is on by default as a mechanism to assist in further development of Ethereum contract deployment products. It can, of course, be turned off (this is open source software).
|
8
|
+
|
9
|
+
# Installing
|
10
|
+
|
11
|
+
This is a Ruby gem and will require that you have Ruby on your system (unless and until someone ports this to Python or Node). Once you have ensured that you have Ruby on your system, `gem install epm`.
|
12
|
+
|
13
|
+
# Using
|
14
|
+
|
15
|
+
The gem is a command line tool. All of the commands are built to run primarily from the command line. Of course the gem will integrate as a Ruby gem into your Ruby application, but primarily it is meant to work from the command line.
|
16
|
+
|
17
|
+
## Contract Tools Features
|
18
|
+
|
19
|
+
`epm install` -- used like brew install to install a particular Ethereum tool. Use in conjuction with the `-l` or `--local` flag to install the tool as the local tool only for this particular project. Otherwise will install the tool as a global user tool.
|
20
|
+
|
21
|
+
`epm uninstall` -- used like brew uninstall to uninstall a particular Ethereum tool. Same restrictions for the `-l` or `--local` flag as with `epm install` are applicable to `epm uninstall`.
|
22
|
+
|
23
|
+
`epm upgrade` -- used like brew upgrade to upgrade a particular Ethereum tool. Same restrictions for the `-l` or `--local` flag as with `epm install` are applicable to `epm upgrade`.
|
24
|
+
|
25
|
+
`epm list` -- list installable tools.
|
26
|
+
|
27
|
+
`epm list-installed` -- list currently installed tools.
|
28
|
+
|
29
|
+
## Package Management Features
|
30
|
+
|
31
|
+
`epm pull` -- will pull contract provisions, contracts, or packages of contracts based on the contract definition files in the project folder. If used without calling any contract definition file after `epm pull` will pull all the necessary components for all of the contract definition files viewable from the project root. If used with a contract definition file after `epm pull` will pull all the necessary components for the contract definition file.
|
32
|
+
|
33
|
+
`epm push` -- will push contract provisions, contracts, or packages of contracts assembled in the project root to the repository noted in the local configuration file's `repository` setting
|
34
|
+
|
35
|
+
`epm update` -- will pull updates to the contract provisions, contracts, or packages of contracts based on the contract definition files in the project folder. Can be used with or without a contract definition file as with `epm pull`.
|
36
|
+
|
37
|
+
## Contract Workflow Features
|
38
|
+
|
39
|
+
`epm make` -- used to pull Ethereum provisions, contracts, or packaged and build out the application or package(s) in this project based on the contract definition files. If used without calling a particular contract definition file after `epm make` will make all the contract definition files visible from the project root (which is where epm make should be called from). If used with a particular contract definition file after `epm make` will only make that particular contract definition.
|
40
|
+
|
41
|
+
`epm test` -- used to test Ethereum contracts based upon the tester included in the global or local configuration file.
|
42
|
+
|
43
|
+
`epm simulate` -- used to simulate Ethereum contracts or sets of contracts based upon the simulator included in the global or locla configuration file.
|
44
|
+
|
45
|
+
`epm deploy` -- used to deploy contracts to the Ethereum blockchain.
|
46
|
+
|
47
|
+
`epm update-deployed` -- used to send a command to currently running contracts on the Ethereum blockchain to update themselves based on the git diff between the most recent commit of the project repository and the current commit when the contracts were deployed to the blockchain.
|
48
|
+
|
49
|
+
`epm destroy` -- used to send a suicide command to all of the contracts in the Ethereum blockchain which are derived from the project root.
|
50
|
+
|
51
|
+
## EPM Self-Reflective Features
|
52
|
+
|
53
|
+
`epm configure-local` -- open the local configuration file in the default editor.
|
54
|
+
|
55
|
+
`epm configure-global` -- open the global configuration file in the default editor.
|
56
|
+
|
57
|
+
`epm self-update` -- update the EPM tool to the latest version.
|
58
|
+
|
59
|
+
`epm implode` -- remove EPM entirely.
|
60
|
+
|
61
|
+
## Package Management Features
|
62
|
+
|
63
|
+
`epm install` --
|
64
|
+
|
65
|
+
`epm pull` --
|
66
|
+
|
67
|
+
`epm push` --
|
68
|
+
|
69
|
+
`epm destroy` --
|
70
|
+
|
71
|
+
`epm update` --
|
72
|
+
|
73
|
+
`epm list` --
|
74
|
+
|
75
|
+
## Contract Workflow Features
|
76
|
+
|
77
|
+
`epm make` --
|
78
|
+
|
79
|
+
`epm test` --
|
80
|
+
|
81
|
+
`epm simulate` --
|
82
|
+
|
83
|
+
`epm deploy` --
|
84
|
+
|
85
|
+
# Configuration Options
|
86
|
+
|
87
|
+
EPM uses what should be a fairly approachable two configuration layers approach to managing configurations. The first level which the gem will look at will be the `~/.epm/config.epm` file. These are the user global configurations. The global configurations will be overwritten by local configuration files in the config.epm file of the root directory of the project you are working on (for the time being epm should be called from this directory). The config.epm file is a [TOML](https://github.com/mojombo/toml) formated configuration file with the following options.
|
88
|
+
|
89
|
+
## Global Configuration Options
|
90
|
+
|
91
|
+
`editor` -- String denoting the path which EPM should call in order to edit the contract. Default: shell environment's editor.
|
92
|
+
|
93
|
+
`linter` -- String denoting the path which EPM should call in order to lint a contract. Default: ???
|
94
|
+
|
95
|
+
`tester` -- String denoting the path which EPM should call in order to run your test suite. Default: ???
|
96
|
+
|
97
|
+
`simulator` -- String denoting the path which EPM should call in order to start the simulator. Default: ???
|
98
|
+
|
99
|
+
`compiler` -- String denoting the path which EPM should call in order to compile the contract into the byte language for deployment to the Ethereum BlockChain. Default: ???
|
100
|
+
|
101
|
+
`blacklisted-repos` -- Array of strings denoting github or other git repos which are Blacklisted. Default: []
|
102
|
+
|
103
|
+
`deployer-keys` -- String denoting the public key of the deploying coder|lawyer -- which some or all contracts can use to ensure a tip is sent to the deployer.
|
104
|
+
|
105
|
+
`infrastructure-keys` -- Array of strings denoting the public keys of the testers, linters, simulators, package managers, and other infrastructure which the deployer used to assist in the deployment of the contract. Strings should be in the form `KEY:AMOUNT:MESSAGE` where KEY is the public hash which the contract will send the tip and where AMOUNT is the **percentage** of the tip which will go to this key. MESSAGE is the signing message of the tip and is optional.
|
106
|
+
|
107
|
+
## Local Configuration Options
|
108
|
+
|
109
|
+
The local configuration options include *all* of the global configuration options, and local configuration options will override the global configuration options. In addition, there are a few local configuration options which are not read by the global config file.
|
110
|
+
|
111
|
+
`name` -- String denoting the name of the package. If the package contains one contract the package and the contract will be the same thing. If the package contains more than one contract then the package will include all of the contracts.
|
112
|
+
|
113
|
+
`author` -- String denoting the author of the package.
|
114
|
+
|
115
|
+
`author-address` -- String denoting the Ethereum address of the author of the package (used for tipping system when others reuse the contract or package).
|
116
|
+
|
117
|
+
`repository` -- String denoting the remote git repository for the package. When the user calls `epm push` EPM will send the package to this address.
|
118
|
+
|
119
|
+
# Contract and Package Definition Files
|
120
|
+
|
121
|
+
EPM uses contract definition files to build and maintain contracts. Contract definition files are TOML files.
|
122
|
+
|
123
|
+
## Package Definition Files
|
124
|
+
|
125
|
+
Define the contracts used in the package and the relationships between them. TODO.
|
126
|
+
|
127
|
+
## Contract Definition Files -- Shortform
|
128
|
+
|
129
|
+
The shortform contract definition allows coder|lawyers to pull in \*.ethereum-contract files to the working folder to be tested, simulated, and deployed from established git repositories.
|
130
|
+
|
131
|
+
EPM will pull from any git repository, but it will default to github repositories, so when you send it the following repository: `watershedlegal/ethereum-boilerplate-prefaces` it will know that that is a github address. If you would like to add a private repository or a bitbucket or any other repository simply add the full address to the line. If the repository contains multiple `.ethereum-contract` files and you only want one of those files, you can state the contract you want EPM to pull into the working directory by specifying that instead of the repository in the `XXXXXXX.ethereum-definition` file.
|
132
|
+
|
133
|
+
The `XXXX.ethereum-definition` file will simply be a list of the repositories or contract files which EPM should import into the working directory's repo folder. After that it will be up to the coder|lawyer to build the contracts into a working network or meta contract, test, simulate, and deploy.
|
134
|
+
|
135
|
+
## Contract Definition Files -- Longform
|
136
|
+
|
137
|
+
The longform contract definition allows coder|lawyers to pull in pieces of contracts from different sources and have EPM attempt to assemble a cohesive contract in which the lawyer|coder can then edit before linting, testing, simulating, and deploying.
|
138
|
+
|
139
|
+
As with the shortform contract definitions, EPM will pull from any repository based on the rules described above. Addresses may point to the entire repository, in which case EPM will pull in all \*.ethereum-provision files. If only one file is wanted for the preface section, that file path can be specified after the repository address. In addition, if only certain line numbers of a certain file are desired to be pulled in then EPM will know to look for that when you add the following string: `REPONAME/FILEPATH:STARTLINE_ENDLINE` where STARTLINE and ENDLINE are the line numbers which you would like to be pulled in.
|
140
|
+
|
141
|
+
The contract definition file is also a TOML formatted configuration file. There are three sections to the contract definition file (which by convention should be XXXXX.ethereum-definition where XXXX is the name of the contract):
|
142
|
+
|
143
|
+
1. `provisions` -- Array of strings denoting the repository addresses which EPM will pull from and formulate into the main provisions of this contract.
|
144
|
+
2. `constants` -- Array of KEY:VALUE pairs which set the constant values after building a contract.
|
145
|
+
3. `tip-amount` -- Integer denoting the amount of ether to be distributed to the infrastructure network which helped you build and deploy this contract or system of contracts.
|
146
|
+
4. `constants` -- Array of KEY:VALUE pairs which set the constant values after building a contract.
|
147
|
+
5. `tip-amount` -- Integer denoting the amount of ether to be distributed to the infrastructure network which helped you build and deploy this contract or system of contracts.
|
148
|
+
|
149
|
+
# Roadmap / TODO
|
150
|
+
|
151
|
+
- [ ] Everything
|
152
|
+
|
153
|
+
# Contributing
|
154
|
+
|
155
|
+
1. Fork the repository.
|
156
|
+
2. Create your feature branch (`git checkout -b my-new-feature`).
|
157
|
+
3. Add Tests (and feel free to help here since I don't (yet) really know how to do that.).
|
158
|
+
4. Commit your changes (`git commit -am 'Add some feature'`).
|
159
|
+
5. Push to the branch (`git push origin my-new-feature`).
|
160
|
+
6. Create new Pull Request.
|
161
|
+
|
162
|
+
# License
|
163
|
+
|
164
|
+
MIT License - (c) 2014 - Watershed Legal Services, PLLC. All copyrights are owned by [Watershed Legal Services, PLLC](http://watershedlegal.com).
|
165
|
+
|
166
|
+
See License file.
|
data/Rakefile
ADDED
data/bin/epm
ADDED
@@ -0,0 +1,90 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# == USAGE
|
4
|
+
# epm subcommand [file]
|
5
|
+
require '../lib/epm.rb'
|
6
|
+
# args = ARGV
|
7
|
+
# EPM::parse args
|
8
|
+
|
9
|
+
require 'commander/import'
|
10
|
+
|
11
|
+
program :version, EPM.version
|
12
|
+
program :description, 'Ethereum Package Manager assists in the management of Ethereum Packages and Tools to ease developers workflows.'
|
13
|
+
|
14
|
+
##
|
15
|
+
## Package Workflow Commands
|
16
|
+
##
|
17
|
+
command :compile do |c|
|
18
|
+
c.syntax = 'epm compile'
|
19
|
+
c.description = 'Compile an ethereum contract and return the byte code array.'
|
20
|
+
c.action do |args|
|
21
|
+
result = EPM.compile(args)
|
22
|
+
result.each{|l| print l + "\n"}
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
command :create do |c|
|
27
|
+
c.syntax = 'epm create'
|
28
|
+
c.description = 'Compile an ethereum contract and deploy to the blockchain.'
|
29
|
+
c.action do |args|
|
30
|
+
result = EPM.create(args)
|
31
|
+
result.each{|l| print l + "\n"}
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
command :deploy do |c|
|
36
|
+
c.syntax = 'epm deploy'
|
37
|
+
c.description = 'Compile and deploy a system of contracts to the blockchain. See gem README for EPM package-definition file syntax.'
|
38
|
+
c.action do |args|
|
39
|
+
EPM.deploy(args)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
##
|
44
|
+
## EPM Tools
|
45
|
+
##
|
46
|
+
command :transact do |c|
|
47
|
+
c.syntax = 'epm transact'
|
48
|
+
c.description = 'Send a transaction to a contract. Note this is to work with contracts, it will not (by default) send ether.'
|
49
|
+
c.action do |args|
|
50
|
+
print "Transaction Sent.\n"
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
command :query do |c|
|
55
|
+
c.syntax = 'epm query'
|
56
|
+
c.description = 'Query a storage position of a contract currently on the blockchain.'
|
57
|
+
c.action do |args|
|
58
|
+
print EPM.query(args) + "\n"
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
command :start do |c|
|
63
|
+
c.syntax = 'epm start'
|
64
|
+
c.description = 'Start your default ethereum server.'
|
65
|
+
c.action do
|
66
|
+
print "Please be patient, this will take a few seconds.\n"
|
67
|
+
EPM.start
|
68
|
+
print "Server has started.\n"
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
command :stop do |c|
|
73
|
+
c.syntax = 'epm stop'
|
74
|
+
c.description = 'Stop your default ethereum server.'
|
75
|
+
c.action do
|
76
|
+
EPM.stop
|
77
|
+
print "Server has stopped.\n"
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
command :restart do |c|
|
82
|
+
c.syntax = 'epm restart'
|
83
|
+
c.summary = ''
|
84
|
+
c.description = 'Restart your default ethereum server.'
|
85
|
+
c.action do
|
86
|
+
print "Please be patient, this will take a few seconds.\n"
|
87
|
+
EPM.restart
|
88
|
+
print "Server has been restarted.\n"
|
89
|
+
end
|
90
|
+
end
|
data/epm.gemspec
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'epm/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = "epm"
|
8
|
+
s.version = VERSION
|
9
|
+
s.platform = Gem::Platform::RUBY
|
10
|
+
s.summary = "Ethereum Contracts Package Manager."
|
11
|
+
s.homepage = "https://github.com/ethereum-package-manager/epm"
|
12
|
+
s.authors = [ "Casey Kuhlman" ]
|
13
|
+
s.email = "caseykuhlman@watershedlegal.com"
|
14
|
+
|
15
|
+
s.date = Time.now.strftime('%Y-%m-%d')
|
16
|
+
s.has_rdoc = false
|
17
|
+
|
18
|
+
s.files = `git ls-files`.split($/)
|
19
|
+
s.executables = s.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
20
|
+
s.test_files = s.files.grep(%r{^(test|spec|features)/})
|
21
|
+
s.require_paths = ["lib"]
|
22
|
+
|
23
|
+
s.add_dependency "commander", "~> 4.1.6"
|
24
|
+
|
25
|
+
s.description = <<desc
|
26
|
+
This gem is designed to assist in distribution, dissemination, compilation, and deployment of Ethereum contracts.
|
27
|
+
desc
|
28
|
+
end
|
data/lib/epm.rb
ADDED
@@ -0,0 +1,81 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# std_lib
|
3
|
+
require 'fileutils'
|
4
|
+
require 'tempfile'
|
5
|
+
require 'shellwords'
|
6
|
+
require 'json'
|
7
|
+
require 'net/http'
|
8
|
+
require 'uri'
|
9
|
+
require 'optparse'
|
10
|
+
|
11
|
+
# this gem
|
12
|
+
Dir[File.dirname(__FILE__) + '/epm/*.rb'].each {|file| require file }
|
13
|
+
|
14
|
+
module EPM
|
15
|
+
extend self
|
16
|
+
|
17
|
+
def compile args
|
18
|
+
output = []
|
19
|
+
until args.empty?
|
20
|
+
file = args.shift
|
21
|
+
settings = setup
|
22
|
+
output << EPM::Compile.new(file, settings).compile
|
23
|
+
end
|
24
|
+
output
|
25
|
+
end
|
26
|
+
|
27
|
+
def create args
|
28
|
+
output = []
|
29
|
+
until args.empty?
|
30
|
+
file = args.shift
|
31
|
+
settings = setup
|
32
|
+
output << EPM::Create.new(file, settings).deploy
|
33
|
+
end
|
34
|
+
output
|
35
|
+
end
|
36
|
+
|
37
|
+
def deploy args
|
38
|
+
output = []
|
39
|
+
until args.empty?
|
40
|
+
file = args.shift
|
41
|
+
settings = setup
|
42
|
+
output << EPM::Deploy.new(file, settings).deploy_package
|
43
|
+
end
|
44
|
+
output
|
45
|
+
end
|
46
|
+
|
47
|
+
def transact args
|
48
|
+
recipient = args.shift
|
49
|
+
data = args
|
50
|
+
settings = setup
|
51
|
+
EPM::Transact.new(recipient, data, settings).transact
|
52
|
+
end
|
53
|
+
|
54
|
+
def query args
|
55
|
+
address = args.shift
|
56
|
+
position = args.shift
|
57
|
+
settings = setup
|
58
|
+
EPM::Query.new(address, position, settings).query
|
59
|
+
end
|
60
|
+
|
61
|
+
def version
|
62
|
+
return VERSION
|
63
|
+
end
|
64
|
+
|
65
|
+
def start
|
66
|
+
EPM::Server.start
|
67
|
+
end
|
68
|
+
|
69
|
+
def stop
|
70
|
+
EPM::Server.stop
|
71
|
+
end
|
72
|
+
|
73
|
+
def restart
|
74
|
+
EPM::Server.stop
|
75
|
+
EPM::Server.start
|
76
|
+
end
|
77
|
+
|
78
|
+
def setup
|
79
|
+
return EPM::Settings.check
|
80
|
+
end
|
81
|
+
end
|
data/lib/epm/compile.rb
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
module EPM
|
4
|
+
class Compile
|
5
|
+
def initialize file, settings={}
|
6
|
+
@file = EPM::FileHelpers.file_guard file
|
7
|
+
@settings = settings
|
8
|
+
end
|
9
|
+
|
10
|
+
def compile
|
11
|
+
if @file
|
12
|
+
if File.extname(@file) == '.lll'
|
13
|
+
return compile_lll
|
14
|
+
elsif File.extname(@file) == ('.mu' || '.mut')
|
15
|
+
return compile_mutan
|
16
|
+
elsif File.extname(@file) == ('.se' || '.ser')
|
17
|
+
return compile_serpent
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def compile_lll
|
23
|
+
contract = `#{@settings["path-to-lllc"]} #{@file}`
|
24
|
+
contract.chomp!
|
25
|
+
contract = EPM::HexData.hex_guard contract
|
26
|
+
return contract
|
27
|
+
end
|
28
|
+
|
29
|
+
def compile_serpent
|
30
|
+
contract = `#{@settings['path-to-serpent']} #{Shellwords.escape(@file)}`
|
31
|
+
contract.chomp!
|
32
|
+
return EPM::HexData.hex_guard contract
|
33
|
+
end
|
34
|
+
|
35
|
+
def compile_mutan
|
36
|
+
contract = `#{@settings['path-to-mutan']} #{Shellwords.escape(@file)}`
|
37
|
+
contract.chomp!
|
38
|
+
return EPM::HexData.hex_guard contract
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
data/lib/epm/create.rb
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
module EPM
|
4
|
+
class Create
|
5
|
+
def initialize file, settings={}
|
6
|
+
if file
|
7
|
+
@uri = URI.parse "http://localhost:#{settings['json-port']}"
|
8
|
+
@settings = settings
|
9
|
+
@contract = EPM::Compile.new(file, @settings).compile
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def deploy
|
14
|
+
if @settings['preferred-client'] == 'cpp'
|
15
|
+
params = {
|
16
|
+
'sec' => @settings["address-private-key"],
|
17
|
+
'xEndowment' => '',
|
18
|
+
'bCode' => @contract,
|
19
|
+
'xGas' => '100000',
|
20
|
+
'xGasPrice' => '100000000000000'
|
21
|
+
}
|
22
|
+
post_body = { 'method' => 'create', 'params' => params, 'id' => 'epm-rpc', "jsonrpc" => "2.0" }.to_json
|
23
|
+
elsif @settings['preferred-client'] == ('go' || 'ethereal')
|
24
|
+
params = {
|
25
|
+
'body' => @contract,
|
26
|
+
'value' => '',
|
27
|
+
'gas' => '100000',
|
28
|
+
'gasprice' => '100000000000000'
|
29
|
+
}
|
30
|
+
post_body = { 'method' => 'EthereumApi.Create', 'params' => params, 'id' => 'epm-rpc', 'jsonrpc' => '2.0'}.to_json
|
31
|
+
end
|
32
|
+
return EPM::Server.http_post_request @uri, post_body
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
data/lib/epm/deploy.rb
ADDED
@@ -0,0 +1,126 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
module EPM
|
4
|
+
class Deploy
|
5
|
+
def initialize def_file, settings={}
|
6
|
+
@dirname = File.dirname(File.absolute_path(def_file))
|
7
|
+
@log_file = File.join(ENV['HOME'], '.epm', 'deployed-log.csv')
|
8
|
+
@settings = settings
|
9
|
+
@brain = {}
|
10
|
+
@def_file = def_file
|
11
|
+
end
|
12
|
+
|
13
|
+
def deploy_package
|
14
|
+
if @def_file
|
15
|
+
commands = File.readlines @def_file
|
16
|
+
commands = commands.reject{|cmd| cmd[/\A#/] || cmd[/\A$/]}.map{|cmd| cmd.gsub("\n",'')}
|
17
|
+
commands = commands.inject([]) do |arr,ele|
|
18
|
+
ele[/\A\S+/] ? arr << [ele] : arr[-1] << ele.strip.split(' => ')
|
19
|
+
arr
|
20
|
+
end
|
21
|
+
commands.each do |cmd|
|
22
|
+
dowit = cmd.shift
|
23
|
+
case dowit
|
24
|
+
when 'deploy:'
|
25
|
+
deploy cmd.shift
|
26
|
+
sleep 1
|
27
|
+
when 'modify-deploy:'
|
28
|
+
modify_deploy cmd
|
29
|
+
sleep 1
|
30
|
+
when 'transact:'
|
31
|
+
transact cmd.shift
|
32
|
+
sleep 1
|
33
|
+
when 'query:'
|
34
|
+
query cmd.shift
|
35
|
+
when 'log:'
|
36
|
+
log cmd.shift
|
37
|
+
when 'set:'
|
38
|
+
set_var cmd.shift
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def deploy command
|
45
|
+
deploy_k = command.shift
|
46
|
+
k_name = command.shift
|
47
|
+
p "Deploying #{deploy_k} with name of #{k_name.gsub(/(\{|\})/,'')}."
|
48
|
+
k_address = EPM::Create.new(File.join(@dirname, deploy_k), @settings).deploy
|
49
|
+
@brain[k_name] = k_address
|
50
|
+
p "#{k_name} => #{k_address}"
|
51
|
+
end
|
52
|
+
|
53
|
+
def modify_deploy command
|
54
|
+
deploy_k = command[0].shift
|
55
|
+
deploy_k = EPM::FileHelpers.file_guard(File.join(@dirname, deploy_k))
|
56
|
+
k_name = command[0].shift
|
57
|
+
dump = command.shift
|
58
|
+
until command.empty?
|
59
|
+
cmd = command.shift
|
60
|
+
to_replace = cmd.shift
|
61
|
+
replacer = cmd.shift
|
62
|
+
until ! replacer[/(\{\{.*?\}\})/]
|
63
|
+
replacer.gsub!($1, @brain[$1])
|
64
|
+
end
|
65
|
+
k_value = File.read deploy_k
|
66
|
+
k_value = k_value.gsub "#{to_replace}", "#{replacer}"
|
67
|
+
File.open(deploy_k, 'w'){|f| f.write k_value}
|
68
|
+
end
|
69
|
+
p "After modifying, am deploying #{deploy_k} with name of #{k_name.gsub(/(\{|\})/,'')}."
|
70
|
+
k_address = EPM::Create.new(deploy_k, @settings).deploy
|
71
|
+
@brain[k_name] = k_address
|
72
|
+
p "#{k_name} => #{k_address}"
|
73
|
+
end
|
74
|
+
|
75
|
+
def transact command
|
76
|
+
recipient = command.shift
|
77
|
+
until ! recipient[/(\{\{.*?\}\})/]
|
78
|
+
recipient.gsub!($1, @brain[$1])
|
79
|
+
end
|
80
|
+
data = command.shift
|
81
|
+
until ! data[/(\{\{.*?\}\})/]
|
82
|
+
data.gsub!($1,@brain[$1])
|
83
|
+
end
|
84
|
+
data = data.split(' ')
|
85
|
+
p "Sending #{recipient} the data: #{data}."
|
86
|
+
EPM::Transact.new(recipient, data, @settings).transact
|
87
|
+
end
|
88
|
+
|
89
|
+
def query command
|
90
|
+
contract = command.shift
|
91
|
+
address = command.shift
|
92
|
+
name = command.shift
|
93
|
+
until ! contract[/(\{\{.*?\}\})/]
|
94
|
+
contract.gsub!($1,@brain[$1])
|
95
|
+
end
|
96
|
+
until ! address[/(\{\{.*?\}\})/]
|
97
|
+
address.gsub!($1,@brain[$1])
|
98
|
+
end
|
99
|
+
p "Querying #{contract} at: #{address}."
|
100
|
+
storage = EPM::Query.new(contract, address, @settings).query
|
101
|
+
p "#{contract}:#{address} => #{storage}"
|
102
|
+
@brain[name] = storage
|
103
|
+
end
|
104
|
+
|
105
|
+
def log command
|
106
|
+
address = command.shift
|
107
|
+
name = command.shift
|
108
|
+
until ! address[/(\{\{.*?\}\})/]
|
109
|
+
address.gsub!($1,@brain[$1])
|
110
|
+
end
|
111
|
+
until ! name[/(\{\{.*?\}\})/]
|
112
|
+
name.gsub!($1,@brain[$1])
|
113
|
+
end
|
114
|
+
log_entry = [address, name].join(',')
|
115
|
+
p "Logging [#{address},#{name}]"
|
116
|
+
`echo #{log_entry} >> #{@log_file}`
|
117
|
+
end
|
118
|
+
|
119
|
+
def set_var command
|
120
|
+
key = command.shift
|
121
|
+
value = command.shift
|
122
|
+
p "Setting #{key} to #{value}"
|
123
|
+
@brain[key] = value
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
data/lib/epm/query.rb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
module EPM
|
4
|
+
class Query
|
5
|
+
def initialize address, position, settings={}
|
6
|
+
@uri = URI.parse "http://localhost:#{settings['json-port']}"
|
7
|
+
@settings = settings
|
8
|
+
@address = EPM::HexData.hex_guard address
|
9
|
+
@position = EPM::HexData.hex_guard position
|
10
|
+
end
|
11
|
+
|
12
|
+
def query
|
13
|
+
if @settings['preferred-client'] == 'cpp'
|
14
|
+
params = {
|
15
|
+
'a' => @address,
|
16
|
+
'x' => @position
|
17
|
+
}
|
18
|
+
post_body = { 'method' => 'storageAt', 'params' => params, 'id' => 'epm-rpc', "jsonrpc" => "2.0" }.to_json
|
19
|
+
elsif @settings['preferred-client'] == ('go' || 'ethereal')
|
20
|
+
params = {
|
21
|
+
'address' => @address,
|
22
|
+
'key' => @position
|
23
|
+
}
|
24
|
+
post_body = { 'method' => 'EthereumApi.GetStorageAt', 'params' => params, 'id' => 'epm-rpc', "jsonrpc" => "2.0" }.to_json
|
25
|
+
end
|
26
|
+
return EPM::Server.http_post_request @uri, post_body
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
data/lib/epm/transact.rb
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
module EPM
|
4
|
+
class Transact
|
5
|
+
def initialize recipient, data, settings={}
|
6
|
+
@uri = URI.parse "http://localhost:#{settings['json-port']}"
|
7
|
+
@settings = settings
|
8
|
+
@recipient = EPM::HexData.hex_guard recipient
|
9
|
+
@data = EPM::HexData.construct_data data
|
10
|
+
end
|
11
|
+
|
12
|
+
def transact
|
13
|
+
if @settings['preferred-client'] == 'cpp'
|
14
|
+
params = {
|
15
|
+
'sec' => @settings["address-private-key"],
|
16
|
+
'xValue' => '',
|
17
|
+
'aDest' => @recipient,
|
18
|
+
'bData' => @data,
|
19
|
+
'xGas' => '100000',
|
20
|
+
'xGasPrice' => '100000000000000'
|
21
|
+
}
|
22
|
+
post_body = { 'method' => 'transact', 'params' => params, 'id' => 'epm-rpc', "jsonrpc" => "2.0" }.to_json
|
23
|
+
elsif @settings['preferred-client'] == ('go' || 'ethereal')
|
24
|
+
params = {
|
25
|
+
'recipient' => @recipient,
|
26
|
+
'value' => '',
|
27
|
+
'gas' => '100000',
|
28
|
+
'gasprice' => '100000000000000',
|
29
|
+
'body' => @data,
|
30
|
+
}
|
31
|
+
post_body = { 'method' => 'EthereumApi.Transact', 'params' => params, 'id' => 'epm-rpc', "jsonrpc" => "2.0" }.to_json
|
32
|
+
end
|
33
|
+
return EPM::Server.http_post_request @uri, post_body
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
data/lib/epm/utils.rb
ADDED
@@ -0,0 +1,154 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
module EPM
|
4
|
+
module Server
|
5
|
+
extend self
|
6
|
+
|
7
|
+
def start debug=false
|
8
|
+
settings = EPM::Settings.check
|
9
|
+
if debug
|
10
|
+
debug = ''
|
11
|
+
else
|
12
|
+
debug = '>> /dev/null'
|
13
|
+
end
|
14
|
+
|
15
|
+
unless is_eth_running?
|
16
|
+
case settings['preferred-client']
|
17
|
+
when 'cpp'
|
18
|
+
server = "#{settings["path-to-eth"]} --json-rpc-port #{settings['json-port']} -r #{settings["remote"]} -d #{settings["directory"]} -m off -l #{settings["eth-listen-port"]} -c #{settings["name"]} -s #{settings["address-private-key"]} #{debug}"
|
19
|
+
when 'go'
|
20
|
+
server = "#{settings['path-to-go-ethereum']}"
|
21
|
+
when 'ethereal'
|
22
|
+
server = "#{settings['path-to-ethereal']}"
|
23
|
+
end
|
24
|
+
pid = spawn server
|
25
|
+
sleep 7
|
26
|
+
end
|
27
|
+
return pid
|
28
|
+
end
|
29
|
+
|
30
|
+
def stop
|
31
|
+
if is_eth_running?
|
32
|
+
processes = eth_processes.map{|e| e.split(' ')[1]}
|
33
|
+
processes.each{|p| `kill #{p}`}
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def is_eth_running?
|
38
|
+
eth = eth_processes
|
39
|
+
return (! eth.empty?)
|
40
|
+
end
|
41
|
+
|
42
|
+
def eth_processes
|
43
|
+
a = `ps ux`.split("\n").select{|e| e[/eth --json-rpc-port/]}
|
44
|
+
# a << `ps ux`.split("\n").select{|e| e[/ethereum/]}
|
45
|
+
a << `ps ux`.split("\n").select{|e| e[/ethereal/]}
|
46
|
+
a = a.flatten
|
47
|
+
return a
|
48
|
+
end
|
49
|
+
|
50
|
+
def http_post_request uri, post_body
|
51
|
+
unless is_eth_running?
|
52
|
+
p "Ethereum RPC Server is not running. Starting now. Please be patient for it to load."
|
53
|
+
start
|
54
|
+
end
|
55
|
+
http = Net::HTTP.new uri.host, uri.port
|
56
|
+
request = Net::HTTP::Post.new uri.request_uri
|
57
|
+
request.content_type = 'application/json'
|
58
|
+
request.body = post_body
|
59
|
+
result = JSON.parse(http.request(request).body)['result']
|
60
|
+
return result
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
module Settings
|
65
|
+
extend self
|
66
|
+
|
67
|
+
def check
|
68
|
+
install_setup_file unless have_setup_file
|
69
|
+
return load_settings
|
70
|
+
end
|
71
|
+
|
72
|
+
def have_setup_file
|
73
|
+
settings_file = File.join(ENV['HOME'], '.epm', 'epm-rpc.json')
|
74
|
+
File.exists? settings_file
|
75
|
+
end
|
76
|
+
|
77
|
+
def install_setup_file
|
78
|
+
settings_example = File.join(File.dirname(__FILE__), '..', '..', 'settings', 'epm-rpc.json')
|
79
|
+
settings_file = File.join(ENV['HOME'], '.epm', 'epm-rpc.json')
|
80
|
+
unless Dir.exists? File.dirname settings_file
|
81
|
+
FileUtils.mkdir(File.dirname settings_file)
|
82
|
+
end
|
83
|
+
FileUtils.cp settings_example, settings_file
|
84
|
+
end
|
85
|
+
|
86
|
+
def install_log_file
|
87
|
+
log_file = File.join(ENV['HOME'], '.epm', 'deployed-log.csv')
|
88
|
+
unless File.exists? log_file
|
89
|
+
File.open(log_file, "w") {}
|
90
|
+
end
|
91
|
+
return log_file
|
92
|
+
end
|
93
|
+
|
94
|
+
def load_settings
|
95
|
+
settings_file = File.join(ENV['HOME'], '.epm', 'epm-rpc.json')
|
96
|
+
settings = JSON.parse(File.read(settings_file))
|
97
|
+
log_file = install_log_file
|
98
|
+
settings["log_file"] = log_file
|
99
|
+
return settings
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
module HexData
|
104
|
+
extend self
|
105
|
+
|
106
|
+
def hex_guard data
|
107
|
+
if data[0..1] != "0x"
|
108
|
+
data = "0x" + data
|
109
|
+
end
|
110
|
+
return data
|
111
|
+
end
|
112
|
+
|
113
|
+
def construct_data deconstructed_data
|
114
|
+
data = "0x"
|
115
|
+
deconstructed_data.each do |bits|
|
116
|
+
if bits[0..1] == "0x"
|
117
|
+
piece = bits[2..-1]
|
118
|
+
piece = piece.rjust(64,'0')
|
119
|
+
else
|
120
|
+
piece = bits.unpack('c*').map{|s| s.to_s(16)}.join('')
|
121
|
+
piece = piece.ljust(64,'0')
|
122
|
+
end
|
123
|
+
data << piece
|
124
|
+
end
|
125
|
+
return data
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
module FileHelpers
|
130
|
+
extend self
|
131
|
+
|
132
|
+
def file_guard file
|
133
|
+
contents = File.read file
|
134
|
+
dir = File.dirname(File.absolute_path(file))
|
135
|
+
unless dir == '/tmp'
|
136
|
+
include_pattern = /(\(include \")(\..*)(\"\))/
|
137
|
+
if contents[include_pattern]
|
138
|
+
included = File.join(dir, $2)
|
139
|
+
included = $1 + included + $3
|
140
|
+
contents.gsub!(include_pattern, included)
|
141
|
+
end
|
142
|
+
save_temp_file contents, file
|
143
|
+
else
|
144
|
+
return file
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
def save_temp_file contents, file
|
149
|
+
tmp = Tempfile.new ['epm', File.extname(file)]
|
150
|
+
File.open(tmp, 'w'){|f| f.write contents}
|
151
|
+
return tmp.path
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
data/lib/epm/version.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
VERSION = "0.3.1"
|
@@ -0,0 +1,17 @@
|
|
1
|
+
{
|
2
|
+
"path-to-ruby": "ruby",
|
3
|
+
"path-to-eth": "/opt/cpp-ethereum/build/eth/eth", // cpp client
|
4
|
+
"path-to-ethereal": "ethereal",
|
5
|
+
"path-to-go-ethereum": "ethereum",
|
6
|
+
"path-to-lllc": "/opt/cpp-ethereum/build/lllc/lllc",
|
7
|
+
"path-to-mutan": "mutan",
|
8
|
+
"path-to-serpent": "serpent",
|
9
|
+
"preferred-client": "cpp", // can also use `go` <- which will run go headless or `ethereal` <- qt go client.
|
10
|
+
"json-port": "9090",
|
11
|
+
"remote": "remote", // this would typically be the default peer server for your client variant
|
12
|
+
"directory": "~/.ethereum", // in cpp world Aleth defaults to this so change to a different directory to run eth headless in
|
13
|
+
"eth-listen-port": "30303", // see the comment above
|
14
|
+
"name": "name", // this is the client name
|
15
|
+
"address-public-key": "0xact",
|
16
|
+
"address-private-key": "0xsec"
|
17
|
+
}
|
@@ -0,0 +1,15 @@
|
|
1
|
+
{
|
2
|
+
(include "./test2.lll")
|
3
|
+
(def 'DOUG 0x9c0182658c9d57928b06d3ee20bb2b619a9cbf7b)
|
4
|
+
(def 'BAindicator 0x10)
|
5
|
+
[[BAindicator]]0x88554646BA
|
6
|
+
[[69]] (caller)
|
7
|
+
[[0xDEADBEEF]]DOUG
|
8
|
+
(return 0 (lll
|
9
|
+
(when (= (caller) @@69)
|
10
|
+
(for {} (< @i (calldatasize)) [i](+ @i 64)
|
11
|
+
[[ (calldataload @i) ]] (calldataload (+ @i 32))
|
12
|
+
)
|
13
|
+
)
|
14
|
+
0))
|
15
|
+
}
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# Package Name: EPM Test
|
2
|
+
# Package Author: Casey Kuhlman
|
3
|
+
# Package Email: casey@projectdouglas.org
|
4
|
+
# Package Repository: https://github.com/ethereum-package-manager/epm
|
5
|
+
|
6
|
+
deploy:
|
7
|
+
test.lll => {{DOUG}}
|
8
|
+
modify-deploy:
|
9
|
+
test.lll => {{rep}}
|
10
|
+
(def 'DOUG 0x9c0182658c9d57928b06d3ee20bb2b619a9cbf7b) => (def 'DOUG {{DOUG}})
|
11
|
+
transact:
|
12
|
+
{{DOUG}} => rep {{rep}}
|
13
|
+
query:
|
14
|
+
{{DOUG}} => 0x7265700000000000000000000000000000000000000000000000000000000000 => {{KEYVALSTORE}}
|
15
|
+
log:
|
16
|
+
{{KEYVALSTORE}} => {{rep}}
|
metadata
ADDED
@@ -0,0 +1,81 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: epm
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.3.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Casey Kuhlman
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-06-11 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: commander
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 4.1.6
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 4.1.6
|
27
|
+
description: |2
|
28
|
+
This gem is designed to assist in distribution, dissemination, compilation, and deployment of Ethereum contracts.
|
29
|
+
email: caseykuhlman@watershedlegal.com
|
30
|
+
executables:
|
31
|
+
- epm
|
32
|
+
extensions: []
|
33
|
+
extra_rdoc_files: []
|
34
|
+
files:
|
35
|
+
- ".gitignore"
|
36
|
+
- ".travis.yml"
|
37
|
+
- Gemfile
|
38
|
+
- LICENSE.md
|
39
|
+
- README.md
|
40
|
+
- Rakefile
|
41
|
+
- bin/epm
|
42
|
+
- epm.gemspec
|
43
|
+
- lib/epm.rb
|
44
|
+
- lib/epm/compile.rb
|
45
|
+
- lib/epm/create.rb
|
46
|
+
- lib/epm/deploy.rb
|
47
|
+
- lib/epm/query.rb
|
48
|
+
- lib/epm/transact.rb
|
49
|
+
- lib/epm/utils.rb
|
50
|
+
- lib/epm/version.rb
|
51
|
+
- settings/epm-rpc.json
|
52
|
+
- spec/fixtures/test.lll
|
53
|
+
- spec/fixtures/test.package-definition
|
54
|
+
- spec/fixtures/test2.lll
|
55
|
+
homepage: https://github.com/ethereum-package-manager/epm
|
56
|
+
licenses: []
|
57
|
+
metadata: {}
|
58
|
+
post_install_message:
|
59
|
+
rdoc_options: []
|
60
|
+
require_paths:
|
61
|
+
- lib
|
62
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
63
|
+
requirements:
|
64
|
+
- - ">="
|
65
|
+
- !ruby/object:Gem::Version
|
66
|
+
version: '0'
|
67
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
68
|
+
requirements:
|
69
|
+
- - ">="
|
70
|
+
- !ruby/object:Gem::Version
|
71
|
+
version: '0'
|
72
|
+
requirements: []
|
73
|
+
rubyforge_project:
|
74
|
+
rubygems_version: 2.2.2
|
75
|
+
signing_key:
|
76
|
+
specification_version: 4
|
77
|
+
summary: Ethereum Contracts Package Manager.
|
78
|
+
test_files:
|
79
|
+
- spec/fixtures/test.lll
|
80
|
+
- spec/fixtures/test.package-definition
|
81
|
+
- spec/fixtures/test2.lll
|