4
0
Fork 0

Merge pull request #18 from hswick/contract-refactor2

Contract refactor
new-events
Harley Swick 6 years ago committed by GitHub
commit 26faa02a81
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 52
      README.md
  2. 134
      lib/exw3.ex
  3. 95
      test/exw3_test.exs

@ -44,22 +44,13 @@ Currently, ExW3 supports a handful of json rpc commands. Mostly just the useful
Check out the [documentation](https://hexdocs.pm/exw3/ExW3.html) Check out the [documentation](https://hexdocs.pm/exw3/ExW3.html)
```elixir ```
iex(1)> accounts = ExW3.accounts() iex(1)> accounts = ExW3.accounts()
["0xb5c17637ccc1a5d91715429de76949fbe49d36f0", ["0x00a329c0648769a73afac7f9381e08fb43dbea72"]
"0xecf00f60a29acf81d7fdf696fd2ca1fa82b623b0",
"0xbf11365685e07ad86387098f27204700d7568ee2",
"0xba76d611c29fb25158e5a7409cb627cf1bd220cf",
"0xbb209f51ef097cc5ca320264b5373a48f7ee0fba",
"0x31b7a2c8b2f82a92bf4cb5fd13971849c6c956fc",
"0xeb943cee8ec3723ab3a06e45dc2a75a3caa04288",
"0x59315d9706ac567d01860d7ede03720876972162",
"0x4dbd23f361a4df1ef5e517b68e099bf2fcc77b10",
"0x150eb320428b9bc93453b850b4ea454a35308f17"]
iex(2)> ExW3.balance(Enum.at(accounts, 0)) iex(2)> ExW3.balance(Enum.at(accounts, 0))
99999999999962720359 1606938044258990275541962092341162602522200978938292835291376
iex(3)> ExW3.block_number() iex(3)> ExW3.block_number()
835 1252
iex(4)> simple_storage_abi = ExW3.load_abi("test/examples/build/SimpleStorage.abi") iex(4)> simple_storage_abi = ExW3.load_abi("test/examples/build/SimpleStorage.abi")
%{ %{
"get" => %{ "get" => %{
@ -81,19 +72,22 @@ iex(4)> simple_storage_abi = ExW3.load_abi("test/examples/build/SimpleStorage.ab
"type" => "function" "type" => "function"
} }
} }
iex(5)> ExW3.Contract.start_link(SimpleStorage, abi: simple_storage_abi) iex(5)> ExW3.Contract.start_link
{:ok, #PID<0.239.0>} {:ok, #PID<0.265.0>}
iex(6)> {:ok, address, tx_hash} = ExW3.Contract.deploy(SimpleStorage, bin: ExW3.load_bin("test/examples/build/SimpleStorage.bin"), options: %{gas: 300_000, from: Enum.at(accounts, 0)}) iex(6)> ExW3.Contract.register(:SimpleStorage, abi: simple_storage_abi)
{:ok, "0xd99306b81bd61cb0ecdd3f2c946af513b3395088"}
iex(7)> ExW3.Contract.at(SimpleStorage, address)
:ok :ok
iex(8)> ExW3.Contract.call(SimpleStorage, :get) iex(7)> {:ok, address, tx_hash} = ExW3.Contract.deploy(:SimpleStorage, bin: ExW3.load_bin("test/examples/build/SimpleStorage.bin"), options: %{gas: 300_000, from: Enum.at(accounts, 0)})
{:ok, "0x22018c2bb98387a39e864cf784e76cb8971889a5",
"0x4ea539048c01194476004ef69f407a10628bed64e88ee8f8b17b4d030d0e7cb7"}
iex(8)> ExW3.Contract.at(:SimpleStorage, address)
:ok
iex(9)> ExW3.Contract.call(:SimpleStorage, :get)
{:ok, 0} {:ok, 0}
iex(9)> ExW3.Contract.send(SimpleStorage, :set, [1], %{from: Enum.at(accounts, 0), gas: 50_000}) iex(10)> ExW3.Contract.send(:SimpleStorage, :set, [1], %{from: Enum.at(accounts, 0), gas: 50_000})
{:ok, "0xb7e9cbdd2cec8ca017e675059a3af063d754496c960f156e1a41fe51ea82f3b8"} {:ok, "0x88838e84a401a1d6162290a1a765507c4a83f5e050658a83992a912f42149ca5"}
iex(10)> ExW3.Contract.call(SimpleStorage, :get) iex(11)> ExW3.Contract.call(:SimpleStorage, :get)
{:ok, 1} {:ok, 1}
``` ```
## Listening for Events ## Listening for Events
@ -105,15 +99,13 @@ Whenever a change is detected it will send a message to whichever process is lis
# Start the background listener # Start the background listener
ExW3.EventListener.start_link ExW3.EventListener.start_link
# Assuming we have already setup our contract called EventTester # Assuming we have already registered our contract called :EventTester
# We can then add a filter for the event listener to look out for # We can then add a filter for the event listener to look out for by passing in the event name, and the process we want to receive the messages when an event is triggered.
# by passing in the event name, and the process we want to receive the messages when an event is triggered.
# For now we are going to use the main process, however, we could pass in a pid of a different process. # For now we are going to use the main process, however, we could pass in a pid of a different process.
filter_id = ExW3.Contract.filter(EventTester, "Simple", self()) filter_id = ExW3.Contract.filter(:EventTester, "Simple", self())
# We can then wait for the event. Using the typical receive keyword we wait for the first instance # We can then wait for the event. Using the typical receive keyword we wait for the first instance of the event, and then continue with the rest of the code. This is useful for testing.
# of the event, and then continue with the rest of the code. This is useful for testing.
receive do receive do
{:event, {filter_id, data}} -> IO.inspect data {:event, {filter_id, data}} -> IO.inspect data
end end
@ -121,7 +113,7 @@ end
# We can then uninstall the filter after we are done using it # We can then uninstall the filter after we are done using it
ExW3.uninstall_filter(filter_id) ExW3.uninstall_filter(filter_id)
# ExW3 also provides a helper method to continuously listen for events. # ExW3 also provides a helper method to continuously listen for events, with the `listen` method.
# One use is to combine all of our filters with pattern matching # One use is to combine all of our filters with pattern matching
ExW3.EventListener.listen(fn result -> ExW3.EventListener.listen(fn result ->
case result do case result do

@ -454,60 +454,62 @@ defmodule ExW3 do
# Client # Client
@spec start_link(atom(), list()) :: {:ok, pid()} @spec start_link() :: {:ok, pid()}
@doc "Begins a Contract GenServer with specified name and state" @doc "Begins the Contract process to manage all interactions with smart contracts"
def start_link(name, state) do def start_link() do
GenServer.start_link(__MODULE__, state, name: name) GenServer.start_link(__MODULE__, %{}, name: ContractManager)
end end
@spec deploy(pid(), []) :: {:ok, []} @spec deploy(keyword(), []) :: {:ok, binary(), []}
@doc "Deploys contracts with given arguments" @doc "Deploys contracts with given arguments"
def deploy(pid, args) do def deploy(name, args) do
GenServer.call(pid, {:deploy, args}) GenServer.call(ContractManager, {:deploy, {name, args}})
end end
@spec at(pid(), binary()) :: :ok @spec register(keyword(), []) :: :ok
@doc "Sets the current Contract GenServer's address to given address" @doc "Registers the contract with the ContractManager process. Only :abi is required field."
def at(pid, address) do def register(name, contract_info) do
GenServer.cast(pid, {:at, address}) GenServer.cast(ContractManager, {:register, {name, contract_info}})
end end
@spec address(pid()) :: {:ok, binary()} @spec at(keyword(), binary()) :: :ok
@doc "Sets the address for the contract specified by the name argument"
def at(name, address) do
GenServer.cast(ContractManager, {:at, {name, address}})
end
@spec address(keyword()) :: {:ok, binary()}
@doc "Returns the current Contract GenServer's address" @doc "Returns the current Contract GenServer's address"
def address(pid) do def address(name) do
GenServer.call(pid, :address) GenServer.call(ContractManager, {:address, name})
end end
@spec call(pid(), keyword(), []) :: {:ok, any()} @spec call(keyword(), keyword(), []) :: {:ok, any()}
@doc "Use a Contract's method with an eth_call" @doc "Use a Contract's method with an eth_call"
def call(pid, method_name, args \\ []) do def call(contract_name, method_name, args \\ []) do
GenServer.call(pid, {:call, {method_name, args}}) GenServer.call(ContractManager, {:call, {contract_name, method_name, args}})
end end
@spec send(pid(), keyword(), [], %{}) :: {:ok, binary()} @spec send(keyword(), keyword(), [], %{}) :: {:ok, binary()}
@doc "Use a Contract's method with an eth_sendTransaction" @doc "Use a Contract's method with an eth_sendTransaction"
def send(pid, method_name, args, options) do def send(contract_name, method_name, args, options) do
GenServer.call(pid, {:send, {method_name, args, options}}) GenServer.call(ContractManager, {:send, {contract_name, method_name, args, options}})
end end
@spec tx_receipt(pid(), binary()) :: %{} @spec tx_receipt(keyword(), binary()) :: %{}
@doc "Returns a formatted transaction receipt for the given transaction hash(id)" @doc "Returns a formatted transaction receipt for the given transaction hash(id)"
def tx_receipt(pid, tx_hash) do def tx_receipt(contract_name, tx_hash) do
GenServer.call(pid, {:tx_receipt, tx_hash}) GenServer.call(ContractManager, {:tx_receipt, {contract_name, tx_hash}})
end end
def filter(pid, event_name, other_pid, event_data \\ %{}) do def filter(contract_name, event_name, other_pid, event_data \\ %{}) do
GenServer.call(pid, {:filter, {event_name, other_pid, event_data}}) GenServer.call(ContractManager, {:filter, {contract_name, event_name, other_pid, event_data}})
end end
# Server # Server
def init(state) do def init(state) do
if state[:abi] do {:ok, state}
{:ok, state ++ init_events(state[:abi])}
else
raise "ABI not provided upon initialization"
end
end end
defp init_events(abi) do defp init_events(abi) do
@ -611,6 +613,13 @@ defmodule ExW3 do
) )
end end
defp add_helper(contract_info) do
if contract_info[:abi] do
contract_info ++ init_events(contract_info[:abi])
else
raise "ABI not provided upon initialization"
end
end
# Options' checkers # Options' checkers
@ -622,66 +631,83 @@ defmodule ExW3 do
# Casts # Casts
def handle_cast({:at, address}, state) do def handle_cast({:at, {name, address}}, state) do
{:noreply, [{:address, address} | state]} contract_info = state[name]
{:noreply, Map.put(state, name, contract_info ++ [address: address])}
end end
def handle_call({:filter, {event_name, other_pid, event_data}}, _from, state) do def handle_cast({:register, {name, contract_info}}, state) do
{:noreply, Map.put(state, name, add_helper(contract_info))}
end
# Calls
def handle_call({:filter, {contract_name, event_name, other_pid, event_data}}, _from, state) do
contract_info = state[contract_name]
unless Process.whereis(Listener) do unless Process.whereis(Listener) do
raise "EventListener process not alive. Call ExW3.EventListener.start_link before using ExW3.Contract.subscribe" raise "EventListener process not alive. Call ExW3.EventListener.start_link before using ExW3.Contract.subscribe"
end end
payload = Map.merge(%{address: state[:address], topics: [state[:event_names][event_name]]}, event_data)
payload = Map.merge(%{address: contract_info[:address], topics: [contract_info[:event_names][event_name]]}, event_data)
filter_id = ExW3.new_filter(payload) filter_id = ExW3.new_filter(payload)
event_signature = state[:events][state[:event_names][event_name]][:signature] event_signature = contract_info[:events][contract_info[:event_names][event_name]][:signature]
event_fields = state[:events][state[:event_names][event_name]][:names] event_fields = contract_info[:events][contract_info[:event_names][event_name]][:names]
EventListener.filter(filter_id, event_signature, event_fields, other_pid) EventListener.filter(filter_id, event_signature, event_fields, other_pid)
{:reply, filter_id, state ++ [event_name, filter_id]} {:reply, filter_id, Map.put(state, contract_name, contract_info ++ [event_name, filter_id])}
end end
# Calls def handle_call({:deploy, {name, args}}, _from, state) do
def handle_call({:deploy, args}, _from, state) do contract_info = state[name]
with {:ok, _} <- check_option(args[:options][:from], :missing_sender), with {:ok, _} <- check_option(args[:options][:from], :missing_sender),
{:ok,_} <- check_option(args[:options][:gas], :missing_gas), {:ok,_} <- check_option(args[:options][:gas], :missing_gas),
{:ok, bin} <- check_option([state[:bin], args[:bin]], :missing_binary) {:ok, bin} <- check_option([state[:bin], args[:bin]], :missing_binary)
do do
{contract_addr, tx_hash} = deploy_helper(bin, state[:abi], args) {contract_addr, tx_hash} = deploy_helper(bin, contract_info[:abi], args)
result = {:ok, contract_addr, tx_hash} result = {:ok, contract_addr, tx_hash}
{:reply, result , state} {:reply, result , state}
else else
err -> {:reply, err, state} err -> {:reply, err, state}
end end
end end
def handle_call(:address, _from, state) do def handle_call({:address, name}, _from, state) do
{:reply, state[:address], state} {:reply, state[name][:address], state}
end end
def handle_call({:call, {method_name, args}}, _from, state) do def handle_call({:call, {contract_name, method_name, args}}, _from, state) do
with {:ok, address} <- check_option(state[:address], :missing_address) contract_info = state[contract_name]
with {:ok, address} <- check_option(contract_info[:address], :missing_address)
do do
result = eth_call_helper(address, state[:abi], Atom.to_string(method_name), args) result = eth_call_helper(address, contract_info[:abi], Atom.to_string(method_name), args)
{:reply, result, state} {:reply, result, state}
else else
err -> {:reply, err, state} err -> {:reply, err, state}
end end
end end
def handle_call({:send, {method_name, args, options}}, _from, state) do def handle_call({:send, {contract_name, method_name, args, options}}, _from, state) do
with {:ok, address} <- check_option(state[:address], :missing_address), contract_info = state[contract_name]
with {:ok, address} <- check_option(contract_info[:address], :missing_address),
{:ok, _} <- check_option(options[:from], :missing_sender), {:ok, _} <- check_option(options[:from], :missing_sender),
{:ok, _} <- check_option(options[:gas], :missing_gas) {:ok, _} <- check_option(options[:gas], :missing_gas)
do do
result = eth_send_helper(address, state[:abi], Atom.to_string(method_name), args, options) result = eth_send_helper(address, contract_info[:abi], Atom.to_string(method_name), args, options)
{:reply, result, state} {:reply, result, state}
else else
err -> {:reply, err, state} err -> {:reply, err, state}
end end
end end
def handle_call({:tx_receipt, tx_hash}, _from, state) do def handle_call({:tx_receipt, {contract_name, tx_hash}}, _from, state) do
contract_info = state[contract_name]
receipt = ExW3.tx_receipt(tx_hash) receipt = ExW3.tx_receipt(tx_hash)
events = state[:events] events = contract_info[:events]
logs = receipt["logs"] logs = receipt["logs"]
formatted_logs = formatted_logs =

@ -3,6 +3,8 @@ defmodule EXW3Test do
doctest ExW3 doctest ExW3
setup_all do setup_all do
ExW3.Contract.start_link
%{ %{
simple_storage_abi: ExW3.load_abi("test/examples/build/SimpleStorage.abi"), simple_storage_abi: ExW3.load_abi("test/examples/build/SimpleStorage.abi"),
array_tester_abi: ExW3.load_abi("test/examples/build/ArrayTester.abi"), array_tester_abi: ExW3.load_abi("test/examples/build/ArrayTester.abi"),
@ -58,11 +60,13 @@ defmodule EXW3Test do
end end
test "starts a Contract GenServer for simple storage contract", context do test "starts a Contract GenServer for simple storage contract", context do
ExW3.Contract.start_link(SimpleStorage, abi: context[:simple_storage_abi])
ExW3.Contract.register(:SimpleStorage, abi: context[:simple_storage_abi])
{:ok, address, _} = {:ok, address, _} =
ExW3.Contract.deploy( ExW3.Contract.deploy(
SimpleStorage, :SimpleStorage,
bin: ExW3.load_bin("test/examples/build/SimpleStorage.bin"), bin: ExW3.load_bin("test/examples/build/SimpleStorage.bin"),
args: [], args: [],
options: %{ options: %{
@ -71,27 +75,27 @@ defmodule EXW3Test do
} }
) )
ExW3.Contract.at(SimpleStorage, address) ExW3.Contract.at(:SimpleStorage, address)
assert address == ExW3.Contract.address(SimpleStorage) assert address == ExW3.Contract.address(:SimpleStorage)
{:ok, data} = ExW3.Contract.call(SimpleStorage, :get) {:ok, data} = ExW3.Contract.call(:SimpleStorage, :get)
assert data == 0 assert data == 0
ExW3.Contract.send(SimpleStorage, :set, [1], %{from: Enum.at(context[:accounts], 0), gas: 50_000}) ExW3.Contract.send(:SimpleStorage, :set, [1], %{from: Enum.at(context[:accounts], 0), gas: 50_000})
{:ok, data} = ExW3.Contract.call(SimpleStorage, :get) {:ok, data} = ExW3.Contract.call(:SimpleStorage, :get)
assert data == 1 assert data == 1
end end
test "starts a Contract GenServer for array tester contract", context do test "starts a Contract GenServer for array tester contract", context do
ExW3.Contract.start_link(ArrayTester, abi: context[:array_tester_abi]) ExW3.Contract.register(:ArrayTester, abi: context[:array_tester_abi])
{:ok, address, _} = {:ok, address, _} =
ExW3.Contract.deploy( ExW3.Contract.deploy(
ArrayTester, :ArrayTester,
bin: ExW3.load_bin("test/examples/build/ArrayTester.bin"), bin: ExW3.load_bin("test/examples/build/ArrayTester.bin"),
options: %{ options: %{
gas: 300_000, gas: 300_000,
@ -99,27 +103,27 @@ defmodule EXW3Test do
} }
) )
ExW3.Contract.at(ArrayTester, address) ExW3.Contract.at(:ArrayTester, address)
assert address == ExW3.Contract.address(ArrayTester) assert address == ExW3.Contract.address(:ArrayTester)
arr = [1, 2, 3, 4, 5] arr = [1, 2, 3, 4, 5]
{:ok, result} = ExW3.Contract.call(ArrayTester, :staticUint, [arr]) {:ok, result} = ExW3.Contract.call(:ArrayTester, :staticUint, [arr])
assert result == arr assert result == arr
{:ok, result} = ExW3.Contract.call(ArrayTester, :dynamicUint, [arr]) {:ok, result} = ExW3.Contract.call(:ArrayTester, :dynamicUint, [arr])
assert result == arr assert result == arr
end end
test "starts a Contract GenServer for event tester contract", context do test "starts a Contract GenServer for event tester contract", context do
ExW3.Contract.start_link(EventTester, abi: context[:event_tester_abi]) ExW3.Contract.register(:EventTester, abi: context[:event_tester_abi])
{:ok, address, _} = {:ok, address, _} =
ExW3.Contract.deploy( ExW3.Contract.deploy(
EventTester, :EventTester,
bin: ExW3.load_bin("test/examples/build/EventTester.bin"), bin: ExW3.load_bin("test/examples/build/EventTester.bin"),
options: %{ options: %{
gas: 300_000, gas: 300_000,
@ -127,17 +131,17 @@ defmodule EXW3Test do
} }
) )
ExW3.Contract.at(EventTester, address) ExW3.Contract.at(:EventTester, address)
assert address == ExW3.Contract.address(EventTester) assert address == ExW3.Contract.address(:EventTester)
{:ok, tx_hash} = {:ok, tx_hash} =
ExW3.Contract.send(EventTester, :simple, ["Hello, World!"], %{ ExW3.Contract.send(:EventTester, :simple, ["Hello, World!"], %{
from: Enum.at(context[:accounts], 0), from: Enum.at(context[:accounts], 0),
gas: 30_000 gas: 30_000
}) })
{:ok, {receipt, logs}} = ExW3.Contract.tx_receipt(EventTester, tx_hash) {:ok, {receipt, logs}} = ExW3.Contract.tx_receipt(:EventTester, tx_hash)
assert receipt |> is_map assert receipt |> is_map
@ -151,11 +155,11 @@ defmodule EXW3Test do
end end
test "starts a Contract GenServer and uses the event listener", context do test "starts a Contract GenServer and uses the event listener", context do
ExW3.Contract.start_link(EventTester, abi: context[:event_tester_abi]) ExW3.Contract.register(:EventTester, abi: context[:event_tester_abi])
{:ok, address, _} = {:ok, address, _} =
ExW3.Contract.deploy( ExW3.Contract.deploy(
EventTester, :EventTester,
bin: ExW3.load_bin("test/examples/build/EventTester.bin"), bin: ExW3.load_bin("test/examples/build/EventTester.bin"),
options: %{ options: %{
gas: 300_000, gas: 300_000,
@ -163,17 +167,17 @@ defmodule EXW3Test do
} }
) )
ExW3.Contract.at(EventTester, address) ExW3.Contract.at(:EventTester, address)
{:ok, agent} = Agent.start_link(fn -> [] end) {:ok, agent} = Agent.start_link(fn -> [] end)
ExW3.EventListener.start_link() ExW3.EventListener.start_link()
filter_id = ExW3.Contract.filter(EventTester, "Simple", self()) filter_id = ExW3.Contract.filter(:EventTester, "Simple", self())
{:ok, _tx_hash} = {:ok, _tx_hash} =
ExW3.Contract.send( ExW3.Contract.send(
EventTester, :EventTester,
:simple, :simple,
["Hello, World!"], ["Hello, World!"],
%{from: Enum.at(context[:accounts], 0), gas: 30_000} %{from: Enum.at(context[:accounts], 0), gas: 30_000}
@ -189,6 +193,7 @@ defmodule EXW3Test do
state = Agent.get(agent, fn list -> list end) state = Agent.get(agent, fn list -> list end)
event_log = Enum.at(state, 0) event_log = Enum.at(state, 0)
assert event_log |> is_map assert event_log |> is_map
log_data = Map.get(event_log, "data") log_data = Map.get(event_log, "data")
assert log_data |> is_map assert log_data |> is_map
assert Map.get(log_data, "num") == 42 assert Map.get(log_data, "num") == 42
@ -198,11 +203,11 @@ defmodule EXW3Test do
end end
test "starts a Contract GenServer for Complex contract", context do test "starts a Contract GenServer for Complex contract", context do
ExW3.Contract.start_link(Complex, abi: context[:complex_abi]) ExW3.Contract.register(:Complex, abi: context[:complex_abi])
{:ok, address, _} = {:ok, address, _} =
ExW3.Contract.deploy( ExW3.Contract.deploy(
Complex, :Complex,
bin: ExW3.load_bin("test/examples/build/Complex.bin"), bin: ExW3.load_bin("test/examples/build/Complex.bin"),
args: [42, "Hello, world!"], args: [42, "Hello, world!"],
options: %{ options: %{
@ -211,11 +216,11 @@ defmodule EXW3Test do
} }
) )
ExW3.Contract.at(Complex, address) ExW3.Contract.at(:Complex, address)
assert address == ExW3.Contract.address(Complex) assert address == ExW3.Contract.address(:Complex)
{:ok, foo, foobar} = ExW3.Contract.call(Complex, :getBoth) {:ok, foo, foobar} = ExW3.Contract.call(:Complex, :getBoth)
assert foo == 42 assert foo == 42
@ -223,11 +228,11 @@ defmodule EXW3Test do
end end
test "starts a Contract GenServer for AddressTester contract", context do test "starts a Contract GenServer for AddressTester contract", context do
ExW3.Contract.start_link(AddressTester, abi: context[:address_tester_abi]) ExW3.Contract.register(:AddressTester, abi: context[:address_tester_abi])
{:ok, address, _} = {:ok, address, _} =
ExW3.Contract.deploy( ExW3.Contract.deploy(
AddressTester, :AddressTester,
bin: ExW3.load_bin("test/examples/build/AddressTester.bin"), bin: ExW3.load_bin("test/examples/build/AddressTester.bin"),
options: %{ options: %{
from: Enum.at(context[:accounts], 0), from: Enum.at(context[:accounts], 0),
@ -235,15 +240,15 @@ defmodule EXW3Test do
} }
) )
ExW3.Contract.at(AddressTester, address) ExW3.Contract.at(:AddressTester, address)
assert address == ExW3.Contract.address(AddressTester) assert address == ExW3.Contract.address(:AddressTester)
formatted_address = formatted_address =
Enum.at(context[:accounts], 0) Enum.at(context[:accounts], 0)
|> ExW3.format_address |> ExW3.format_address
{:ok, same_address} = ExW3.Contract.call(AddressTester, :get, [formatted_address]) {:ok, same_address} = ExW3.Contract.call(:AddressTester, :get, [formatted_address])
assert ExW3.to_address(same_address) == Enum.at(context[:accounts], 0) assert ExW3.to_address(same_address) == Enum.at(context[:accounts], 0)
end end
@ -283,11 +288,11 @@ defmodule EXW3Test do
test "returns proper error messages at contract deployment", context do test "returns proper error messages at contract deployment", context do
ExW3.Contract.start_link(SimpleStorage, abi: context[:simple_storage_abi]) ExW3.Contract.register(:SimpleStorage, abi: context[:simple_storage_abi])
assert {:error, :missing_gas} == assert {:error, :missing_gas} ==
ExW3.Contract.deploy( ExW3.Contract.deploy(
SimpleStorage, :SimpleStorage,
bin: ExW3.load_bin("test/examples/build/SimpleStorage.bin"), bin: ExW3.load_bin("test/examples/build/SimpleStorage.bin"),
args: [], args: [],
options: %{ options: %{
@ -297,7 +302,7 @@ defmodule EXW3Test do
assert {:error, :missing_sender} == assert {:error, :missing_sender} ==
ExW3.Contract.deploy( ExW3.Contract.deploy(
SimpleStorage, :SimpleStorage,
bin: ExW3.load_bin("test/examples/build/SimpleStorage.bin"), bin: ExW3.load_bin("test/examples/build/SimpleStorage.bin"),
args: [], args: [],
options: %{ options: %{
@ -307,7 +312,7 @@ defmodule EXW3Test do
assert {:error, :missing_binary} == assert {:error, :missing_binary} ==
ExW3.Contract.deploy( ExW3.Contract.deploy(
SimpleStorage, :SimpleStorage,
args: [], args: [],
options: %{ options: %{
gas: 300_000, gas: 300_000,
@ -318,11 +323,11 @@ defmodule EXW3Test do
end end
test "return proper error messages at send and call", context do test "return proper error messages at send and call", context do
ExW3.Contract.start_link(SimpleStorage, abi: context[:simple_storage_abi]) ExW3.Contract.register(:SimpleStorage, abi: context[:simple_storage_abi])
{:ok, address, _} = {:ok, address, _} =
ExW3.Contract.deploy( ExW3.Contract.deploy(
SimpleStorage, :SimpleStorage,
bin: ExW3.load_bin("test/examples/build/SimpleStorage.bin"), bin: ExW3.load_bin("test/examples/build/SimpleStorage.bin"),
args: [], args: [],
options: %{ options: %{
@ -331,13 +336,13 @@ defmodule EXW3Test do
} }
) )
assert {:error, :missing_address} == ExW3.Contract.call(SimpleStorage, :get) assert {:error, :missing_address} == ExW3.Contract.call(:SimpleStorage, :get)
assert {:error, :missing_address} == ExW3.Contract.send(SimpleStorage, :set, [1], %{from: Enum.at(context[:accounts], 0), gas: 50_000}) assert {:error, :missing_address} == ExW3.Contract.send(:SimpleStorage, :set, [1], %{from: Enum.at(context[:accounts], 0), gas: 50_000})
ExW3.Contract.at(SimpleStorage, address) ExW3.Contract.at(:SimpleStorage, address)
assert {:error, :missing_sender} == ExW3.Contract.send(SimpleStorage, :set, [1], %{gas: 50_000}) assert {:error, :missing_sender} == ExW3.Contract.send(:SimpleStorage, :set, [1], %{gas: 50_000})
assert {:error, :missing_gas} == ExW3.Contract.send(SimpleStorage, :set, [1], %{from: Enum.at(context[:accounts], 0)}) assert {:error, :missing_gas} == ExW3.Contract.send(:SimpleStorage, :set, [1], %{from: Enum.at(context[:accounts], 0)})
end end

Loading…
Cancel
Save