From 767ad18163f09d59d943e65a8f0b8385dbf495cd Mon Sep 17 00:00:00 2001 From: Afr Schoe <58883403+q9f@users.noreply.github.com> Date: Tue, 14 Feb 2023 12:18:43 +0100 Subject: [PATCH 1/3] eth/eip712: prepare tests for packed encoding --- lib/eth/abi/type.rb | 2 +- lib/eth/eip712.rb | 3 +- spec/eth/eip712_spec.rb | 74 +++++++++++++++++++++++++++++++++++++++-- 3 files changed, 74 insertions(+), 5 deletions(-) diff --git a/lib/eth/abi/type.rb b/lib/eth/abi/type.rb index 62b862cd..bf63e90d 100644 --- a/lib/eth/abi/type.rb +++ b/lib/eth/abi/type.rb @@ -86,7 +86,7 @@ def parse(type, components = nil, component_name = nil) @base_type = base_type @sub_type = sub_type @dimensions = dims.map { |x| x[1...-1].to_i } - @components = components.map { |component| Abi::Type.parse(component["type"], component.dig("components"), component.dig("name")) } unless components.nil? + @components = components.map { |component| Abi::Type.parse(component["type"], component.dig("components"), component.dig("name")) } if components&.any? @name = component_name end diff --git a/lib/eth/eip712.rb b/lib/eth/eip712.rb index 7d091b98..fa65a528 100644 --- a/lib/eth/eip712.rb +++ b/lib/eth/eip712.rb @@ -113,7 +113,6 @@ def encode_data(primary_type, data, types) types[primary_type.to_sym].each do |field| value = data[field[:name].to_sym] type = field[:type] - raise NotImplementedError, "Arrays currently unimplemented for EIP-712." if type.end_with? "]" if type == "string" or type == "bytes" encoded_types.push "bytes32" encoded_values.push Util.keccak256 value @@ -121,6 +120,8 @@ def encode_data(primary_type, data, types) encoded_types.push "bytes32" value = encode_data type, value, types encoded_values.push Util.keccak256 value + elsif type.end_with? "]" + raise NotImplementedError, "Arrays currently unimplemented for EIP-712." else encoded_types.push type encoded_values.push value diff --git a/spec/eth/eip712_spec.rb b/spec/eth/eip712_spec.rb index 0d28498a..d4f79ae7 100644 --- a/spec/eth/eip712_spec.rb +++ b/spec/eth/eip712_spec.rb @@ -35,7 +35,7 @@ :name => "Ether Mail", :version => "1", :chainId => Chain::ETHEREUM, - :verifyingContract => Address.new("0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC").checksummed, + :verifyingContract => Address.new("0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC"), } } @@ -44,11 +44,11 @@ { :from => { :name => "Cow", - :wallet => Address.new("0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826").checksummed, + :wallet => Address.new("0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826"), }, :to => { :name => "Bob", - :wallet => Address.new("0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB").checksummed, + :wallet => Address.new("0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB"), }, :contents => "Hello, Bob!", } @@ -127,4 +127,72 @@ expect(Eip712.hash typed_data).to eq Util.hex_to_bin "0xbe609aee343fb3c4b28e1df9e632fca64fcfaede20f02e86244efddf30957bd2" end end + + context "eip 712 arrays" do + subject(:domain) { + [ + { name: "name", type: "string" }, + { name: "version", type: "string" }, + { name: "chainId", type: "uint256" }, + { name: "verifyingContract", type: "address" }, + { name: "salt", type: "bytes32" }, + ] + } + + subject(:sell_orders) { + [ + { name: "id", type: "uint256[]" }, + { name: "tokenId", type: "uint256[]" }, + { name: "price", type: "uint256[]" }, + { name: "proto", type: "uint256[]" }, + { name: "purity", type: "uint256[]" }, + { name: "seller", type: "address" }, + ] + } + + subject(:card_exchange_contract) { Address.new("0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC") } + + subject(:domain_data) { + { + name: "app", + version: "1", + chainId: 3, + verifyingContract: card_exchange_contract, + salt: "0xa222082684812afae4e093416fff16bc218b569abe4db590b6a058e1f2c1cd3e", + } + } + + subject(:address) { Address.new "0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826" } + + subject(:message) { + { + id: [1], + tokenId: [1], + price: [1], + proto: [1], + purity: [1], + seller: address, + } + } + + subject(:data) { + { + :types => { + :EIP712Domain => domain, + :SellOrders => sell_orders, + }, + :primaryType => "SellOrders", + :domain => domain_data, + :message => message, + } + } + + it "encodes arrays in an eip 712 domain" do + expect(Eip712.encode_type "EIP712Domain", data[:types]).to eq "EIP712Domain(string name,string version,uint256 chainId,address verifyingContract,bytes32 salt)" + expect(Eip712.encode_type "SellOrders", data[:types]).to eq "SellOrders(uint256[] id,uint256[] tokenId,uint256[] price,uint256[] proto,uint256[] purity,address seller)" + + expect(Util.bin_to_hex(Eip712.encode_data("EIP712Domain", domain_data, data[:types]))).to eq "d87cd6ef79d4e2b95e15ce8abf732db51ec771f1ca2edccf22a46c729ac56472d6f028ca0e8edb4a8c9757ca4fdccab25fa1e0317da1188108f7d2dee14902fbc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc60000000000000000000000000000000000000000000000000000000000000003000000000000000000000000cccccccccccccccccccccccccccccccccccccccca222082684812afae4e093416fff16bc218b569abe4db590b6a058e1f2c1cd3e" + expect(Util.bin_to_hex(Eip712.encode_data("SellOrders", message, data[:types]))).to eq "58682cd513b67511a4ef89156104cf2bc7835c7289308bb112fdafe49897324200000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000001a000000000000000000000000000000000000000000000000000000000000001e0000000000000000000000000cd2a3d9f938e13cd947ec05abc7fe734df8dd8260000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001" + end + end end From ccf6a00ee551eb86c7d7769b87c8af8e3b544362 Mon Sep 17 00:00:00 2001 From: afr q9f <58883403+q9f@users.noreply.github.com> Date: Tue, 11 Feb 2025 09:53:08 +0100 Subject: [PATCH 2/3] spec: run rufo --- spec/eth/eip712_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/eth/eip712_spec.rb b/spec/eth/eip712_spec.rb index c1fd3172..2ceab0d3 100644 --- a/spec/eth/eip712_spec.rb +++ b/spec/eth/eip712_spec.rb @@ -195,7 +195,7 @@ expect(Util.bin_to_hex(Eip712.encode_data("SellOrders", message, data[:types]))).to eq "58682cd513b67511a4ef89156104cf2bc7835c7289308bb112fdafe49897324200000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000001a000000000000000000000000000000000000000000000000000000000000001e0000000000000000000000000cd2a3d9f938e13cd947ec05abc7fe734df8dd8260000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001" end end - + context "end to end" do it "can hash the correct data type" do key = Key.new(priv: "0x8e589ba6280400cfa426229684f7c2ac9ebf132f7ad658a82ed57553a0a9dee8") From 274556807100c569739f3def87260710356058f3 Mon Sep 17 00:00:00 2001 From: afr q9f <58883403+q9f@users.noreply.github.com> Date: Tue, 11 Feb 2025 09:57:00 +0100 Subject: [PATCH 3/3] spec/abi: set eip712 test to pending, ref #127 --- spec/eth/eip712_spec.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/spec/eth/eip712_spec.rb b/spec/eth/eip712_spec.rb index 2ceab0d3..76f7966b 100644 --- a/spec/eth/eip712_spec.rb +++ b/spec/eth/eip712_spec.rb @@ -192,6 +192,7 @@ expect(Eip712.encode_type "SellOrders", data[:types]).to eq "SellOrders(uint256[] id,uint256[] tokenId,uint256[] price,uint256[] proto,uint256[] purity,address seller)" expect(Util.bin_to_hex(Eip712.encode_data("EIP712Domain", domain_data, data[:types]))).to eq "d87cd6ef79d4e2b95e15ce8abf732db51ec771f1ca2edccf22a46c729ac56472d6f028ca0e8edb4a8c9757ca4fdccab25fa1e0317da1188108f7d2dee14902fbc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc60000000000000000000000000000000000000000000000000000000000000003000000000000000000000000cccccccccccccccccccccccccccccccccccccccca222082684812afae4e093416fff16bc218b569abe4db590b6a058e1f2c1cd3e" + pending("https://github.com/q9f/eth.rb/issues/127") expect(Util.bin_to_hex(Eip712.encode_data("SellOrders", message, data[:types]))).to eq "58682cd513b67511a4ef89156104cf2bc7835c7289308bb112fdafe49897324200000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000001a000000000000000000000000000000000000000000000000000000000000001e0000000000000000000000000cd2a3d9f938e13cd947ec05abc7fe734df8dd8260000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001" end end