ethereum.rb 2.0.1 → 2.0.2
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 +4 -4
- data/.travis.yml +2 -6
- data/README.md +3 -3
- data/lib/ethereum/contract.rb +6 -17
- data/lib/ethereum/decoder.rb +9 -2
- data/lib/ethereum/encoder.rb +22 -16
- data/lib/ethereum/formatter.rb +0 -33
- data/lib/ethereum/solidity.rb +14 -21
- data/lib/ethereum/version.rb +1 -1
- data/lib/tasks/ethereum_node.rake +5 -4
- metadata +3 -3
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA1:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: 9c3d499f0acb7794b25b60c3caec8f728ce1212e
         | 
| 4 | 
            +
              data.tar.gz: e3a239e91d23154acb7bbbc2ba4a528e7754b1eb
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: 5b91b2eeb93f071839e1f7985915c4ec1ca47a98d58741e6e314b374a7c3aed13db7e2da53672b2075f3783a8508050aa5830404b79755cba04cf91ebf69a453
         | 
| 7 | 
            +
              data.tar.gz: c82e52904d885da8073c8a1af9f33a9f70610d2dd12e1acbeb35c937e9dffdb73e8a707b1025f2527c5b914881c4b2bfb43d96ce993a54388ccd90bb880f08ef
         | 
    
        data/.travis.yml
    CHANGED
    
    | @@ -3,11 +3,7 @@ language: ruby | |
| 3 3 | 
             
            rvm:
         | 
| 4 4 | 
             
              - 2.3.1
         | 
| 5 5 | 
             
            env:
         | 
| 6 | 
            -
              - PARITY="1.4.8"
         | 
| 7 6 | 
             
              - PARITY="1.5.0"
         | 
| 8 | 
            -
            matrix:
         | 
| 9 | 
            -
              allow_failures:
         | 
| 10 | 
            -
              - env: PARITY="1.5.0"
         | 
| 11 7 | 
             
            cache:
         | 
| 12 8 | 
             
              bundler: true
         | 
| 13 9 | 
             
              directories:
         | 
| @@ -16,10 +12,10 @@ before_install: | |
| 16 12 | 
             
              - sudo bin/install_parity
         | 
| 17 13 | 
             
              - gem install bundler -v 1.11.2
         | 
| 18 14 | 
             
            before_script:
         | 
| 19 | 
            -
              - parity --chain ~/.parity | 
| 15 | 
            +
              - parity --chain testnet -d ~/.parity --password ~/.parity/pass --unlock 3089630d06fD90Ef48a0c43f000971587c1F3247 --author 3089630d06fD90Ef48a0c43f000971587c1F3247 daemon ~/.parity.pid --log-file ~/.parity.log
         | 
| 20 16 | 
             
              - cat ~/.parity.log
         | 
| 21 17 | 
             
              - sleep 5
         | 
| 22 | 
            -
              - parity --chain  | 
| 18 | 
            +
              - parity --chain testnet account list
         | 
| 23 19 | 
             
              - cat ~/.parity.log
         | 
| 24 20 | 
             
              - bundle exec rake ethereum:node:waitforsync
         | 
| 25 21 | 
             
              - bundle exec rake ethereum:test:setup
         | 
    
        data/README.md
    CHANGED
    
    | @@ -2,7 +2,7 @@ | |
| 2 2 |  | 
| 3 3 | 
             
            [](https://travis-ci.org/marekkirejczyk/ethereum.rb) [](https://hakiri.io/github/NullVoxPopuli/MetaHash/master) [](https://gemnasium.com/marekkirejczyk/ethereum.rb) [](https://codeclimate.com/github/marekkirejczyk/ethereum.rb)
         | 
| 4 4 |  | 
| 5 | 
            -
             | 
| 5 | 
            +
            The goal of ethereum.rb is to make interacting with ethereum blockchain from ruby as easy as possible (but not easier).
         | 
| 6 6 |  | 
| 7 7 | 
             
            ## Highlights
         | 
| 8 8 |  | 
| @@ -14,8 +14,8 @@ A ruby gem for interacting with Ethereum. | |
| 14 14 |  | 
| 15 15 | 
             
            ## Compatibility and requirements
         | 
| 16 16 |  | 
| 17 | 
            -
            * Tested with parity 1. | 
| 18 | 
            -
            * Tested with solc 0.4. | 
| 17 | 
            +
            * Tested with parity 1.5.0, might work with geth (but was not tested)
         | 
| 18 | 
            +
            * Tested with solc 0.4.9
         | 
| 19 19 | 
             
            * Ruby 2.x
         | 
| 20 20 | 
             
            * UNIX/Linux or OS X environment
         | 
| 21 21 |  | 
    
        data/lib/ethereum/contract.rb
    CHANGED
    
    | @@ -77,16 +77,11 @@ module Ethereum | |
| 77 77 | 
             
                end
         | 
| 78 78 |  | 
| 79 79 | 
             
                def call_raw(fun, *args)
         | 
| 80 | 
            -
                   | 
| 81 | 
            -
                   | 
| 82 | 
            -
                  payload = [fun.signature]
         | 
| 83 | 
            -
                  arg_types.zip(args).each do |arg|
         | 
| 84 | 
            -
                    payload << @formatter.to_payload(arg)
         | 
| 85 | 
            -
                  end
         | 
| 86 | 
            -
                  raw_result = @client.eth_call({to: @address, from: @sender, data: "0x" + payload.join()})
         | 
| 80 | 
            +
                  payload = fun.signature + @encoder.encode_arguments(fun.inputs, args)
         | 
| 81 | 
            +
                  raw_result = @client.eth_call({to: @address, from: @sender, data: "0x" + payload})
         | 
| 87 82 | 
             
                  raw_result = raw_result["result"]
         | 
| 88 83 | 
             
                  output = @decoder.decode_arguments(fun.outputs, raw_result)
         | 
| 89 | 
            -
                  return {data: "0x" + payload | 
| 84 | 
            +
                  return {data: "0x" + payload, raw: raw_result, formatted: output}
         | 
| 90 85 | 
             
                end
         | 
| 91 86 |  | 
| 92 87 | 
             
                def call(fun, *args)
         | 
| @@ -99,15 +94,9 @@ module Ethereum | |
| 99 94 | 
             
                end
         | 
| 100 95 |  | 
| 101 96 | 
             
                def transact(fun, *args)
         | 
| 102 | 
            -
                   | 
| 103 | 
            -
                   | 
| 104 | 
            -
                  payload  | 
| 105 | 
            -
                  payload << fun.signature
         | 
| 106 | 
            -
                  arg_types.zip(args).each do |arg|
         | 
| 107 | 
            -
                    payload << @formatter.to_payload(arg)
         | 
| 108 | 
            -
                  end
         | 
| 109 | 
            -
                  txid = @client.eth_send_transaction({to: @address, from: @sender, data: "0x" + payload.join()})["result"]
         | 
| 110 | 
            -
                  return Ethereum::Transaction.new(txid, @client, payload.join(), args)
         | 
| 97 | 
            +
                  payload = fun.signature + @encoder.encode_arguments(fun.inputs, args)
         | 
| 98 | 
            +
                  txid = @client.eth_send_transaction({to: @address, from: @sender, data: "0x" + payload})["result"]
         | 
| 99 | 
            +
                  return Ethereum::Transaction.new(txid, @client, payload, args)
         | 
| 111 100 | 
             
                end
         | 
| 112 101 |  | 
| 113 102 | 
             
                def transact_and_wait(fun, *args)
         | 
    
        data/lib/ethereum/decoder.rb
    CHANGED
    
    | @@ -9,18 +9,25 @@ module Ethereum | |
| 9 9 | 
             
                    decode_dynamic_bytes(value, start)
         | 
| 10 10 | 
             
                  elsif "string" == core
         | 
| 11 11 | 
             
                    self.send(method_name, value, start)
         | 
| 12 | 
            +
                  elsif "int" == core
         | 
| 13 | 
            +
                    size = subtype.present? ? subtype.to_i : 256
         | 
| 14 | 
            +
                    self.send(method_name, value[start+63-(size/4-1)..start+63], size)
         | 
| 12 15 | 
             
                  else
         | 
| 13 16 | 
             
                    self.send(method_name, value[start..start+63])
         | 
| 14 17 | 
             
                  end
         | 
| 15 18 | 
             
                end
         | 
| 16 19 |  | 
| 20 | 
            +
                def decode_fixed(value, n = 128)
         | 
| 21 | 
            +
                  decode_int(value).to_f / 2**n
         | 
| 22 | 
            +
                end
         | 
| 23 | 
            +
             | 
| 17 24 | 
             
                def decode_uint(value)
         | 
| 18 25 | 
             
                  value.hex
         | 
| 19 26 | 
             
                end
         | 
| 20 27 |  | 
| 21 | 
            -
                def decode_int(value)
         | 
| 28 | 
            +
                def decode_int(value, size = 256)
         | 
| 22 29 | 
             
                  raise ArgumentError if value.nil?
         | 
| 23 | 
            -
                  (value[0..1] == "ff") ? (value.hex - (2 **  | 
| 30 | 
            +
                  (value[0..1] == "ff") ? (value.hex - (2 ** size)) : value.hex
         | 
| 24 31 | 
             
                end
         | 
| 25 32 |  | 
| 26 33 | 
             
                def decode_bool(value)
         | 
    
        data/lib/ethereum/encoder.rb
    CHANGED
    
    | @@ -4,54 +4,59 @@ module Ethereum | |
| 4 4 |  | 
| 5 5 | 
             
                def encode(type, value)
         | 
| 6 6 | 
             
                  core, subtype = Abi::parse_type(type)
         | 
| 7 | 
            -
                   | 
| 8 | 
            -
             | 
| 9 | 
            -
                  else
         | 
| 10 | 
            -
                    method_name = "encode_#{core}".to_sym
         | 
| 11 | 
            -
                    self.send(method_name, value)
         | 
| 12 | 
            -
                  end
         | 
| 7 | 
            +
                  method_name = "encode_#{core}".to_sym
         | 
| 8 | 
            +
                  self.send(method_name, value, subtype)
         | 
| 13 9 | 
             
                end
         | 
| 14 10 |  | 
| 15 | 
            -
                def encode_int(value)
         | 
| 11 | 
            +
                def encode_int(value, _ = nil)
         | 
| 16 12 | 
             
                  to_twos_complement(value).to_s(16).rjust(64, '0')
         | 
| 17 13 | 
             
                end
         | 
| 18 14 |  | 
| 19 | 
            -
                def encode_uint(value)
         | 
| 15 | 
            +
                def encode_uint(value, _ = nil)
         | 
| 20 16 | 
             
                  raise ArgumentError if value < 0
         | 
| 21 17 | 
             
                  encode_int(value)
         | 
| 22 18 | 
             
                end
         | 
| 23 19 |  | 
| 24 | 
            -
                def encode_bool(value)
         | 
| 20 | 
            +
                def encode_bool(value, _)
         | 
| 25 21 | 
             
                  (value ? "1" : "0").rjust(64, '0')
         | 
| 26 22 | 
             
                end
         | 
| 27 23 |  | 
| 28 | 
            -
                def encode_fixed( | 
| 29 | 
            -
                   | 
| 24 | 
            +
                def encode_fixed(value, subtype)
         | 
| 25 | 
            +
                  n = subtype.nil? ? 128 : /(\d+)x(\d+)/.match(subtype)[2].to_i
         | 
| 26 | 
            +
                  do_encode_fixed(value, n)
         | 
| 30 27 | 
             
                end
         | 
| 31 28 |  | 
| 32 | 
            -
                def  | 
| 29 | 
            +
                def do_encode_fixed(value, n)
         | 
| 30 | 
            +
                  encode_uint((value * 2**n).to_i)
         | 
| 31 | 
            +
                end
         | 
| 32 | 
            +
             | 
| 33 | 
            +
                def encode_ufixed(_value, _)
         | 
| 33 34 | 
             
                  raise NotImplementedError
         | 
| 34 35 | 
             
                end
         | 
| 35 36 |  | 
| 36 | 
            -
                def encode_bytes(value)
         | 
| 37 | 
            +
                def encode_bytes(value, subtype)
         | 
| 38 | 
            +
                  subtype.nil? ? encode_dynamic_bytes(value) : encode_static_bytes(value)
         | 
| 39 | 
            +
                end
         | 
| 40 | 
            +
                
         | 
| 41 | 
            +
                def encode_static_bytes(value)
         | 
| 37 42 | 
             
                  value.each_char.map {|x| x.ord.to_s(16)}.join("").ljust(64, '0')
         | 
| 38 43 | 
             
                end
         | 
| 39 44 |  | 
| 40 45 | 
             
                def encode_dynamic_bytes(value)
         | 
| 41 46 | 
             
                  location = encode_uint(@inputs ? @inputs.size * 32 : 32)
         | 
| 42 47 | 
             
                  size = encode_uint(value.size)
         | 
| 43 | 
            -
                  content =  | 
| 48 | 
            +
                  content = encode_static_bytes(value)
         | 
| 44 49 | 
             
                  [location, size + content]
         | 
| 45 50 | 
             
                end
         | 
| 46 51 |  | 
| 47 | 
            -
                def encode_string(value)
         | 
| 52 | 
            +
                def encode_string(value, _)
         | 
| 48 53 | 
             
                  location = encode_uint(@inputs ? @inputs.size * 32 : 32)
         | 
| 49 54 | 
             
                  size = encode_uint(value.bytes.size)
         | 
| 50 55 | 
             
                  content = value.bytes.map {|x| x.to_s(16)}.join("").ljust(64, '0')
         | 
| 51 56 | 
             
                  [location, size + content]
         | 
| 52 57 | 
             
                end
         | 
| 53 58 |  | 
| 54 | 
            -
                def encode_address(value)
         | 
| 59 | 
            +
                def encode_address(value, _)
         | 
| 55 60 | 
             
                  value = value.gsub(/^0x/,'')
         | 
| 56 61 | 
             
                  raise ArgumentError if value.size != 40
         | 
| 57 62 | 
             
                  value
         | 
| @@ -62,6 +67,7 @@ module Ethereum | |
| 62 67 | 
             
                end
         | 
| 63 68 |  | 
| 64 69 | 
             
                def encode_arguments(inputs, args)
         | 
| 70 | 
            +
                  raise "Wrong number of arguments" if inputs.length != args.length
         | 
| 65 71 | 
             
                  @head = ""
         | 
| 66 72 | 
             
                  @tail = ""
         | 
| 67 73 | 
             
                  @inputs = inputs
         | 
    
        data/lib/ethereum/formatter.rb
    CHANGED
    
    | @@ -103,43 +103,10 @@ module Ethereum | |
| 103 103 | 
             
                  (hexstring.gsub(/^0x/,'')[0..1] == "ff") ? (hexstring.hex - (2 ** 256)) : hexstring.hex
         | 
| 104 104 | 
             
                end
         | 
| 105 105 |  | 
| 106 | 
            -
                def bool_to_payload(bool)
         | 
| 107 | 
            -
                  int_to_payload(bool ? 1 : 0)
         | 
| 108 | 
            -
                end
         | 
| 109 | 
            -
             | 
| 110 | 
            -
                def address_to_payload(address)
         | 
| 111 | 
            -
                  from_address(address)
         | 
| 112 | 
            -
                end
         | 
| 113 | 
            -
             | 
| 114 | 
            -
                def uint_to_payload(uint)
         | 
| 115 | 
            -
                  self.to_twos_complement(uint).rjust(64, '0')
         | 
| 116 | 
            -
                end
         | 
| 117 | 
            -
             | 
| 118 | 
            -
                def int_to_payload(int)
         | 
| 119 | 
            -
                  self.to_twos_complement(int).rjust(64, '0')
         | 
| 120 | 
            -
                end
         | 
| 121 | 
            -
             | 
| 122 | 
            -
                def bytes_to_payload(bytes)
         | 
| 123 | 
            -
                  self.from_utf8(bytes).ljust(64, '0')
         | 
| 124 | 
            -
                end
         | 
| 125 | 
            -
             | 
| 126 | 
            -
                def string_to_payload(bytes)
         | 
| 127 | 
            -
                  self.bytes_to_payload(bytes)
         | 
| 128 | 
            -
                end
         | 
| 129 | 
            -
             | 
| 130 | 
            -
                def construtor_params_to_payload(abi, params)
         | 
| 131 | 
            -
                  abi.map.with_index { |var, i| to_payload([var["type"], params[i]]) }.join
         | 
| 132 | 
            -
                end
         | 
| 133 | 
            -
             | 
| 134 106 | 
             
                def get_base_type(typename)
         | 
| 135 107 | 
             
                  typename.gsub(/\d+/,'')
         | 
| 136 108 | 
             
                end
         | 
| 137 109 |  | 
| 138 | 
            -
                def to_payload(args)
         | 
| 139 | 
            -
                  converter = "#{self.get_base_type(args[0])}_to_payload".to_sym
         | 
| 140 | 
            -
                  self.send(converter, args[1]) 
         | 
| 141 | 
            -
                end
         | 
| 142 | 
            -
             | 
| 143 110 | 
             
                def from_payload(args)
         | 
| 144 111 | 
             
                  converter = "output_to_#{self.get_base_type(args[0])}".to_sym
         | 
| 145 112 | 
             
                  self.send(converter, args[1])
         | 
    
        data/lib/ethereum/solidity.rb
    CHANGED
    
    | @@ -10,38 +10,31 @@ module Ethereum | |
| 10 10 |  | 
| 11 11 | 
             
              class Solidity
         | 
| 12 12 |  | 
| 13 | 
            +
                OUTPUT_REGEXP = /======= (\S*):(\S*) =======\s*Binary:\s*(\S*)\sContract JSON ABI\s(\S*)/
         | 
| 14 | 
            +
             | 
| 13 15 | 
             
                def initialize(bin_path = "solc")
         | 
| 14 16 | 
             
                  @bin_path = bin_path
         | 
| 15 | 
            -
                  @args = "--bin --abi -- | 
| 17 | 
            +
                  @args = "--bin --abi --add-std --optimize"
         | 
| 16 18 | 
             
                end
         | 
| 17 19 |  | 
| 18 20 | 
             
                def compile(filename)
         | 
| 19 | 
            -
                  {} | 
| 20 | 
            -
             | 
| 21 | 
            -
             | 
| 22 | 
            -
             | 
| 23 | 
            -
             | 
| 24 | 
            -
             | 
| 25 | 
            -
                    end
         | 
| 21 | 
            +
                  result = {}
         | 
| 22 | 
            +
                  execute_solc(nil, filename).scan(OUTPUT_REGEXP).each do |match|
         | 
| 23 | 
            +
                    file, name, bin, abi = match
         | 
| 24 | 
            +
                    result[name] = {}
         | 
| 25 | 
            +
                    result[name]["abi"] = abi
         | 
| 26 | 
            +
                    result[name]["bin"] = bin
         | 
| 26 27 | 
             
                  end
         | 
| 28 | 
            +
                  result
         | 
| 27 29 | 
             
                end
         | 
| 28 | 
            -
             | 
| 30 | 
            +
             | 
| 29 31 | 
             
                private    
         | 
| 30 | 
            -
                  def process_file(dir, file, result)
         | 
| 31 | 
            -
                    extension = File.extname(file)
         | 
| 32 | 
            -
                    path = "#{dir}/#{file}"
         | 
| 33 | 
            -
                    basename = File.basename(path, extension)
         | 
| 34 | 
            -
                    unless File.directory?(path)
         | 
| 35 | 
            -
                      result[basename] ||= {}
         | 
| 36 | 
            -
                      result[basename][extension[1..-1]] = File.read(path) 
         | 
| 37 | 
            -
                    end
         | 
| 38 | 
            -
                  end
         | 
| 39 | 
            -
                  
         | 
| 40 32 | 
             
                  def execute_solc(dir, filename)
         | 
| 41 | 
            -
                    cmd = "#{@bin_path} #{@args} '#{ | 
| 42 | 
            -
                     | 
| 33 | 
            +
                    cmd = "#{@bin_path} #{@args} '#{filename}'"
         | 
| 34 | 
            +
                    out, stderr, status = Open3.capture3(cmd)
         | 
| 43 35 | 
             
                    raise SystemCallError, "Unanable to run solc compliers" if status.exitstatus == 127
         | 
| 44 36 | 
             
                    raise CompilationError, stderr unless status.exitstatus == 0
         | 
| 37 | 
            +
                    out
         | 
| 45 38 | 
             
                  end    
         | 
| 46 39 | 
             
              end 
         | 
| 47 40 | 
             
            end
         | 
    
        data/lib/ethereum/version.rb
    CHANGED
    
    
| @@ -3,16 +3,17 @@ require 'open3' | |
| 3 3 | 
             
            namespace :ethereum do
         | 
| 4 4 | 
             
              namespace :node do
         | 
| 5 5 |  | 
| 6 | 
            -
                desc "Run testnet node | 
| 6 | 
            +
                desc "Run testnet (ropsten) node"
         | 
| 7 7 | 
             
                task :test do
         | 
| 8 | 
            -
                   | 
| 8 | 
            +
                  args = "--chain testnet -d ~/.parity"
         | 
| 9 | 
            +
                  out, _, _ = Open3.capture3("parity #{args} account list")
         | 
| 9 10 | 
             
                  account = out.split(/[\[,\]]/)[1]
         | 
| 10 | 
            -
                  cmd = "parity  | 
| 11 | 
            +
                  cmd = "parity #{args} --password ~/.parity/pass --unlock #{account} --author #{account}"
         | 
| 11 12 | 
             
                  puts cmd
         | 
| 12 13 | 
             
                  system cmd
         | 
| 13 14 | 
             
                end
         | 
| 14 15 |  | 
| 15 | 
            -
                desc "Run  | 
| 16 | 
            +
                desc "Run production node"
         | 
| 16 17 | 
             
                task :run do
         | 
| 17 18 | 
             
                  _, out, _ = Open3.capture3("parity account list")
         | 
| 18 19 | 
             
                  account = out.split(/[\[,\]]/)[1]
         | 
    
        metadata
    CHANGED
    
    | @@ -1,14 +1,14 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: ethereum.rb
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 2.0. | 
| 4 | 
            +
              version: 2.0.2
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - Marek Kirejczyk
         | 
| 8 8 | 
             
            autorequire: 
         | 
| 9 9 | 
             
            bindir: exe
         | 
| 10 10 | 
             
            cert_chain: []
         | 
| 11 | 
            -
            date: 2017-01 | 
| 11 | 
            +
            date: 2017-02-01 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies:
         | 
| 13 13 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 14 14 | 
             
              name: bundler
         | 
| @@ -194,7 +194,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement | |
| 194 194 | 
             
                  version: '0'
         | 
| 195 195 | 
             
            requirements: []
         | 
| 196 196 | 
             
            rubyforge_project: 
         | 
| 197 | 
            -
            rubygems_version: 2.5. | 
| 197 | 
            +
            rubygems_version: 2.5.2
         | 
| 198 198 | 
             
            signing_key: 
         | 
| 199 199 | 
             
            specification_version: 4
         | 
| 200 200 | 
             
            summary: Ruby Ethereum client using the JSON-RPC interface
         |