4
0
Fork 0

Initial commit

contracts
hswick 7 years ago
commit d23139c181
  1. 5
      .gitignore
  2. 17
      README.md
  3. 28
      config/config.exs
  4. 44
      lib/exw3.ex
  5. 36
      mix.exs
  6. 17
      mix.lock
  7. 21
      test/examples/array_tester.rb
  8. 1
      test/examples/build/ArrayTester.abi
  9. 1
      test/examples/build/ArrayTester.bin
  10. 1
      test/examples/build/Complex.abi
  11. 1
      test/examples/build/Complex.bin
  12. 1
      test/examples/build/SimpleStorage.abi
  13. 1
      test/examples/build/SimpleStorage.bin
  14. 25
      test/examples/complex.rb
  15. 11
      test/examples/contracts/ArrayTester.sol
  16. 48
      test/examples/contracts/Complex.sol
  17. 13
      test/examples/contracts/SimpleStorage.sol
  18. 21
      test/examples/simple_storage.rb
  19. 46
      test/exw3_test.exs
  20. 1
      test/test_helper.exs

5
.gitignore vendored

@ -0,0 +1,5 @@
/_build
/cover
/deps
erl_crash.dump
*.ez

@ -0,0 +1,17 @@
# EXW3
**TODO: Add description**
## Installation
1. Add exw3 to your list of dependencies in mix.exs:
def deps do
[{:exw3, "~> 0.0.1"}]
end
2. Ensure exw3 is started before your application:
def application do
[applications: [:exw3]]
end

@ -0,0 +1,28 @@
# This file is responsible for configuring your application
# and its dependencies with the aid of the Mix.Config module.
use Mix.Config
# This configuration is loaded before any dependency and is restricted
# to this project. If another project depends on this project, this
# file won't be loaded nor affect the parent project. For this reason,
# if you want to provide default values for your application for third-
# party users, it should be done in your mix.exs file.
# Sample configuration:
#
# config :logger,
# level: :info
#
# config :logger, :console,
# format: "$date $time [$level] $metadata$message\n",
# metadata: [:user_id]
# It is also possible to import configuration files, relative to this
# directory. For example, you can emulate configuration per environment
# by uncommenting the line below and defining dev.exs, test.exs and such.
# Configuration from the imported file will override the ones defined
# here (which is why it is important to import them last).
#
# import_config "#{Mix.env}.exs"
config :ethereumex,
url: "http://localhost:8545"

@ -0,0 +1,44 @@
defmodule EXW3 do
@moduledoc """
Documentation for EXW3.
"""
@doc """
Hello world.
## Examples
iex> EXW3.hello
:world
"""
def hello do
:world
end
def accounts do
case Ethereumex.HttpClient.eth_accounts do
{:ok, accounts} -> accounts
err -> err
end
end
def reformat_abi abi do
Map.new Enum.map(abi, fn x -> {x["name"], x} end)
end
def load_abi file_path do
file = File.read Path.join(System.cwd, file_path)
case file do
{:ok, abi} -> reformat_abi Poison.Parser.parse! abi
err -> err
end
end
def encode abi, name, args do
inputs = Enum.map abi[name]["inputs"], fn x -> x["type"] end
fn_signature = Enum.join [name, "(", Enum.join(inputs, ","), ")"]
ABI.encode(fn_signature, args)
end
end

@ -0,0 +1,36 @@
defmodule EXW3.Mixfile do
use Mix.Project
def project do
[app: :exw3,
version: "0.0.1",
elixir: "~> 1.1-dev",
build_embedded: Mix.env == :prod,
start_permanent: Mix.env == :prod,
deps: deps()]
end
# Configuration for the OTP application
#
# Type `mix help compile.app` for more information
def application do
[applications: [:logger, :ethereumex]]
end
# Dependencies can be Hex packages:
#
# {:mydep, "~> 0.3.0"}
#
# Or git/path repositories:
#
# {:mydep, git: "https://github.com/elixir-lang/mydep.git", tag: "0.1.0"}
#
# Type `mix help deps` for more examples and options
defp deps do
[
{:ethereumex, "~> 0.3.2"},
{:abi, "~> 0.1.8"},
{:poison, "~> 3.1"}
]
end
end

@ -0,0 +1,17 @@
%{
"abi": {:hex, :abi, "0.1.12", "87ae04cb09e2308db7b3c350584dc3934de0e308f6a056ba82be5756b081a1ca", [:mix], [{:exth_crypto, "~> 0.1.4", [hex: :exth_crypto, repo: "hexpm", optional: false]}], "hexpm"},
"binary": {:hex, :binary, "0.0.4", "dd077db70c0ded3e85c132b802338e14b80694684a7e2277666bfa4004b7fa66", [:mix], [], "hexpm"},
"certifi": {:hex, :certifi, "2.0.0", "a0c0e475107135f76b8c1d5bc7efb33cd3815cb3cf3dea7aefdd174dabead064", [:rebar3], [], "hexpm"},
"ethereumex": {:hex, :ethereumex, "0.3.2", "ee01a49c781c9751317b2918f799e84185203c81c8314ebebb1f1e22b754db3e", [:mix], [{:httpoison, "~> 1.0.0", [hex: :httpoison, repo: "hexpm", optional: false]}, {:poison, "~> 3.1.0", [hex: :poison, repo: "hexpm", optional: false]}], "hexpm"},
"exth_crypto": {:hex, :exth_crypto, "0.1.4", "11f9084dfd70d4f9e96f2710a472f4e6b23044b97530c719550c2b0450ffeb61", [:mix], [{:binary, "~> 0.0.4", [hex: :binary, repo: "hexpm", optional: false]}, {:keccakf1600, "~> 2.0.0", [hex: :keccakf1600_orig, repo: "hexpm", optional: false]}, {:libsecp256k1, "~> 0.1.3", [hex: :libsecp256k1, repo: "hexpm", optional: false]}], "hexpm"},
"hackney": {:hex, :hackney, "1.11.0", "4951ee019df102492dabba66a09e305f61919a8a183a7860236c0fde586134b6", [:rebar3], [{:certifi, "2.0.0", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "5.1.0", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "1.0.1", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "1.0.2", [hex: :mimerl, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "1.1.1", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}], "hexpm"},
"httpoison": {:hex, :httpoison, "1.0.0", "1f02f827148d945d40b24f0b0a89afe40bfe037171a6cf70f2486976d86921cd", [:mix], [{:hackney, "~> 1.8", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm"},
"idna": {:hex, :idna, "5.1.0", "d72b4effeb324ad5da3cab1767cb16b17939004e789d8c0ad5b70f3cea20c89a", [:rebar3], [{:unicode_util_compat, "0.3.1", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm"},
"keccakf1600": {:hex, :keccakf1600_orig, "2.0.0", "0a7217ddb3ee8220d449bbf7575ec39d4e967099f220a91e3dfca4dbaef91963", [:rebar3], [], "hexpm"},
"libsecp256k1": {:hex, :libsecp256k1, "0.1.3", "57468b986af7c9633527875f71c7ca08bf4150b07b38a60d5bd48fba299ff6c1", [:rebar3], [], "hexpm"},
"metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm"},
"mimerl": {:hex, :mimerl, "1.0.2", "993f9b0e084083405ed8252b99460c4f0563e41729ab42d9074fd5e52439be88", [:rebar3], [], "hexpm"},
"poison": {:hex, :poison, "3.1.0", "d9eb636610e096f86f25d9a46f35a9facac35609a7591b3be3326e99a0484665", [:mix], [], "hexpm"},
"ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.1", "28a4d65b7f59893bc2c7de786dec1e1555bd742d336043fe644ae956c3497fbe", [:make, :rebar], [], "hexpm"},
"unicode_util_compat": {:hex, :unicode_util_compat, "0.3.1", "a1f612a7b512638634a603c8f401892afbf99b8ce93a45041f8aaca99cadb85e", [:rebar3], [], "hexpm"},
}

@ -0,0 +1,21 @@
require './lib/w3'
url = "http://localhost:8545"
http_client = W3::Http_Client.new(url)
eth = W3::ETH.new(http_client)
accounts = eth.get_accounts
pp accounts
puts "Block number: #{eth.get_block_number}"
abi = JSON.parse(File.read(File.join(File.dirname(__FILE__), './build/ArrayTester.abi')))
array_tester = W3::Contract.new(eth, abi)
bin = File.read(File.join(File.dirname(__FILE__), './build/ArrayTester.bin'))
array_tester.at! array_tester.deploy!(bin, {"from" => accounts[0], "gas" => 300000})
pp array_tester.dynamic_uint([1, 2, 3, 4, 5,])
#pp array_tester.static_uint([1, 2, 3, 4, 5,])

@ -0,0 +1 @@
[{"constant":true,"inputs":[{"name":"ints","type":"uint256[5]"}],"name":"staticUint","outputs":[{"name":"","type":"uint256[5]"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[{"name":"ints","type":"uint256[]"}],"name":"dynamicUint","outputs":[{"name":"","type":"uint256[]"}],"payable":false,"stateMutability":"pure","type":"function"}]

@ -0,0 +1 @@
6060604052341561000f57600080fd5b61020a8061001e6000396000f30060606040526004361061004c576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680635cfd038d146100515780635d4e0342146100d3575b600080fd5b341561005c57600080fd5b6100956004808060a001906005806020026040519081016040528092919082600560200280828437820191505050505091905050610182565b6040518082600560200280838360005b838110156100c05780820151818401526020810190506100a5565b5050505090500191505060405180910390f35b34156100de57600080fd5b61012b600480803590602001908201803590602001908080602002602001604051908101604052809392919081815260200183836020028082843782019150505050505091905050610192565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b8381101561016e578082015181840152602081019050610153565b505050509050019250505060405180910390f35b61018a6101a2565b819050919050565b61019a6101ca565b819050919050565b60a0604051908101604052806005905b60008152602001906001900390816101b25790505090565b6020604051908101604052806000815250905600a165627a7a72305820e41e488a9545e9fa5a98095e6bc74e07ed21def3a9ba0d3867003099fab1eec00029

@ -0,0 +1 @@
[{"constant":true,"inputs":[],"name":"getBroAndBroBro","outputs":[{"name":"bro","type":"uint256"},{"name":"broBro","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getBarFoo","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_foobar","type":"bytes32"}],"name":"setFooBar","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getBoth","outputs":[{"name":"","type":"uint256"},{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_barFoo","type":"bool"}],"name":"setBarFoo","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_fooboo","type":"uint256"}],"name":"getFooBoo","outputs":[{"name":"fooBoo","type":"uint256"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[],"name":"getFooBar","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_foo","type":"uint256"}],"name":"setFoo","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_foo","type":"uint256"},{"name":"_foobar","type":"bytes32"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"name":"foo","type":"uint256"},{"indexed":false,"name":"person","type":"address"}],"name":"Bar","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"fooboo","type":"bool"},{"indexed":false,"name":"foo","type":"uint256"},{"indexed":false,"name":"foobar","type":"bytes32"}],"name":"FooBar","type":"event"}]

@ -0,0 +1 @@
6060604052341561000f57600080fd5b6040516040806103128339810160405280805190602001909190805190602001909190505081600081905550806001816000191690555050506102bb806100576000396000f30060606040526004361061008e576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680631b85502e1461009357806354fcb8a6146100cb5780637b07059b146100f857806393affe511461011f5780639aa7c12014610157578063b17e413b1461017c578063cfd91f2b146101b3578063dc80035d146101e4575b600080fd5b341561009e57600080fd5b6100a6610207565b6040518083815260200182600019166000191681526020019250505060405180910390f35b34156100d657600080fd5b6100de61021b565b604051808215151515815260200191505060405180910390f35b341561010357600080fd5b61011d600480803560001916906020019091905050610232565b005b341561012a57600080fd5b610132610240565b6040518083815260200182600019166000191681526020019250505060405180910390f35b341561016257600080fd5b61017a60048080351515906020019091905050610251565b005b341561018757600080fd5b61019d600480803590602001909190505061026e565b6040518082815260200191505060405180910390f35b34156101be57600080fd5b6101c661027b565b60405180826000191660001916815260200191505060405180910390f35b34156101ef57600080fd5b6102056004808035906020019091905050610285565b005b600080602a60005401600154915091509091565b6000600260009054906101000a900460ff16905090565b806001816000191690555050565b600080600054600154915091509091565b80600260006101000a81548160ff02191690831515021790555050565b6000602a82019050919050565b6000600154905090565b80600081905550505600a165627a7a72305820fbec4ee932ff7d288a752933ae6cb2b6b01949e15a49b6b854142cc9acb3efa10029

@ -0,0 +1 @@
[{"constant":false,"inputs":[{"name":"_data","type":"uint256"}],"name":"set","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"get","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"}]

@ -0,0 +1 @@
6060604052341561000f57600080fd5b60d38061001d6000396000f3006060604052600436106049576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806360fe47b114604e5780636d4ce63c14606e575b600080fd5b3415605857600080fd5b606c60048080359060200190919050506094565b005b3415607857600080fd5b607e609e565b6040518082815260200191505060405180910390f35b8060008190555050565b600080549050905600a165627a7a723058202d68adcfe82d5e51b80e2a9202eb808515f4ba8f98e4dfcca08a018132d33e530029

@ -0,0 +1,25 @@
require './lib/w3'
url = "http://localhost:8545"
http_client = W3::Http_Client.new(url)
eth = W3::ETH.new(http_client)
accounts = eth.get_accounts
abi = JSON.parse(File.read(File.join(File.dirname(__FILE__), './build/Complex.abi')))
complex = W3::Contract.new(eth, abi)
bin = File.read(File.join(File.dirname(__FILE__), './build/Complex.bin'))
complex.at! complex.deploy!(bin, {"from" => accounts[0], "gas" => 300000}, 6, "foo")
pp complex.address
pp complex.get_both
# complex.set_bar_foo! true, {"from" => accounts[0]}
# pp complex.get_bar_foo
# pp complex.get_foo_boo 66
# pp complex.get_bro_and_bro_bro

@ -0,0 +1,11 @@
pragma solidity ^0.4.18;
contract ArrayTester {
function dynamicUint(uint[] ints) public pure returns (uint[]) {
return ints;
}
function staticUint(uint[5] ints) public pure returns (uint[5]) {
return ints;
}
}

@ -0,0 +1,48 @@
pragma solidity ^0.4.0;
contract Complex {
uint foo;
bytes32 foobar;
bool barFoo;
event Bar(uint foo, address person);
event FooBar(bool fooboo, uint foo, bytes32 foobar);
function Complex(uint _foo, bytes32 _foobar) public {
foo = _foo;
foobar = _foobar;
}
function getBoth() public view returns (uint, bytes32) {
return (foo, foobar);
}
function getBarFoo() public view returns (bool) {
return barFoo;
}
function getFooBar() public view returns (bytes32) {
return foobar;
}
function getFooBoo(uint _fooboo) public pure returns (uint fooBoo) {
fooBoo = _fooboo + 42;
}
function getBroAndBroBro() public view returns (uint bro, bytes32 broBro) {
return (foo + 42, foobar);
}
function setFoo(uint _foo) public {
foo = _foo;
}
function setFooBar(bytes32 _foobar) public {
foobar = _foobar;
}
function setBarFoo(bool _barFoo) public {
barFoo = _barFoo;
}
}

@ -0,0 +1,13 @@
pragma solidity ^0.4.0;
contract SimpleStorage {
uint data;
function set(uint _data) public {
data = _data;
}
function get() public view returns (uint) {
return data;
}
}

@ -0,0 +1,21 @@
require './lib/w3'
url = "http://localhost:8545"
http_client = W3::Http_Client.new(url)
eth = W3::ETH.new(http_client)
accounts = eth.get_accounts
pp accounts
puts "Block number: #{eth.get_block_number}"
abi = JSON.parse(File.read(File.join(File.dirname(__FILE__), './build/SimpleStorage.abi')))
simple_storage = W3::Contract.new(eth, abi)
bin = File.read(File.join(File.dirname(__FILE__), './build/SimpleStorage.bin'))
simple_storage.at! simple_storage.deploy!(bin, {"from" => accounts[0], "gas" => 300000})
pp simple_storage.get
simple_storage.set!(2, {"from" => accounts[0]})
pp simple_storage.get

@ -0,0 +1,46 @@
defmodule EXW3Test do
use ExUnit.Case
doctest EXW3
setup_all do
simple_storage_abi = EXW3.load_abi("test/examples/build/SimpleStorage.abi")
%{simple_storage_abi: simple_storage_abi}
end
test "loads abi", context do
assert is_map context[:simple_storage_abi]
end
test "encodes value and sends it", context do
tx = %{
data: EXW3.encode(context[:simple_storage_abi], "get", [])
}
tx
|> Kernel.inspect
|> IO.puts
end
test "the truth" do
assert 1 + 1 == 2
end
test "greets the world" do
assert EXW3.hello() == :world
end
test "gets accounts" do
assert EXW3.accounts |> is_list
end
# test "testing simple storage" do
# SimpleStorageTester.test_simple_storage "test/examples/build/SimpleStorage.abi"
# end
# test "get value" do
# abi = EXW3.load_abi "test/examples/build/SimpleStorage.abi"
# |> Kernel.inspect
# |> IO.puts
# end
end

@ -0,0 +1 @@
ExUnit.start()
Loading…
Cancel
Save