Skip to content

Commit c254a72

Browse files
committed
added EIP1559 signed tx decoding
1 parent 3cfcc7a commit c254a72

File tree

3 files changed

+163
-30
lines changed

3 files changed

+163
-30
lines changed

eea/src/main/java/org/web3j/protocol/eea/crypto/PrivateTransactionDecoder.java

+79-30
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import java.util.stream.Collectors;
1919

2020
import org.web3j.crypto.RawTransaction;
21+
import org.web3j.crypto.Sign;
2122
import org.web3j.crypto.SignedRawTransaction;
2223
import org.web3j.crypto.TransactionDecoder;
2324
import org.web3j.crypto.transaction.type.TransactionType;
@@ -69,37 +70,85 @@ private static RawPrivateTransaction decodePrivateTransaction1559(final byte[] t
6970
final String to = ((RlpString) temp.getValues().get(5)).asString();
7071
final String data = ((RlpString) temp.getValues().get(7)).asString();
7172

72-
final Base64String privateFrom = extractBase64(values.get(8));
73-
final Restriction restriction = extractRestriction(values.get(10));
74-
75-
if (values.get(9) instanceof RlpList) {
76-
List<Base64String> privateForList = extractBase64List(values.get(9));
77-
return RawPrivateTransaction.createTransaction(
78-
chainId,
79-
nonce,
80-
maxPriorityFeePerGas,
81-
maxFeePerGas,
82-
gasLimit,
83-
to,
84-
data,
85-
privateFrom,
86-
privateForList,
87-
null,
88-
restriction);
73+
if (values.size() == 11) {
74+
final Base64String privateFrom = extractBase64(values.get(8));
75+
final Restriction restriction = extractRestriction(values.get(10));
76+
77+
if (values.get(9) instanceof RlpList) {
78+
List<Base64String> privateForList = extractBase64List(values.get(9));
79+
return RawPrivateTransaction.createTransaction(
80+
chainId,
81+
nonce,
82+
maxPriorityFeePerGas,
83+
maxFeePerGas,
84+
gasLimit,
85+
to,
86+
data,
87+
privateFrom,
88+
privateForList,
89+
null,
90+
restriction);
91+
} else {
92+
Base64String privacyGroupId = extractBase64(values.get(9));
93+
return RawPrivateTransaction.createTransaction(
94+
chainId,
95+
nonce,
96+
maxPriorityFeePerGas,
97+
maxFeePerGas,
98+
gasLimit,
99+
to,
100+
data,
101+
privateFrom,
102+
null,
103+
privacyGroupId,
104+
restriction);
105+
}
89106
} else {
90-
Base64String privacyGroupId = extractBase64(values.get(9));
91-
return RawPrivateTransaction.createTransaction(
92-
chainId,
93-
nonce,
94-
maxPriorityFeePerGas,
95-
maxFeePerGas,
96-
gasLimit,
97-
to,
98-
data,
99-
privateFrom,
100-
null,
101-
privacyGroupId,
102-
restriction);
107+
final Base64String privateFrom = extractBase64(values.get(11));
108+
final Restriction restriction = extractRestriction(values.get(13));
109+
110+
final byte[] v =
111+
Sign.getVFromRecId(
112+
Numeric.toBigInt(((RlpString) values.get(8)).getBytes()).intValue());
113+
final byte[] r =
114+
Numeric.toBytesPadded(
115+
Numeric.toBigInt(((RlpString) values.get(9)).getBytes()), 32);
116+
final byte[] s =
117+
Numeric.toBytesPadded(
118+
Numeric.toBigInt(((RlpString) values.get(10)).getBytes()), 32);
119+
final Sign.SignatureData signatureData = new Sign.SignatureData(v, r, s);
120+
121+
if (values.get(12) instanceof RlpList) {
122+
List<Base64String> privateForList = extractBase64List(values.get(12));
123+
return new SignedRawPrivateTransaction(
124+
chainId,
125+
nonce,
126+
maxPriorityFeePerGas,
127+
maxFeePerGas,
128+
gasLimit,
129+
to,
130+
data,
131+
signatureData,
132+
privateFrom,
133+
privateForList,
134+
null,
135+
restriction);
136+
} else {
137+
Base64String privacyGroupId = extractBase64(values.get(12));
138+
return new SignedRawPrivateTransaction(
139+
chainId,
140+
nonce,
141+
maxPriorityFeePerGas,
142+
maxFeePerGas,
143+
gasLimit,
144+
to,
145+
data,
146+
signatureData,
147+
privateFrom,
148+
null,
149+
privacyGroupId,
150+
restriction);
151+
}
103152
}
104153
}
105154

eea/src/main/java/org/web3j/protocol/eea/crypto/SignedRawPrivateTransaction.java

+28
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,34 @@ public SignedRawPrivateTransaction(
8686
restriction);
8787
}
8888

89+
public SignedRawPrivateTransaction(
90+
final long chainId,
91+
final BigInteger nonce,
92+
final BigInteger maxPriorityFeePerGas,
93+
final BigInteger maxFeePerGas,
94+
final BigInteger gasLimit,
95+
final String to,
96+
final String data,
97+
final Sign.SignatureData signatureData,
98+
final Base64String privateFrom,
99+
final List<Base64String> privateFor,
100+
final Base64String privacyGroupId,
101+
final Restriction restriction) {
102+
super(
103+
chainId,
104+
nonce,
105+
maxPriorityFeePerGas,
106+
maxFeePerGas,
107+
gasLimit,
108+
to,
109+
data,
110+
privateFrom,
111+
privateFor,
112+
privacyGroupId,
113+
restriction);
114+
this.signatureData = signatureData;
115+
}
116+
89117
public Sign.SignatureData getSignatureData() {
90118
return signatureData;
91119
}

eea/src/test/java/org/web3j/protocol/eea/crypto/PrivateTransactionDecoderTest.java

+56
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,62 @@ public void testDecodingSigned() throws Exception {
187187
assertNull(signedResult.getChainId());
188188
}
189189

190+
@Test
191+
public void testDecodingSigned1559() throws Exception {
192+
final BigInteger nonce = BigInteger.ZERO;
193+
final long chainId = 2018;
194+
final BigInteger gasLimit = BigInteger.TEN;
195+
final BigInteger maxPriorityFeePerGas = BigInteger.ONE;
196+
final BigInteger maxFeePerGas = BigInteger.ONE;
197+
final String to = "0x0add5355";
198+
199+
final RawPrivateTransaction rawTransaction =
200+
RawPrivateTransaction.createTransaction(
201+
chainId,
202+
nonce,
203+
maxPriorityFeePerGas,
204+
maxFeePerGas,
205+
gasLimit,
206+
to,
207+
"",
208+
MOCK_ENCLAVE_KEY,
209+
MOCK_PRIVATE_FOR,
210+
RESTRICTED);
211+
final String privateKey =
212+
"8f2a55949038a9610f50fb23b5883af3b4ecb3c3bb792cbcefbd1542c692be63";
213+
final Credentials credentials = Credentials.create(privateKey);
214+
final byte[] encodedMessage =
215+
PrivateTransactionEncoder.signMessage(rawTransaction, credentials);
216+
final String hexMessage = Numeric.toHexString(encodedMessage);
217+
218+
final RawPrivateTransaction result = PrivateTransactionDecoder.decode(hexMessage);
219+
220+
final PrivateTransaction1559 result1559 =
221+
(PrivateTransaction1559) result.getPrivateTransaction();
222+
assertNotNull(result1559);
223+
assertEquals(nonce, result1559.getNonce());
224+
assertEquals(chainId, result1559.getChainId());
225+
assertEquals(maxPriorityFeePerGas, result1559.getMaxPriorityFeePerGas());
226+
assertEquals(maxFeePerGas, result1559.getMaxFeePerGas());
227+
assertEquals(gasLimit, result1559.getGasLimit());
228+
assertEquals(to, result1559.getTo());
229+
assertEquals("0x", result1559.getData());
230+
assertEquals(MOCK_ENCLAVE_KEY, result1559.getPrivateFrom());
231+
assertEquals(MOCK_PRIVATE_FOR, result1559.getPrivateFor().get());
232+
assertEquals(RESTRICTED, result1559.getRestriction());
233+
234+
assertTrue(result instanceof SignedRawPrivateTransaction);
235+
final SignedRawPrivateTransaction signedResult = (SignedRawPrivateTransaction) result;
236+
assertNotNull(signedResult.getSignatureData());
237+
Sign.SignatureData signatureData = signedResult.getSignatureData();
238+
final byte[] encodedTransaction = PrivateTransactionEncoder.encode(rawTransaction);
239+
final BigInteger key = Sign.signedMessageToKey(encodedTransaction, signatureData);
240+
assertEquals(key, credentials.getEcKeyPair().getPublicKey());
241+
assertEquals(credentials.getAddress(), signedResult.getFrom());
242+
signedResult.verify(credentials.getAddress());
243+
assertNull(signedResult.getChainId());
244+
}
245+
190246
@Test
191247
public void testDecodingSignedPrivacyGroup() throws Exception {
192248
final BigInteger nonce = BigInteger.ZERO;

0 commit comments

Comments
 (0)