Skip to content

Commit

Permalink
Fix the decoding of unsigned transactions (#243)
Browse files Browse the repository at this point in the history
* Recover sender address only for signed transactions

* Add a test case for decoding an unsigned transaction

* Add a test case for an EIP-2930 transaction
  • Loading branch information
pienkowb committed Aug 3, 2023
1 parent 723977c commit 031652b
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 12 deletions.
15 changes: 10 additions & 5 deletions lib/eth/tx/eip1559.rb
Original file line number Diff line number Diff line change
Expand Up @@ -186,11 +186,16 @@ def decode(hex)
# last but not least, set the type.
@type = TYPE_1559

# recover sender address
v = Chain.to_v recovery_id, chain_id
public_key = Signature.recover(unsigned_hash, "#{r.rjust(64, "0")}#{s.rjust(64, "0")}#{v.to_s(16)}", chain_id)
address = Util.public_key_to_address(public_key).to_s
@sender = Tx.sanitize_address address
unless recovery_id.nil?
# recover sender address
v = Chain.to_v recovery_id, chain_id
public_key = Signature.recover(unsigned_hash, "#{r.rjust(64, "0")}#{s.rjust(64, "0")}#{v.to_s(16)}", chain_id)
address = Util.public_key_to_address(public_key).to_s
@sender = Tx.sanitize_address address
else
# keep the 'from' field blank
@sender = Tx.sanitize_address nil
end
end

# Creates an unsigned copy of a transaction payload.
Expand Down
15 changes: 10 additions & 5 deletions lib/eth/tx/eip2930.rb
Original file line number Diff line number Diff line change
Expand Up @@ -181,11 +181,16 @@ def decode(hex)
# last but not least, set the type.
@type = TYPE_2930

# recover sender address
v = Chain.to_v recovery_id, chain_id
public_key = Signature.recover(unsigned_hash, "#{r.rjust(64, "0")}#{s.rjust(64, "0")}#{v.to_s(16)}", chain_id)
address = Util.public_key_to_address(public_key).to_s
@sender = Tx.sanitize_address address
unless recovery_id.nil?
# recover sender address
v = Chain.to_v recovery_id, chain_id
public_key = Signature.recover(unsigned_hash, "#{r.rjust(64, "0")}#{s.rjust(64, "0")}#{v.to_s(16)}", chain_id)
address = Util.public_key_to_address(public_key).to_s
@sender = Tx.sanitize_address address
else
# keep the 'from' field blank
@sender = Tx.sanitize_address nil
end
end

# Creates an unsigned copy of a transaction payload.
Expand Down
2 changes: 0 additions & 2 deletions lib/eth/tx/legacy.rb
Original file line number Diff line number Diff line change
Expand Up @@ -154,13 +154,11 @@ def decode(hex)
_set_signature(v, r, s)

unless chain_id.nil?

# recover sender address
public_key = Signature.recover(unsigned_hash, "#{r.rjust(64, "0")}#{s.rjust(64, "0")}#{v}", chain_id)
address = Util.public_key_to_address(public_key).to_s
@sender = Tx.sanitize_address address
else

# keep the 'from' field blank
@sender = Tx.sanitize_address nil
end
Expand Down
28 changes: 28 additions & 0 deletions spec/eth/tx_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -122,4 +122,32 @@
expect(tx.chain_id).to eq 56
end
end

describe '.decode an unsigned transaction' do
context 'EIP-1559' do
it "keeps the 'from' field blank" do
raw = "0x02f0050584b2d05e00851010b872008303841494caedbd63fb25c3126bfe96c1af208e4688e9817e87f6a3d9c63df00080c0"
tx = Tx.decode raw

expect(tx.signature_y_parity).to eq nil
expect(tx.signature_r).to eq 0
expect(tx.signature_s).to eq 0

expect(tx.sender).to eq ""
end
end

context 'EIP-2930' do
it "keeps the 'from' field blank" do
raw = "01eb050585037e11d6008303841494caedbd63fb25c3126bfe96c1af208e4688e9817e87f6a3d9c63df00080c0"
tx = Tx.decode raw

expect(tx.signature_y_parity).to eq nil
expect(tx.signature_r).to eq 0
expect(tx.signature_s).to eq 0

expect(tx.sender).to eq ""
end
end
end
end

0 comments on commit 031652b

Please sign in to comment.