ExPlasma.Transaction behaviour (ExPlasma v0.2.0)
Contains the base structure of transactions.
Link to this section Summary
Functions
Attempt to decode the given RLP list into a Transaction.
Encode the given Transaction into an RLP encodable list.
Throwing version of encode/2
Returns the hash of the transaction involved without the signatures
Signs the inputs of the transaction with the given keys in the corresponding order. Only signs transactions that implement the ExPlasma.TypedData protocol.
Maps the given RLP list into a transaction.
Encode the given Transaction into an RLP encodable list.
Statelessly validate a transation.
Recovers the witnesses as addresses and add them to the transaction struct under
the witnesses
key.
Link to this section Types
decoding_error()
Specs
decoding_error() :: :malformed_rlp | mapping_error()
encoding_error()
Specs
encoding_error() :: :unrecognized_transaction_type
mapping_error()
Specs
mapping_error() :: :malformed_transaction | :unrecognized_transaction_type | atom()
metadata()
Specs
metadata() :: <<_::256>> | nil
nonce()
Specs
nonce() :: ExPlasma.Crypto.hash_t() | nil
outputs()
Specs
outputs() :: [ExPlasma.Output.t()] | []
Specs
t() :: %ExPlasma.Transaction{ inputs: outputs(), metadata: metadata(), nonce: nonce(), outputs: outputs(), sigs: ExPlasma.Transaction.Signed.sigs(), tx_data: non_neg_integer(), tx_type: pos_integer(), witnesses: [ExPlasma.Transaction.Witness.t()] }
tx_bytes()
Specs
tx_bytes() :: binary()
tx_hash()
Specs
tx_hash() :: ExPlasma.Crypto.hash_t()
Link to this section Functions
decode(tx_bytes, opts \\ [])
Specs
decode(tx_bytes(), keyword()) :: {:ok, t()} | {:error, decoding_error()}
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, 117, 192, 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.Transaction.decode(rlp)
{: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
}
}
encode(transaction, opts \\ [])
Specs
encode(t() | list(), keyword()) :: {:ok, tx_bytes()} | {:error, encoding_error()}
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.Transaction.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>>}
encode!(rlp_items, opts \\ [])
Throwing version of encode/2
hash(transaction)
Specs
hash(t() | tx_bytes()) :: {:ok, tx_hash()} | {:error, encoding_error()}
Returns the hash of the transaction involved without the signatures
sign(transaction, keys)
Signs the inputs of the transaction with the given keys in the corresponding order. Only signs transactions that implement the ExPlasma.TypedData protocol.
Returns
{:ok, %Transaction{}}
with sigs when succesfuly signed{:error, :not_signable}
when the given transaction is not supported.
Example
iex> key = "0x79298b0292bbfa9b15705c56b6133201c62b798f102d7d096d31d7637f9b2382"
iex> txn = %ExPlasma.Transaction{tx_type: 1}
iex> ExPlasma.Transaction.sign(txn, [key])
{:ok, %ExPlasma.Transaction{
sigs: [
<<129, 213, 32, 15, 183, 218, 255, 22, 82, 95, 22, 86, 103, 227, 92, 109, 9,
89, 7, 142, 235, 107, 203, 29, 20, 231, 91, 168, 255, 119, 204, 239, 44,
125, 76, 109, 200, 196, 204, 230, 224, 241, 84, 75, 9, 3, 160, 177, 37,
181, 174, 98, 51, 15, 136, 235, 47, 96, 15, 209, 45, 85, 153, 2, 28>>
],
inputs: [],
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: [],
tx_type: 1,
witnesses: [],
tx_data: 0
}}
to_map(rlp)
Specs
to_map(list()) :: {:ok, t()} | {:error, mapping_error()}
Maps the given RLP list into a transaction.
When the RLP list starts with a list, assumes it's the sigs and map it accordingly. If not starting with a list, assumes it's the transaction type.
Only validates that the RLP is structurally correct. Does not perform any other kind of validation, use validate/1 for that.
to_rlp(transaction, opts \\ [])
Specs
Encode the given Transaction into an RLP encodable list.
If signed: false
is given in the list of opts, will not prepend the signatures to the RLP list.
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>>,
...> 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.Transaction.to_rlp(txn)
{:ok, [
[],
<<1>>,
[<<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>>],
[
[
<<1>>,
[
<<29, 246, 47, 41, 27, 46, 150, 159, 176, 132, 157, 153, 217, 206, 65, 226, 241, 55, 0, 110>>,
<<46, 38, 45, 41, 28, 46, 150, 159, 176, 132, 157, 153, 217, 206, 65, 226, 241, 55, 0, 110>>,
<<1>>
]
]
],
0,
<<0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0>>
]}
validate(transaction)
Statelessly validate a transation.
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::256>>,
...> outputs: [
...> %ExPlasma.Output{
...> output_data: %{
...> amount: <<0, 0, 0, 0, 0, 0, 0, 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> :ok = ExPlasma.Transaction.validate(txn)
with_nonce(transaction, params)
Specs
with_witnesses(transaction)
Specs
with_witnesses(t()) :: {:ok, t()} | {:error, ExPlasma.Transaction.Witness.recovery_error()}
Recovers the witnesses as addresses and add them to the transaction struct under
the witnesses
key.