teth 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 7635b781f5fd78703f5bbddb1dcea9fd0804eb0c
4
+ data.tar.gz: 47c054a1f298a4e8ff2645af025a1cc347a40945
5
+ SHA512:
6
+ metadata.gz: c8582ab1a8eb8152f4d61e7d6203cdacf6eac0d0182fe2b02db75af672f518de50a86fab6b4b96ab09908506ca9d3a984de40c5665e5772c688e3eabaf0f0a62
7
+ data.tar.gz: 411a9aee288dfb9c0d84f247afee074d02026277eec33dea92187fd8096b6d1c6262a9eab93490c988d40fe76d97629569468376d216cb9472a9cf77e68d1615
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2016 YaNing Zhang, Jan Xie
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 all
13
+ 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 THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,77 @@
1
+ ## Introduction
2
+ Teth is a Ethereum smart contract test framework in ruby.It provides two testing environments: testing in ruby EVM and testing in geth.You don't need to understand ruby grammar, just enjoy syntactic sugar.
3
+
4
+ ## Dependencies
5
+ - Solidity ~> 0.3.6
6
+ - Ruby ~> 2.2.2
7
+ - Go-ethereum ~> 1.4.11
8
+
9
+ ## Install
10
+ ```shell
11
+ bundle install teth
12
+ ```
13
+
14
+ ## How to use
15
+
16
+ Help command:
17
+ ```
18
+ $ teth
19
+ ```
20
+ Create a new Smart Contract application
21
+ ```
22
+ $ teth n project
23
+ $ cd project
24
+ ```
25
+ Generate new Smart Contract and test file
26
+ ```
27
+ $ teth g game
28
+ ```
29
+ Run tests
30
+ ```
31
+ $ teth t game
32
+ ```
33
+
34
+ ## Unit tests
35
+ You can wirte fast, simple tests.
36
+ ```ruby
37
+ class TokenTest < Minitest::Test
38
+ include Ethereum
39
+
40
+ def setup
41
+ @state = Tester::State.new
42
+ @solidity_code = File.read('./contracts/Token.sol')
43
+ @c = @state.abi_contract @solidity_code, language: :solidity
44
+ end
45
+
46
+ def test_issue_balance
47
+ assert_equal 0, @c.getBalance(Tester::Fixture.accounts[2])
48
+ @c.issue Tester::Fixture.accounts[2], 100
49
+ assert_equal 100, @c.getBalance(Tester::Fixture.accounts[2])
50
+ end
51
+
52
+ def test_issue_exception
53
+ assert_raises(TransactionFailed) { @c.issue Tester::Fixture.accounts[3], 100, sender: Tester::Fixture.keys[4] }
54
+ assert_equal 0, @c.getBalance(Tester::Fixture.accounts[3])
55
+ end
56
+
57
+ def test_token_transfer
58
+ @c.issue Tester::Fixture.accounts[2], 100
59
+ @c.transfer Tester::Fixture.accounts[3], 90, sender: Tester::Fixture.keys[2]
60
+ assert_equal 90, @c.getBalance(Tester::Fixture.accounts[3])
61
+
62
+ assert_raises(TransactionFailed) { @c.transfer Tester::Fixture.accounts[3], 90, sender: Tester::Fixture.keys[2] }
63
+ end
64
+ end
65
+
66
+ ```
67
+ More details:
68
+ https://github.com/seattlerb/minitest
69
+
70
+ ## TODO
71
+ - Extract test file require and others
72
+ - Save migrate address
73
+ - Migrate ARGV
74
+ - Script for preload
75
+ - Easy way to load contract on chain
76
+ - Easy way to test on chain
77
+ - ES6
data/bin/teth ADDED
@@ -0,0 +1,170 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'erb'
4
+ require 'json'
5
+ require 'fileutils'
6
+
7
+ ARGV << "--help" if ARGV.empty?
8
+
9
+ ALIASES = {
10
+ "n" => "new",
11
+ "g" => "generate",
12
+ "t" => "test",
13
+ "i" => "init",
14
+ "ik" => "import_keys",
15
+ "b" => "build",
16
+ "m" => "migrate",
17
+ "s" => "server",
18
+ "c" => "console",
19
+ "gt" => "geth_test"
20
+ }
21
+
22
+ command = ARGV.shift
23
+ command = ALIASES[command] || command
24
+
25
+ HELP_MESSAGE = <<-EOF
26
+ Usage: teth COMMAND [ARGS]
27
+ The most common teth commands are:
28
+ new Create a new Smart Contract application. "teth new my_app" creates a
29
+ new application called MyApp in "./my_app" (short-cut alias: "n")
30
+ generate Generate new Smart Contract and test file (short-cut alias: "g")
31
+ test Run tests (short-cut alias: "t")
32
+ init Init private geth chain (short-cut alias: "i")
33
+ import_keys Import keys to chain (short-cut alias: "ik")
34
+ build Build contract (short-cut alias: "b")
35
+ migrate Deploy contract on chain (short-cut alias: "m")
36
+ server Start chain server (short-cut alias: "s")
37
+ console Open Chain console (short-cut alias: "c")
38
+ geth_test Test on chain (short-cut alias: "gt")
39
+
40
+ All commands can be run with -h (or --help) for more information.
41
+ EOF
42
+
43
+ KEYS_TEMPLATE = {
44
+ "3ae88fe370c39384fc16da2c9e768cf5d2495b48" => "095e53c9c20e23fd01eaad953c01da9e9d3ed9bebcfed8e5b2c2fce94037d963",
45
+ "81063419f13cab5ac090cd8329d8fff9feead4a0" => "5bc505a123a695176a9688ffe22798cfd40424c5b91c818e985574ea8ebda167",
46
+ "9da26fc2e1d6ad9fdd46138906b0104ae68a65d8" => "b6a03207128827eaae0d31d97a7a6243de31f2baf99eabd764e33389ecf436fc"
47
+ }
48
+
49
+ def gem_dir
50
+ spec = Gem::Specification.find_by_name("teth")
51
+ spec.gem_dir
52
+ end
53
+
54
+ def new
55
+ name = ARGV.shift
56
+ if name
57
+ puts "Creating project #{name}..."
58
+ system("mkdir #{name} && cd #{name} && mkdir private_keys && mkdir builds && mkdir db && mkdir contracts && mkdir tests")
59
+
60
+ gemfile = File.read("#{gem_dir}/lib/teth/erbs/Gemfile")
61
+
62
+ File.open("#{name}/Gemfile", "w+") {|f| f.write(gemfile) }
63
+ system("cd #{name} && bundle install")
64
+
65
+ KEYS_TEMPLATE.each do |k, v|
66
+ File.open("#{name}/private_keys/#{k}.key", "w+") { |f| f.write(v) }
67
+ end
68
+
69
+ FileUtils.cp("#{gem_dir}/lib/teth/templates/private_keys/import.sh", "#{name}/private_keys/import.sh")
70
+ FileUtils.chmod 0700, "#{name}/private_keys/import.sh"
71
+
72
+ FileUtils.cp("#{gem_dir}/lib/teth/templates/genesis.json", "#{name}/genesis.json")
73
+ FileUtils.cp("#{gem_dir}/lib/teth/templates/rakefile", "#{name}/rakefile")
74
+
75
+ FileUtils.cp_r("#{gem_dir}/lib/teth/templates/bin/", "#{name}")
76
+ FileUtils.chmod_R 0700, "#{name}/bin/"
77
+ puts "Done."
78
+ else
79
+ puts "Need project name"
80
+ end
81
+ end
82
+
83
+ def generate
84
+ name = ARGV.shift
85
+ if name
86
+ contract_template = ERB.new File.read("#{gem_dir}/lib/teth/erbs/contract.sol")
87
+ contract = contract_template.result(binding)
88
+ puts "Create #{name.capitalize}.sol contract file..."
89
+ File.open("contracts/#{name.capitalize}.sol", "w+") { |f| f.write(contract) }
90
+
91
+ test_template = ERB.new File.read("#{gem_dir}/lib/teth/erbs/contract_test.rb")
92
+ test = test_template.result(binding)
93
+ puts "Create #{name}_test.rb test file..."
94
+ File.open("tests/#{name.capitalize}_test.rb", "w+") {|f| f.write(test) }
95
+ puts "Done."
96
+ else
97
+ puts "Need contract name"
98
+ end
99
+ end
100
+
101
+ def test
102
+ name = ARGV.shift
103
+ if name
104
+ puts "Test #{name.capitalize} contract..."
105
+ system("bundle exec ruby -Ilib:test tests/#{name}_test.rb")
106
+ else
107
+ puts "Test all contracts..."
108
+ system("bundle exec rake")
109
+ end
110
+ puts "Done."
111
+ end
112
+
113
+ def init
114
+ system("./bin/init.sh")
115
+ end
116
+
117
+ def import_keys
118
+ system("./bin/import_keys.sh")
119
+ end
120
+
121
+ def build
122
+ name = ARGV.shift
123
+ system("./bin/build.sh #{name}")
124
+ end
125
+
126
+ def server
127
+ system("./bin/private_blockchain.sh")
128
+ end
129
+
130
+ def migrate
131
+ name = ARGV.shift
132
+ system("./bin/migrate.sh #{name}")
133
+ end
134
+
135
+ def console
136
+ system("./bin/attach.sh")
137
+ end
138
+
139
+ def geth_test
140
+ system("./bin/test.sh")
141
+ end
142
+
143
+ def help
144
+ write_help_message
145
+ end
146
+
147
+ def write_help_message
148
+ puts HELP_MESSAGE
149
+ end
150
+
151
+ def parse_command(command)
152
+ case command
153
+ when "--help", "-h"
154
+ "help"
155
+ else
156
+ command
157
+ end
158
+ end
159
+
160
+ def run_command!(command)
161
+ command = parse_command(command)
162
+
163
+ if ALIASES.values.include?(command)
164
+ send(command)
165
+ else
166
+ help
167
+ end
168
+ end
169
+
170
+ run_command!(command)
@@ -0,0 +1,15 @@
1
+ module Teth
2
+ module Configurable
3
+ def option(name, default=nil)
4
+ singleton_class.send(:define_method, name) do |*args|
5
+ if args.empty?
6
+ v = instance_variable_get("@#{name}")
7
+ return default if v.nil?
8
+ v
9
+ else
10
+ instance_variable_set("@#{name}", args[0])
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1 @@
1
+ gem 'teth', '>= 0.1.0'
@@ -0,0 +1,2 @@
1
+ contract <%= name.capitalize %> {
2
+ }
@@ -0,0 +1,6 @@
1
+ require 'teth/minitest'
2
+
3
+ class <%=name.capitalize%>Test < Teth::Minitest
4
+ print_logs false
5
+ print_events false
6
+ end
@@ -0,0 +1,164 @@
1
+ require 'minitest/autorun'
2
+ require 'ethereum'
3
+
4
+ require 'teth/configurable'
5
+
6
+ module Teth
7
+ class Minitest < ::Minitest::Test
8
+ extend Configurable
9
+ include Ethereum
10
+
11
+ option :contract_dir_name, 'contracts'
12
+ option :account_num, 10
13
+ option :print_events, false
14
+ option :print_logs, true
15
+
16
+ def setup
17
+ path = find_contract_source
18
+ raise "Cannot find corresponding contract source" unless path
19
+ setup_contract(path)
20
+ end
21
+
22
+ def teardown
23
+ @state = nil
24
+ @account = nil
25
+ @contract = nil
26
+ end
27
+
28
+ def setup_contract(path)
29
+ case path
30
+ when /\.sol\z/
31
+ type = :solidity
32
+ when /\.se\z/
33
+ raise NotImplemented, "Serpent not supported yet"
34
+ else
35
+ raise "Unknown contract source type: #{path}"
36
+ end
37
+
38
+ code = File.read path
39
+ log_listener = ->(log) do
40
+ if log.instance_of?(Log) # unrecognized event
41
+ if self.class.print_logs
42
+ topics = log.topics.map {|t| heuristic_prettify Utils.int_to_big_endian(t) }
43
+ data = heuristic_prettify(log.data)
44
+ puts "[Log] #{Utils.encode_hex(log.address)} >>> topics=#{topics} data=#{data}"
45
+ end
46
+ else # user defined event
47
+ if self.class.print_logs && self.class.print_events
48
+ from = log.delete '_from'
49
+ name = log.delete '_event_type'
50
+ s = log.keys.map {|k| "#{k}=#{log[k]}" }.join(' ')
51
+ puts "[Event] #{from} #{name} >>> #{s}"
52
+ end
53
+ end
54
+ end
55
+ @contract = state.abi_contract code,
56
+ language: type, sender: privkey, log_listener: log_listener
57
+ end
58
+
59
+ def heuristic_prettify(bytes)
60
+ dry_bytes = bytes.gsub(/\A(\x00)+/, '')
61
+ dry_bytes = dry_bytes.gsub(/(\x00)+\z/, '')
62
+ if (bytes.size - dry_bytes.size) > 3
63
+ # there's many ZERO bytes in the head or tail of bytes, it must be padded
64
+ if dry_bytes.size == 20 # address
65
+ Utils.encode_hex(dry_bytes)
66
+ else
67
+ dry_bytes
68
+ end
69
+ else
70
+ Utils.encode_hex(bytes)
71
+ end
72
+ end
73
+
74
+ def contract
75
+ @contract
76
+ end
77
+
78
+ def find_contract_source
79
+ name = self.class.name[0...-4]
80
+ dir = find_contracts_directory
81
+ find_source(dir, name, 'sol') || find_source(dir, name, 'se')
82
+ end
83
+
84
+ def find_contracts_directory
85
+ last = nil
86
+ cur = ENV['PWD']
87
+ while cur != last
88
+ path = File.join cur, self.class.contract_dir_name
89
+ return path if File.directory?(path)
90
+ last = cur
91
+ cur = File.dirname cur
92
+ end
93
+ nil
94
+ end
95
+
96
+ def find_source(dir, name, ext)
97
+ name = "#{name}.#{ext}"
98
+ list = Dir.glob File.join(dir, "**/*.#{ext}")
99
+ list.find {|fn| File.basename(fn) =~ /\A#{name}\z/i }
100
+ end
101
+
102
+ ##
103
+ # Fixtures
104
+ #
105
+
106
+ @@privkeys = account_num.times.map do |i|
107
+ Utils.keccak256 rand(Constant::TT256).to_s
108
+ end
109
+
110
+ def privkey
111
+ account[0]
112
+ end
113
+
114
+ def pubkey
115
+ account[1]
116
+ end
117
+
118
+ def address
119
+ account[2]
120
+ end
121
+
122
+ def account
123
+ return @account if @account
124
+
125
+ i = rand(self.class.account_num)
126
+ @account = [privkeys[i], pubkeys[i], addresses[i]]
127
+ end
128
+
129
+ def privkeys
130
+ @privkeys ||= @@privkeys
131
+ end
132
+
133
+ def pubkeys
134
+ @pubkeys ||= privkeys.map {|k| PrivateKey.new(k).to_pubkey }
135
+ end
136
+
137
+ def addresses
138
+ @addresses ||= privkeys.map {|k| PrivateKey.new(k).to_address }
139
+ end
140
+
141
+ %w(alice bob carol chuck dave eve mallet oscar sybil).each_with_index do |n, i|
142
+ class_eval <<-METHOD
143
+ def #{n}
144
+ addresses[#{i}]
145
+ end
146
+ def #{n}_pubkey
147
+ pubkeys[#{i}]
148
+ end
149
+ def #{n}_privkey
150
+ privkeys[#{i}]
151
+ end
152
+ METHOD
153
+ end
154
+
155
+ def state
156
+ @state ||= Tester::State.new privkeys: privkeys
157
+ end
158
+
159
+ def head
160
+ state.head
161
+ end
162
+
163
+ end
164
+ end
@@ -0,0 +1,4 @@
1
+ #!/bin/bash
2
+
3
+ geth=${GETH:-geth}
4
+ $geth attach ipc:data/geth.ipc
@@ -0,0 +1,30 @@
1
+ #!/bin/bash
2
+ if [ -z "$1" ]
3
+ then
4
+ echo "Build all contracts ..."
5
+ for sol in `find ./contracts -name '*.sol'`
6
+ do
7
+ filename="${sol}"
8
+ echo "Build ${filename}"
9
+ let len=${#filename}-16
10
+ # echo $len
11
+ jsfile="${filename:12:len}_compiled.js"
12
+ echo $jsfile
13
+ ./bin/solc_helper.rb $sol $jsfile
14
+ mv $jsfile builds/
15
+ done
16
+ echo "Done."
17
+ else
18
+ foo=$1
19
+ foo="$(tr '[:lower:]' '[:upper:]' <<< ${foo:0:1})${foo:1}"
20
+ sol="contracts/$1.sol"
21
+ filename="${sol}"
22
+ echo "Build ${filename}"
23
+ let len=${#filename}-16
24
+ # echo $len
25
+ jsfile="${foo}_compiled.js"
26
+ echo "Build $foo to $jsfile"
27
+ ./bin/solc_helper.rb $sol $jsfile
28
+ mv $jsfile builds/
29
+ echo "Done."
30
+ fi
@@ -0,0 +1,13 @@
1
+ #!/bin/sh
2
+
3
+ geth=${GETH:-geth}
4
+ echo "***** Using geth at: $geth"
5
+
6
+ echo "***** Import all pre-funded private keys"
7
+
8
+ for key in `find ./private_keys -name '*.key'`
9
+ do
10
+ ./private_keys/import.sh $key $geth
11
+ done
12
+
13
+ echo "***** Done."
@@ -0,0 +1,2 @@
1
+ #! /bin/bash
2
+ geth --datadir `pwd`/data init genesis.json
@@ -0,0 +1,22 @@
1
+ #!/bin/bash
2
+
3
+ geth=${GETH:-geth}
4
+
5
+ if [ -z "$1" ]
6
+ then
7
+ echo "Migrate all contract ..."
8
+ scripts=""
9
+ for file in `find ./builds -name '*compiled.js'`
10
+ do
11
+ scripts="${scripts};loadScript('$file')"
12
+ done
13
+ scripts="${scripts};miner.start();admin.sleepBlocks(2);miner.stop()"
14
+ # echo "$scripts"
15
+ $geth --exec "$scripts" attach ipc:data/geth.ipc
16
+ else
17
+ file=$1
18
+ file="$(tr '[:lower:]' '[:upper:]' <<< ${file:0:1})${file:1}"
19
+ file+="_compiled.js"
20
+ echo "Migrate $file ..."
21
+ $geth --exec "loadScript('builds/$file');miner.start();admin.sleepBlocks(2);miner.stop()" attach ipc:data/geth.ipc
22
+ fi
@@ -0,0 +1,5 @@
1
+ #!/bin/bash
2
+
3
+ geth=${GETH:-geth}
4
+
5
+ $geth --datadir data --networkid 31415926 --rpc --rpccorsdomain "*" --nodiscover --unlock 3ae88fe370c39384fc16da2c9e768cf5d2495b48 --password <(echo -n 123456)
@@ -0,0 +1,104 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'json'
4
+ def library_code
5
+ 'function create(abiDefinition) { return web3.eth.contract(abiDefinition);}/*function deploy(account, value, gas, contract, code, input) */function deploy() { var account = arguments[0]; var value = arguments[1]; var gas = arguments[2]; var contract = arguments[3]; var code = arguments[4]; var codeString = "contract.new(inputMarker,{from:\'accountMarker\', value: valueMarker, data: \'codeMarker\', gas: gasMarker}, function (e, contract) { if(!e) { if(!contract.address) { console.log(\"Contract transaction send: TransactionHash: \" + contract.transactionHash + \" waiting to be mined...\"); } else { console.log(\"Contract mined! Address: \" + contract.address); } } else { console.log(e) } })"; codeString = codeString.replace("accountMarker", account); codeString = codeString.replace("valueMarker", value); codeString = codeString.replace("codeMarker", code); codeString = codeString.replace("gasMarker", gas); input = "null"; if (arguments.length > 5) { if (arguments[5] != null) { var args = []; for (var i = 5;i < arguments.length; i++) { var val = arguments[i]; if (typeof(val) === \'string\') { val = "\"" + val + "\""; } args.push(val); } input = args.join(","); } } codeString = codeString.replace("inputMarker", input); console.log(input); var instance = eval(codeString); return instance;}function watcher(error, result) { if (!error) { console.log("Result"); console.log(JSON.stringify(result)); return; } console.log("Error" + error);}/*function call(account, gas, func, input) */function call() { var account = "eth.accounts["+arguments[0]+"]"; var gas = arguments[1]; var func = arguments[2]; input = "null"; if (arguments.length > 3) { if (arguments[3] != null) { var args = Array.prototype.slice.call(arguments, 3); input = args.join(","); } } codeString = "func.sendTransaction(inputMarker, gasMarker, {from:accountMarker}, watcher);"; codeString = codeString.replace("accountMarker",account); codeString = codeString.replace("gasMarker",gas); codeString = codeString.replace("inputMarker",input); eval(codeString);}function send(from_index, to, value, gas){ return eth.sendTransaction({from:eth.accounts[from_index], to:to, value:web3.toWei(value,\'ether\'), gas:gas});}function bal() { for (var i = 0; i < eth.accounts.length; i++) { account = eth.accounts[i]; balance = web3.fromWei(eth.getBalance(eth.accounts[i]), \'ether\'); console.log("Index : " + i); console.log("Account : "+ account); console.log("Balance : "+ balance); console.log("\n"); }}'
6
+ end
7
+
8
+ def compile_solidity(file)
9
+ json_string = `solc --add-std --optimize --combined-json abi,bin,userdoc,devdoc #{file}`
10
+ json_string = json_string.gsub("\\n","")
11
+ begin
12
+ json_object = JSON.parse(json_string)
13
+ throw if json_object.nil?
14
+ puts `solc --optimize --gas #{file}`
15
+ puts "\n\n"
16
+ puts "-------------------------------------"
17
+ json_object["contracts"]
18
+ rescue
19
+ puts "Failed to Compile."
20
+ abort
21
+ end
22
+ end
23
+
24
+ def process_code(contracts)
25
+ contracts.keys.each.with_index do |key, i|
26
+ contracts[key]["bin"] = "0x" + contracts[key]["bin"]
27
+ contracts[key]["abi"] = JSON.parse(contracts[key]["abi"])
28
+ contracts[key]["devdoc"] = JSON.parse(contracts[key]["devdoc"])
29
+ contracts[key]["userdoc"] = JSON.parse(contracts[key]["userdoc"])
30
+ end
31
+ return contracts
32
+ end
33
+
34
+
35
+ def javascript_file_name(file_name)
36
+ file_name = file_name.split('/')[-1]
37
+ file_name.split('.')[0] + '_compiled.js'
38
+ end
39
+
40
+ def get_contract_to_deploy(compiled_object)
41
+ return compiled_object.keys[0] if compiled_object.keys.count == 1
42
+ puts "Which contract do you want to deploy?"
43
+ choice = 0
44
+ while choice <= 0 || choice > compiled_object.keys.count
45
+ compiled_object.keys.each.with_index do |key, i|
46
+ puts "#{(i+1)}. "+key
47
+ end
48
+ choice = $stdin.gets.to_i
49
+ end
50
+ return compiled_object.keys[choice - 1]
51
+ end
52
+
53
+ def get_input
54
+ puts "Enter Input: "
55
+ input = $stdin.gets
56
+ input.strip.chomp == "" ? "null" : input
57
+ end
58
+
59
+ def get_gas
60
+ gas = 0
61
+ while gas == 0
62
+ puts "Enter Gas: "
63
+ gas = $stdin.gets.to_i
64
+ end
65
+ gas
66
+ end
67
+
68
+ def get_value
69
+ gas = -1
70
+ while gas < 0
71
+ puts "Enter Value To Be Transferred: "
72
+ gas = $stdin.gets.to_i
73
+ end
74
+ gas
75
+ end
76
+
77
+ file_name = ARGV[0]
78
+
79
+ compiled_object = compile_solidity(file_name)
80
+ compiled_object = process_code(compiled_object)
81
+ javascript_file_name = javascript_file_name(file_name)
82
+
83
+ current_contract = get_contract_to_deploy(compiled_object)
84
+
85
+ compiled_variable_name = "#{current_contract}Compiled"
86
+ contract_variable_name = "#{current_contract}Contract"
87
+ contract_instance_variable_name = "#{current_contract}"
88
+
89
+ gas = get_gas
90
+ value = get_value
91
+ input = get_input
92
+
93
+ File.open(javascript_file_name, 'w') do |f|
94
+ f.write("#{library_code};\nvar #{compiled_variable_name} = #{compiled_object.to_json};")
95
+ f.write("#{contract_variable_name} = create(#{compiled_variable_name}.#{current_contract}.abi);")
96
+ f.write("#{contract_instance_variable_name} = deploy(eth.coinbase,#{value},#{gas},#{contract_variable_name},#{compiled_variable_name}.#{current_contract}.bin,#{input});")
97
+ f.write("console.log('Compiled Object : #{compiled_variable_name}');")
98
+ f.write("console.log('Contract : #{contract_variable_name}');")
99
+ f.write("console.log('Contract Instance : #{contract_instance_variable_name}');")
100
+ end
101
+
102
+ File.open("db/#{current_contract}.json", "w") do |f|
103
+ f.write(compiled_object.to_json)
104
+ end
@@ -0,0 +1,18 @@
1
+ #!/bin/bash
2
+
3
+ geth=${GETH:-geth}
4
+
5
+ scripts=""
6
+
7
+ for file in `find ./builds -name '*compiled.js'`
8
+ do
9
+ scripts="${scripts};loadScript('$file')"
10
+ done
11
+
12
+ for file in `find ./test -name '*.js'`
13
+ do
14
+ scripts="${scripts};loadScript('$file');"
15
+ done
16
+
17
+ echo $scripts
18
+ $geth --datadir data --networkid 31415926 --rpc --rpccorsdomain "*" --nodiscover --unlock 3ae88fe370c39384fc16da2c9e768cf5d2495b48 --password <(echo -n 123456) --exec "$scripts" console 2>> ./logfile
@@ -0,0 +1,10 @@
1
+ {
2
+ "nonce": "0x0000000000000042",
3
+ "difficulty": "0x020000",
4
+ "mixhash": "0x0000000000000000000000000000000000000000000000000000000000000000",
5
+ "coinbase": "0x0000000000000000000000000000000000000000",
6
+ "timestamp": "0x00",
7
+ "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
8
+ "extraData": "0x11bbe8db4e347b4e8c937c1c8370e4b5ed33adb3db69cbdb7a38e1e50b1b82fa",
9
+ "gasLimit": "0x4c4b40"
10
+ }
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/expect -f
2
+
3
+ set key [lindex $argv 0];
4
+ set geth [lindex $argv 1];
5
+
6
+ spawn $geth --datadir data account import $key
7
+ expect "Passphrase:"
8
+ send "123456\r"
9
+ expect "Repeat Passphrase:"
10
+ send "123456\r"
11
+ interact
@@ -0,0 +1,9 @@
1
+ require 'rake/testtask'
2
+
3
+ Rake::TestTask.new do |t|
4
+ t.libs += %w(lib test)
5
+ t.test_files = FileList['tests/**/*_test.rb']
6
+ t.verbose = true
7
+ end
8
+
9
+ task default: [:test]
metadata ADDED
@@ -0,0 +1,97 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: teth
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.1
5
+ platform: ruby
6
+ authors:
7
+ - Zhang YaNing
8
+ - Jan Xie
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2016-09-17 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: ruby-ethereum
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - "~>"
19
+ - !ruby/object:Gem::Version
20
+ version: '0.9'
21
+ type: :runtime
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - "~>"
26
+ - !ruby/object:Gem::Version
27
+ version: '0.9'
28
+ - !ruby/object:Gem::Dependency
29
+ name: minitest
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - "~>"
33
+ - !ruby/object:Gem::Version
34
+ version: '5.8'
35
+ type: :runtime
36
+ prerelease: false
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - "~>"
40
+ - !ruby/object:Gem::Version
41
+ version: '5.8'
42
+ description: 'Teth is a Ethereum smart contract test framework in ruby. It provides
43
+ two testing environments: testing in ruby EVM and testing in geth. You don''t need
44
+ to understand ruby grammar, just enjoy syntactic sugar.'
45
+ email:
46
+ - zhangyaning1985@gmail.com
47
+ - jan.h.xie@gmail.com
48
+ executables:
49
+ - teth
50
+ extensions: []
51
+ extra_rdoc_files: []
52
+ files:
53
+ - LICENSE
54
+ - README.md
55
+ - bin/teth
56
+ - lib/teth/configurable.rb
57
+ - lib/teth/erbs/Gemfile
58
+ - lib/teth/erbs/contract.sol
59
+ - lib/teth/erbs/contract_test.rb
60
+ - lib/teth/minitest.rb
61
+ - lib/teth/templates/bin/attach.sh
62
+ - lib/teth/templates/bin/build.sh
63
+ - lib/teth/templates/bin/import_keys.sh
64
+ - lib/teth/templates/bin/init.sh
65
+ - lib/teth/templates/bin/migrate.sh
66
+ - lib/teth/templates/bin/private_blockchain.sh
67
+ - lib/teth/templates/bin/solc_helper.rb
68
+ - lib/teth/templates/bin/test.sh
69
+ - lib/teth/templates/genesis.json
70
+ - lib/teth/templates/private_keys/import.sh
71
+ - lib/teth/templates/rakefile
72
+ homepage: https://github.com/cryptape/teth
73
+ licenses:
74
+ - MIT
75
+ metadata: {}
76
+ post_install_message:
77
+ rdoc_options: []
78
+ require_paths:
79
+ - lib
80
+ required_ruby_version: !ruby/object:Gem::Requirement
81
+ requirements:
82
+ - - ">="
83
+ - !ruby/object:Gem::Version
84
+ version: '0'
85
+ required_rubygems_version: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ requirements: []
91
+ rubyforge_project:
92
+ rubygems_version: 2.4.5.1
93
+ signing_key:
94
+ specification_version: 4
95
+ summary: Testing and deployment framework for Ethereum smart contracts.
96
+ test_files: []
97
+ has_rdoc: