teth 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
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: