Current section
Files
Jump to
Current section
Files
lib/ex_plasma.ex
defmodule ExPlasma do
@moduledoc """
Documentation for ExPlasma.
"""
alias ExPlasma.Transaction
alias ExPlasma.Transaction.TypeMapper
# constants that identify payment types, make sure that
# when we introduce a new payment type, you name it `paymentV2`
# https://github.com/omisego/plasma-contracts/blob/6ab35256b805e25cfc30d85f95f0616415220b20/plasma_framework/docs/design/tx-types-dependencies.md
@payment_v1 TypeMapper.tx_type_for(:tx_payment_v1)
@fee TypeMapper.tx_type_for(:tx_fee_token_claim)
@type transaction_type :: non_neg_integer()
@doc """
Simple payment type V1
## Example
iex> ExPlasma.payment_v1()
1
"""
@spec payment_v1() :: 1
def payment_v1(), do: @payment_v1
@doc """
Transaction fee claim V1
## Example
iex> ExPlasma.fee()
3
"""
@spec fee() :: 3
def fee(), do: @fee
@doc """
Transaction types
## Example
iex> ExPlasma.transaction_types()
[1, 3]
"""
@spec transaction_types :: [1 | 3, ...]
def transaction_types(), do: [payment_v1(), fee()]
@doc """
Encode the given Transaction into an RLP encodable list.
If `signed: false` is given in the list of opts, will encode the transaction without its signatures.
## Example
iex> txn =
...> %ExPlasma.Transaction{
...> inputs: [
...> %ExPlasma.Output{
...> output_data: nil,
...> output_id: %{blknum: 0, oindex: 0, position: 0, txindex: 0},
...> output_type: nil
...> }
...> ],
...> metadata: <<0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0>>,
...> outputs: [
...> %ExPlasma.Output{
...> output_data: %{
...> amount: 1,
...> output_guard: <<29, 246, 47, 41, 27, 46, 150, 159, 176, 132, 157, 153,
...> 217, 206, 65, 226, 241, 55, 0, 110>>,
...> token: <<46, 38, 45, 41, 28, 46, 150, 159, 176, 132, 157, 153, 217, 206,
...> 65, 226, 241, 55, 0, 110>>
...> },
...> output_id: nil,
...> output_type: 1
...> }
...> ],
...> sigs: [],
...> tx_data: 0,
...> tx_type: 1
...> }
iex> ExPlasma.encode(txn, signed: false)
{:ok, <<248, 116, 1, 225, 160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 238, 237, 1, 235, 148, 29, 246, 47,
41, 27, 46, 150, 159, 176, 132, 157, 153, 217, 206, 65, 226, 241, 55, 0, 110,
148, 46, 38, 45, 41, 28, 46, 150, 159, 176, 132, 157, 153, 217, 206, 65, 226,
241, 55, 0, 110, 1, 128, 160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0>>}
"""
defdelegate encode(transaction, opts \\ []), to: Transaction
@doc """
Throwing version of encode/2
"""
defdelegate encode!(transaction, opts \\ []), to: Transaction
@doc """
Attempt to decode the given RLP list into a Transaction.
If `signed: false` is given in the list of opts, expects the underlying RLP to not contain signatures.
Only validates that the RLP is structurally correct and that the tx type is supported.
Does not perform any other kind of validation, use validate/1 for that.
## Example
iex> rlp = <<248, 116, 1, 225, 160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
...> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 238, 237, 1, 235, 148,
...> 29, 246, 47, 41, 27, 46, 150, 159, 176, 132, 157, 153, 217, 206, 65, 226, 241,
...> 55, 0, 110, 148, 46, 38, 45, 41, 28, 46, 150, 159, 176, 132, 157, 153, 217,
...> 206, 65, 226, 241, 55, 0, 110, 1, 128, 160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
...> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0>>
iex> ExPlasma.decode(rlp, signed: false)
{:ok,
%ExPlasma.Transaction{
inputs: [
%ExPlasma.Output{
output_data: nil,
output_id: %{blknum: 0, oindex: 0, position: 0, txindex: 0},
output_type: nil
}
],
metadata: <<0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0>>,
outputs: [
%ExPlasma.Output{
output_data: %{
amount: 1,
output_guard: <<29, 246, 47, 41, 27, 46, 150, 159, 176, 132, 157, 153,
217, 206, 65, 226, 241, 55, 0, 110>>,
token: <<46, 38, 45, 41, 28, 46, 150, 159, 176, 132, 157, 153, 217, 206,
65, 226, 241, 55, 0, 110>>
},
output_id: nil,
output_type: 1
}
],
witnesses: [],
sigs: [],
tx_data: 0,
tx_type: 1
}
}
"""
defdelegate decode(tx_bytes, opts \\ []), to: Transaction
@doc """
Keccak hash the Transaction. This is used in the contracts and events to to reference transactions.
## Example
iex> rlp = <<248, 74, 192, 1, 193, 128, 239, 174, 237, 1, 235, 148, 29, 246, 47, 41, 27,
...> 46, 150, 159, 176, 132, 157, 153, 217, 206, 65, 226, 241, 55, 0, 110, 148, 46,
...> 38, 45, 41, 28, 46, 150, 159, 176, 132, 157, 153, 217, 206, 65, 226, 241, 55,
...> 0, 110, 1, 128, 148, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
...> 0>>
iex> ExPlasma.hash(rlp)
{:ok, <<87, 132, 239, 36, 144, 239, 129, 88, 63, 88, 116, 147, 164, 200, 113, 191,
124, 14, 55, 131, 119, 96, 112, 13, 28, 178, 251, 49, 16, 127, 58, 96>>}
"""
defdelegate hash(transaction), to: Transaction
@doc """
Statelessly validate a transation.
Returns :ok if valid or {:error, {atom, atom}} otherwise
"""
defdelegate validate(transaction), to: Transaction
end