4
0
Fork 0

Added typespecs and docs to methods

pull/5/head
hswick 7 years ago
parent db705033d8
commit 3b3ea4c654
  1. 54
      lib/exw3.ex

@ -1,5 +1,7 @@
defmodule ExW3 do defmodule ExW3 do
@spec bytes_to_string(binary()) :: binary()
@doc "converts Ethereum style bytes to string"
def bytes_to_string bytes do def bytes_to_string bytes do
bytes bytes
|> Base.encode16(case: :lower) |> Base.encode16(case: :lower)
@ -7,6 +9,8 @@ defmodule ExW3 do
|> Base.decode16!(case: :lower) |> Base.decode16!(case: :lower)
end end
@spec accounts() :: list()
@doc "returns all available accounts"
def accounts do def accounts do
case Ethereumex.HttpClient.eth_accounts() do case Ethereumex.HttpClient.eth_accounts() do
{:ok, accounts} -> accounts {:ok, accounts} -> accounts
@ -14,13 +18,16 @@ defmodule ExW3 do
end end
end end
# Converts ethereum hex string to decimal number @spec to_decimal(binary()) :: number()
@doc "Converts ethereum hex string to decimal number"
def to_decimal(hex_string) do def to_decimal(hex_string) do
hex_string hex_string
|> String.slice(2..-1) |> String.slice(2..-1)
|> String.to_integer(16) |> String.to_integer(16)
end end
@spec block_number() :: integer()
@doc "Returns the current block number"
def block_number do def block_number do
case Ethereumex.HttpClient.eth_block_number() do case Ethereumex.HttpClient.eth_block_number() do
{:ok, block_number} -> {:ok, block_number} ->
@ -31,6 +38,8 @@ defmodule ExW3 do
end end
end end
@spec balance(binary()) :: integer()
@doc "Returns current balance of account"
def balance(account) do def balance(account) do
case Ethereumex.HttpClient.eth_get_balance(account) do case Ethereumex.HttpClient.eth_get_balance(account) do
{:ok, balance} -> {:ok, balance} ->
@ -41,6 +50,7 @@ defmodule ExW3 do
end end
end end
@spec keys_to_decimal(%{}, []) :: %{}
def keys_to_decimal(map, keys) do def keys_to_decimal(map, keys) do
Map.new( Map.new(
Enum.map(keys, fn k -> Enum.map(keys, fn k ->
@ -49,6 +59,8 @@ defmodule ExW3 do
) )
end end
@spec tx_receipt(binary()) :: %{}
@doc "Returns transaction receipt for specified transaction hash(id)"
def tx_receipt(tx_hash) do def tx_receipt(tx_hash) do
case Ethereumex.HttpClient.eth_get_transaction_receipt(tx_hash) do case Ethereumex.HttpClient.eth_get_transaction_receipt(tx_hash) do
{:ok, receipt} -> {:ok, receipt} ->
@ -59,6 +71,8 @@ defmodule ExW3 do
end end
end end
@spec block(integer()) :: any()
@doc "Returns block data for specified block number"
def block(block_number) do def block(block_number) do
case Ethereumex.HttpClient.eth_get_block_by_number(block_number, true) do case Ethereumex.HttpClient.eth_get_block_by_number(block_number, true) do
{:ok, block} -> block {:ok, block} -> block
@ -66,16 +80,22 @@ defmodule ExW3 do
end end
end end
@spec mine(integer()) :: any()
@doc "Mines number of blocks specified. Default is 1"
def mine(num_blocks \\ 1) do def mine(num_blocks \\ 1) do
for _ <- 0..(num_blocks - 1) do for _ <- 0..(num_blocks - 1) do
Ethereumex.HttpClient.request("evm_mine", [], []) Ethereumex.HttpClient.request("evm_mine", [], [])
end end
end end
@spec encode_event(binary()) :: binary()
@doc "Encodes event based on signature"
def encode_event(signature) do def encode_event(signature) do
ExthCrypto.Hash.Keccak.kec(signature) |> Base.encode16(case: :lower) ExthCrypto.Hash.Keccak.kec(signature) |> Base.encode16(case: :lower)
end end
@spec decode_event(binary(), binary()) :: any()
@doc "Decodes event based on given data and provided signature"
def decode_event(data, signature) do def decode_event(data, signature) do
formatted_data = formatted_data =
data data
@ -87,10 +107,14 @@ defmodule ExW3 do
ABI.TypeDecoder.decode(formatted_data, fs) ABI.TypeDecoder.decode(formatted_data, fs)
end end
@spec reformat_abi([]) :: %{}
@doc "Reformats abi from list to map with event and function names as keys"
def reformat_abi(abi) do def reformat_abi(abi) do
Map.new(Enum.map(abi, fn x -> {x["name"], x} end)) Map.new(Enum.map(abi, fn x -> {x["name"], x} end))
end end
@spec load_abi(binary()) :: []
@doc "Loads the abi at the file path and reformats it to a map"
def load_abi(file_path) do def load_abi(file_path) do
file = File.read(Path.join(System.cwd(), file_path)) file = File.read(Path.join(System.cwd(), file_path))
@ -100,6 +124,8 @@ defmodule ExW3 do
end end
end end
@spec load_bin(binary()) :: binary()
@doc "Loads the bin ar the file path"
def load_bin(file_path) do def load_bin(file_path) do
file = File.read(Path.join(System.cwd(), file_path)) file = File.read(Path.join(System.cwd(), file_path))
@ -109,6 +135,8 @@ defmodule ExW3 do
end end
end end
@spec decode_output(%{}, binary(), binary()) :: []
@doc "Decodes output based on specified functions return signature"
def decode_output(abi, name, output) do def decode_output(abi, name, output) do
{:ok, trim_output} = {:ok, trim_output} =
String.slice(output, 2..String.length(output)) |> Base.decode16(case: :lower) String.slice(output, 2..String.length(output)) |> Base.decode16(case: :lower)
@ -124,12 +152,16 @@ defmodule ExW3 do
outputs outputs
end end
@spec types_signature(%{}, binary()) :: binary()
@doc "Returns the type signature of a given function"
def types_signature(abi, name) do def types_signature(abi, name) do
input_types = Enum.map(abi[name]["inputs"], fn x -> x["type"] end) input_types = Enum.map(abi[name]["inputs"], fn x -> x["type"] end)
types_signature = Enum.join(["(", Enum.join(input_types, ","), ")"]) types_signature = Enum.join(["(", Enum.join(input_types, ","), ")"])
types_signature types_signature
end end
@spec method_signature(%{}, binary()) :: binary()
@doc "Returns the 4 character method id based on the hash of the method signature"
def method_signature(abi, name) do def method_signature(abi, name) do
if abi[name] do if abi[name] do
input_signature = "#{name}#{types_signature(abi, name)}" |> ExthCrypto.Hash.Keccak.kec() input_signature = "#{name}#{types_signature(abi, name)}" |> ExthCrypto.Hash.Keccak.kec()
@ -142,6 +174,8 @@ defmodule ExW3 do
end end
end end
@spec encode_data(binary(), []) :: binary()
@doc "Encodes data into Ethereum hex string based on types signature"
def encode_data(types_signature, data) do def encode_data(types_signature, data) do
ABI.TypeEncoder.encode_raw( ABI.TypeEncoder.encode_raw(
[List.to_tuple(data)], [List.to_tuple(data)],
@ -149,11 +183,15 @@ defmodule ExW3 do
) )
end end
@spec encode_method_call(%{}, binary(), []) :: binary()
@doc "Encodes data and appends it to the encoded method id"
def encode_method_call(abi, name, input) do def encode_method_call(abi, name, input) do
encoded_method_call = method_signature(abi, name) <> encode_data(types_signature(abi, name), input) encoded_method_call = method_signature(abi, name) <> encode_data(types_signature(abi, name), input)
encoded_method_call |> Base.encode16(case: :lower) encoded_method_call |> Base.encode16(case: :lower)
end end
@spec encode_input(%{}, binary(), []) :: binary()
@doc "Encodes input from a method call based on function signature"
def encode_input(abi, name, input) do def encode_input(abi, name, input) do
if abi[name]["inputs"] do if abi[name]["inputs"] do
input_types = Enum.map(abi[name]["inputs"], fn x -> x["type"] end) input_types = Enum.map(abi[name]["inputs"], fn x -> x["type"] end)
@ -181,30 +219,44 @@ defmodule ExW3 do
# Client # Client
@spec start_link(atom(), list()) :: {:ok, pid()}
@doc "Begins a Contract GenServer with specified name and state"
def start_link(name, state) do def start_link(name, state) do
GenServer.start_link(__MODULE__, state, name: name) GenServer.start_link(__MODULE__, state, name: name)
end end
@spec deploy(pid(), []) :: {:ok, []}
@doc "Deploys contracts with given arguments"
def deploy(pid, args) do def deploy(pid, args) do
GenServer.call(pid, {:deploy, args}) GenServer.call(pid, {:deploy, args})
end end
@spec at(pid(), binary()) :: :ok
@doc "Sets the current Contract GenServer's address to given address"
def at(pid, address) do def at(pid, address) do
GenServer.cast(pid, {:at, address}) GenServer.cast(pid, {:at, address})
end end
@spec address(pid()) :: {:ok, binary()}
@doc "Returns the current Contract GenServer's address"
def address(pid) do def address(pid) do
GenServer.call(pid, :address) GenServer.call(pid, :address)
end end
@spec call(pid(), keyword(), []) :: {:ok, any()}
@doc "Use a Contract's method with an eth_call"
def call(pid, method_name, args \\ []) do def call(pid, method_name, args \\ []) do
GenServer.call(pid, {:call, {method_name, args}}) GenServer.call(pid, {:call, {method_name, args}})
end end
@spec send(pid(), keyword(), [], %{}) :: {:ok, binary()}
@doc "Use a Contract's method with an eth_sendTransaction"
def send(pid, method_name, args, options) do def send(pid, method_name, args, options) do
GenServer.call(pid, {:send, {method_name, args, options}}) GenServer.call(pid, {:send, {method_name, args, options}})
end end
@spec tx_receipt(pid(), binary()) :: %{}
@doc "Returns a formatted transaction receipt for the given transaction hash(id)"
def tx_receipt(pid, tx_hash) do def tx_receipt(pid, tx_hash) do
GenServer.call(pid, {:tx_receipt, tx_hash}) GenServer.call(pid, {:tx_receipt, tx_hash})
end end

Loading…
Cancel
Save