Skip to content

Commit

Permalink
hash transaction tx_id/1
Browse files Browse the repository at this point in the history
  • Loading branch information
piyushthapa committed Dec 2, 2024
1 parent 9f96e83 commit 82937fc
Show file tree
Hide file tree
Showing 4 changed files with 72 additions and 5 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/elixir.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ jobs:
# and running the workflow steps.
matrix:
otp: ["25.0.4"] # Define the OTP version [required]
elixir: ["1.15.0"] # Define the elixir version [required]
elixir: ["1.17.3"] # Define the elixir version [required]
steps:
# Step: Setup Elixir + Erlang image as the base.
- name: Set up Elixir
Expand Down
53 changes: 49 additions & 4 deletions lib/sutra/cardano/transaction.ex
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ defmodule Sutra.Cardano.Transaction do
Cardano Transaction
"""

alias Sutra.Blake2b
alias Sutra.Cardano.Transaction.TxBody
alias Sutra.Cardano.Transaction.Witness
alias Sutra.Data.Cbor
Expand All @@ -19,18 +20,34 @@ defmodule Sutra.Cardano.Transaction do
field(:metadata, any())
end

@doc """
Generate transaction from hex encoded cbor
iex> from_hex("valid-hex-transaction")
{:ok, %Sutra.Cardano.Transaction{}}
iex> from_hex("some-invalid-hex-transaction")
{:error, :invalid_cbor}
"""
def from_hex(cbor) when is_binary(cbor) do
case Sutra.Data.decode(cbor) do
{:ok, data} -> from_cbor(data)
{:error, _} -> {:error, :invalid_cbor}
end
end

# Conway era transaction
def from_cbor(%PList{value: [tx_body, witness, is_valid, metadata]})
@doc """
Generate transaction from cbor
iex> from_cbor(%PList{value: [valid_tx_body, valid_witness_cbor, true, metadata]})
%Sutra.Cardano.Transaction{}
"""
@spec from_cbor(CBOR.Tag.t()) :: __MODULE__.t()
def from_cbor(%PList{value: [tx_body, witness_cbor, is_valid, metadata]})
when is_boolean(is_valid) do
witness =
Enum.reduce(Cbor.extract_value!(witness), [], fn w, acc ->
Enum.reduce(Cbor.extract_value!(witness_cbor), [], fn w, acc ->
acc ++ Witness.decode(w)
end)

Expand All @@ -44,7 +61,35 @@ defmodule Sutra.Cardano.Transaction do

def from_cbor(%PList{value: _values}) do
raise """
Only Conway era transaction supported
Only Conway era transaction supported. Todo: support other eras.
"""
end

@doc """
Convert transaction to hex encoded cbor
iex> to_hex(%Sutra.Cardano.Transaction{})
"some-valid-hex-encoded-cbor"
"""
@spec to_cbor(__MODULE__.t()) :: Cbor.t()
def to_cbor(%__MODULE__{} = tx) do
tx_body_cbor = TxBody.to_cbor(tx.tx_body)

%PList{value: [tx_body_cbor, Witness.to_cbor(tx.witnesses), tx.is_valid, tx.metadata]}
end

@doc """
Get transaction id
iex> tx_id(%Sutra.Cardano.Transaction{})
"88350824a9557e16a8f18b9b3cc4ab7cc0c282c178132083babde3cdb33393ee"
"""
@spec tx_id(__MODULE__.t()) :: Blake2b.blake2b_256()
def tx_id(%__MODULE__{} = tx) do
tx.tx_body
|> TxBody.to_cbor()
|> CBOR.encode()
|> Blake2b.blake2b_256()
end
end
5 changes: 5 additions & 0 deletions lib/sutra/data/cbor.ex
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,16 @@ defmodule Sutra.Data.Cbor do
do: %CBOR.Tag{tag: :bytes, value: Base.decode16!(value, case: :mixed)}

def as_nonempty_set(value), do: %CBOR.Tag{tag: 258, value: value}
def as_set(value), do: %CBOR.Tag{tag: 258, value: value}

def as_indexed_map(value, index, map \\ %{}) do
Map.put(map, index, value)
end

def as_unit_interval({numerator, denomanator}) do
%CBOR.Tag{tag: 30, value: [numerator, denomanator]}
end

def as_tagged(values) when is_list(values) do
Enum.map(values, &as_tagged/1)
end
Expand Down
17 changes: 17 additions & 0 deletions test/sutra/cardano/transaction_test.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
defmodule Sutra.Cardano.TransactionTest do
@moduledoc false

use ExUnit.Case

alias Sutra.Cardano.Transaction

describe "Transaction Utility Functions" do
# Tx raw for tx_id: b7132e1233ec3898c5190b6c35853c08b99316c133d8a946ee29be63c34aab84, preprod
@valid_cbor_hex1 "84a800d901028282582039fbe758f447a2a0e3f219c88f52a55946ab34aee8b506531d0554767164c71f00825820f8314222bc4ec30bccdc4b7e78d624c9f57f7f7b60722dd23db37e417fd95fe90001818258390025195af85c41b9d97da7f4f215d3e74c9cef7f04739d6ba473ba72a2358a4e4105c08f59e4779070699c7a72566893332f9857db4e742beb821a002ee49ba1581cc6e65ba7878b2f8ea0ad39287d3e2fd256dc5c4160fc19bdf4c4d87ea1457447454e531a01f78a40021a00033c670b58209917c9109930038c163b1d8c9e7bce627925d6b95ca8b458022482522e6c47d30dd901028182582033971398f5b7c7c0773e96414e757c44e0659cc09f080154fca3dcca52ed316b040ed9010281581c25195af85c41b9d97da7f4f215d3e74c9cef7f04739d6ba473ba72a2108258390025195af85c41b9d97da7f4f215d3e74c9cef7f04739d6ba473ba72a2358a4e4105c08f59e4779070699c7a72566893332f9857db4e742beb1a004770a5111a0004da9ba400d901028182582056cf5d8dbb766190b751681732b36d877aac24e6a50738fe78bdceb8b8d97d1658403b1a306f48b807fab76051cbf66c5fee5b01a75b2b9d71c8b0bd3c0c24ad90325acc8cceb3720ccaf7ae108e455ad68e9f6274dceb2702d102088add0906cf0603d90102815901bf5901bc0100003232323232323232323232322223232323232323253330123015300f0021533301200314985854ccc04800c4c8c94ccc0514ccc050cc034c058008c0580044cc034c058c04c004c058c04c0085280a4c2c60286ea8c054c044c050dd500418099baa30163300e30163300e3374a9001198071ba8375a602800297ae03300e300d4a297ae03300e30163300e3374a900225eb80cc038c03528a5eb812f5c02c60240026ea8c048c03cc03cc044dd5004198011198010010009bac3011300e300d301037540084600446600400400244a666aae7c0045280a99980799baf301100100314a226004601c0026ea4dd7180718069baa004300d300c3754002446464646464646464a666022a66602266e200080045288a99980899b8700200113232533301330160041337106eb4c054008dd6980a8008a503013004301200414a0294454ccc044cdd78030028999808980598099808004180598099808003a5114a0601a00460180046ea8008dd50011807001180680118059baa002300a37540044601460086ea80048cdd2999803000a4004900025eb815d02ab9d23002300230023002300230020015744ae6955cf2ba1370e90011ba548000104d9010281d8799f581c25195af85c41b9d97da7f4f215d3e74c9cef7f04739d6ba473ba72a2d8799fd8799f581c25195af85c41b9d97da7f4f215d3e74c9cef7f04739d6ba473ba72a2ffd8799fd8799fd8799f581c358a4e4105c08f59e4779070699c7a72566893332f9857db4e742bebffffffffd87a80ff05a182000082d8798082194be91a006592d4f5f6"

test "tx_id/1 returns valid TransactionId" do
assert Transaction.from_hex(@valid_cbor_hex1) |> Transaction.tx_id() ==
"b7132e1233ec3898c5190b6c35853c08b99316c133d8a946ee29be63c34aab84"
end
end
end

0 comments on commit 82937fc

Please sign in to comment.