Skip to content

Commit

Permalink
new plasma contracts support
Browse files Browse the repository at this point in the history
  • Loading branch information
InoMurko committed Mar 31, 2021
1 parent 367228e commit e1d190b
Show file tree
Hide file tree
Showing 14 changed files with 658 additions and 691 deletions.
2 changes: 1 addition & 1 deletion config/config.exs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use Mix.Config

config :ex_plasma,
# 168 for v2
exit_id_size: 160,
exit_id_size: 168,
eip_712_domain: %{
name: "OMG Network",
salt: "0xfad5c7f626d80f9256ef01929f3beb96e058b8b4b0e3fe52d84f054c0e2a7a83",
Expand Down
11 changes: 5 additions & 6 deletions lib/ex_plasma/builder.ex
Original file line number Diff line number Diff line change
Expand Up @@ -134,12 +134,11 @@ defmodule ExPlasma.Builder do
0, 0, 0, 0, 0, 0, 0, 0, 0, 0>>,
outputs: [],
tx_data: 0,
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>>
],
sigs: [<<74, 172, 40, 90, 141, 61, 61, 67, 59, 242, 28, 172, 15, 2, 68, 246, 222,
52, 250, 67, 15, 50, 14, 127, 137, 234, 238, 210, 95, 224, 4, 45, 101,
211, 238, 252, 225, 118, 109, 43, 83, 124, 30, 109, 217, 248, 3, 78, 160,
94, 182, 219, 144, 119, 148, 5, 163, 191, 6, 214, 247, 178, 192, 108,
27>>],
tx_type: 1
}}
"""
Expand Down
6 changes: 1 addition & 5 deletions lib/ex_plasma/signature.ex
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,7 @@ defmodule ExPlasma.Signature do
def signature_digest(hash_digest, private_key_hash) do
private_key_binary = Encoding.to_binary!(private_key_hash)

{:ok, {r, s, recovery_id}} =
ExSecp256k1.sign(
hash_digest,
private_key_binary
)
{:ok, {r, s, recovery_id}} = ExSecp256k1.sign(hash_digest, private_key_binary)

# EIP-155
# See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-155.md
Expand Down
11 changes: 6 additions & 5 deletions lib/ex_plasma/transaction.ex
Original file line number Diff line number Diff line change
Expand Up @@ -350,15 +350,16 @@ defmodule ExPlasma.Transaction do
## Example
iex> key = "0x79298b0292bbfa9b15705c56b6133201c62b798f102d7d096d31d7637f9b2382"
iex> key = "0x99d483781114bc01e264a3da892760fdb84555927a331e0f305531e97f9a20cf"
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>>
<<47, 217, 63, 72, 91, 172, 102, 200, 31, 43, 199, 3, 219, 234, 6, 15, 1,
252, 13, 119, 153, 73, 196, 179, 219, 251, 81, 227, 110, 3, 242, 136, 14,
160, 132, 214, 183, 80, 62, 103, 221, 113, 209, 196, 116, 44, 210, 187,
10, 97, 166, 177, 243, 190, 250, 154, 228, 67, 15, 103, 12, 53, 101, 246,
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,
Expand Down
43 changes: 23 additions & 20 deletions lib/ex_plasma/typed_data/output.ex
Original file line number Diff line number Diff line change
@@ -1,43 +1,46 @@
defimpl ExPlasma.TypedData, for: ExPlasma.Output do
import ExPlasma.Crypto, only: [keccak_hash: 1]
import ABI.TypeEncoder, only: [encode_raw: 2]

alias ExPlasma.Crypto
alias ABI.TypeEncoder
alias ExPlasma.Output

@output_signature "Output(uint256 outputType,bytes20 outputGuard,address currency,uint256 amount)"
@input_signature "Input(uint256 blknum,uint256 txindex,uint256 oindex)"
@output_signature Crypto.keccak_hash("Output(uint256 outputType,bytes20 outputGuard,address currency,uint256 amount)")
@input_signature Crypto.keccak_hash("Input(uint256 blknum,uint256 txindex,uint256 oindex)")

@spec encode(Output.t(), as: atom()) :: list()
def encode(output, as: :input), do: do_to_rlp_id(output.output_id)
def encode(output, as: :output), do: do_encode(output)

@spec hash(Output.t(), [{:as, :input | :output}, ...]) :: <<_::256>>
def hash(output, options), do: output |> encode(options) |> do_hash(options)
@spec hash(Output.t(), [{:as, :input | :output}, ...]) :: :not_implemented
def hash(_output, _options), do: :not_implemented

defp do_encode(%{output_type: type, output_data: data}) do
[
@output_signature,
encode_raw([type], [{:uint, 256}]),
encode_raw([data.output_guard], [{:bytes, 20}]),
encode_raw([data.token], [:address]),
encode_raw([data.amount], [{:uint, 256}])
TypeEncoder.encode_raw([type], [{:uint, 256}]),
TypeEncoder.encode_raw([data.output_guard], [{:bytes, 20}]),
TypeEncoder.encode_raw([data.token], [:address]),
TypeEncoder.encode_raw([data.amount], [{:uint, 256}])
]
|> Enum.join()
|> Crypto.keccak_hash()
end

defp do_to_rlp_id(%{blknum: blknum, txindex: txindex, oindex: oindex}) do
[
@input_signature,
encode_raw([blknum], [{:uint, 256}]),
encode_raw([txindex], [{:uint, 256}]),
encode_raw([oindex], [{:uint, 256}])
TypeEncoder.encode_raw([blknum], [{:uint, 256}]),
TypeEncoder.encode_raw([txindex], [{:uint, 256}]),
TypeEncoder.encode_raw([oindex], [{:uint, 256}])
]
|> Enum.join()
|> Crypto.keccak_hash()
end

defp do_hash([signature | encoded_list], _options) do
data = [keccak_hash(signature) | encoded_list]
# defp do_hash([signature | encoded_list], _options) do
# data = [Crypto.keccak_hash(signature) | encoded_list]

data
|> Enum.join()
|> keccak_hash()
end
# data
# |> Enum.join()
# |> Crypto.keccak_hash()
# end
end
125 changes: 67 additions & 58 deletions lib/ex_plasma/typed_data/transaction.ex
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
defimpl ExPlasma.TypedData, for: ExPlasma.Transaction do
import ExPlasma.Crypto, only: [keccak_hash: 1]
import ExPlasma.Encoding, only: [to_binary!: 1]
import ABI.TypeEncoder, only: [encode_raw: 2]

alias ExPlasma.Crypto
alias ExPlasma.Encoding
alias ABI.TypeEncoder
alias ExPlasma.Configuration
alias ExPlasma.Output
alias ExPlasma.TypedData

# Prefix and version byte motivated by http://eips.ethereum.org/EIPS/eip-191
Expand All @@ -16,14 +14,18 @@ defimpl ExPlasma.TypedData, for: ExPlasma.Transaction do
@input_signature "Input(uint256 blknum,uint256 txindex,uint256 oindex)"

# The full encoded signature for the transaction
@encoded_signature @signature <> @input_signature <> @output_signature
@encoded_signature Crypto.keccak_hash(@signature <> @input_signature <> @output_signature)

def encode(transaction, _options) do
encoded_inputs =
transaction.inputs |> Enum.map(&encode_as_input/1) |> List.flatten() |> Enum.join() |> Crypto.keccak_hash()

encoded_outputs =
transaction.outputs |> Enum.map(&encode_as_output/1) |> List.flatten() |> Enum.join() |> Crypto.keccak_hash()

def encode(%{} = transaction, _options) do
encoded_inputs = transaction.inputs |> Enum.map(&encode_as_input/1) |> Enum.join() |> keccak_hash
encoded_outputs = transaction.outputs |> Enum.map(&encode_as_output/1) |> Enum.join() |> keccak_hash
encoded_transaction_type = encode_raw([transaction.tx_type], [{:uint, 256}])
encoded_transaction_data = encode_raw([transaction.tx_data], [{:uint, 256}])
encoded_metadata = encode_raw([transaction.metadata], [{:bytes, 32}])
encoded_transaction_type = TypeEncoder.encode_raw([transaction.tx_type], [{:uint, 256}])
encoded_transaction_data = TypeEncoder.encode_raw([transaction.tx_data], [{:uint, 256}])
encoded_metadata = TypeEncoder.encode_raw([transaction.metadata], [{:bytes, 32}])

[
@eip_191_prefix,
Expand All @@ -37,71 +39,78 @@ defimpl ExPlasma.TypedData, for: ExPlasma.Transaction do
]
end

def hash(%{} = transaction, options), do: transaction |> encode(options) |> hash(options)

def hash([prefix, domain_separator | encoded_transaction], _options) do
keccak_hash(prefix <> hash_domain(domain_separator) <> hash_encoded(encoded_transaction))
def hash(%{} = transaction, options) do
transaction
|> encode(options)
|> hash(options)
end

defp domain_separator() do
domain = Configuration.eip_712_domain()

[
@domain_signature,
domain.name,
domain.version,
domain.verifying_contract,
domain.salt
]
def hash([prefix, domain_separator | encoded_transaction], _options) do
Crypto.keccak_hash(prefix <> hash_domain(domain_separator) <> hash_encoded(encoded_transaction))
end

defp hash_domain([signature, name, version, verifying_contract, salt]) do
[
keccak_hash(signature),
keccak_hash(name),
keccak_hash(version),
encode_raw([to_binary!(verifying_contract)], [:address]),
encode_raw([to_binary!(salt)], [{:bytes, 32}])
]
|> Enum.join()
|> keccak_hash()
end
defp encode_as_input(output), do: TypedData.encode(output, as: :input)
defp encode_as_output(output), do: TypedData.encode(output, as: :output)

defp hash_encoded([signature, transaction_type, inputs, outputs, transaction_data, metadata]) do
[
keccak_hash(signature),
signature,
transaction_type,
hash_inputs(inputs),
hash_outputs(outputs),
inputs,
outputs,
transaction_data,
metadata
]
|> List.flatten()
|> Enum.join()
|> keccak_hash()
|> Crypto.keccak_hash()
end

defp encode_as_input(output), do: TypedData.encode(output, as: :input)
defp encode_as_output(output), do: TypedData.encode(output, as: :output)
# defp hash_inputs(inputs) do
# inputs
# |> Enum.map(&hash_output/1)
# |> List.flatten()
# |> Enum.join()
# |> Crypto.keccak_hash()
# end

# defp hash_outputs(outputs) do
# outputs
# |> Enum.map(&hash_output/1)
# |> List.flatten()
# |> Enum.join()
# |> Crypto.keccak_hash()
# end

# defp hash_output([signature | encoded_list]) do
# data = [Crypto.keccak_hash(signature) | encoded_list]

# data
# |> Enum.join()
# |> Crypto.keccak_hash()
# end

defp hash_inputs(inputs) do
inputs
|> Enum.map(&hash_output/1)
|> keccak_hash()
end
defp domain_separator() do
domain = Configuration.eip_712_domain()

defp hash_outputs(outputs) do
outputs
|> Enum.map(&hash_output/1)
|> Enum.join()
|> keccak_hash()
[
@domain_signature,
domain.name,
domain.version,
domain.verifying_contract,
domain.salt
]
end

defp hash_output([signature | encoded_list]) do
data = [keccak_hash(signature) | encoded_list]

data
defp hash_domain([signature, name, version, verifying_contract, salt]) do
[
Crypto.keccak_hash(signature),
Crypto.keccak_hash(name),
Crypto.keccak_hash(version),
TypeEncoder.encode_raw([Encoding.to_binary!(verifying_contract)], [:address]),
TypeEncoder.encode_raw([Encoding.to_binary!(salt)], [{:bytes, 32}])
]
|> Enum.join()
|> keccak_hash()
|> Crypto.keccak_hash()
end
end
4 changes: 1 addition & 3 deletions mix.exs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ defmodule ExPlasma.MixProject do
# Run "mix help compile.app" to learn about applications.
def application do
[
applications: [:ex_abi, :ex_rlp, :ex_keccak, :ex_secp256k1, :merkle_tree],
applications: [:ex_abi, :ex_rlp, :ex_keccak, :ex_secp256k1, :merkle_tree, :ethereumex],
extra_applications: [:logger]
]
end
Expand All @@ -74,8 +74,6 @@ defmodule ExPlasma.MixProject do
{:stream_data, "~>0.4.3", only: [:test]},
{:telemetry, "~> 0.4", only: [:test]},
{:ex_doc, ">= 0.0.0", only: :dev, runtime: false}
# {:dep_from_hexpm, "~> 0.3.0"},
# {:dep_from_git, git: "https://github.com/elixir-lang/my_dep.git", tag: "0.1.0"}
]
end

Expand Down
2 changes: 1 addition & 1 deletion plasma-contract.Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,5 @@ RUN apk add --update \
git

RUN git clone https://github.com/omisego/plasma-contracts.git
RUN cd /home/node/plasma-contracts && git checkout 5ce7d0b
RUN cd /home/node/plasma-contracts && git checkout 5d29c432e9b55ae2c7ec7a06a5e66761eca7ab28
RUN cd /home/node/plasma-contracts/plasma_framework && npm install
6 changes: 3 additions & 3 deletions test/conformance/signatures_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ defmodule Conformance.SignaturesTest do
assert_signs_conform(%Transaction{tx_type: 1, inputs: [input], outputs: [output]})
end

test "signs with a minimal transaction (4x4)" do
test "signs with a max transaction (5x5)" do
input = %Output{output_id: %{blknum: 1, txindex: 0, oindex: 0}}

output = %Output{
Expand All @@ -52,8 +52,8 @@ defmodule Conformance.SignaturesTest do

assert_signs_conform(%Transaction{
tx_type: 1,
inputs: List.duplicate(input, 4),
outputs: List.duplicate(output, 4)
inputs: List.duplicate(input, 5),
outputs: List.duplicate(output, 5)
})
end

Expand Down
13 changes: 3 additions & 10 deletions test/ex_plasma/builder_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -241,16 +241,9 @@ defmodule ExPlasma.BuilderTest do
tx_data: 0,
tx_type: 1,
sigs: [
<<130, 89, 40, 246, 220, 178, 131, 241, 16, 106, 27, 67, 32, 118, 106, 91, 161, 143, 162, 136, 87, 57,
17, 98, 208, 210, 218, 181, 15, 6, 163, 2, 26, 127, 8, 14, 150, 44, 116, 72, 46, 90, 255, 243, 144,
39, 175, 13, 47, 107, 179, 178, 240, 160, 166, 94, 252, 119, 38, 82, 49, 254, 192, 250, 27>>,
<<130, 89, 40, 246, 220, 178, 131, 241, 16, 106, 27, 67, 32, 118, 106, 91, 161, 143, 162, 136, 87, 57,
17, 98, 208, 210, 218, 181, 15, 6, 163, 2, 26, 127, 8, 14, 150, 44, 116, 72, 46, 90, 255, 243, 144,
39, 175, 13, 47, 107, 179, 178, 240, 160, 166, 94, 252, 119, 38, 82, 49, 254, 192, 250, 27>>,
<<50, 96, 3, 234, 168, 162, 52, 142, 174, 145, 201, 159, 24, 143, 251, 111, 1, 26, 48, 243, 140, 215,
21, 137, 161, 128, 184, 139, 183, 28, 161, 146, 22, 132, 29, 228, 34, 241, 196, 53, 155, 142, 69,
183, 16, 105, 65, 14, 185, 194, 147, 143, 146, 218, 206, 63, 233, 66, 151, 171, 32, 212, 234, 25,
28>>
"|\e\xFF\x99\xC6\x01\x97R\xC3\xEE\xF6|\xA06:N\xC4\xD5\xF8\x99\xD6n\xB6\xB0˚\x02\x04\xCF&CM-E\xCEh\xB8\xC8N\x99\xD6\ah\xE0\x94\xD74\x17\"T\x99[\xF1\x05s9Bz\x91\xC7av\xA5\xC7\x1C",
"|\e\xFF\x99\xC6\x01\x97R\xC3\xEE\xF6|\xA06:N\xC4\xD5\xF8\x99\xD6n\xB6\xB0˚\x02\x04\xCF&CM-E\xCEh\xB8\xC8N\x99\xD6\ah\xE0\x94\xD74\x17\"T\x99[\xF1\x05s9Bz\x91\xC7av\xA5\xC7\x1C",
"ZiK\x01\xBFu\xDE\e\x99`Z}|\xCC\xD0\xD6Ah\x85\xF5SWk\xC1PZ\d\xC1\xDD7\xD21,Q\x0E\x99bc\n\xE2\x05\x13i\x8A\0\xA3\xEF\xFF\x91\x84\xE0b~_\x9A\xA7Ll\x1D\x02\xC3 \x01\xED\x1C"
]
}
end
Expand Down

0 comments on commit e1d190b

Please sign in to comment.