From 6b6f97b894ff53c21cb5e0548e43e6186c1e54f0 Mon Sep 17 00:00:00 2001 From: Nischal Sharma Date: Wed, 4 Oct 2023 12:08:01 +0530 Subject: [PATCH 1/7] initial commit --- .../eea/crypto/PrivateTransactionEncoder.java | 15 +- .../eea/crypto/RawPrivateTransaction.java | 51 +++++++ .../eea/crypto/RawPrivateTransaction1559.java | 140 ++++++++++++++++++ 3 files changed, 192 insertions(+), 14 deletions(-) create mode 100644 eea/src/main/java/org/web3j/protocol/eea/crypto/RawPrivateTransaction1559.java diff --git a/eea/src/main/java/org/web3j/protocol/eea/crypto/PrivateTransactionEncoder.java b/eea/src/main/java/org/web3j/protocol/eea/crypto/PrivateTransactionEncoder.java index ddbefcce1..8085ec11f 100644 --- a/eea/src/main/java/org/web3j/protocol/eea/crypto/PrivateTransactionEncoder.java +++ b/eea/src/main/java/org/web3j/protocol/eea/crypto/PrivateTransactionEncoder.java @@ -77,19 +77,6 @@ public static List asRlpValues( final RawPrivateTransaction privateTransaction, final Sign.SignatureData signatureData) { - final List result = - new ArrayList<>(TransactionEncoder.asRlpValues(privateTransaction, signatureData)); - - result.add(privateTransaction.getPrivateFrom().asRlp()); - - privateTransaction - .getPrivateFor() - .ifPresent(privateFor -> result.add(Base64String.unwrapListToRlp(privateFor))); - - privateTransaction.getPrivacyGroupId().map(Base64String::asRlp).ifPresent(result::add); - - result.add(RlpString.create(privateTransaction.getRestriction().getRestriction())); - - return result; + return privateTransaction.asRlpValues(signatureData); } } diff --git a/eea/src/main/java/org/web3j/protocol/eea/crypto/RawPrivateTransaction.java b/eea/src/main/java/org/web3j/protocol/eea/crypto/RawPrivateTransaction.java index aaa5b32df..2b127725e 100644 --- a/eea/src/main/java/org/web3j/protocol/eea/crypto/RawPrivateTransaction.java +++ b/eea/src/main/java/org/web3j/protocol/eea/crypto/RawPrivateTransaction.java @@ -13,14 +13,21 @@ package org.web3j.protocol.eea.crypto; import java.math.BigInteger; +import java.util.ArrayList; import java.util.List; import java.util.Optional; import org.web3j.crypto.RawTransaction; +import org.web3j.crypto.Sign; +import org.web3j.crypto.TransactionEncoder; import org.web3j.crypto.transaction.type.ITransaction; import org.web3j.crypto.transaction.type.LegacyTransaction; import org.web3j.crypto.transaction.type.Transaction1559; +import org.web3j.rlp.RlpString; +import org.web3j.rlp.RlpType; import org.web3j.utils.Base64String; +import org.web3j.utils.Bytes; +import org.web3j.utils.Numeric; import org.web3j.utils.Restriction; /** @@ -90,6 +97,50 @@ private RawPrivateTransaction( this(rawTransaction.getTransaction(), privateFrom, privateFor, privacyGroupId, restriction); } + public List asRlpValues( + final Sign.SignatureData signatureData) { + + List result = new ArrayList<>(); + + result.add(RlpString.create(getNonce())); + + result.add(RlpString.create(getGasPrice())); + result.add(RlpString.create(getGasLimit())); + + // an empty to address (contract creation) should not be encoded as a numeric 0 value + String to = getTo(); + if (to != null && to.length() > 0) { + // addresses that start with zeros should be encoded with the zeros included, not + // as numeric values + result.add(RlpString.create(Numeric.hexStringToByteArray(to))); + } else { + result.add(RlpString.create("")); + } + + result.add(RlpString.create(getValue())); + + // value field will already be hex encoded, so we need to convert into binary first + byte[] data = Numeric.hexStringToByteArray(getData()); + result.add(RlpString.create(data)); + + if (signatureData != null) { + result.add(RlpString.create(Bytes.trimLeadingZeroes(signatureData.getV()))); + result.add(RlpString.create(Bytes.trimLeadingZeroes(signatureData.getR()))); + result.add(RlpString.create(Bytes.trimLeadingZeroes(signatureData.getS()))); + } + + result.add(getPrivateFrom().asRlp()); + + getPrivateFor() + .ifPresent(privateFor -> result.add(Base64String.unwrapListToRlp(privateFor))); + + getPrivacyGroupId().map(Base64String::asRlp).ifPresent(result::add); + + result.add(RlpString.create(getRestriction().getRestriction())); + + return result; + } + public static RawPrivateTransaction createContractTransaction( final BigInteger nonce, final BigInteger gasPrice, diff --git a/eea/src/main/java/org/web3j/protocol/eea/crypto/RawPrivateTransaction1559.java b/eea/src/main/java/org/web3j/protocol/eea/crypto/RawPrivateTransaction1559.java new file mode 100644 index 000000000..f19adbbd6 --- /dev/null +++ b/eea/src/main/java/org/web3j/protocol/eea/crypto/RawPrivateTransaction1559.java @@ -0,0 +1,140 @@ +package org.web3j.protocol.eea.crypto; + +import org.web3j.crypto.RawTransaction; +import org.web3j.crypto.Sign; +import org.web3j.crypto.transaction.type.ITransaction; +import org.web3j.rlp.RlpList; +import org.web3j.rlp.RlpString; +import org.web3j.rlp.RlpType; +import org.web3j.utils.Base64String; +import org.web3j.utils.Bytes; +import org.web3j.utils.Numeric; +import org.web3j.utils.Restriction; + +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.List; + +public class RawPrivateTransaction1559 extends RawPrivateTransaction{ + + private long chainId; + private BigInteger maxPriorityFeePerGas; + private BigInteger maxFeePerGas; + + + protected RawPrivateTransaction1559(long chainId, + BigInteger nonce, + BigInteger gasLimit, + String to, + String data, + BigInteger maxPriorityFeePerGas, + BigInteger maxFeePerGas, + Base64String privateFrom, + List privateFor, + Base64String privacyGroupId, + Restriction restriction) { + super(nonce, null, gasLimit, to, data, privateFrom, privateFor, privacyGroupId, restriction); + this.chainId = chainId; + this.maxPriorityFeePerGas = maxPriorityFeePerGas; + this.maxFeePerGas = maxFeePerGas; + } + + protected RawPrivateTransaction1559( + long chainId, + BigInteger nonce, + BigInteger gasLimit, + String to, + String data, + BigInteger maxPriorityFeePerGas, + BigInteger maxFeePerGas, + Base64String privateFrom, + Base64String privacyGroupId, + Restriction restriction) { + this(chainId, nonce, gasLimit, to, data, maxPriorityFeePerGas, maxFeePerGas, privateFrom, null, privacyGroupId, restriction); + } + + protected RawPrivateTransaction1559( + long chainId, + BigInteger nonce, + BigInteger gasLimit, + String to, + String data, + BigInteger maxPriorityFeePerGas, + BigInteger maxFeePerGas, + Base64String privateFrom, + List privateFor, + Restriction restriction) { + this(chainId, nonce, gasLimit, to, data, maxPriorityFeePerGas, maxFeePerGas, privateFrom, privateFor, null, restriction); + } + + @Override + public List asRlpValues( + final Sign.SignatureData signatureData) { + + List result = new ArrayList<>(); + + result.add(RlpString.create(getChainId())); + + result.add(RlpString.create(getNonce())); + + // add maxPriorityFeePerGas and maxFeePerGas if this is an EIP-1559 transaction + result.add(RlpString.create(getMaxPriorityFeePerGas())); + result.add(RlpString.create(getMaxFeePerGas())); + + result.add(RlpString.create(getGasLimit())); + + // an empty to address (contract creation) should not be encoded as a numeric 0 value + String to = getTo(); + if (to != null && to.length() > 0) { + // addresses that start with zeros should be encoded with the zeros included, not + // as numeric values + result.add(RlpString.create(Numeric.hexStringToByteArray(to))); + } else { + result.add(RlpString.create("")); + } + + result.add(RlpString.create(getValue())); + + // value field will already be hex encoded, so we need to convert into binary first + byte[] data = Numeric.hexStringToByteArray(getData()); + result.add(RlpString.create(data)); + + // access list + result.add(new RlpList()); + + if (signatureData != null) { + result.add(RlpString.create(Sign.getRecId(signatureData, getChainId()))); + result.add(RlpString.create(Bytes.trimLeadingZeroes(signatureData.getR()))); + result.add(RlpString.create(Bytes.trimLeadingZeroes(signatureData.getS()))); + } + + result.add(getPrivateFrom().asRlp()); + + getPrivateFor() + .ifPresent(privateFor -> result.add(Base64String.unwrapListToRlp(privateFor))); + + getPrivacyGroupId().map(Base64String::asRlp).ifPresent(result::add); + + result.add(RlpString.create(getRestriction().getRestriction())); + + return result; + } + + + @Override + public BigInteger getGasPrice() { + throw new UnsupportedOperationException("not available for 1559 transaction"); + } + + public long getChainId() { + return chainId; + } + + public BigInteger getMaxPriorityFeePerGas() { + return maxPriorityFeePerGas; + } + + public BigInteger getMaxFeePerGas() { + return maxFeePerGas; + } +} From bbd48474107bda92de99b0dab8a731fe90b3855a Mon Sep 17 00:00:00 2001 From: Nischal Sharma Date: Fri, 3 Nov 2023 14:07:09 +0530 Subject: [PATCH 2/7] code refractored and added eip1559 private tx class Signed-off-by: Nischal Sharma --- .../main/java/org/web3j/abi/TypeDecoder.java | 3 +- .../OnChainPrivacyTransactionBuilder.java | 6 +- .../web3j/tx/PrivateTransactionManager.java | 72 ++-- .../eea/crypto/PrivateTransactionDecoder.java | 41 ++- .../eea/crypto/PrivateTransactionEncoder.java | 24 +- .../eea/crypto/PrivateTxSignServiceImpl.java | 13 +- .../crypto/SignedRawPrivateTransaction.java | 26 +- .../transaction/type/IPrivateTransaction.java | 47 +++ .../type/LegacyPrivateTransaction.java} | 314 ++++++++---------- .../type/PrivateTransaction1559.java} | 94 ++++-- .../type/PrivateTransactionType.java | 28 ++ .../crypto/PrivateTransactionDecoderTest.java | 31 +- .../crypto/PrivateTransactionEncoderTest.java | 9 +- .../BesuPrivacyQuickstartIntegrationTest.java | 6 +- 14 files changed, 414 insertions(+), 300 deletions(-) create mode 100644 eea/src/main/java/org/web3j/protocol/eea/crypto/transaction/type/IPrivateTransaction.java rename eea/src/main/java/org/web3j/protocol/eea/crypto/{RawPrivateTransaction.java => transaction/type/LegacyPrivateTransaction.java} (50%) rename eea/src/main/java/org/web3j/protocol/eea/crypto/{RawPrivateTransaction1559.java => transaction/type/PrivateTransaction1559.java} (62%) create mode 100644 eea/src/main/java/org/web3j/protocol/eea/crypto/transaction/type/PrivateTransactionType.java diff --git a/abi/src/main/java/org/web3j/abi/TypeDecoder.java b/abi/src/main/java/org/web3j/abi/TypeDecoder.java index eb9394504..76eca28c9 100644 --- a/abi/src/main/java/org/web3j/abi/TypeDecoder.java +++ b/abi/src/main/java/org/web3j/abi/TypeDecoder.java @@ -565,7 +565,8 @@ private static T decodeDynamicParameterFromStruct( value = decodeDynamicStruct(dynamicElementData, 0, TypeReference.create(declaredField)); } else if (DynamicArray.class.isAssignableFrom(declaredField)) { if (parameter == null) { - throw new RuntimeException("parameter can not be null, try to use annotation @Parameterized to specify the parameter type"); + throw new RuntimeException( + "parameter can not be null, try to use annotation @Parameterized to specify the parameter type"); } value = (T) diff --git a/besu/src/main/java/org/web3j/protocol/besu/privacy/OnChainPrivacyTransactionBuilder.java b/besu/src/main/java/org/web3j/protocol/besu/privacy/OnChainPrivacyTransactionBuilder.java index 2ad9a89eb..01d820c15 100644 --- a/besu/src/main/java/org/web3j/protocol/besu/privacy/OnChainPrivacyTransactionBuilder.java +++ b/besu/src/main/java/org/web3j/protocol/besu/privacy/OnChainPrivacyTransactionBuilder.java @@ -24,7 +24,7 @@ import org.web3j.abi.datatypes.generated.Bytes32; import org.web3j.crypto.Credentials; import org.web3j.protocol.eea.crypto.PrivateTransactionEncoder; -import org.web3j.protocol.eea.crypto.RawPrivateTransaction; +import org.web3j.protocol.eea.crypto.transaction.type.LegacyPrivateTransaction; import org.web3j.tx.gas.BesuPrivacyGasProvider; import org.web3j.utils.Base64String; import org.web3j.utils.Numeric; @@ -87,8 +87,8 @@ public String buildOnChainPrivateTransaction( Base64String enclaveKey, final BigInteger nonce, String call) { - RawPrivateTransaction rawTransaction = - RawPrivateTransaction.createTransaction( + LegacyPrivateTransaction rawTransaction = + LegacyPrivateTransaction.createTransaction( nonce, gasProvider.getGasPrice(), gasProvider.getGasLimit(), diff --git a/besu/src/main/java/org/web3j/tx/PrivateTransactionManager.java b/besu/src/main/java/org/web3j/tx/PrivateTransactionManager.java index ee70d0863..87e2d3875 100644 --- a/besu/src/main/java/org/web3j/tx/PrivateTransactionManager.java +++ b/besu/src/main/java/org/web3j/tx/PrivateTransactionManager.java @@ -25,7 +25,7 @@ import org.web3j.protocol.core.methods.response.EthGetCode; import org.web3j.protocol.core.methods.response.EthSendTransaction; import org.web3j.protocol.eea.crypto.PrivateTxSignServiceImpl; -import org.web3j.protocol.eea.crypto.RawPrivateTransaction; +import org.web3j.protocol.eea.crypto.transaction.type.LegacyPrivateTransaction; import org.web3j.service.TxSignService; import org.web3j.tx.response.TransactionReceiptProcessor; import org.web3j.utils.Base64String; @@ -138,11 +138,11 @@ public EthSendTransaction sendTransaction( .send() .getTransactionCount(); - final RawPrivateTransaction transaction; + final LegacyPrivateTransaction transaction; if (privateFor != null) { transaction = - RawPrivateTransaction.createTransaction( + LegacyPrivateTransaction.createTransaction( nonce, gasPrice, gasLimit, @@ -153,7 +153,7 @@ public EthSendTransaction sendTransaction( restriction); } else { transaction = - RawPrivateTransaction.createTransaction( + LegacyPrivateTransaction.createTransaction( nonce, gasPrice, gasLimit, @@ -183,36 +183,36 @@ public EthSendTransaction sendEIP1559Transaction( .send() .getTransactionCount(); - final RawPrivateTransaction transaction; - if (privateFor != null) { - transaction = - RawPrivateTransaction.createTransaction( - chainId, - nonce, - maxPriorityFeePerGas, - maxFeePerGas, - gasLimit, - to, - data, - privateFrom, - privateFor, - restriction); - } else { - transaction = - RawPrivateTransaction.createTransaction( - chainId, - nonce, - maxPriorityFeePerGas, - maxFeePerGas, - gasLimit, - to, - data, - privateFrom, - privacyGroupId, - restriction); - } + final LegacyPrivateTransaction transaction; + // if (privateFor != null) { + // transaction = + // RawPrivateTransaction.createTransaction( + // chainId, + // nonce, + // maxPriorityFeePerGas, + // maxFeePerGas, + // gasLimit, + // to, + // data, + // privateFrom, + // privateFor, + // restriction); + // } else { + // transaction = + // RawPrivateTransaction.createTransaction( + // chainId, + // nonce, + // maxPriorityFeePerGas, + // maxFeePerGas, + // gasLimit, + // to, + // data, + // privateFrom, + // privacyGroupId, + // restriction); + // } - return signAndSend(transaction); + return signAndSend(null); } @Override @@ -239,20 +239,20 @@ public EthGetCode getCode( .send(); } - public String sign(final RawPrivateTransaction rawTransaction) { + public String sign(final LegacyPrivateTransaction rawTransaction) { final byte[] signedMessage = txSignService.sign(rawTransaction, chainId); return Numeric.toHexString(signedMessage); } - public EthSendTransaction signAndSend(final RawPrivateTransaction rawTransaction) + public EthSendTransaction signAndSend(final LegacyPrivateTransaction rawTransaction) throws IOException { final String hexValue = sign(rawTransaction); return this.besu.eeaSendRawTransaction(hexValue).send(); } - public PrivateEnclaveKey signAndDistribute(RawPrivateTransaction rawTransaction) + public PrivateEnclaveKey signAndDistribute(LegacyPrivateTransaction rawTransaction) throws IOException { String hexValue = sign(rawTransaction); return this.besu.privDistributeRawTransaction(hexValue).send(); diff --git a/eea/src/main/java/org/web3j/protocol/eea/crypto/PrivateTransactionDecoder.java b/eea/src/main/java/org/web3j/protocol/eea/crypto/PrivateTransactionDecoder.java index 496adfd7f..7826857d9 100644 --- a/eea/src/main/java/org/web3j/protocol/eea/crypto/PrivateTransactionDecoder.java +++ b/eea/src/main/java/org/web3j/protocol/eea/crypto/PrivateTransactionDecoder.java @@ -18,6 +18,8 @@ import org.web3j.crypto.RawTransaction; import org.web3j.crypto.SignedRawTransaction; import org.web3j.crypto.TransactionDecoder; +import org.web3j.protocol.eea.crypto.transaction.type.LegacyPrivateTransaction; +import org.web3j.protocol.eea.crypto.transaction.type.PrivateTransactionType; import org.web3j.rlp.RlpDecoder; import org.web3j.rlp.RlpList; import org.web3j.rlp.RlpString; @@ -30,25 +32,50 @@ public class PrivateTransactionDecoder { - public static RawPrivateTransaction decode(final String hexTransaction) { + public static LegacyPrivateTransaction decode(final String hexTransaction) { final byte[] transaction = Numeric.hexStringToByteArray(hexTransaction); + final PrivateTransactionType transactionType = getPrivateTransactionType(transaction); + + switch (transactionType) { + case PRIVATE_LEGACY: + return decodeLegacyPrivateTransaction(transaction); + default: + throw new IllegalArgumentException("Unsupported private transaction type."); + } + } + + private static PrivateTransactionType getPrivateTransactionType(final byte[] transaction) { + // Determine the type of the private transaction, similar to TransactionDecoder. + byte firstByte = transaction[0]; + // if (firstByte == PrivateTransactionType.PRIVATE_LEGACY.getRlpType()) + // return PrivateTransactionType.PRIVATE_LEGACY; + + // Return LEGACY as default, or throw an exception depending on your needs + return PrivateTransactionType.PRIVATE_LEGACY; + } + + private static LegacyPrivateTransaction decodeLegacyPrivateTransaction( + final byte[] transaction) { final RlpList rlpList = RlpDecoder.decode(transaction); final RlpList temp = (RlpList) rlpList.getValues().get(0); final List values = temp.getValues(); - final RawTransaction rawTransaction = TransactionDecoder.decode(hexTransaction); + final RawTransaction rawTransaction = + TransactionDecoder.decode(Numeric.toHexString(transaction)); if (values.size() == 9) { final Base64String privateFrom = extractBase64(values.get(6)); final Restriction restriction = extractRestriction(values.get(8)); + if (values.get(7) instanceof RlpList) { - return new RawPrivateTransaction( - rawTransaction, privateFrom, extractBase64List(values.get(7)), restriction); + List privateForList = extractBase64List(values.get(7)); + return new LegacyPrivateTransaction( + rawTransaction, privateFrom, privateForList, null, restriction); } else { - return new RawPrivateTransaction( - rawTransaction, privateFrom, extractBase64(values.get(7)), restriction); + Base64String privacyGroupId = extractBase64(values.get(7)); + return new LegacyPrivateTransaction( + rawTransaction, privateFrom, null, privacyGroupId, restriction); } - } else { final Base64String privateFrom = extractBase64(values.get(9)); final Restriction restriction = extractRestriction(values.get(11)); diff --git a/eea/src/main/java/org/web3j/protocol/eea/crypto/PrivateTransactionEncoder.java b/eea/src/main/java/org/web3j/protocol/eea/crypto/PrivateTransactionEncoder.java index 8085ec11f..175414e32 100644 --- a/eea/src/main/java/org/web3j/protocol/eea/crypto/PrivateTransactionEncoder.java +++ b/eea/src/main/java/org/web3j/protocol/eea/crypto/PrivateTransactionEncoder.java @@ -13,23 +13,21 @@ package org.web3j.protocol.eea.crypto; import java.nio.ByteBuffer; -import java.util.ArrayList; import java.util.List; import org.web3j.crypto.Credentials; import org.web3j.crypto.Sign; import org.web3j.crypto.TransactionEncoder; +import org.web3j.protocol.eea.crypto.transaction.type.LegacyPrivateTransaction; import org.web3j.rlp.RlpEncoder; import org.web3j.rlp.RlpList; -import org.web3j.rlp.RlpString; import org.web3j.rlp.RlpType; -import org.web3j.utils.Base64String; /** Create signed RLP encoded private transaction. */ public class PrivateTransactionEncoder { public static byte[] signMessage( - final RawPrivateTransaction rawTransaction, final Credentials credentials) { + final LegacyPrivateTransaction rawTransaction, final Credentials credentials) { final byte[] encodedTransaction = encode(rawTransaction); final Sign.SignatureData signatureData = Sign.signMessage(encodedTransaction, credentials.getEcKeyPair()); @@ -38,7 +36,7 @@ public static byte[] signMessage( } public static byte[] signMessage( - final RawPrivateTransaction rawTransaction, + final LegacyPrivateTransaction rawTransaction, final long chainId, final Credentials credentials) { final byte[] encodedTransaction = encode(rawTransaction, chainId); @@ -50,19 +48,20 @@ public static byte[] signMessage( return encode(rawTransaction, eip155SignatureData); } - public static byte[] encode(final RawPrivateTransaction rawTransaction) { + public static byte[] encode(final LegacyPrivateTransaction rawTransaction) { return encode(rawTransaction, null); } - public static byte[] encode(final RawPrivateTransaction rawTransaction, final long chainId) { + public static byte[] encode(final LegacyPrivateTransaction rawTransaction, final long chainId) { final Sign.SignatureData signatureData = new Sign.SignatureData(longToBytes(chainId), new byte[] {}, new byte[] {}); return encode(rawTransaction, signatureData); } private static byte[] encode( - final RawPrivateTransaction rawTransaction, final Sign.SignatureData signatureData) { - final List values = asRlpValues(rawTransaction, signatureData); + final LegacyPrivateTransaction rawTransaction, final Sign.SignatureData signatureData) { + // final List values = asRlpValues(rawTransaction, signatureData); + final List values = rawTransaction.asRlpValues(signatureData); final RlpList rlpList = new RlpList(values); return RlpEncoder.encode(rlpList); } @@ -72,11 +71,4 @@ private static byte[] longToBytes(long x) { buffer.putLong(x); return buffer.array(); } - - public static List asRlpValues( - final RawPrivateTransaction privateTransaction, - final Sign.SignatureData signatureData) { - - return privateTransaction.asRlpValues(signatureData); - } } diff --git a/eea/src/main/java/org/web3j/protocol/eea/crypto/PrivateTxSignServiceImpl.java b/eea/src/main/java/org/web3j/protocol/eea/crypto/PrivateTxSignServiceImpl.java index 7991c23da..b1f3bcc20 100644 --- a/eea/src/main/java/org/web3j/protocol/eea/crypto/PrivateTxSignServiceImpl.java +++ b/eea/src/main/java/org/web3j/protocol/eea/crypto/PrivateTxSignServiceImpl.java @@ -14,6 +14,7 @@ import org.web3j.crypto.Credentials; import org.web3j.crypto.RawTransaction; +import org.web3j.protocol.eea.crypto.transaction.type.LegacyPrivateTransaction; import org.web3j.service.TxSignService; import org.web3j.tx.ChainId; @@ -26,10 +27,9 @@ public PrivateTxSignServiceImpl(Credentials credentials) { this.credentials = credentials; } - @Override - public byte[] sign(RawTransaction rawTransaction, long chainId) { - if (!(rawTransaction instanceof RawPrivateTransaction)) { - throw new RuntimeException("Can only sign RawPrivateTransaction"); + public byte[] sign(RawTransaction privateTransaction, long chainId) { + if (!(privateTransaction instanceof LegacyPrivateTransaction)) { + throw new RuntimeException("Can only sign LegacyPrivateTransaction"); } final byte[] signedMessage; @@ -37,16 +37,15 @@ public byte[] sign(RawTransaction rawTransaction, long chainId) { if (chainId > ChainId.NONE) { signedMessage = PrivateTransactionEncoder.signMessage( - (RawPrivateTransaction) rawTransaction, chainId, credentials); + (LegacyPrivateTransaction) privateTransaction, chainId, credentials); } else { signedMessage = PrivateTransactionEncoder.signMessage( - (RawPrivateTransaction) rawTransaction, credentials); + (LegacyPrivateTransaction) privateTransaction, credentials); } return signedMessage; } - @Override public String getAddress() { return credentials.getAddress(); } diff --git a/eea/src/main/java/org/web3j/protocol/eea/crypto/SignedRawPrivateTransaction.java b/eea/src/main/java/org/web3j/protocol/eea/crypto/SignedRawPrivateTransaction.java index 80f3c0437..4ba253b45 100644 --- a/eea/src/main/java/org/web3j/protocol/eea/crypto/SignedRawPrivateTransaction.java +++ b/eea/src/main/java/org/web3j/protocol/eea/crypto/SignedRawPrivateTransaction.java @@ -18,10 +18,11 @@ import org.web3j.crypto.Sign; import org.web3j.crypto.SignatureDataOperations; import org.web3j.crypto.SignedRawTransaction; +import org.web3j.protocol.eea.crypto.transaction.type.LegacyPrivateTransaction; import org.web3j.utils.Base64String; import org.web3j.utils.Restriction; -public class SignedRawPrivateTransaction extends RawPrivateTransaction +public class SignedRawPrivateTransaction extends LegacyPrivateTransaction implements SignatureDataOperations { private final Sign.SignatureData signatureData; @@ -55,7 +56,17 @@ public SignedRawPrivateTransaction( final Base64String privateFrom, final List privateFor, final Restriction restriction) { - this(signedRawTransaction, privateFrom, privateFor, null, restriction); + this( + signedRawTransaction.getNonce(), + signedRawTransaction.getGasPrice(), + signedRawTransaction.getGasLimit(), + signedRawTransaction.getTo(), + signedRawTransaction.getData(), + signedRawTransaction.getSignatureData(), + privateFrom, + privateFor, + null, + restriction); } public SignedRawPrivateTransaction( @@ -63,15 +74,6 @@ public SignedRawPrivateTransaction( final Base64String privateFrom, final Base64String privacyGroupId, final Restriction restriction) { - this(signedRawTransaction, privateFrom, null, privacyGroupId, restriction); - } - - private SignedRawPrivateTransaction( - final SignedRawTransaction signedRawTransaction, - final Base64String privateFrom, - final List privateFor, - final Base64String privacyGroupId, - final Restriction restriction) { this( signedRawTransaction.getNonce(), signedRawTransaction.getGasPrice(), @@ -80,7 +82,7 @@ private SignedRawPrivateTransaction( signedRawTransaction.getData(), signedRawTransaction.getSignatureData(), privateFrom, - privateFor, + null, privacyGroupId, restriction); } diff --git a/eea/src/main/java/org/web3j/protocol/eea/crypto/transaction/type/IPrivateTransaction.java b/eea/src/main/java/org/web3j/protocol/eea/crypto/transaction/type/IPrivateTransaction.java new file mode 100644 index 000000000..70eeda626 --- /dev/null +++ b/eea/src/main/java/org/web3j/protocol/eea/crypto/transaction/type/IPrivateTransaction.java @@ -0,0 +1,47 @@ +/* + * Copyright 2023 Web3 Labs Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ +package org.web3j.protocol.eea.crypto.transaction.type; + +import java.math.BigInteger; +import java.util.List; +import java.util.Optional; + +import org.web3j.crypto.Sign; +import org.web3j.rlp.RlpType; +import org.web3j.utils.Base64String; +import org.web3j.utils.Restriction; + +public interface IPrivateTransaction { + + BigInteger getNonce(); + + BigInteger getGasPrice(); + + BigInteger getGasLimit(); + + String getTo(); + + String getData(); + + Base64String getPrivateFrom(); + + Optional> getPrivateFor(); + + Optional getPrivacyGroupId(); + + Restriction getRestriction(); + + List asRlpValues(Sign.SignatureData signatureData); + + PrivateTransactionType getTransactionType(); +} diff --git a/eea/src/main/java/org/web3j/protocol/eea/crypto/RawPrivateTransaction.java b/eea/src/main/java/org/web3j/protocol/eea/crypto/transaction/type/LegacyPrivateTransaction.java similarity index 50% rename from eea/src/main/java/org/web3j/protocol/eea/crypto/RawPrivateTransaction.java rename to eea/src/main/java/org/web3j/protocol/eea/crypto/transaction/type/LegacyPrivateTransaction.java index 2b127725e..a15edd524 100644 --- a/eea/src/main/java/org/web3j/protocol/eea/crypto/RawPrivateTransaction.java +++ b/eea/src/main/java/org/web3j/protocol/eea/crypto/transaction/type/LegacyPrivateTransaction.java @@ -1,5 +1,5 @@ /* - * Copyright 2019 Web3 Labs Ltd. + * Copyright 2023 Web3 Labs Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at @@ -10,7 +10,7 @@ * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the * specific language governing permissions and limitations under the License. */ -package org.web3j.protocol.eea.crypto; +package org.web3j.protocol.eea.crypto.transaction.type; import java.math.BigInteger; import java.util.ArrayList; @@ -19,10 +19,8 @@ import org.web3j.crypto.RawTransaction; import org.web3j.crypto.Sign; -import org.web3j.crypto.TransactionEncoder; import org.web3j.crypto.transaction.type.ITransaction; import org.web3j.crypto.transaction.type.LegacyTransaction; -import org.web3j.crypto.transaction.type.Transaction1559; import org.web3j.rlp.RlpString; import org.web3j.rlp.RlpType; import org.web3j.utils.Base64String; @@ -30,23 +28,24 @@ import org.web3j.utils.Numeric; import org.web3j.utils.Restriction; -/** - * Transaction class used for signing transactions locally.
- * For the specification, refer to p4 of the yellow - * paper. - */ -public class RawPrivateTransaction extends RawTransaction { +public class LegacyPrivateTransaction extends RawTransaction implements IPrivateTransaction { - protected RawPrivateTransaction( - final BigInteger nonce, - final BigInteger gasPrice, - final BigInteger gasLimit, - final String to, - final String data, - final Base64String privateFrom, - final List privateFor, - final Base64String privacyGroupId, - final Restriction restriction) { + private final Base64String privateFrom; + private final List privateFor; + private final Base64String privacyGroupId; + private final Restriction restriction; + + // Constructor + public LegacyPrivateTransaction( + BigInteger nonce, + BigInteger gasPrice, + BigInteger gasLimit, + String to, + String data, + Base64String privateFrom, + List privateFor, + Base64String privacyGroupId, + Restriction restriction) { super(new LegacyTransaction(nonce, gasPrice, gasLimit, to, BigInteger.ZERO, data)); this.privateFrom = privateFrom; this.privateFor = privateFor; @@ -54,7 +53,16 @@ protected RawPrivateTransaction( this.restriction = restriction; } - protected RawPrivateTransaction( + public LegacyPrivateTransaction( + final RawTransaction rawTransaction, + final Base64String privateFrom, + final List privateFor, + final Base64String privacyGroupId, + final Restriction restriction) { + this(rawTransaction.getTransaction(), privateFrom, privateFor, privacyGroupId, restriction); + } + + protected LegacyPrivateTransaction( final ITransaction transaction, final Base64String privateFrom, final List privateFor, @@ -67,38 +75,124 @@ protected RawPrivateTransaction( this.restriction = restriction; } - private final Base64String privateFrom; - private final List privateFor; - private final Base64String privacyGroupId; - private final Restriction restriction; + public static LegacyPrivateTransaction createContractTransaction( + BigInteger nonce, + BigInteger gasPrice, + BigInteger gasLimit, + String data, + Base64String privateFrom, + List privateFor, + Base64String privacyGroupId, + Restriction restriction) { + + return new LegacyPrivateTransaction( + nonce, + gasPrice, + gasLimit, + null, + data, + privateFrom, + privateFor, + privacyGroupId, + restriction); + } - protected RawPrivateTransaction( - final RawTransaction rawTransaction, - final Base64String privateFrom, - final Base64String privacyGroupId, - final Restriction restriction) { - this(rawTransaction, privateFrom, null, privacyGroupId, restriction); + public static LegacyPrivateTransaction createContractTransaction( + BigInteger nonce, + BigInteger gasPrice, + BigInteger gasLimit, + String data, + Base64String privateFrom, + Base64String privacyGroupId, + Restriction restriction) { + + return createContractTransaction( + nonce, gasPrice, gasLimit, data, privateFrom, null, privacyGroupId, restriction); } - protected RawPrivateTransaction( - final RawTransaction rawTransaction, + public static LegacyPrivateTransaction createTransaction( + final BigInteger nonce, + final BigInteger gasPrice, + final BigInteger gasLimit, + final String to, + final String data, final Base64String privateFrom, final List privateFor, + final Base64String privacyGroupId, final Restriction restriction) { - this(rawTransaction, privateFrom, privateFor, null, restriction); + + return new LegacyPrivateTransaction( + nonce, + gasPrice, + gasLimit, + to, + data, + privateFrom, + privateFor, + privacyGroupId, + restriction); } - private RawPrivateTransaction( - final RawTransaction rawTransaction, - final Base64String privateFrom, + public static LegacyPrivateTransaction createTransaction( + BigInteger nonce, + BigInteger gasPrice, + BigInteger gasLimit, + String to, + Base64String privateFrom, + List privateFor, + Base64String privacyGroupId, + Restriction restriction) { + + return createTransaction( + nonce, + gasPrice, + gasLimit, + to, + "", + privateFrom, + privateFor, + privacyGroupId, + restriction); + } + + public static LegacyPrivateTransaction createTransaction( + BigInteger nonce, + BigInteger gasPrice, + BigInteger gasLimit, + String to, + String data, + Base64String privateFrom, + Base64String privacyGroupId, + Restriction restriction) { + + return createTransaction( + nonce, + gasPrice, + gasLimit, + to, + data, + privateFrom, + null, + privacyGroupId, + restriction); + } + + public static LegacyPrivateTransaction createTransaction( + BigInteger nonce, + BigInteger gasPrice, + BigInteger gasLimit, + String to, + String data, + Base64String privateFrom, final List privateFor, - final Base64String privacyGroupId, - final Restriction restriction) { - this(rawTransaction.getTransaction(), privateFrom, privateFor, privacyGroupId, restriction); + Restriction restriction) { + + return createTransaction( + nonce, gasPrice, gasLimit, to, data, privateFrom, privateFor, null, restriction); } - public List asRlpValues( - final Sign.SignatureData signatureData) { + @Override + public List asRlpValues(final Sign.SignatureData signatureData) { List result = new ArrayList<>(); @@ -141,146 +235,28 @@ public List asRlpValues( return result; } - public static RawPrivateTransaction createContractTransaction( - final BigInteger nonce, - final BigInteger gasPrice, - final BigInteger gasLimit, - final String init, - final Base64String privateFrom, - final List privateFor, - final Restriction restriction) { - - return new RawPrivateTransaction( - LegacyTransaction.createContractTransaction( - nonce, gasPrice, gasLimit, BigInteger.ZERO, init), - privateFrom, - privateFor, - null, - restriction); - } - - public static RawPrivateTransaction createContractTransaction( - final BigInteger nonce, - final BigInteger gasPrice, - final BigInteger gasLimit, - final String init, - final Base64String privateFrom, - final Base64String privacyGroupId, - final Restriction restriction) { - - return new RawPrivateTransaction( - LegacyTransaction.createContractTransaction( - nonce, gasPrice, gasLimit, BigInteger.ZERO, init), - privateFrom, - null, - privacyGroupId, - restriction); - } - - public static RawPrivateTransaction createTransaction( - final BigInteger nonce, - final BigInteger gasPrice, - final BigInteger gasLimit, - final String to, - final String data, - final Base64String privateFrom, - final List privateFor, - final Restriction restriction) { - - return new RawPrivateTransaction( - LegacyTransaction.createTransaction(nonce, gasPrice, gasLimit, to, data), - privateFrom, - privateFor, - null, - restriction); - } - - public static RawPrivateTransaction createTransaction( - final BigInteger nonce, - final BigInteger gasPrice, - final BigInteger gasLimit, - final String to, - final String data, - final Base64String privateFrom, - final Base64String privacyGroupId, - final Restriction restriction) { - - return new RawPrivateTransaction( - LegacyTransaction.createTransaction(nonce, gasPrice, gasLimit, to, data), - privateFrom, - null, - privacyGroupId, - restriction); - } - - public static RawPrivateTransaction createTransaction( - final long chainId, - final BigInteger nonce, - final BigInteger maxPriorityFeePerGas, - final BigInteger maxFeePerGas, - final BigInteger gasLimit, - final String to, - final String data, - final Base64String privateFrom, - final List privateFor, - final Restriction restriction) { - return new RawPrivateTransaction( - Transaction1559.createTransaction( - chainId, - nonce, - gasLimit, - to, - BigInteger.ZERO, - data, - maxPriorityFeePerGas, - maxFeePerGas), - privateFrom, - privateFor, - null, - restriction); - } - - public static RawPrivateTransaction createTransaction( - final long chainId, - final BigInteger nonce, - final BigInteger maxPriorityFeePerGas, - final BigInteger maxFeePerGas, - final BigInteger gasLimit, - final String to, - final String data, - final Base64String privateFrom, - final Base64String privacyGroupId, - final Restriction restriction) { - - return new RawPrivateTransaction( - Transaction1559.createTransaction( - chainId, - nonce, - gasLimit, - to, - BigInteger.ZERO, - data, - maxPriorityFeePerGas, - maxFeePerGas), - privateFrom, - null, - privacyGroupId, - restriction); - } - + @Override public Base64String getPrivateFrom() { return privateFrom; } + @Override public Optional> getPrivateFor() { return Optional.ofNullable(privateFor); } + @Override public Optional getPrivacyGroupId() { return Optional.ofNullable(privacyGroupId); } + @Override public Restriction getRestriction() { return restriction; } + + @Override + public PrivateTransactionType getTransactionType() { + return PrivateTransactionType.PRIVATE_LEGACY; + } } diff --git a/eea/src/main/java/org/web3j/protocol/eea/crypto/RawPrivateTransaction1559.java b/eea/src/main/java/org/web3j/protocol/eea/crypto/transaction/type/PrivateTransaction1559.java similarity index 62% rename from eea/src/main/java/org/web3j/protocol/eea/crypto/RawPrivateTransaction1559.java rename to eea/src/main/java/org/web3j/protocol/eea/crypto/transaction/type/PrivateTransaction1559.java index f19adbbd6..80a47cd09 100644 --- a/eea/src/main/java/org/web3j/protocol/eea/crypto/RawPrivateTransaction1559.java +++ b/eea/src/main/java/org/web3j/protocol/eea/crypto/transaction/type/PrivateTransaction1559.java @@ -1,6 +1,21 @@ -package org.web3j.protocol.eea.crypto; +/* + * Copyright 2023 Web3 Labs Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ +package org.web3j.protocol.eea.crypto.transaction.type; + +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.List; -import org.web3j.crypto.RawTransaction; import org.web3j.crypto.Sign; import org.web3j.crypto.transaction.type.ITransaction; import org.web3j.rlp.RlpList; @@ -11,35 +26,40 @@ import org.web3j.utils.Numeric; import org.web3j.utils.Restriction; -import java.math.BigInteger; -import java.util.ArrayList; -import java.util.List; - -public class RawPrivateTransaction1559 extends RawPrivateTransaction{ +public class PrivateTransaction1559 extends LegacyPrivateTransaction implements ITransaction { private long chainId; private BigInteger maxPriorityFeePerGas; private BigInteger maxFeePerGas; - - protected RawPrivateTransaction1559(long chainId, - BigInteger nonce, - BigInteger gasLimit, - String to, - String data, - BigInteger maxPriorityFeePerGas, - BigInteger maxFeePerGas, - Base64String privateFrom, - List privateFor, - Base64String privacyGroupId, - Restriction restriction) { - super(nonce, null, gasLimit, to, data, privateFrom, privateFor, privacyGroupId, restriction); + protected PrivateTransaction1559( + long chainId, + BigInteger nonce, + BigInteger gasLimit, + String to, + String data, + BigInteger maxPriorityFeePerGas, + BigInteger maxFeePerGas, + Base64String privateFrom, + List privateFor, + Base64String privacyGroupId, + Restriction restriction) { + super( + nonce, + null, + gasLimit, + to, + data, + privateFrom, + privateFor, + privacyGroupId, + restriction); this.chainId = chainId; this.maxPriorityFeePerGas = maxPriorityFeePerGas; this.maxFeePerGas = maxFeePerGas; } - protected RawPrivateTransaction1559( + protected PrivateTransaction1559( long chainId, BigInteger nonce, BigInteger gasLimit, @@ -50,10 +70,21 @@ protected RawPrivateTransaction1559( Base64String privateFrom, Base64String privacyGroupId, Restriction restriction) { - this(chainId, nonce, gasLimit, to, data, maxPriorityFeePerGas, maxFeePerGas, privateFrom, null, privacyGroupId, restriction); + this( + chainId, + nonce, + gasLimit, + to, + data, + maxPriorityFeePerGas, + maxFeePerGas, + privateFrom, + null, + privacyGroupId, + restriction); } - protected RawPrivateTransaction1559( + protected PrivateTransaction1559( long chainId, BigInteger nonce, BigInteger gasLimit, @@ -64,12 +95,22 @@ protected RawPrivateTransaction1559( Base64String privateFrom, List privateFor, Restriction restriction) { - this(chainId, nonce, gasLimit, to, data, maxPriorityFeePerGas, maxFeePerGas, privateFrom, privateFor, null, restriction); + this( + chainId, + nonce, + gasLimit, + to, + data, + maxPriorityFeePerGas, + maxFeePerGas, + privateFrom, + privateFor, + null, + restriction); } @Override - public List asRlpValues( - final Sign.SignatureData signatureData) { + public List asRlpValues(final Sign.SignatureData signatureData) { List result = new ArrayList<>(); @@ -120,7 +161,6 @@ public List asRlpValues( return result; } - @Override public BigInteger getGasPrice() { throw new UnsupportedOperationException("not available for 1559 transaction"); diff --git a/eea/src/main/java/org/web3j/protocol/eea/crypto/transaction/type/PrivateTransactionType.java b/eea/src/main/java/org/web3j/protocol/eea/crypto/transaction/type/PrivateTransactionType.java new file mode 100644 index 000000000..7e47e9d5f --- /dev/null +++ b/eea/src/main/java/org/web3j/protocol/eea/crypto/transaction/type/PrivateTransactionType.java @@ -0,0 +1,28 @@ +/* + * Copyright 2023 Web3 Labs Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ +package org.web3j.protocol.eea.crypto.transaction.type; + +public enum PrivateTransactionType { + PRIVATE_LEGACY("Legacy"), + PRIVATE_1559("EIP-1559"); + + private String description; + + PrivateTransactionType(String description) { + this.description = description; + } + + public String getDescription() { + return description; + } +} diff --git a/eea/src/test/java/org/web3j/protocol/eea/crypto/PrivateTransactionDecoderTest.java b/eea/src/test/java/org/web3j/protocol/eea/crypto/PrivateTransactionDecoderTest.java index 16c09904e..0e90954d2 100644 --- a/eea/src/test/java/org/web3j/protocol/eea/crypto/PrivateTransactionDecoderTest.java +++ b/eea/src/test/java/org/web3j/protocol/eea/crypto/PrivateTransactionDecoderTest.java @@ -20,6 +20,7 @@ import org.web3j.crypto.Credentials; import org.web3j.crypto.Sign; +import org.web3j.protocol.eea.crypto.transaction.type.LegacyPrivateTransaction; import org.web3j.utils.Base64String; import org.web3j.utils.Numeric; @@ -42,8 +43,8 @@ public void testDecoding() { final BigInteger gasPrice = BigInteger.ONE; final BigInteger gasLimit = BigInteger.TEN; final String to = "0x0add5355"; - final RawPrivateTransaction rawTransaction = - RawPrivateTransaction.createTransaction( + final LegacyPrivateTransaction rawTransaction = + LegacyPrivateTransaction.createTransaction( nonce, gasPrice, gasLimit, @@ -55,7 +56,7 @@ public void testDecoding() { byte[] encodedMessage = PrivateTransactionEncoder.encode(rawTransaction); final String hexMessage = Numeric.toHexString(encodedMessage); - final RawPrivateTransaction result = PrivateTransactionDecoder.decode(hexMessage); + final LegacyPrivateTransaction result = PrivateTransactionDecoder.decode(hexMessage); assertNotNull(result); assertEquals(nonce, result.getNonce()); assertEquals(gasPrice, result.getGasPrice()); @@ -73,8 +74,8 @@ public void testDecodingPrivacyGroup() { final BigInteger gasPrice = BigInteger.ONE; final BigInteger gasLimit = BigInteger.TEN; final String to = "0x0add5355"; - final RawPrivateTransaction rawTransaction = - RawPrivateTransaction.createTransaction( + final LegacyPrivateTransaction rawTransaction = + LegacyPrivateTransaction.createTransaction( nonce, gasPrice, gasLimit, @@ -86,7 +87,7 @@ public void testDecodingPrivacyGroup() { byte[] encodedMessage = PrivateTransactionEncoder.encode(rawTransaction); final String hexMessage = Numeric.toHexString(encodedMessage); - final RawPrivateTransaction result = PrivateTransactionDecoder.decode(hexMessage); + final LegacyPrivateTransaction result = PrivateTransactionDecoder.decode(hexMessage); assertNotNull(result); assertEquals(nonce, result.getNonce()); assertEquals(gasPrice, result.getGasPrice()); @@ -104,8 +105,8 @@ public void testDecodingSigned() throws Exception { final BigInteger gasPrice = BigInteger.ONE; final BigInteger gasLimit = BigInteger.TEN; final String to = "0x0add5355"; - final RawPrivateTransaction rawTransaction = - RawPrivateTransaction.createTransaction( + final LegacyPrivateTransaction rawTransaction = + LegacyPrivateTransaction.createTransaction( nonce, gasPrice, gasLimit, @@ -121,7 +122,7 @@ public void testDecodingSigned() throws Exception { PrivateTransactionEncoder.signMessage(rawTransaction, credentials); final String hexMessage = Numeric.toHexString(encodedMessage); - final RawPrivateTransaction result = PrivateTransactionDecoder.decode(hexMessage); + final LegacyPrivateTransaction result = PrivateTransactionDecoder.decode(hexMessage); assertNotNull(result); assertEquals(nonce, result.getNonce()); assertEquals(gasPrice, result.getGasPrice()); @@ -149,8 +150,8 @@ public void testDecodingSignedPrivacyGroup() throws Exception { final BigInteger gasPrice = BigInteger.ONE; final BigInteger gasLimit = BigInteger.TEN; final String to = "0x0add5355"; - final RawPrivateTransaction rawTransaction = - RawPrivateTransaction.createTransaction( + final LegacyPrivateTransaction rawTransaction = + LegacyPrivateTransaction.createTransaction( nonce, gasPrice, gasLimit, @@ -166,7 +167,7 @@ public void testDecodingSignedPrivacyGroup() throws Exception { PrivateTransactionEncoder.signMessage(rawTransaction, credentials); final String hexMessage = Numeric.toHexString(encodedMessage); - final RawPrivateTransaction result = PrivateTransactionDecoder.decode(hexMessage); + final LegacyPrivateTransaction result = PrivateTransactionDecoder.decode(hexMessage); assertNotNull(result); assertEquals(nonce, result.getNonce()); assertEquals(gasPrice, result.getGasPrice()); @@ -195,8 +196,8 @@ public void testDecodingSignedChainId() throws Exception { final BigInteger gasLimit = BigInteger.TEN; final String to = "0x0add5355"; final long chainId = 2018L; - final RawPrivateTransaction rawTransaction = - RawPrivateTransaction.createTransaction( + final LegacyPrivateTransaction rawTransaction = + LegacyPrivateTransaction.createTransaction( nonce, gasPrice, gasLimit, @@ -212,7 +213,7 @@ public void testDecodingSignedChainId() throws Exception { PrivateTransactionEncoder.signMessage(rawTransaction, chainId, credentials); final String hexMessage = Numeric.toHexString(signedMessage); - final RawPrivateTransaction result = PrivateTransactionDecoder.decode(hexMessage); + final LegacyPrivateTransaction result = PrivateTransactionDecoder.decode(hexMessage); assertNotNull(result); assertEquals(nonce, result.getNonce()); assertEquals(gasPrice, result.getGasPrice()); diff --git a/eea/src/test/java/org/web3j/protocol/eea/crypto/PrivateTransactionEncoderTest.java b/eea/src/test/java/org/web3j/protocol/eea/crypto/PrivateTransactionEncoderTest.java index 9439ea0c9..1646d237c 100644 --- a/eea/src/test/java/org/web3j/protocol/eea/crypto/PrivateTransactionEncoderTest.java +++ b/eea/src/test/java/org/web3j/protocol/eea/crypto/PrivateTransactionEncoderTest.java @@ -19,6 +19,7 @@ import org.junit.jupiter.api.Test; import org.web3j.crypto.Credentials; +import org.web3j.protocol.eea.crypto.transaction.type.LegacyPrivateTransaction; import org.web3j.utils.Base64String; import org.web3j.utils.Numeric; @@ -40,8 +41,8 @@ public class PrivateTransactionEncoderTest { public void testSignLegacyTransaction() { final String expected = "0xf8d4808203e8832dc6c094627306090abab3a6e1400e9345bc60c78a8bef578080820fe8a0e0b547d71d7a23d52382288b3a2a5a1610e0b504c404cc5009d7ada97d9015b2a076e997a83856d876fa2397b74510890eea3b73ffeda33daa4188120dac42d62fa0035695b4cc4b0941e60551d7a19cf30603db5bfc23e5ac43a56f57f25f75486af842a0035695b4cc4b0941e60551d7a19cf30603db5bfc23e5ac43a56f57f25f75486aa02a8d9b56a0fe9cd94d60be4413bcb721d3a7be27ed8e28b3a6346df874ee141b8a72657374726963746564"; - final RawPrivateTransaction privateTransactionCreation = - new RawPrivateTransaction( + final LegacyPrivateTransaction privateTransactionCreation = + new LegacyPrivateTransaction( BigInteger.ZERO, BigInteger.valueOf(1000), BigInteger.valueOf(3000000), @@ -67,8 +68,8 @@ public void testSignLegacyTransaction() { public void testSignBesuTransaction() { final String expected = "0xf8b1808203e8832dc6c094627306090abab3a6e1400e9345bc60c78a8bef578080820fe7a060c70c3f989ef5459021142959f8fc1ad6e5fe8542cf238484c6d6b8c8a6dbcca075727642ce691c4bf5ae945523cdd172d44b451ddfe11ae67c376f1e5c7069eea0035695b4cc4b0941e60551d7a19cf30603db5bfc23e5ac43a56f57f25f75486aa00f200e885ff29e973e2576b6600181d1b0a2b5294e30d9be4a1981ffb33a0b8c8a72657374726963746564"; - final RawPrivateTransaction privateTransactionCreation = - new RawPrivateTransaction( + final LegacyPrivateTransaction privateTransactionCreation = + new LegacyPrivateTransaction( BigInteger.ZERO, BigInteger.valueOf(1000), BigInteger.valueOf(3000000), diff --git a/integration-tests/src/test/java/org/web3j/protocol/besu/BesuPrivacyQuickstartIntegrationTest.java b/integration-tests/src/test/java/org/web3j/protocol/besu/BesuPrivacyQuickstartIntegrationTest.java index 3ee4cc1b6..f51edcd9e 100644 --- a/integration-tests/src/test/java/org/web3j/protocol/besu/BesuPrivacyQuickstartIntegrationTest.java +++ b/integration-tests/src/test/java/org/web3j/protocol/besu/BesuPrivacyQuickstartIntegrationTest.java @@ -28,7 +28,7 @@ import org.web3j.protocol.besu.response.privacy.PrivateTransactionReceipt; import org.web3j.protocol.besu.response.privacy.PrivateTransactionWithPrivacyGroup; import org.web3j.protocol.eea.crypto.PrivateTransactionEncoder; -import org.web3j.protocol.eea.crypto.RawPrivateTransaction; +import org.web3j.protocol.eea.crypto.transaction.type.LegacyPrivateTransaction; import org.web3j.protocol.http.HttpService; import org.web3j.test.contract.HumanStandardToken; import org.web3j.tx.ChainIdLong; @@ -127,8 +127,8 @@ public void simplePrivateTransactions() throws Exception { .privGetTransactionCount(ALICE.getAddress(), privacyGroupId) .send() .getTransactionCount(); - final RawPrivateTransaction rawPrivateTransaction = - RawPrivateTransaction.createContractTransaction( + final LegacyPrivateTransaction rawPrivateTransaction = + LegacyPrivateTransaction.createContractTransaction( nonce, ZERO_GAS_PROVIDER.getGasPrice(), ZERO_GAS_PROVIDER.getGasLimit(), From d47d0a5211768155414954a3bd5de30308754818 Mon Sep 17 00:00:00 2001 From: Nischal Sharma Date: Mon, 6 Nov 2023 14:30:43 +0530 Subject: [PATCH 3/7] added privateTx EIP1559 Signed-off-by: Nischal Sharma --- .../web3j/tx/PrivateTransactionManager.java | 76 ++++++++--------- .../tx/PrivateTransactionManagerTest.java | 3 + .../eea/crypto/PrivateTransactionDecoder.java | 84 +++++++++++++++++-- .../eea/crypto/PrivateTransactionEncoder.java | 21 +++-- .../type/PrivateTransaction1559.java | 15 ++-- .../type/PrivateTransactionType.java | 22 +++-- .../crypto/PrivateTransactionDecoderTest.java | 42 ++++++++++ .../crypto/PrivateTransactionEncoderTest.java | 31 +++++++ 8 files changed, 227 insertions(+), 67 deletions(-) diff --git a/besu/src/main/java/org/web3j/tx/PrivateTransactionManager.java b/besu/src/main/java/org/web3j/tx/PrivateTransactionManager.java index 87e2d3875..407c21244 100644 --- a/besu/src/main/java/org/web3j/tx/PrivateTransactionManager.java +++ b/besu/src/main/java/org/web3j/tx/PrivateTransactionManager.java @@ -26,7 +26,7 @@ import org.web3j.protocol.core.methods.response.EthSendTransaction; import org.web3j.protocol.eea.crypto.PrivateTxSignServiceImpl; import org.web3j.protocol.eea.crypto.transaction.type.LegacyPrivateTransaction; -import org.web3j.service.TxSignService; +import org.web3j.protocol.eea.crypto.transaction.type.PrivateTransaction1559; import org.web3j.tx.response.TransactionReceiptProcessor; import org.web3j.utils.Base64String; import org.web3j.utils.Numeric; @@ -37,7 +37,7 @@ public class PrivateTransactionManager extends TransactionManager { private final Besu besu; - private final TxSignService txSignService; + private final PrivateTxSignServiceImpl privateTxSignService; private final long chainId; private final Base64String privateFrom; @@ -74,7 +74,7 @@ public PrivateTransactionManager( final Base64String privateFrom, final Base64String privacyGroupId, final Restriction restriction, - final TxSignService txSignService) { + final PrivateTxSignServiceImpl privateTxSignService) { super(transactionReceiptProcessor, credentials.getAddress()); this.besu = besu; this.chainId = chainId; @@ -82,7 +82,7 @@ public PrivateTransactionManager( this.privateFor = null; this.privacyGroupId = privacyGroupId; this.restriction = restriction; - this.txSignService = txSignService; + this.privateTxSignService = privateTxSignService; } public PrivateTransactionManager( @@ -112,7 +112,7 @@ public PrivateTransactionManager( final Base64String privateFrom, final List privateFor, final Restriction restriction, - final TxSignService txSignService) { + final PrivateTxSignServiceImpl privateTxSignService) { super(transactionReceiptProcessor, credentials.getAddress()); this.besu = besu; this.chainId = chainId; @@ -120,7 +120,7 @@ public PrivateTransactionManager( this.privateFor = privateFor; this.privacyGroupId = PrivacyGroupUtils.generateLegacyGroup(privateFrom, privateFor); this.restriction = restriction; - this.txSignService = txSignService; + this.privateTxSignService = privateTxSignService; } @Override @@ -134,7 +134,7 @@ public EthSendTransaction sendTransaction( throws IOException { final BigInteger nonce = - besu.privGetTransactionCount(txSignService.getAddress(), privacyGroupId) + besu.privGetTransactionCount(privateTxSignService.getAddress(), privacyGroupId) .send() .getTransactionCount(); @@ -179,40 +179,40 @@ public EthSendTransaction sendEIP1559Transaction( boolean constructor) throws IOException { final BigInteger nonce = - besu.privGetTransactionCount(txSignService.getAddress(), privacyGroupId) + besu.privGetTransactionCount(privateTxSignService.getAddress(), privacyGroupId) .send() .getTransactionCount(); - final LegacyPrivateTransaction transaction; - // if (privateFor != null) { - // transaction = - // RawPrivateTransaction.createTransaction( - // chainId, - // nonce, - // maxPriorityFeePerGas, - // maxFeePerGas, - // gasLimit, - // to, - // data, - // privateFrom, - // privateFor, - // restriction); - // } else { - // transaction = - // RawPrivateTransaction.createTransaction( - // chainId, - // nonce, - // maxPriorityFeePerGas, - // maxFeePerGas, - // gasLimit, - // to, - // data, - // privateFrom, - // privacyGroupId, - // restriction); - // } + final PrivateTransaction1559 transaction; + if (privateFor != null) { + transaction = + new PrivateTransaction1559( + chainId, + nonce, + gasLimit, + to, + data, + maxPriorityFeePerGas, + maxFeePerGas, + privateFrom, + privateFor, + restriction); + } else { + transaction = + new PrivateTransaction1559( + chainId, + nonce, + gasLimit, + to, + data, + maxPriorityFeePerGas, + maxFeePerGas, + privateFrom, + privacyGroupId, + restriction); + } - return signAndSend(null); + return signAndSend(transaction); } @Override @@ -241,7 +241,7 @@ public EthGetCode getCode( public String sign(final LegacyPrivateTransaction rawTransaction) { - final byte[] signedMessage = txSignService.sign(rawTransaction, chainId); + final byte[] signedMessage = privateTxSignService.sign(rawTransaction, chainId); return Numeric.toHexString(signedMessage); } diff --git a/besu/src/test/java/org/web3j/tx/PrivateTransactionManagerTest.java b/besu/src/test/java/org/web3j/tx/PrivateTransactionManagerTest.java index 415cb772b..2f1e8d624 100644 --- a/besu/src/test/java/org/web3j/tx/PrivateTransactionManagerTest.java +++ b/besu/src/test/java/org/web3j/tx/PrivateTransactionManagerTest.java @@ -21,6 +21,7 @@ import org.web3j.protocol.besu.Besu; import org.web3j.protocol.core.DefaultBlockParameter; import org.web3j.protocol.core.methods.response.EthCall; +import org.web3j.protocol.core.methods.response.EthSendTransaction; import org.web3j.tx.exceptions.ContractCallException; import org.web3j.tx.response.PollingPrivateTransactionReceiptProcessor; import org.web3j.tx.response.TransactionReceiptProcessor; @@ -51,6 +52,8 @@ class PrivateTransactionManagerTest { DefaultBlockParameter defaultBlockParameter = mock(DefaultBlockParameter.class); EthCall response = mock(EthCall.class); + EthSendTransaction sendTransaction = mock(EthSendTransaction.class); + @Test public void sendPrivCallTest() throws IOException { when(response.getValue()).thenReturn("test"); diff --git a/eea/src/main/java/org/web3j/protocol/eea/crypto/PrivateTransactionDecoder.java b/eea/src/main/java/org/web3j/protocol/eea/crypto/PrivateTransactionDecoder.java index 7826857d9..325771cd7 100644 --- a/eea/src/main/java/org/web3j/protocol/eea/crypto/PrivateTransactionDecoder.java +++ b/eea/src/main/java/org/web3j/protocol/eea/crypto/PrivateTransactionDecoder.java @@ -12,6 +12,8 @@ */ package org.web3j.protocol.eea.crypto; +import java.math.BigInteger; +import java.util.Arrays; import java.util.List; import java.util.stream.Collectors; @@ -19,6 +21,7 @@ import org.web3j.crypto.SignedRawTransaction; import org.web3j.crypto.TransactionDecoder; import org.web3j.protocol.eea.crypto.transaction.type.LegacyPrivateTransaction; +import org.web3j.protocol.eea.crypto.transaction.type.PrivateTransaction1559; import org.web3j.protocol.eea.crypto.transaction.type.PrivateTransactionType; import org.web3j.rlp.RlpDecoder; import org.web3j.rlp.RlpList; @@ -36,22 +39,85 @@ public static LegacyPrivateTransaction decode(final String hexTransaction) { final byte[] transaction = Numeric.hexStringToByteArray(hexTransaction); final PrivateTransactionType transactionType = getPrivateTransactionType(transaction); - switch (transactionType) { - case PRIVATE_LEGACY: - return decodeLegacyPrivateTransaction(transaction); - default: - throw new IllegalArgumentException("Unsupported private transaction type."); + if (transactionType == PrivateTransactionType.PRIVATE_1559) { + return decodePrivateTransaction1559(transaction); } + return decodeLegacyPrivateTransaction(transaction); } private static PrivateTransactionType getPrivateTransactionType(final byte[] transaction) { // Determine the type of the private transaction, similar to TransactionDecoder. byte firstByte = transaction[0]; - // if (firstByte == PrivateTransactionType.PRIVATE_LEGACY.getRlpType()) - // return PrivateTransactionType.PRIVATE_LEGACY; + if (firstByte == PrivateTransactionType.PRIVATE_1559.getRlpType()) + return PrivateTransactionType.PRIVATE_1559; + else return PrivateTransactionType.PRIVATE_LEGACY; + } + + private static LegacyPrivateTransaction decodePrivateTransaction1559(final byte[] transaction) { + final byte[] encodedTx = Arrays.copyOfRange(transaction, 1, transaction.length); + final RlpList rlpList = RlpDecoder.decode(encodedTx); + final RlpList temp = (RlpList) rlpList.getValues().get(0); + final List values = temp.getValues(); + + System.out.println(rlpList); + System.out.println(temp); + System.out.println(values); + + final long chainId = + ((RlpString) temp.getValues().get(0)).asPositiveBigInteger().longValue(); + System.out.println("chainId " + chainId); + final BigInteger nonce = ((RlpString) temp.getValues().get(1)).asPositiveBigInteger(); + System.out.println("nonce " + nonce); - // Return LEGACY as default, or throw an exception depending on your needs - return PrivateTransactionType.PRIVATE_LEGACY; + final BigInteger maxPriorityFeePerGas = + ((RlpString) temp.getValues().get(2)).asPositiveBigInteger(); + System.out.println("maxPriorityFeePerGas " + maxPriorityFeePerGas); + final BigInteger maxFeePerGas = + ((RlpString) temp.getValues().get(3)).asPositiveBigInteger(); + System.out.println("maxFeePerGas " + maxFeePerGas); + + final BigInteger gasLimit = ((RlpString) temp.getValues().get(4)).asPositiveBigInteger(); + System.out.println("gasLimit " + gasLimit); + final String to = ((RlpString) temp.getValues().get(5)).asString(); + System.out.println("to " + to); + + final String data = ((RlpString) temp.getValues().get(7)).asString(); + System.out.println("data " + data); + + final Base64String privateFrom = extractBase64(values.get(8)); + System.out.println("privateFrom " + privateFrom); + final Restriction restriction = extractRestriction(values.get(10)); + System.out.println("restriction " + restriction); + + if (values.get(9) instanceof RlpList) { + List privateForList = extractBase64List(values.get(9)); + return new PrivateTransaction1559( + chainId, + nonce, + gasLimit, + to, + data, + maxPriorityFeePerGas, + maxFeePerGas, + privateFrom, + privateForList, + null, + restriction); + } else { + Base64String privacyGroupId = extractBase64(values.get(9)); + return new PrivateTransaction1559( + chainId, + nonce, + gasLimit, + to, + data, + maxPriorityFeePerGas, + maxFeePerGas, + privateFrom, + null, + privacyGroupId, + restriction); + } } private static LegacyPrivateTransaction decodeLegacyPrivateTransaction( diff --git a/eea/src/main/java/org/web3j/protocol/eea/crypto/PrivateTransactionEncoder.java b/eea/src/main/java/org/web3j/protocol/eea/crypto/PrivateTransactionEncoder.java index 175414e32..7f8308dad 100644 --- a/eea/src/main/java/org/web3j/protocol/eea/crypto/PrivateTransactionEncoder.java +++ b/eea/src/main/java/org/web3j/protocol/eea/crypto/PrivateTransactionEncoder.java @@ -27,12 +27,12 @@ public class PrivateTransactionEncoder { public static byte[] signMessage( - final LegacyPrivateTransaction rawTransaction, final Credentials credentials) { - final byte[] encodedTransaction = encode(rawTransaction); + final LegacyPrivateTransaction privateTransaction, final Credentials credentials) { + final byte[] encodedTransaction = encode(privateTransaction); final Sign.SignatureData signatureData = Sign.signMessage(encodedTransaction, credentials.getEcKeyPair()); - return encode(rawTransaction, signatureData); + return encode(privateTransaction, signatureData); } public static byte[] signMessage( @@ -59,11 +59,20 @@ public static byte[] encode(final LegacyPrivateTransaction rawTransaction, final } private static byte[] encode( - final LegacyPrivateTransaction rawTransaction, final Sign.SignatureData signatureData) { + final LegacyPrivateTransaction privateTransaction, + final Sign.SignatureData signatureData) { // final List values = asRlpValues(rawTransaction, signatureData); - final List values = rawTransaction.asRlpValues(signatureData); + final List values = privateTransaction.asRlpValues(signatureData); final RlpList rlpList = new RlpList(values); - return RlpEncoder.encode(rlpList); + byte[] encoded = RlpEncoder.encode(rlpList); + + if (privateTransaction.getTransactionType().isPrivateEip1559()) { + return ByteBuffer.allocate(encoded.length + 1) + .put(privateTransaction.getTransactionType().getRlpType()) + .put(encoded) + .array(); + } + return encoded; } private static byte[] longToBytes(long x) { diff --git a/eea/src/main/java/org/web3j/protocol/eea/crypto/transaction/type/PrivateTransaction1559.java b/eea/src/main/java/org/web3j/protocol/eea/crypto/transaction/type/PrivateTransaction1559.java index 80a47cd09..b5260c865 100644 --- a/eea/src/main/java/org/web3j/protocol/eea/crypto/transaction/type/PrivateTransaction1559.java +++ b/eea/src/main/java/org/web3j/protocol/eea/crypto/transaction/type/PrivateTransaction1559.java @@ -18,7 +18,6 @@ import org.web3j.crypto.Sign; import org.web3j.crypto.transaction.type.ITransaction; -import org.web3j.rlp.RlpList; import org.web3j.rlp.RlpString; import org.web3j.rlp.RlpType; import org.web3j.utils.Base64String; @@ -32,7 +31,7 @@ public class PrivateTransaction1559 extends LegacyPrivateTransaction implements private BigInteger maxPriorityFeePerGas; private BigInteger maxFeePerGas; - protected PrivateTransaction1559( + public PrivateTransaction1559( long chainId, BigInteger nonce, BigInteger gasLimit, @@ -59,7 +58,7 @@ protected PrivateTransaction1559( this.maxFeePerGas = maxFeePerGas; } - protected PrivateTransaction1559( + public PrivateTransaction1559( long chainId, BigInteger nonce, BigInteger gasLimit, @@ -84,7 +83,7 @@ protected PrivateTransaction1559( restriction); } - protected PrivateTransaction1559( + public PrivateTransaction1559( long chainId, BigInteger nonce, BigInteger gasLimit, @@ -140,9 +139,6 @@ public List asRlpValues(final Sign.SignatureData signatureData) { byte[] data = Numeric.hexStringToByteArray(getData()); result.add(RlpString.create(data)); - // access list - result.add(new RlpList()); - if (signatureData != null) { result.add(RlpString.create(Sign.getRecId(signatureData, getChainId()))); result.add(RlpString.create(Bytes.trimLeadingZeroes(signatureData.getR()))); @@ -177,4 +173,9 @@ public BigInteger getMaxPriorityFeePerGas() { public BigInteger getMaxFeePerGas() { return maxFeePerGas; } + + @Override + public PrivateTransactionType getTransactionType() { + return PrivateTransactionType.PRIVATE_1559; + } } diff --git a/eea/src/main/java/org/web3j/protocol/eea/crypto/transaction/type/PrivateTransactionType.java b/eea/src/main/java/org/web3j/protocol/eea/crypto/transaction/type/PrivateTransactionType.java index 7e47e9d5f..0f70d74de 100644 --- a/eea/src/main/java/org/web3j/protocol/eea/crypto/transaction/type/PrivateTransactionType.java +++ b/eea/src/main/java/org/web3j/protocol/eea/crypto/transaction/type/PrivateTransactionType.java @@ -13,16 +13,24 @@ package org.web3j.protocol.eea.crypto.transaction.type; public enum PrivateTransactionType { - PRIVATE_LEGACY("Legacy"), - PRIVATE_1559("EIP-1559"); + PRIVATE_LEGACY(null), + PRIVATE_1559(((byte) 0x01)); - private String description; + Byte type; - PrivateTransactionType(String description) { - this.description = description; + PrivateTransactionType(final Byte type) { + this.type = type; } - public String getDescription() { - return description; + public Byte getRlpType() { + return type; + } + + public boolean isPrivateLegacy() { + return this.equals(PrivateTransactionType.PRIVATE_LEGACY); + } + + public boolean isPrivateEip1559() { + return this.equals(PrivateTransactionType.PRIVATE_1559); } } diff --git a/eea/src/test/java/org/web3j/protocol/eea/crypto/PrivateTransactionDecoderTest.java b/eea/src/test/java/org/web3j/protocol/eea/crypto/PrivateTransactionDecoderTest.java index 0e90954d2..7e5cf2853 100644 --- a/eea/src/test/java/org/web3j/protocol/eea/crypto/PrivateTransactionDecoderTest.java +++ b/eea/src/test/java/org/web3j/protocol/eea/crypto/PrivateTransactionDecoderTest.java @@ -21,6 +21,7 @@ import org.web3j.crypto.Credentials; import org.web3j.crypto.Sign; import org.web3j.protocol.eea.crypto.transaction.type.LegacyPrivateTransaction; +import org.web3j.protocol.eea.crypto.transaction.type.PrivateTransaction1559; import org.web3j.utils.Base64String; import org.web3j.utils.Numeric; @@ -68,6 +69,47 @@ public void testDecoding() { assertEquals(RESTRICTED, result.getRestriction()); } + @Test + public void testDecoding1559() { + final BigInteger nonce = BigInteger.ZERO; + final long chainId = 2018; + final BigInteger gasLimit = BigInteger.TEN; + final BigInteger maxPriorityFeePerGas = BigInteger.ONE; + final BigInteger maxFeePerGas = BigInteger.ONE; + final String to = "0x0add5355"; + + final PrivateTransaction1559 privateTx = + new PrivateTransaction1559( + chainId, + nonce, + gasLimit, + to, + "", + maxPriorityFeePerGas, + maxFeePerGas, + MOCK_ENCLAVE_KEY, + MOCK_PRIVATE_FOR, + null, + RESTRICTED); + + byte[] encodedMessage = PrivateTransactionEncoder.encode(privateTx); + final String hexMessage = Numeric.toHexString(encodedMessage); + + final PrivateTransaction1559 result = + (PrivateTransaction1559) PrivateTransactionDecoder.decode(hexMessage); + assertNotNull(result); + assertEquals(nonce, result.getNonce()); + assertEquals(chainId, result.getChainId()); + assertEquals(maxPriorityFeePerGas, result.getMaxPriorityFeePerGas()); + assertEquals(maxFeePerGas, result.getMaxFeePerGas()); + assertEquals(gasLimit, result.getGasLimit()); + assertEquals(to, result.getTo()); + assertEquals("", result.getData()); + assertEquals(MOCK_ENCLAVE_KEY, result.getPrivateFrom()); + assertEquals(MOCK_PRIVATE_FOR, result.getPrivateFor().get()); + assertEquals(RESTRICTED, result.getRestriction()); + } + @Test public void testDecodingPrivacyGroup() { final BigInteger nonce = BigInteger.ZERO; diff --git a/eea/src/test/java/org/web3j/protocol/eea/crypto/PrivateTransactionEncoderTest.java b/eea/src/test/java/org/web3j/protocol/eea/crypto/PrivateTransactionEncoderTest.java index 1646d237c..f57e673d9 100644 --- a/eea/src/test/java/org/web3j/protocol/eea/crypto/PrivateTransactionEncoderTest.java +++ b/eea/src/test/java/org/web3j/protocol/eea/crypto/PrivateTransactionEncoderTest.java @@ -20,6 +20,7 @@ import org.web3j.crypto.Credentials; import org.web3j.protocol.eea.crypto.transaction.type.LegacyPrivateTransaction; +import org.web3j.protocol.eea.crypto.transaction.type.PrivateTransaction1559; import org.web3j.utils.Base64String; import org.web3j.utils.Numeric; @@ -64,6 +65,36 @@ public void testSignLegacyTransaction() { assertEquals(expected, privateRawTransaction); } + @Test + public void testSign1559Transaction() { + final String expected = + "0x01f8d48207e2800101832dc6c094627306090abab3a6e1400e9345bc60c78a8bef57808001a0c0e9d5c7656fdf74a5b5423b20c01663e6c3ee9f855a2371a0bbb07569fafd6ea02543caba35757c6b9401eebfe724c538cb94f817106927fedaa4669ffcbae7efa0035695b4cc4b0941e60551d7a19cf30603db5bfc23e5ac43a56f57f25f75486af842a0035695b4cc4b0941e60551d7a19cf30603db5bfc23e5ac43a56f57f25f75486aa02a8d9b56a0fe9cd94d60be4413bcb721d3a7be27ed8e28b3a6346df874ee141b8a72657374726963746564"; + final long chainId = 2018; + final PrivateTransaction1559 privateTransactionCreation = + new PrivateTransaction1559( + chainId, + BigInteger.ZERO, + BigInteger.valueOf(3000000), + "0x627306090abab3a6e1400e9345bc60c78a8bef57", + "0x", + BigInteger.ONE, + BigInteger.ONE, + MOCK_ENCLAVE_KEY, + MOCK_PRIVATE_FOR, + null, + RESTRICTED); + + final String privateKey = + "8f2a55949038a9610f50fb23b5883af3b4ecb3c3bb792cbcefbd1542c692be63"; + final Credentials credentials = Credentials.create(privateKey); + final String privateRawTransaction = + Numeric.toHexString( + PrivateTransactionEncoder.signMessage( + privateTransactionCreation, credentials)); + + assertEquals(expected, privateRawTransaction); + } + @Test public void testSignBesuTransaction() { final String expected = From cf25d0e4f4ae9266de417be4d3b39d3de858ce21 Mon Sep 17 00:00:00 2001 From: Nischal Sharma Date: Mon, 6 Nov 2023 22:09:12 +0530 Subject: [PATCH 4/7] fixed comments and breaking changes Signed-off-by: Nischal Sharma --- .../OnChainPrivacyTransactionBuilder.java | 6 +- .../web3j/tx/PrivateTransactionManager.java | 25 ++--- .../eea/crypto/PrivateTransactionDecoder.java | 51 +++++------ .../eea/crypto/PrivateTransactionEncoder.java | 12 +-- .../eea/crypto/PrivateTxSignServiceImpl.java | 8 +- .../crypto/SignedRawPrivateTransaction.java | 4 +- .../type/PrivateTransaction1559.java | 91 +++++++++++++++++-- ...action.java => RawPrivateTransaction.java} | 24 ++--- .../crypto/PrivateTransactionDecoderTest.java | 35 ++++--- .../crypto/PrivateTransactionEncoderTest.java | 15 ++- .../BesuPrivacyQuickstartIntegrationTest.java | 6 +- 11 files changed, 175 insertions(+), 102 deletions(-) rename eea/src/main/java/org/web3j/protocol/eea/crypto/transaction/type/{LegacyPrivateTransaction.java => RawPrivateTransaction.java} (92%) diff --git a/besu/src/main/java/org/web3j/protocol/besu/privacy/OnChainPrivacyTransactionBuilder.java b/besu/src/main/java/org/web3j/protocol/besu/privacy/OnChainPrivacyTransactionBuilder.java index 01d820c15..2ba0d7c31 100644 --- a/besu/src/main/java/org/web3j/protocol/besu/privacy/OnChainPrivacyTransactionBuilder.java +++ b/besu/src/main/java/org/web3j/protocol/besu/privacy/OnChainPrivacyTransactionBuilder.java @@ -24,7 +24,7 @@ import org.web3j.abi.datatypes.generated.Bytes32; import org.web3j.crypto.Credentials; import org.web3j.protocol.eea.crypto.PrivateTransactionEncoder; -import org.web3j.protocol.eea.crypto.transaction.type.LegacyPrivateTransaction; +import org.web3j.protocol.eea.crypto.transaction.type.RawPrivateTransaction; import org.web3j.tx.gas.BesuPrivacyGasProvider; import org.web3j.utils.Base64String; import org.web3j.utils.Numeric; @@ -87,8 +87,8 @@ public String buildOnChainPrivateTransaction( Base64String enclaveKey, final BigInteger nonce, String call) { - LegacyPrivateTransaction rawTransaction = - LegacyPrivateTransaction.createTransaction( + RawPrivateTransaction rawTransaction = + RawPrivateTransaction.createTransaction( nonce, gasProvider.getGasPrice(), gasProvider.getGasLimit(), diff --git a/besu/src/main/java/org/web3j/tx/PrivateTransactionManager.java b/besu/src/main/java/org/web3j/tx/PrivateTransactionManager.java index 407c21244..d9530befd 100644 --- a/besu/src/main/java/org/web3j/tx/PrivateTransactionManager.java +++ b/besu/src/main/java/org/web3j/tx/PrivateTransactionManager.java @@ -25,8 +25,9 @@ import org.web3j.protocol.core.methods.response.EthGetCode; import org.web3j.protocol.core.methods.response.EthSendTransaction; import org.web3j.protocol.eea.crypto.PrivateTxSignServiceImpl; -import org.web3j.protocol.eea.crypto.transaction.type.LegacyPrivateTransaction; import org.web3j.protocol.eea.crypto.transaction.type.PrivateTransaction1559; +import org.web3j.protocol.eea.crypto.transaction.type.RawPrivateTransaction; +import org.web3j.service.TxSignService; import org.web3j.tx.response.TransactionReceiptProcessor; import org.web3j.utils.Base64String; import org.web3j.utils.Numeric; @@ -37,7 +38,7 @@ public class PrivateTransactionManager extends TransactionManager { private final Besu besu; - private final PrivateTxSignServiceImpl privateTxSignService; + private final TxSignService privateTxSignService; private final long chainId; private final Base64String privateFrom; @@ -74,7 +75,7 @@ public PrivateTransactionManager( final Base64String privateFrom, final Base64String privacyGroupId, final Restriction restriction, - final PrivateTxSignServiceImpl privateTxSignService) { + final TxSignService privateTxSignService) { super(transactionReceiptProcessor, credentials.getAddress()); this.besu = besu; this.chainId = chainId; @@ -112,7 +113,7 @@ public PrivateTransactionManager( final Base64String privateFrom, final List privateFor, final Restriction restriction, - final PrivateTxSignServiceImpl privateTxSignService) { + final TxSignService privateTxSignService) { super(transactionReceiptProcessor, credentials.getAddress()); this.besu = besu; this.chainId = chainId; @@ -138,11 +139,11 @@ public EthSendTransaction sendTransaction( .send() .getTransactionCount(); - final LegacyPrivateTransaction transaction; + final RawPrivateTransaction transaction; if (privateFor != null) { transaction = - LegacyPrivateTransaction.createTransaction( + RawPrivateTransaction.createTransaction( nonce, gasPrice, gasLimit, @@ -153,7 +154,7 @@ public EthSendTransaction sendTransaction( restriction); } else { transaction = - LegacyPrivateTransaction.createTransaction( + RawPrivateTransaction.createTransaction( nonce, gasPrice, gasLimit, @@ -186,7 +187,7 @@ public EthSendTransaction sendEIP1559Transaction( final PrivateTransaction1559 transaction; if (privateFor != null) { transaction = - new PrivateTransaction1559( + PrivateTransaction1559.createTransaction( chainId, nonce, gasLimit, @@ -199,7 +200,7 @@ public EthSendTransaction sendEIP1559Transaction( restriction); } else { transaction = - new PrivateTransaction1559( + PrivateTransaction1559.createTransaction( chainId, nonce, gasLimit, @@ -239,20 +240,20 @@ public EthGetCode getCode( .send(); } - public String sign(final LegacyPrivateTransaction rawTransaction) { + public String sign(final RawPrivateTransaction rawTransaction) { final byte[] signedMessage = privateTxSignService.sign(rawTransaction, chainId); return Numeric.toHexString(signedMessage); } - public EthSendTransaction signAndSend(final LegacyPrivateTransaction rawTransaction) + public EthSendTransaction signAndSend(final RawPrivateTransaction rawTransaction) throws IOException { final String hexValue = sign(rawTransaction); return this.besu.eeaSendRawTransaction(hexValue).send(); } - public PrivateEnclaveKey signAndDistribute(LegacyPrivateTransaction rawTransaction) + public PrivateEnclaveKey signAndDistribute(RawPrivateTransaction rawTransaction) throws IOException { String hexValue = sign(rawTransaction); return this.besu.privDistributeRawTransaction(hexValue).send(); diff --git a/eea/src/main/java/org/web3j/protocol/eea/crypto/PrivateTransactionDecoder.java b/eea/src/main/java/org/web3j/protocol/eea/crypto/PrivateTransactionDecoder.java index 325771cd7..2055c6ede 100644 --- a/eea/src/main/java/org/web3j/protocol/eea/crypto/PrivateTransactionDecoder.java +++ b/eea/src/main/java/org/web3j/protocol/eea/crypto/PrivateTransactionDecoder.java @@ -20,9 +20,9 @@ import org.web3j.crypto.RawTransaction; import org.web3j.crypto.SignedRawTransaction; import org.web3j.crypto.TransactionDecoder; -import org.web3j.protocol.eea.crypto.transaction.type.LegacyPrivateTransaction; import org.web3j.protocol.eea.crypto.transaction.type.PrivateTransaction1559; import org.web3j.protocol.eea.crypto.transaction.type.PrivateTransactionType; +import org.web3j.protocol.eea.crypto.transaction.type.RawPrivateTransaction; import org.web3j.rlp.RlpDecoder; import org.web3j.rlp.RlpList; import org.web3j.rlp.RlpString; @@ -35,7 +35,7 @@ public class PrivateTransactionDecoder { - public static LegacyPrivateTransaction decode(final String hexTransaction) { + public static RawPrivateTransaction decode(final String hexTransaction) { final byte[] transaction = Numeric.hexStringToByteArray(hexTransaction); final PrivateTransactionType transactionType = getPrivateTransactionType(transaction); @@ -53,45 +53,31 @@ private static PrivateTransactionType getPrivateTransactionType(final byte[] tra else return PrivateTransactionType.PRIVATE_LEGACY; } - private static LegacyPrivateTransaction decodePrivateTransaction1559(final byte[] transaction) { + private static RawPrivateTransaction decodePrivateTransaction1559(final byte[] transaction) { final byte[] encodedTx = Arrays.copyOfRange(transaction, 1, transaction.length); final RlpList rlpList = RlpDecoder.decode(encodedTx); final RlpList temp = (RlpList) rlpList.getValues().get(0); final List values = temp.getValues(); - System.out.println(rlpList); - System.out.println(temp); - System.out.println(values); - final long chainId = ((RlpString) temp.getValues().get(0)).asPositiveBigInteger().longValue(); - System.out.println("chainId " + chainId); final BigInteger nonce = ((RlpString) temp.getValues().get(1)).asPositiveBigInteger(); - System.out.println("nonce " + nonce); final BigInteger maxPriorityFeePerGas = ((RlpString) temp.getValues().get(2)).asPositiveBigInteger(); - System.out.println("maxPriorityFeePerGas " + maxPriorityFeePerGas); final BigInteger maxFeePerGas = ((RlpString) temp.getValues().get(3)).asPositiveBigInteger(); - System.out.println("maxFeePerGas " + maxFeePerGas); final BigInteger gasLimit = ((RlpString) temp.getValues().get(4)).asPositiveBigInteger(); - System.out.println("gasLimit " + gasLimit); final String to = ((RlpString) temp.getValues().get(5)).asString(); - System.out.println("to " + to); - final String data = ((RlpString) temp.getValues().get(7)).asString(); - System.out.println("data " + data); final Base64String privateFrom = extractBase64(values.get(8)); - System.out.println("privateFrom " + privateFrom); final Restriction restriction = extractRestriction(values.get(10)); - System.out.println("restriction " + restriction); if (values.get(9) instanceof RlpList) { List privateForList = extractBase64List(values.get(9)); - return new PrivateTransaction1559( + return PrivateTransaction1559.createTransaction( chainId, nonce, gasLimit, @@ -101,11 +87,10 @@ private static LegacyPrivateTransaction decodePrivateTransaction1559(final byte[ maxFeePerGas, privateFrom, privateForList, - null, restriction); } else { Base64String privacyGroupId = extractBase64(values.get(9)); - return new PrivateTransaction1559( + return PrivateTransaction1559.createTransaction( chainId, nonce, gasLimit, @@ -114,14 +99,12 @@ private static LegacyPrivateTransaction decodePrivateTransaction1559(final byte[ maxPriorityFeePerGas, maxFeePerGas, privateFrom, - null, privacyGroupId, restriction); } } - private static LegacyPrivateTransaction decodeLegacyPrivateTransaction( - final byte[] transaction) { + private static RawPrivateTransaction decodeLegacyPrivateTransaction(final byte[] transaction) { final RlpList rlpList = RlpDecoder.decode(transaction); final RlpList temp = (RlpList) rlpList.getValues().get(0); final List values = temp.getValues(); @@ -135,12 +118,26 @@ private static LegacyPrivateTransaction decodeLegacyPrivateTransaction( if (values.get(7) instanceof RlpList) { List privateForList = extractBase64List(values.get(7)); - return new LegacyPrivateTransaction( - rawTransaction, privateFrom, privateForList, null, restriction); + return RawPrivateTransaction.createTransaction( + rawTransaction.getNonce(), + rawTransaction.getGasPrice(), + rawTransaction.getGasLimit(), + rawTransaction.getTo(), + rawTransaction.getData(), + privateFrom, + privateForList, + restriction); } else { Base64String privacyGroupId = extractBase64(values.get(7)); - return new LegacyPrivateTransaction( - rawTransaction, privateFrom, null, privacyGroupId, restriction); + return RawPrivateTransaction.createTransaction( + rawTransaction.getNonce(), + rawTransaction.getGasPrice(), + rawTransaction.getGasLimit(), + rawTransaction.getTo(), + rawTransaction.getData(), + privateFrom, + privacyGroupId, + restriction); } } else { final Base64String privateFrom = extractBase64(values.get(9)); diff --git a/eea/src/main/java/org/web3j/protocol/eea/crypto/PrivateTransactionEncoder.java b/eea/src/main/java/org/web3j/protocol/eea/crypto/PrivateTransactionEncoder.java index 7f8308dad..d3c92267f 100644 --- a/eea/src/main/java/org/web3j/protocol/eea/crypto/PrivateTransactionEncoder.java +++ b/eea/src/main/java/org/web3j/protocol/eea/crypto/PrivateTransactionEncoder.java @@ -18,7 +18,7 @@ import org.web3j.crypto.Credentials; import org.web3j.crypto.Sign; import org.web3j.crypto.TransactionEncoder; -import org.web3j.protocol.eea.crypto.transaction.type.LegacyPrivateTransaction; +import org.web3j.protocol.eea.crypto.transaction.type.RawPrivateTransaction; import org.web3j.rlp.RlpEncoder; import org.web3j.rlp.RlpList; import org.web3j.rlp.RlpType; @@ -27,7 +27,7 @@ public class PrivateTransactionEncoder { public static byte[] signMessage( - final LegacyPrivateTransaction privateTransaction, final Credentials credentials) { + final RawPrivateTransaction privateTransaction, final Credentials credentials) { final byte[] encodedTransaction = encode(privateTransaction); final Sign.SignatureData signatureData = Sign.signMessage(encodedTransaction, credentials.getEcKeyPair()); @@ -36,7 +36,7 @@ public static byte[] signMessage( } public static byte[] signMessage( - final LegacyPrivateTransaction rawTransaction, + final RawPrivateTransaction rawTransaction, final long chainId, final Credentials credentials) { final byte[] encodedTransaction = encode(rawTransaction, chainId); @@ -48,18 +48,18 @@ public static byte[] signMessage( return encode(rawTransaction, eip155SignatureData); } - public static byte[] encode(final LegacyPrivateTransaction rawTransaction) { + public static byte[] encode(final RawPrivateTransaction rawTransaction) { return encode(rawTransaction, null); } - public static byte[] encode(final LegacyPrivateTransaction rawTransaction, final long chainId) { + public static byte[] encode(final RawPrivateTransaction rawTransaction, final long chainId) { final Sign.SignatureData signatureData = new Sign.SignatureData(longToBytes(chainId), new byte[] {}, new byte[] {}); return encode(rawTransaction, signatureData); } private static byte[] encode( - final LegacyPrivateTransaction privateTransaction, + final RawPrivateTransaction privateTransaction, final Sign.SignatureData signatureData) { // final List values = asRlpValues(rawTransaction, signatureData); final List values = privateTransaction.asRlpValues(signatureData); diff --git a/eea/src/main/java/org/web3j/protocol/eea/crypto/PrivateTxSignServiceImpl.java b/eea/src/main/java/org/web3j/protocol/eea/crypto/PrivateTxSignServiceImpl.java index b1f3bcc20..ebd2e6e2f 100644 --- a/eea/src/main/java/org/web3j/protocol/eea/crypto/PrivateTxSignServiceImpl.java +++ b/eea/src/main/java/org/web3j/protocol/eea/crypto/PrivateTxSignServiceImpl.java @@ -14,7 +14,7 @@ import org.web3j.crypto.Credentials; import org.web3j.crypto.RawTransaction; -import org.web3j.protocol.eea.crypto.transaction.type.LegacyPrivateTransaction; +import org.web3j.protocol.eea.crypto.transaction.type.RawPrivateTransaction; import org.web3j.service.TxSignService; import org.web3j.tx.ChainId; @@ -28,7 +28,7 @@ public PrivateTxSignServiceImpl(Credentials credentials) { } public byte[] sign(RawTransaction privateTransaction, long chainId) { - if (!(privateTransaction instanceof LegacyPrivateTransaction)) { + if (!(privateTransaction instanceof RawPrivateTransaction)) { throw new RuntimeException("Can only sign LegacyPrivateTransaction"); } @@ -37,11 +37,11 @@ public byte[] sign(RawTransaction privateTransaction, long chainId) { if (chainId > ChainId.NONE) { signedMessage = PrivateTransactionEncoder.signMessage( - (LegacyPrivateTransaction) privateTransaction, chainId, credentials); + (RawPrivateTransaction) privateTransaction, chainId, credentials); } else { signedMessage = PrivateTransactionEncoder.signMessage( - (LegacyPrivateTransaction) privateTransaction, credentials); + (RawPrivateTransaction) privateTransaction, credentials); } return signedMessage; } diff --git a/eea/src/main/java/org/web3j/protocol/eea/crypto/SignedRawPrivateTransaction.java b/eea/src/main/java/org/web3j/protocol/eea/crypto/SignedRawPrivateTransaction.java index 4ba253b45..39286b2b1 100644 --- a/eea/src/main/java/org/web3j/protocol/eea/crypto/SignedRawPrivateTransaction.java +++ b/eea/src/main/java/org/web3j/protocol/eea/crypto/SignedRawPrivateTransaction.java @@ -18,11 +18,11 @@ import org.web3j.crypto.Sign; import org.web3j.crypto.SignatureDataOperations; import org.web3j.crypto.SignedRawTransaction; -import org.web3j.protocol.eea.crypto.transaction.type.LegacyPrivateTransaction; +import org.web3j.protocol.eea.crypto.transaction.type.RawPrivateTransaction; import org.web3j.utils.Base64String; import org.web3j.utils.Restriction; -public class SignedRawPrivateTransaction extends LegacyPrivateTransaction +public class SignedRawPrivateTransaction extends RawPrivateTransaction implements SignatureDataOperations { private final Sign.SignatureData signatureData; diff --git a/eea/src/main/java/org/web3j/protocol/eea/crypto/transaction/type/PrivateTransaction1559.java b/eea/src/main/java/org/web3j/protocol/eea/crypto/transaction/type/PrivateTransaction1559.java index b5260c865..46145dc19 100644 --- a/eea/src/main/java/org/web3j/protocol/eea/crypto/transaction/type/PrivateTransaction1559.java +++ b/eea/src/main/java/org/web3j/protocol/eea/crypto/transaction/type/PrivateTransaction1559.java @@ -25,13 +25,13 @@ import org.web3j.utils.Numeric; import org.web3j.utils.Restriction; -public class PrivateTransaction1559 extends LegacyPrivateTransaction implements ITransaction { +public class PrivateTransaction1559 extends RawPrivateTransaction implements ITransaction { private long chainId; private BigInteger maxPriorityFeePerGas; private BigInteger maxFeePerGas; - public PrivateTransaction1559( + protected PrivateTransaction1559( long chainId, BigInteger nonce, BigInteger gasLimit, @@ -58,7 +58,84 @@ public PrivateTransaction1559( this.maxFeePerGas = maxFeePerGas; } - public PrivateTransaction1559( + public static PrivateTransaction1559 createContractTransaction( + long chainId, + BigInteger nonce, + BigInteger gasLimit, + String data, + BigInteger maxPriorityFeePerGas, + BigInteger maxFeePerGas, + Base64String privateFrom, + List privateFor, + Base64String privacyGroupId, + Restriction restriction) { + + return new PrivateTransaction1559( + chainId, + nonce, + gasLimit, + null, + data, + maxPriorityFeePerGas, + maxFeePerGas, + privateFrom, + privateFor, + privacyGroupId, + restriction); + } + + public static PrivateTransaction1559 createContractTransaction( + long chainId, + BigInteger nonce, + BigInteger gasLimit, + String data, + BigInteger maxPriorityFeePerGas, + BigInteger maxFeePerGas, + Base64String privateFrom, + Base64String privacyGroupId, + Restriction restriction) { + + return createContractTransaction( + chainId, + nonce, + gasLimit, + data, + maxPriorityFeePerGas, + maxFeePerGas, + privateFrom, + null, + privacyGroupId, + restriction); + } + + public static PrivateTransaction1559 createTransaction( + long chainId, + BigInteger nonce, + BigInteger gasLimit, + String to, + String data, + BigInteger maxPriorityFeePerGas, + BigInteger maxFeePerGas, + Base64String privateFrom, + List privateFor, + Base64String privacyGroupId, + Restriction restriction) { + + return new PrivateTransaction1559( + chainId, + nonce, + gasLimit, + to, + data, + maxPriorityFeePerGas, + maxFeePerGas, + privateFrom, + privateFor, + privacyGroupId, + restriction); + } + + public static PrivateTransaction1559 createTransaction( long chainId, BigInteger nonce, BigInteger gasLimit, @@ -69,7 +146,8 @@ public PrivateTransaction1559( Base64String privateFrom, Base64String privacyGroupId, Restriction restriction) { - this( + + return createTransaction( chainId, nonce, gasLimit, @@ -83,7 +161,7 @@ public PrivateTransaction1559( restriction); } - public PrivateTransaction1559( + public static PrivateTransaction1559 createTransaction( long chainId, BigInteger nonce, BigInteger gasLimit, @@ -94,7 +172,8 @@ public PrivateTransaction1559( Base64String privateFrom, List privateFor, Restriction restriction) { - this( + + return new PrivateTransaction1559( chainId, nonce, gasLimit, diff --git a/eea/src/main/java/org/web3j/protocol/eea/crypto/transaction/type/LegacyPrivateTransaction.java b/eea/src/main/java/org/web3j/protocol/eea/crypto/transaction/type/RawPrivateTransaction.java similarity index 92% rename from eea/src/main/java/org/web3j/protocol/eea/crypto/transaction/type/LegacyPrivateTransaction.java rename to eea/src/main/java/org/web3j/protocol/eea/crypto/transaction/type/RawPrivateTransaction.java index a15edd524..6b2f7fbf1 100644 --- a/eea/src/main/java/org/web3j/protocol/eea/crypto/transaction/type/LegacyPrivateTransaction.java +++ b/eea/src/main/java/org/web3j/protocol/eea/crypto/transaction/type/RawPrivateTransaction.java @@ -28,7 +28,7 @@ import org.web3j.utils.Numeric; import org.web3j.utils.Restriction; -public class LegacyPrivateTransaction extends RawTransaction implements IPrivateTransaction { +public class RawPrivateTransaction extends RawTransaction implements IPrivateTransaction { private final Base64String privateFrom; private final List privateFor; @@ -36,7 +36,7 @@ public class LegacyPrivateTransaction extends RawTransaction implements IPrivate private final Restriction restriction; // Constructor - public LegacyPrivateTransaction( + protected RawPrivateTransaction( BigInteger nonce, BigInteger gasPrice, BigInteger gasLimit, @@ -53,7 +53,7 @@ public LegacyPrivateTransaction( this.restriction = restriction; } - public LegacyPrivateTransaction( + protected RawPrivateTransaction( final RawTransaction rawTransaction, final Base64String privateFrom, final List privateFor, @@ -62,7 +62,7 @@ public LegacyPrivateTransaction( this(rawTransaction.getTransaction(), privateFrom, privateFor, privacyGroupId, restriction); } - protected LegacyPrivateTransaction( + protected RawPrivateTransaction( final ITransaction transaction, final Base64String privateFrom, final List privateFor, @@ -75,7 +75,7 @@ protected LegacyPrivateTransaction( this.restriction = restriction; } - public static LegacyPrivateTransaction createContractTransaction( + public static RawPrivateTransaction createContractTransaction( BigInteger nonce, BigInteger gasPrice, BigInteger gasLimit, @@ -85,7 +85,7 @@ public static LegacyPrivateTransaction createContractTransaction( Base64String privacyGroupId, Restriction restriction) { - return new LegacyPrivateTransaction( + return new RawPrivateTransaction( nonce, gasPrice, gasLimit, @@ -97,7 +97,7 @@ public static LegacyPrivateTransaction createContractTransaction( restriction); } - public static LegacyPrivateTransaction createContractTransaction( + public static RawPrivateTransaction createContractTransaction( BigInteger nonce, BigInteger gasPrice, BigInteger gasLimit, @@ -110,7 +110,7 @@ public static LegacyPrivateTransaction createContractTransaction( nonce, gasPrice, gasLimit, data, privateFrom, null, privacyGroupId, restriction); } - public static LegacyPrivateTransaction createTransaction( + public static RawPrivateTransaction createTransaction( final BigInteger nonce, final BigInteger gasPrice, final BigInteger gasLimit, @@ -121,7 +121,7 @@ public static LegacyPrivateTransaction createTransaction( final Base64String privacyGroupId, final Restriction restriction) { - return new LegacyPrivateTransaction( + return new RawPrivateTransaction( nonce, gasPrice, gasLimit, @@ -133,7 +133,7 @@ public static LegacyPrivateTransaction createTransaction( restriction); } - public static LegacyPrivateTransaction createTransaction( + public static RawPrivateTransaction createTransaction( BigInteger nonce, BigInteger gasPrice, BigInteger gasLimit, @@ -155,7 +155,7 @@ public static LegacyPrivateTransaction createTransaction( restriction); } - public static LegacyPrivateTransaction createTransaction( + public static RawPrivateTransaction createTransaction( BigInteger nonce, BigInteger gasPrice, BigInteger gasLimit, @@ -177,7 +177,7 @@ public static LegacyPrivateTransaction createTransaction( restriction); } - public static LegacyPrivateTransaction createTransaction( + public static RawPrivateTransaction createTransaction( BigInteger nonce, BigInteger gasPrice, BigInteger gasLimit, diff --git a/eea/src/test/java/org/web3j/protocol/eea/crypto/PrivateTransactionDecoderTest.java b/eea/src/test/java/org/web3j/protocol/eea/crypto/PrivateTransactionDecoderTest.java index 7e5cf2853..214ab90f8 100644 --- a/eea/src/test/java/org/web3j/protocol/eea/crypto/PrivateTransactionDecoderTest.java +++ b/eea/src/test/java/org/web3j/protocol/eea/crypto/PrivateTransactionDecoderTest.java @@ -20,8 +20,8 @@ import org.web3j.crypto.Credentials; import org.web3j.crypto.Sign; -import org.web3j.protocol.eea.crypto.transaction.type.LegacyPrivateTransaction; import org.web3j.protocol.eea.crypto.transaction.type.PrivateTransaction1559; +import org.web3j.protocol.eea.crypto.transaction.type.RawPrivateTransaction; import org.web3j.utils.Base64String; import org.web3j.utils.Numeric; @@ -44,8 +44,8 @@ public void testDecoding() { final BigInteger gasPrice = BigInteger.ONE; final BigInteger gasLimit = BigInteger.TEN; final String to = "0x0add5355"; - final LegacyPrivateTransaction rawTransaction = - LegacyPrivateTransaction.createTransaction( + final RawPrivateTransaction rawTransaction = + RawPrivateTransaction.createTransaction( nonce, gasPrice, gasLimit, @@ -57,7 +57,7 @@ public void testDecoding() { byte[] encodedMessage = PrivateTransactionEncoder.encode(rawTransaction); final String hexMessage = Numeric.toHexString(encodedMessage); - final LegacyPrivateTransaction result = PrivateTransactionDecoder.decode(hexMessage); + final RawPrivateTransaction result = PrivateTransactionDecoder.decode(hexMessage); assertNotNull(result); assertEquals(nonce, result.getNonce()); assertEquals(gasPrice, result.getGasPrice()); @@ -79,7 +79,7 @@ public void testDecoding1559() { final String to = "0x0add5355"; final PrivateTransaction1559 privateTx = - new PrivateTransaction1559( + PrivateTransaction1559.createTransaction( chainId, nonce, gasLimit, @@ -89,7 +89,6 @@ public void testDecoding1559() { maxFeePerGas, MOCK_ENCLAVE_KEY, MOCK_PRIVATE_FOR, - null, RESTRICTED); byte[] encodedMessage = PrivateTransactionEncoder.encode(privateTx); @@ -116,8 +115,8 @@ public void testDecodingPrivacyGroup() { final BigInteger gasPrice = BigInteger.ONE; final BigInteger gasLimit = BigInteger.TEN; final String to = "0x0add5355"; - final LegacyPrivateTransaction rawTransaction = - LegacyPrivateTransaction.createTransaction( + final RawPrivateTransaction rawTransaction = + RawPrivateTransaction.createTransaction( nonce, gasPrice, gasLimit, @@ -129,7 +128,7 @@ public void testDecodingPrivacyGroup() { byte[] encodedMessage = PrivateTransactionEncoder.encode(rawTransaction); final String hexMessage = Numeric.toHexString(encodedMessage); - final LegacyPrivateTransaction result = PrivateTransactionDecoder.decode(hexMessage); + final RawPrivateTransaction result = PrivateTransactionDecoder.decode(hexMessage); assertNotNull(result); assertEquals(nonce, result.getNonce()); assertEquals(gasPrice, result.getGasPrice()); @@ -147,8 +146,8 @@ public void testDecodingSigned() throws Exception { final BigInteger gasPrice = BigInteger.ONE; final BigInteger gasLimit = BigInteger.TEN; final String to = "0x0add5355"; - final LegacyPrivateTransaction rawTransaction = - LegacyPrivateTransaction.createTransaction( + final RawPrivateTransaction rawTransaction = + RawPrivateTransaction.createTransaction( nonce, gasPrice, gasLimit, @@ -164,7 +163,7 @@ public void testDecodingSigned() throws Exception { PrivateTransactionEncoder.signMessage(rawTransaction, credentials); final String hexMessage = Numeric.toHexString(encodedMessage); - final LegacyPrivateTransaction result = PrivateTransactionDecoder.decode(hexMessage); + final RawPrivateTransaction result = PrivateTransactionDecoder.decode(hexMessage); assertNotNull(result); assertEquals(nonce, result.getNonce()); assertEquals(gasPrice, result.getGasPrice()); @@ -192,8 +191,8 @@ public void testDecodingSignedPrivacyGroup() throws Exception { final BigInteger gasPrice = BigInteger.ONE; final BigInteger gasLimit = BigInteger.TEN; final String to = "0x0add5355"; - final LegacyPrivateTransaction rawTransaction = - LegacyPrivateTransaction.createTransaction( + final RawPrivateTransaction rawTransaction = + RawPrivateTransaction.createTransaction( nonce, gasPrice, gasLimit, @@ -209,7 +208,7 @@ public void testDecodingSignedPrivacyGroup() throws Exception { PrivateTransactionEncoder.signMessage(rawTransaction, credentials); final String hexMessage = Numeric.toHexString(encodedMessage); - final LegacyPrivateTransaction result = PrivateTransactionDecoder.decode(hexMessage); + final RawPrivateTransaction result = PrivateTransactionDecoder.decode(hexMessage); assertNotNull(result); assertEquals(nonce, result.getNonce()); assertEquals(gasPrice, result.getGasPrice()); @@ -238,8 +237,8 @@ public void testDecodingSignedChainId() throws Exception { final BigInteger gasLimit = BigInteger.TEN; final String to = "0x0add5355"; final long chainId = 2018L; - final LegacyPrivateTransaction rawTransaction = - LegacyPrivateTransaction.createTransaction( + final RawPrivateTransaction rawTransaction = + RawPrivateTransaction.createTransaction( nonce, gasPrice, gasLimit, @@ -255,7 +254,7 @@ public void testDecodingSignedChainId() throws Exception { PrivateTransactionEncoder.signMessage(rawTransaction, chainId, credentials); final String hexMessage = Numeric.toHexString(signedMessage); - final LegacyPrivateTransaction result = PrivateTransactionDecoder.decode(hexMessage); + final RawPrivateTransaction result = PrivateTransactionDecoder.decode(hexMessage); assertNotNull(result); assertEquals(nonce, result.getNonce()); assertEquals(gasPrice, result.getGasPrice()); diff --git a/eea/src/test/java/org/web3j/protocol/eea/crypto/PrivateTransactionEncoderTest.java b/eea/src/test/java/org/web3j/protocol/eea/crypto/PrivateTransactionEncoderTest.java index f57e673d9..f303bcbe7 100644 --- a/eea/src/test/java/org/web3j/protocol/eea/crypto/PrivateTransactionEncoderTest.java +++ b/eea/src/test/java/org/web3j/protocol/eea/crypto/PrivateTransactionEncoderTest.java @@ -19,8 +19,8 @@ import org.junit.jupiter.api.Test; import org.web3j.crypto.Credentials; -import org.web3j.protocol.eea.crypto.transaction.type.LegacyPrivateTransaction; import org.web3j.protocol.eea.crypto.transaction.type.PrivateTransaction1559; +import org.web3j.protocol.eea.crypto.transaction.type.RawPrivateTransaction; import org.web3j.utils.Base64String; import org.web3j.utils.Numeric; @@ -42,8 +42,8 @@ public class PrivateTransactionEncoderTest { public void testSignLegacyTransaction() { final String expected = "0xf8d4808203e8832dc6c094627306090abab3a6e1400e9345bc60c78a8bef578080820fe8a0e0b547d71d7a23d52382288b3a2a5a1610e0b504c404cc5009d7ada97d9015b2a076e997a83856d876fa2397b74510890eea3b73ffeda33daa4188120dac42d62fa0035695b4cc4b0941e60551d7a19cf30603db5bfc23e5ac43a56f57f25f75486af842a0035695b4cc4b0941e60551d7a19cf30603db5bfc23e5ac43a56f57f25f75486aa02a8d9b56a0fe9cd94d60be4413bcb721d3a7be27ed8e28b3a6346df874ee141b8a72657374726963746564"; - final LegacyPrivateTransaction privateTransactionCreation = - new LegacyPrivateTransaction( + final RawPrivateTransaction privateTransactionCreation = + RawPrivateTransaction.createTransaction( BigInteger.ZERO, BigInteger.valueOf(1000), BigInteger.valueOf(3000000), @@ -51,7 +51,6 @@ public void testSignLegacyTransaction() { "0x", MOCK_ENCLAVE_KEY, MOCK_PRIVATE_FOR, - null, RESTRICTED); final long chainId = 2018; final String privateKey = @@ -71,7 +70,7 @@ public void testSign1559Transaction() { "0x01f8d48207e2800101832dc6c094627306090abab3a6e1400e9345bc60c78a8bef57808001a0c0e9d5c7656fdf74a5b5423b20c01663e6c3ee9f855a2371a0bbb07569fafd6ea02543caba35757c6b9401eebfe724c538cb94f817106927fedaa4669ffcbae7efa0035695b4cc4b0941e60551d7a19cf30603db5bfc23e5ac43a56f57f25f75486af842a0035695b4cc4b0941e60551d7a19cf30603db5bfc23e5ac43a56f57f25f75486aa02a8d9b56a0fe9cd94d60be4413bcb721d3a7be27ed8e28b3a6346df874ee141b8a72657374726963746564"; final long chainId = 2018; final PrivateTransaction1559 privateTransactionCreation = - new PrivateTransaction1559( + PrivateTransaction1559.createTransaction( chainId, BigInteger.ZERO, BigInteger.valueOf(3000000), @@ -81,7 +80,6 @@ public void testSign1559Transaction() { BigInteger.ONE, MOCK_ENCLAVE_KEY, MOCK_PRIVATE_FOR, - null, RESTRICTED); final String privateKey = @@ -99,15 +97,14 @@ public void testSign1559Transaction() { public void testSignBesuTransaction() { final String expected = "0xf8b1808203e8832dc6c094627306090abab3a6e1400e9345bc60c78a8bef578080820fe7a060c70c3f989ef5459021142959f8fc1ad6e5fe8542cf238484c6d6b8c8a6dbcca075727642ce691c4bf5ae945523cdd172d44b451ddfe11ae67c376f1e5c7069eea0035695b4cc4b0941e60551d7a19cf30603db5bfc23e5ac43a56f57f25f75486aa00f200e885ff29e973e2576b6600181d1b0a2b5294e30d9be4a1981ffb33a0b8c8a72657374726963746564"; - final LegacyPrivateTransaction privateTransactionCreation = - new LegacyPrivateTransaction( + final RawPrivateTransaction privateTransactionCreation = + RawPrivateTransaction.createTransaction( BigInteger.ZERO, BigInteger.valueOf(1000), BigInteger.valueOf(3000000), "0x627306090abab3a6e1400e9345bc60c78a8bef57", "0x", MOCK_ENCLAVE_KEY, - null, MOCK_PRIVACY_GROUP_ID, RESTRICTED); final long chainId = 2018; diff --git a/integration-tests/src/test/java/org/web3j/protocol/besu/BesuPrivacyQuickstartIntegrationTest.java b/integration-tests/src/test/java/org/web3j/protocol/besu/BesuPrivacyQuickstartIntegrationTest.java index f51edcd9e..06332af24 100644 --- a/integration-tests/src/test/java/org/web3j/protocol/besu/BesuPrivacyQuickstartIntegrationTest.java +++ b/integration-tests/src/test/java/org/web3j/protocol/besu/BesuPrivacyQuickstartIntegrationTest.java @@ -28,7 +28,7 @@ import org.web3j.protocol.besu.response.privacy.PrivateTransactionReceipt; import org.web3j.protocol.besu.response.privacy.PrivateTransactionWithPrivacyGroup; import org.web3j.protocol.eea.crypto.PrivateTransactionEncoder; -import org.web3j.protocol.eea.crypto.transaction.type.LegacyPrivateTransaction; +import org.web3j.protocol.eea.crypto.transaction.type.RawPrivateTransaction; import org.web3j.protocol.http.HttpService; import org.web3j.test.contract.HumanStandardToken; import org.web3j.tx.ChainIdLong; @@ -127,8 +127,8 @@ public void simplePrivateTransactions() throws Exception { .privGetTransactionCount(ALICE.getAddress(), privacyGroupId) .send() .getTransactionCount(); - final LegacyPrivateTransaction rawPrivateTransaction = - LegacyPrivateTransaction.createContractTransaction( + final RawPrivateTransaction rawPrivateTransaction = + RawPrivateTransaction.createContractTransaction( nonce, ZERO_GAS_PROVIDER.getGasPrice(), ZERO_GAS_PROVIDER.getGasLimit(), From b71b19f87576c78df40c7ccb91db616b2e14da8d Mon Sep 17 00:00:00 2001 From: Nischal Sharma Date: Sat, 11 Nov 2023 20:45:49 +0530 Subject: [PATCH 5/7] changed IPrivateTransaction interface logic and removed PrivateTransactionType Signed-off-by: Nischal Sharma --- .../OnChainPrivacyTransactionBuilder.java | 2 +- .../web3j/tx/PrivateTransactionManager.java | 17 +- .../eea/crypto/PrivateTransactionDecoder.java | 31 +- .../eea/crypto/PrivateTransactionEncoder.java | 8 +- .../eea/crypto/PrivateTxSignServiceImpl.java | 1 - .../eea/crypto/RawPrivateTransaction.java | 314 ++++++++++++++++++ .../crypto/SignedRawPrivateTransaction.java | 1 - .../transaction/type/IPrivateTransaction.java | 20 +- ...ion.java => LegacyPrivateTransaction.java} | 100 +++--- .../type/PrivateTransaction1559.java | 55 +-- .../type/PrivateTransactionType.java | 36 -- .../crypto/PrivateTransactionDecoderTest.java | 10 +- .../crypto/PrivateTransactionEncoderTest.java | 12 +- .../BesuPrivacyQuickstartIntegrationTest.java | 2 +- 14 files changed, 444 insertions(+), 165 deletions(-) create mode 100644 eea/src/main/java/org/web3j/protocol/eea/crypto/RawPrivateTransaction.java rename eea/src/main/java/org/web3j/protocol/eea/crypto/transaction/type/{RawPrivateTransaction.java => LegacyPrivateTransaction.java} (79%) delete mode 100644 eea/src/main/java/org/web3j/protocol/eea/crypto/transaction/type/PrivateTransactionType.java diff --git a/besu/src/main/java/org/web3j/protocol/besu/privacy/OnChainPrivacyTransactionBuilder.java b/besu/src/main/java/org/web3j/protocol/besu/privacy/OnChainPrivacyTransactionBuilder.java index 2ba0d7c31..2ad9a89eb 100644 --- a/besu/src/main/java/org/web3j/protocol/besu/privacy/OnChainPrivacyTransactionBuilder.java +++ b/besu/src/main/java/org/web3j/protocol/besu/privacy/OnChainPrivacyTransactionBuilder.java @@ -24,7 +24,7 @@ import org.web3j.abi.datatypes.generated.Bytes32; import org.web3j.crypto.Credentials; import org.web3j.protocol.eea.crypto.PrivateTransactionEncoder; -import org.web3j.protocol.eea.crypto.transaction.type.RawPrivateTransaction; +import org.web3j.protocol.eea.crypto.RawPrivateTransaction; import org.web3j.tx.gas.BesuPrivacyGasProvider; import org.web3j.utils.Base64String; import org.web3j.utils.Numeric; diff --git a/besu/src/main/java/org/web3j/tx/PrivateTransactionManager.java b/besu/src/main/java/org/web3j/tx/PrivateTransactionManager.java index d9530befd..bafcd931c 100644 --- a/besu/src/main/java/org/web3j/tx/PrivateTransactionManager.java +++ b/besu/src/main/java/org/web3j/tx/PrivateTransactionManager.java @@ -25,8 +25,7 @@ import org.web3j.protocol.core.methods.response.EthGetCode; import org.web3j.protocol.core.methods.response.EthSendTransaction; import org.web3j.protocol.eea.crypto.PrivateTxSignServiceImpl; -import org.web3j.protocol.eea.crypto.transaction.type.PrivateTransaction1559; -import org.web3j.protocol.eea.crypto.transaction.type.RawPrivateTransaction; +import org.web3j.protocol.eea.crypto.RawPrivateTransaction; import org.web3j.service.TxSignService; import org.web3j.tx.response.TransactionReceiptProcessor; import org.web3j.utils.Base64String; @@ -184,30 +183,30 @@ public EthSendTransaction sendEIP1559Transaction( .send() .getTransactionCount(); - final PrivateTransaction1559 transaction; + final RawPrivateTransaction transaction; if (privateFor != null) { transaction = - PrivateTransaction1559.createTransaction( + RawPrivateTransaction.createTransaction( chainId, nonce, + maxPriorityFeePerGas, + maxFeePerGas, gasLimit, to, data, - maxPriorityFeePerGas, - maxFeePerGas, privateFrom, privateFor, restriction); } else { transaction = - PrivateTransaction1559.createTransaction( + RawPrivateTransaction.createTransaction( chainId, nonce, + maxPriorityFeePerGas, + maxFeePerGas, gasLimit, to, data, - maxPriorityFeePerGas, - maxFeePerGas, privateFrom, privacyGroupId, restriction); diff --git a/eea/src/main/java/org/web3j/protocol/eea/crypto/PrivateTransactionDecoder.java b/eea/src/main/java/org/web3j/protocol/eea/crypto/PrivateTransactionDecoder.java index 2055c6ede..1a21ec0f1 100644 --- a/eea/src/main/java/org/web3j/protocol/eea/crypto/PrivateTransactionDecoder.java +++ b/eea/src/main/java/org/web3j/protocol/eea/crypto/PrivateTransactionDecoder.java @@ -20,9 +20,7 @@ import org.web3j.crypto.RawTransaction; import org.web3j.crypto.SignedRawTransaction; import org.web3j.crypto.TransactionDecoder; -import org.web3j.protocol.eea.crypto.transaction.type.PrivateTransaction1559; -import org.web3j.protocol.eea.crypto.transaction.type.PrivateTransactionType; -import org.web3j.protocol.eea.crypto.transaction.type.RawPrivateTransaction; +import org.web3j.crypto.transaction.type.TransactionType; import org.web3j.rlp.RlpDecoder; import org.web3j.rlp.RlpList; import org.web3j.rlp.RlpString; @@ -37,20 +35,19 @@ public class PrivateTransactionDecoder { public static RawPrivateTransaction decode(final String hexTransaction) { final byte[] transaction = Numeric.hexStringToByteArray(hexTransaction); - final PrivateTransactionType transactionType = getPrivateTransactionType(transaction); + final TransactionType transactionType = getPrivateTransactionType(transaction); - if (transactionType == PrivateTransactionType.PRIVATE_1559) { + if (transactionType == TransactionType.EIP1559) { return decodePrivateTransaction1559(transaction); } return decodeLegacyPrivateTransaction(transaction); } - private static PrivateTransactionType getPrivateTransactionType(final byte[] transaction) { + private static TransactionType getPrivateTransactionType(final byte[] transaction) { // Determine the type of the private transaction, similar to TransactionDecoder. byte firstByte = transaction[0]; - if (firstByte == PrivateTransactionType.PRIVATE_1559.getRlpType()) - return PrivateTransactionType.PRIVATE_1559; - else return PrivateTransactionType.PRIVATE_LEGACY; + if (firstByte == TransactionType.EIP1559.getRlpType()) return TransactionType.EIP1559; + else return TransactionType.LEGACY; } private static RawPrivateTransaction decodePrivateTransaction1559(final byte[] transaction) { @@ -77,28 +74,30 @@ private static RawPrivateTransaction decodePrivateTransaction1559(final byte[] t if (values.get(9) instanceof RlpList) { List privateForList = extractBase64List(values.get(9)); - return PrivateTransaction1559.createTransaction( + return RawPrivateTransaction.createTransaction( chainId, nonce, + maxPriorityFeePerGas, + maxFeePerGas, gasLimit, to, data, - maxPriorityFeePerGas, - maxFeePerGas, privateFrom, privateForList, + null, restriction); } else { Base64String privacyGroupId = extractBase64(values.get(9)); - return PrivateTransaction1559.createTransaction( + return RawPrivateTransaction.createTransaction( chainId, nonce, + maxPriorityFeePerGas, + maxFeePerGas, gasLimit, to, data, - maxPriorityFeePerGas, - maxFeePerGas, privateFrom, + null, privacyGroupId, restriction); } @@ -126,6 +125,7 @@ private static RawPrivateTransaction decodeLegacyPrivateTransaction(final byte[] rawTransaction.getData(), privateFrom, privateForList, + null, restriction); } else { Base64String privacyGroupId = extractBase64(values.get(7)); @@ -136,6 +136,7 @@ private static RawPrivateTransaction decodeLegacyPrivateTransaction(final byte[] rawTransaction.getTo(), rawTransaction.getData(), privateFrom, + null, privacyGroupId, restriction); } diff --git a/eea/src/main/java/org/web3j/protocol/eea/crypto/PrivateTransactionEncoder.java b/eea/src/main/java/org/web3j/protocol/eea/crypto/PrivateTransactionEncoder.java index d3c92267f..31933d5be 100644 --- a/eea/src/main/java/org/web3j/protocol/eea/crypto/PrivateTransactionEncoder.java +++ b/eea/src/main/java/org/web3j/protocol/eea/crypto/PrivateTransactionEncoder.java @@ -18,7 +18,6 @@ import org.web3j.crypto.Credentials; import org.web3j.crypto.Sign; import org.web3j.crypto.TransactionEncoder; -import org.web3j.protocol.eea.crypto.transaction.type.RawPrivateTransaction; import org.web3j.rlp.RlpEncoder; import org.web3j.rlp.RlpList; import org.web3j.rlp.RlpType; @@ -62,13 +61,14 @@ private static byte[] encode( final RawPrivateTransaction privateTransaction, final Sign.SignatureData signatureData) { // final List values = asRlpValues(rawTransaction, signatureData); - final List values = privateTransaction.asRlpValues(signatureData); + final List values = + privateTransaction.getPrivateTransaction().asRlpValues(signatureData); final RlpList rlpList = new RlpList(values); byte[] encoded = RlpEncoder.encode(rlpList); - if (privateTransaction.getTransactionType().isPrivateEip1559()) { + if (privateTransaction.getType().isEip1559()) { return ByteBuffer.allocate(encoded.length + 1) - .put(privateTransaction.getTransactionType().getRlpType()) + .put(privateTransaction.getType().getRlpType()) .put(encoded) .array(); } diff --git a/eea/src/main/java/org/web3j/protocol/eea/crypto/PrivateTxSignServiceImpl.java b/eea/src/main/java/org/web3j/protocol/eea/crypto/PrivateTxSignServiceImpl.java index ebd2e6e2f..a8ea3230b 100644 --- a/eea/src/main/java/org/web3j/protocol/eea/crypto/PrivateTxSignServiceImpl.java +++ b/eea/src/main/java/org/web3j/protocol/eea/crypto/PrivateTxSignServiceImpl.java @@ -14,7 +14,6 @@ import org.web3j.crypto.Credentials; import org.web3j.crypto.RawTransaction; -import org.web3j.protocol.eea.crypto.transaction.type.RawPrivateTransaction; import org.web3j.service.TxSignService; import org.web3j.tx.ChainId; diff --git a/eea/src/main/java/org/web3j/protocol/eea/crypto/RawPrivateTransaction.java b/eea/src/main/java/org/web3j/protocol/eea/crypto/RawPrivateTransaction.java new file mode 100644 index 000000000..6e52b2f4b --- /dev/null +++ b/eea/src/main/java/org/web3j/protocol/eea/crypto/RawPrivateTransaction.java @@ -0,0 +1,314 @@ +/* + * Copyright 2019 Web3 Labs Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ +package org.web3j.protocol.eea.crypto; + +import java.math.BigInteger; +import java.util.List; +import java.util.Optional; + +import org.web3j.crypto.RawTransaction; +import org.web3j.protocol.eea.crypto.transaction.type.IPrivateTransaction; +import org.web3j.protocol.eea.crypto.transaction.type.LegacyPrivateTransaction; +import org.web3j.protocol.eea.crypto.transaction.type.PrivateTransaction1559; +import org.web3j.utils.Base64String; +import org.web3j.utils.Restriction; + +/** + * Transaction class used for signing transactions locally.
+ * For the specification, refer to p4 of the yellow + * paper. + */ +public class RawPrivateTransaction extends RawTransaction { + + private final IPrivateTransaction privateTransaction; + + protected RawPrivateTransaction(final IPrivateTransaction privateTransaction) { + super(privateTransaction); + this.privateTransaction = privateTransaction; + } + + protected RawPrivateTransaction( + final BigInteger nonce, + final BigInteger gasPrice, + final BigInteger gasLimit, + final String to, + final String data, + final Base64String privateFrom, + final List privateFor, + final Base64String privacyGroupId, + final Restriction restriction) { + this( + new LegacyPrivateTransaction( + nonce, + gasPrice, + gasLimit, + to, + data, + privateFrom, + privateFor, + privacyGroupId, + restriction)); + } + + protected RawPrivateTransaction( + final long chainId, + final BigInteger nonce, + final BigInteger maxPriorityFeePerGas, + final BigInteger maxFeePerGas, + final BigInteger gasLimit, + final String to, + final String data, + final Base64String privateFrom, + final List privateFor, + final Base64String privacyGroupId, + final Restriction restriction) { + this( + new PrivateTransaction1559( + chainId, + nonce, + maxPriorityFeePerGas, + maxFeePerGas, + gasLimit, + to, + data, + privateFrom, + privateFor, + privacyGroupId, + restriction)); + } + + public static RawPrivateTransaction createContractTransaction( + final BigInteger nonce, + final BigInteger gasPrice, + final BigInteger gasLimit, + final String data, + final Base64String privateFrom, + final List privateFor, + final Base64String privacyGroupId, + final Restriction restriction) { + + return new RawPrivateTransaction( + LegacyPrivateTransaction.createContractTransaction( + nonce, + gasPrice, + gasLimit, + data, + privateFrom, + privateFor, + privacyGroupId, + restriction)); + } + + public static RawPrivateTransaction createContractTransaction( + final BigInteger nonce, + final BigInteger gasPrice, + final BigInteger gasLimit, + final String data, + final Base64String privateFrom, + final Base64String privacyGroupId, + final Restriction restriction) { + + return new RawPrivateTransaction( + LegacyPrivateTransaction.createContractTransaction( + nonce, gasPrice, gasLimit, data, privateFrom, privacyGroupId, restriction)); + } + + public static RawPrivateTransaction createContractTransaction( + long chainId, + BigInteger nonce, + BigInteger maxPriorityFeePerGas, + BigInteger maxFeePerGas, + final BigInteger gasLimit, + final String data, + final Base64String privateFrom, + final List privateFor, + final Base64String privacyGroupId, + final Restriction restriction) { + + return new RawPrivateTransaction( + PrivateTransaction1559.createContractTransaction( + chainId, + nonce, + maxPriorityFeePerGas, + maxFeePerGas, + gasLimit, + data, + privateFrom, + privateFor, + privacyGroupId, + restriction)); + } + + public static RawPrivateTransaction createTransaction( + final BigInteger nonce, + final BigInteger gasPrice, + final BigInteger gasLimit, + final String to, + final String data, + final Base64String privateFrom, + final List privateFor, + final Base64String privacyGroupId, + final Restriction restriction) { + + return new RawPrivateTransaction( + LegacyPrivateTransaction.createTransaction( + nonce, + gasPrice, + gasLimit, + to, + data, + privateFrom, + privateFor, + privacyGroupId, + restriction)); + } + + public static RawPrivateTransaction createTransaction( + final BigInteger nonce, + final BigInteger gasPrice, + final BigInteger gasLimit, + final String to, + final String data, + final Base64String privateFrom, + final Base64String privacyGroupId, + final Restriction restriction) { + + return new RawPrivateTransaction( + LegacyPrivateTransaction.createTransaction( + nonce, + gasPrice, + gasLimit, + to, + data, + privateFrom, + privacyGroupId, + restriction)); + } + + public static RawPrivateTransaction createTransaction( + final BigInteger nonce, + final BigInteger gasPrice, + final BigInteger gasLimit, + final String to, + final String data, + final Base64String privateFrom, + final List privateFor, + final Restriction restriction) { + + return new RawPrivateTransaction( + LegacyPrivateTransaction.createTransaction( + nonce, gasPrice, gasLimit, to, data, privateFrom, privateFor, restriction)); + } + + public static RawPrivateTransaction createTransaction( + long chainId, + BigInteger nonce, + BigInteger maxPriorityFeePerGas, + BigInteger maxFeePerGas, + BigInteger gasLimit, + String to, + String data, + Base64String privateFrom, + List privateFor, + Base64String privacyGroupId, + Restriction restriction) { + + return new RawPrivateTransaction( + PrivateTransaction1559.createTransaction( + chainId, + nonce, + maxPriorityFeePerGas, + maxFeePerGas, + gasLimit, + to, + data, + privateFrom, + privateFor, + privacyGroupId, + restriction)); + } + + public static RawPrivateTransaction createTransaction( + long chainId, + BigInteger nonce, + BigInteger maxPriorityFeePerGas, + BigInteger maxFeePerGas, + BigInteger gasLimit, + String to, + String data, + Base64String privateFrom, + Base64String privacyGroupId, + Restriction restriction) { + + return new RawPrivateTransaction( + PrivateTransaction1559.createTransaction( + chainId, + nonce, + maxPriorityFeePerGas, + maxFeePerGas, + gasLimit, + to, + data, + privateFrom, + null, + privacyGroupId, + restriction)); + } + + public static RawPrivateTransaction createTransaction( + long chainId, + BigInteger nonce, + BigInteger maxPriorityFeePerGas, + BigInteger maxFeePerGas, + BigInteger gasLimit, + String to, + String data, + Base64String privateFrom, + List privateFor, + Restriction restriction) { + + return new RawPrivateTransaction( + PrivateTransaction1559.createTransaction( + chainId, + nonce, + maxPriorityFeePerGas, + maxFeePerGas, + gasLimit, + to, + data, + privateFrom, + privateFor, + null, + restriction)); + } + + public Base64String getPrivateFrom() { + return privateTransaction.getPrivateFrom(); + } + + public Optional> getPrivateFor() { + return privateTransaction.getPrivateFor(); + } + + public Optional getPrivacyGroupId() { + return privateTransaction.getPrivacyGroupId(); + } + + public Restriction getRestriction() { + return privateTransaction.getRestriction(); + } + + public IPrivateTransaction getPrivateTransaction() { + return privateTransaction; + } +} diff --git a/eea/src/main/java/org/web3j/protocol/eea/crypto/SignedRawPrivateTransaction.java b/eea/src/main/java/org/web3j/protocol/eea/crypto/SignedRawPrivateTransaction.java index 39286b2b1..109455933 100644 --- a/eea/src/main/java/org/web3j/protocol/eea/crypto/SignedRawPrivateTransaction.java +++ b/eea/src/main/java/org/web3j/protocol/eea/crypto/SignedRawPrivateTransaction.java @@ -18,7 +18,6 @@ import org.web3j.crypto.Sign; import org.web3j.crypto.SignatureDataOperations; import org.web3j.crypto.SignedRawTransaction; -import org.web3j.protocol.eea.crypto.transaction.type.RawPrivateTransaction; import org.web3j.utils.Base64String; import org.web3j.utils.Restriction; diff --git a/eea/src/main/java/org/web3j/protocol/eea/crypto/transaction/type/IPrivateTransaction.java b/eea/src/main/java/org/web3j/protocol/eea/crypto/transaction/type/IPrivateTransaction.java index 70eeda626..662abb8a0 100644 --- a/eea/src/main/java/org/web3j/protocol/eea/crypto/transaction/type/IPrivateTransaction.java +++ b/eea/src/main/java/org/web3j/protocol/eea/crypto/transaction/type/IPrivateTransaction.java @@ -12,26 +12,14 @@ */ package org.web3j.protocol.eea.crypto.transaction.type; -import java.math.BigInteger; import java.util.List; import java.util.Optional; -import org.web3j.crypto.Sign; -import org.web3j.rlp.RlpType; +import org.web3j.crypto.transaction.type.ITransaction; import org.web3j.utils.Base64String; import org.web3j.utils.Restriction; -public interface IPrivateTransaction { - - BigInteger getNonce(); - - BigInteger getGasPrice(); - - BigInteger getGasLimit(); - - String getTo(); - - String getData(); +public interface IPrivateTransaction extends ITransaction { Base64String getPrivateFrom(); @@ -40,8 +28,4 @@ public interface IPrivateTransaction { Optional getPrivacyGroupId(); Restriction getRestriction(); - - List asRlpValues(Sign.SignatureData signatureData); - - PrivateTransactionType getTransactionType(); } diff --git a/eea/src/main/java/org/web3j/protocol/eea/crypto/transaction/type/RawPrivateTransaction.java b/eea/src/main/java/org/web3j/protocol/eea/crypto/transaction/type/LegacyPrivateTransaction.java similarity index 79% rename from eea/src/main/java/org/web3j/protocol/eea/crypto/transaction/type/RawPrivateTransaction.java rename to eea/src/main/java/org/web3j/protocol/eea/crypto/transaction/type/LegacyPrivateTransaction.java index 6b2f7fbf1..374e1fea4 100644 --- a/eea/src/main/java/org/web3j/protocol/eea/crypto/transaction/type/RawPrivateTransaction.java +++ b/eea/src/main/java/org/web3j/protocol/eea/crypto/transaction/type/LegacyPrivateTransaction.java @@ -17,10 +17,8 @@ import java.util.List; import java.util.Optional; -import org.web3j.crypto.RawTransaction; import org.web3j.crypto.Sign; -import org.web3j.crypto.transaction.type.ITransaction; -import org.web3j.crypto.transaction.type.LegacyTransaction; +import org.web3j.crypto.transaction.type.TransactionType; import org.web3j.rlp.RlpString; import org.web3j.rlp.RlpType; import org.web3j.utils.Base64String; @@ -28,15 +26,20 @@ import org.web3j.utils.Numeric; import org.web3j.utils.Restriction; -public class RawPrivateTransaction extends RawTransaction implements IPrivateTransaction { +public class LegacyPrivateTransaction implements IPrivateTransaction { + private final TransactionType transactionType; + private final BigInteger nonce; + private final BigInteger gasPrice; + private final BigInteger gasLimit; + private final String to; + private final String data; private final Base64String privateFrom; private final List privateFor; private final Base64String privacyGroupId; private final Restriction restriction; - // Constructor - protected RawPrivateTransaction( + public LegacyPrivateTransaction( BigInteger nonce, BigInteger gasPrice, BigInteger gasLimit, @@ -46,36 +49,19 @@ protected RawPrivateTransaction( List privateFor, Base64String privacyGroupId, Restriction restriction) { - super(new LegacyTransaction(nonce, gasPrice, gasLimit, to, BigInteger.ZERO, data)); + this.transactionType = TransactionType.LEGACY; + this.nonce = nonce; + this.gasPrice = gasPrice; + this.gasLimit = gasLimit; + this.to = to; + this.data = data; this.privateFrom = privateFrom; this.privateFor = privateFor; this.privacyGroupId = privacyGroupId; this.restriction = restriction; } - protected RawPrivateTransaction( - final RawTransaction rawTransaction, - final Base64String privateFrom, - final List privateFor, - final Base64String privacyGroupId, - final Restriction restriction) { - this(rawTransaction.getTransaction(), privateFrom, privateFor, privacyGroupId, restriction); - } - - protected RawPrivateTransaction( - final ITransaction transaction, - final Base64String privateFrom, - final List privateFor, - final Base64String privacyGroupId, - final Restriction restriction) { - super(transaction); - this.privateFrom = privateFrom; - this.privateFor = privateFor; - this.privacyGroupId = privacyGroupId; - this.restriction = restriction; - } - - public static RawPrivateTransaction createContractTransaction( + public static LegacyPrivateTransaction createContractTransaction( BigInteger nonce, BigInteger gasPrice, BigInteger gasLimit, @@ -85,7 +71,7 @@ public static RawPrivateTransaction createContractTransaction( Base64String privacyGroupId, Restriction restriction) { - return new RawPrivateTransaction( + return new LegacyPrivateTransaction( nonce, gasPrice, gasLimit, @@ -97,7 +83,7 @@ public static RawPrivateTransaction createContractTransaction( restriction); } - public static RawPrivateTransaction createContractTransaction( + public static LegacyPrivateTransaction createContractTransaction( BigInteger nonce, BigInteger gasPrice, BigInteger gasLimit, @@ -110,7 +96,7 @@ public static RawPrivateTransaction createContractTransaction( nonce, gasPrice, gasLimit, data, privateFrom, null, privacyGroupId, restriction); } - public static RawPrivateTransaction createTransaction( + public static LegacyPrivateTransaction createTransaction( final BigInteger nonce, final BigInteger gasPrice, final BigInteger gasLimit, @@ -121,7 +107,7 @@ public static RawPrivateTransaction createTransaction( final Base64String privacyGroupId, final Restriction restriction) { - return new RawPrivateTransaction( + return new LegacyPrivateTransaction( nonce, gasPrice, gasLimit, @@ -133,7 +119,7 @@ public static RawPrivateTransaction createTransaction( restriction); } - public static RawPrivateTransaction createTransaction( + public static LegacyPrivateTransaction createTransaction( BigInteger nonce, BigInteger gasPrice, BigInteger gasLimit, @@ -155,7 +141,7 @@ public static RawPrivateTransaction createTransaction( restriction); } - public static RawPrivateTransaction createTransaction( + public static LegacyPrivateTransaction createTransaction( BigInteger nonce, BigInteger gasPrice, BigInteger gasLimit, @@ -177,7 +163,7 @@ public static RawPrivateTransaction createTransaction( restriction); } - public static RawPrivateTransaction createTransaction( + public static LegacyPrivateTransaction createTransaction( BigInteger nonce, BigInteger gasPrice, BigInteger gasLimit, @@ -235,6 +221,41 @@ public List asRlpValues(final Sign.SignatureData signatureData) { return result; } + @Override + public BigInteger getNonce() { + return nonce; + } + + @Override + public BigInteger getGasPrice() { + return gasPrice; + } + + @Override + public BigInteger getGasLimit() { + return gasLimit; + } + + @Override + public String getTo() { + return to; + } + + @Override + public BigInteger getValue() { + return BigInteger.ZERO; + } + + @Override + public String getData() { + return data; + } + + @Override + public TransactionType getType() { + return transactionType; + } + @Override public Base64String getPrivateFrom() { return privateFrom; @@ -254,9 +275,4 @@ public Optional getPrivacyGroupId() { public Restriction getRestriction() { return restriction; } - - @Override - public PrivateTransactionType getTransactionType() { - return PrivateTransactionType.PRIVATE_LEGACY; - } } diff --git a/eea/src/main/java/org/web3j/protocol/eea/crypto/transaction/type/PrivateTransaction1559.java b/eea/src/main/java/org/web3j/protocol/eea/crypto/transaction/type/PrivateTransaction1559.java index 46145dc19..32dc1a1de 100644 --- a/eea/src/main/java/org/web3j/protocol/eea/crypto/transaction/type/PrivateTransaction1559.java +++ b/eea/src/main/java/org/web3j/protocol/eea/crypto/transaction/type/PrivateTransaction1559.java @@ -17,7 +17,7 @@ import java.util.List; import org.web3j.crypto.Sign; -import org.web3j.crypto.transaction.type.ITransaction; +import org.web3j.crypto.transaction.type.TransactionType; import org.web3j.rlp.RlpString; import org.web3j.rlp.RlpType; import org.web3j.utils.Base64String; @@ -25,20 +25,22 @@ import org.web3j.utils.Numeric; import org.web3j.utils.Restriction; -public class PrivateTransaction1559 extends RawPrivateTransaction implements ITransaction { +public class PrivateTransaction1559 extends LegacyPrivateTransaction + implements IPrivateTransaction { - private long chainId; - private BigInteger maxPriorityFeePerGas; - private BigInteger maxFeePerGas; + private final TransactionType transactionType; + private final long chainId; + private final BigInteger maxPriorityFeePerGas; + private final BigInteger maxFeePerGas; - protected PrivateTransaction1559( + public PrivateTransaction1559( long chainId, BigInteger nonce, + BigInteger maxPriorityFeePerGas, + BigInteger maxFeePerGas, BigInteger gasLimit, String to, String data, - BigInteger maxPriorityFeePerGas, - BigInteger maxFeePerGas, Base64String privateFrom, List privateFor, Base64String privacyGroupId, @@ -53,6 +55,7 @@ protected PrivateTransaction1559( privateFor, privacyGroupId, restriction); + this.transactionType = TransactionType.EIP1559; this.chainId = chainId; this.maxPriorityFeePerGas = maxPriorityFeePerGas; this.maxFeePerGas = maxFeePerGas; @@ -61,10 +64,10 @@ protected PrivateTransaction1559( public static PrivateTransaction1559 createContractTransaction( long chainId, BigInteger nonce, - BigInteger gasLimit, - String data, BigInteger maxPriorityFeePerGas, BigInteger maxFeePerGas, + BigInteger gasLimit, + String data, Base64String privateFrom, List privateFor, Base64String privacyGroupId, @@ -73,11 +76,11 @@ public static PrivateTransaction1559 createContractTransaction( return new PrivateTransaction1559( chainId, nonce, + maxPriorityFeePerGas, + maxFeePerGas, gasLimit, null, data, - maxPriorityFeePerGas, - maxFeePerGas, privateFrom, privateFor, privacyGroupId, @@ -87,10 +90,10 @@ public static PrivateTransaction1559 createContractTransaction( public static PrivateTransaction1559 createContractTransaction( long chainId, BigInteger nonce, - BigInteger gasLimit, - String data, BigInteger maxPriorityFeePerGas, BigInteger maxFeePerGas, + BigInteger gasLimit, + String data, Base64String privateFrom, Base64String privacyGroupId, Restriction restriction) { @@ -98,10 +101,10 @@ public static PrivateTransaction1559 createContractTransaction( return createContractTransaction( chainId, nonce, - gasLimit, - data, maxPriorityFeePerGas, maxFeePerGas, + gasLimit, + data, privateFrom, null, privacyGroupId, @@ -111,11 +114,11 @@ public static PrivateTransaction1559 createContractTransaction( public static PrivateTransaction1559 createTransaction( long chainId, BigInteger nonce, + BigInteger maxPriorityFeePerGas, + BigInteger maxFeePerGas, BigInteger gasLimit, String to, String data, - BigInteger maxPriorityFeePerGas, - BigInteger maxFeePerGas, Base64String privateFrom, List privateFor, Base64String privacyGroupId, @@ -124,11 +127,11 @@ public static PrivateTransaction1559 createTransaction( return new PrivateTransaction1559( chainId, nonce, + maxPriorityFeePerGas, + maxFeePerGas, gasLimit, to, data, - maxPriorityFeePerGas, - maxFeePerGas, privateFrom, privateFor, privacyGroupId, @@ -150,11 +153,11 @@ public static PrivateTransaction1559 createTransaction( return createTransaction( chainId, nonce, + maxPriorityFeePerGas, + maxFeePerGas, gasLimit, to, data, - maxPriorityFeePerGas, - maxFeePerGas, privateFrom, null, privacyGroupId, @@ -176,11 +179,11 @@ public static PrivateTransaction1559 createTransaction( return new PrivateTransaction1559( chainId, nonce, + maxPriorityFeePerGas, + maxFeePerGas, gasLimit, to, data, - maxPriorityFeePerGas, - maxFeePerGas, privateFrom, privateFor, null, @@ -254,7 +257,7 @@ public BigInteger getMaxFeePerGas() { } @Override - public PrivateTransactionType getTransactionType() { - return PrivateTransactionType.PRIVATE_1559; + public TransactionType getType() { + return transactionType; } } diff --git a/eea/src/main/java/org/web3j/protocol/eea/crypto/transaction/type/PrivateTransactionType.java b/eea/src/main/java/org/web3j/protocol/eea/crypto/transaction/type/PrivateTransactionType.java deleted file mode 100644 index 0f70d74de..000000000 --- a/eea/src/main/java/org/web3j/protocol/eea/crypto/transaction/type/PrivateTransactionType.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright 2023 Web3 Labs Ltd. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ -package org.web3j.protocol.eea.crypto.transaction.type; - -public enum PrivateTransactionType { - PRIVATE_LEGACY(null), - PRIVATE_1559(((byte) 0x01)); - - Byte type; - - PrivateTransactionType(final Byte type) { - this.type = type; - } - - public Byte getRlpType() { - return type; - } - - public boolean isPrivateLegacy() { - return this.equals(PrivateTransactionType.PRIVATE_LEGACY); - } - - public boolean isPrivateEip1559() { - return this.equals(PrivateTransactionType.PRIVATE_1559); - } -} diff --git a/eea/src/test/java/org/web3j/protocol/eea/crypto/PrivateTransactionDecoderTest.java b/eea/src/test/java/org/web3j/protocol/eea/crypto/PrivateTransactionDecoderTest.java index 214ab90f8..3c5d35f0b 100644 --- a/eea/src/test/java/org/web3j/protocol/eea/crypto/PrivateTransactionDecoderTest.java +++ b/eea/src/test/java/org/web3j/protocol/eea/crypto/PrivateTransactionDecoderTest.java @@ -21,7 +21,6 @@ import org.web3j.crypto.Credentials; import org.web3j.crypto.Sign; import org.web3j.protocol.eea.crypto.transaction.type.PrivateTransaction1559; -import org.web3j.protocol.eea.crypto.transaction.type.RawPrivateTransaction; import org.web3j.utils.Base64String; import org.web3j.utils.Numeric; @@ -53,6 +52,7 @@ public void testDecoding() { "", MOCK_ENCLAVE_KEY, MOCK_PRIVATE_FOR, + null, RESTRICTED); byte[] encodedMessage = PrivateTransactionEncoder.encode(rawTransaction); final String hexMessage = Numeric.toHexString(encodedMessage); @@ -91,11 +91,13 @@ public void testDecoding1559() { MOCK_PRIVATE_FOR, RESTRICTED); - byte[] encodedMessage = PrivateTransactionEncoder.encode(privateTx); + byte[] encodedMessage = + PrivateTransactionEncoder.encode(new RawPrivateTransaction(privateTx)); final String hexMessage = Numeric.toHexString(encodedMessage); final PrivateTransaction1559 result = - (PrivateTransaction1559) PrivateTransactionDecoder.decode(hexMessage); + (PrivateTransaction1559) + PrivateTransactionDecoder.decode(hexMessage).getPrivateTransaction(); assertNotNull(result); assertEquals(nonce, result.getNonce()); assertEquals(chainId, result.getChainId()); @@ -103,7 +105,7 @@ public void testDecoding1559() { assertEquals(maxFeePerGas, result.getMaxFeePerGas()); assertEquals(gasLimit, result.getGasLimit()); assertEquals(to, result.getTo()); - assertEquals("", result.getData()); + assertEquals("0x", result.getData()); assertEquals(MOCK_ENCLAVE_KEY, result.getPrivateFrom()); assertEquals(MOCK_PRIVATE_FOR, result.getPrivateFor().get()); assertEquals(RESTRICTED, result.getRestriction()); diff --git a/eea/src/test/java/org/web3j/protocol/eea/crypto/PrivateTransactionEncoderTest.java b/eea/src/test/java/org/web3j/protocol/eea/crypto/PrivateTransactionEncoderTest.java index f303bcbe7..9568a7690 100644 --- a/eea/src/test/java/org/web3j/protocol/eea/crypto/PrivateTransactionEncoderTest.java +++ b/eea/src/test/java/org/web3j/protocol/eea/crypto/PrivateTransactionEncoderTest.java @@ -19,8 +19,6 @@ import org.junit.jupiter.api.Test; import org.web3j.crypto.Credentials; -import org.web3j.protocol.eea.crypto.transaction.type.PrivateTransaction1559; -import org.web3j.protocol.eea.crypto.transaction.type.RawPrivateTransaction; import org.web3j.utils.Base64String; import org.web3j.utils.Numeric; @@ -67,17 +65,17 @@ public void testSignLegacyTransaction() { @Test public void testSign1559Transaction() { final String expected = - "0x01f8d48207e2800101832dc6c094627306090abab3a6e1400e9345bc60c78a8bef57808001a0c0e9d5c7656fdf74a5b5423b20c01663e6c3ee9f855a2371a0bbb07569fafd6ea02543caba35757c6b9401eebfe724c538cb94f817106927fedaa4669ffcbae7efa0035695b4cc4b0941e60551d7a19cf30603db5bfc23e5ac43a56f57f25f75486af842a0035695b4cc4b0941e60551d7a19cf30603db5bfc23e5ac43a56f57f25f75486aa02a8d9b56a0fe9cd94d60be4413bcb721d3a7be27ed8e28b3a6346df874ee141b8a72657374726963746564"; + "0x02f8d48207e2800101832dc6c094627306090abab3a6e1400e9345bc60c78a8bef57808001a0c4b5ae238eaa5cb154788d675ff61946e6886bfcc007591042d6a7daf14cbd6fa047f417ac1923e7e6adc77b3384dc1dd3bdf9208e4f1e5436775d56e5f595e249a0035695b4cc4b0941e60551d7a19cf30603db5bfc23e5ac43a56f57f25f75486af842a0035695b4cc4b0941e60551d7a19cf30603db5bfc23e5ac43a56f57f25f75486aa02a8d9b56a0fe9cd94d60be4413bcb721d3a7be27ed8e28b3a6346df874ee141b8a72657374726963746564"; final long chainId = 2018; - final PrivateTransaction1559 privateTransactionCreation = - PrivateTransaction1559.createTransaction( + final RawPrivateTransaction privateTransactionCreation = + RawPrivateTransaction.createTransaction( chainId, BigInteger.ZERO, + BigInteger.ONE, + BigInteger.ONE, BigInteger.valueOf(3000000), "0x627306090abab3a6e1400e9345bc60c78a8bef57", "0x", - BigInteger.ONE, - BigInteger.ONE, MOCK_ENCLAVE_KEY, MOCK_PRIVATE_FOR, RESTRICTED); diff --git a/integration-tests/src/test/java/org/web3j/protocol/besu/BesuPrivacyQuickstartIntegrationTest.java b/integration-tests/src/test/java/org/web3j/protocol/besu/BesuPrivacyQuickstartIntegrationTest.java index 06332af24..3ee4cc1b6 100644 --- a/integration-tests/src/test/java/org/web3j/protocol/besu/BesuPrivacyQuickstartIntegrationTest.java +++ b/integration-tests/src/test/java/org/web3j/protocol/besu/BesuPrivacyQuickstartIntegrationTest.java @@ -28,7 +28,7 @@ import org.web3j.protocol.besu.response.privacy.PrivateTransactionReceipt; import org.web3j.protocol.besu.response.privacy.PrivateTransactionWithPrivacyGroup; import org.web3j.protocol.eea.crypto.PrivateTransactionEncoder; -import org.web3j.protocol.eea.crypto.transaction.type.RawPrivateTransaction; +import org.web3j.protocol.eea.crypto.RawPrivateTransaction; import org.web3j.protocol.http.HttpService; import org.web3j.test.contract.HumanStandardToken; import org.web3j.tx.ChainIdLong; From 3cfcc7a1f9105d4c1674a6d6ab23c3b4216aa6cc Mon Sep 17 00:00:00 2001 From: Nischal Sharma Date: Sat, 11 Nov 2023 21:40:47 +0530 Subject: [PATCH 6/7] removed a comment Signed-off-by: Nischal Sharma --- .../org/web3j/protocol/eea/crypto/PrivateTransactionEncoder.java | 1 - 1 file changed, 1 deletion(-) diff --git a/eea/src/main/java/org/web3j/protocol/eea/crypto/PrivateTransactionEncoder.java b/eea/src/main/java/org/web3j/protocol/eea/crypto/PrivateTransactionEncoder.java index 31933d5be..f39951bd3 100644 --- a/eea/src/main/java/org/web3j/protocol/eea/crypto/PrivateTransactionEncoder.java +++ b/eea/src/main/java/org/web3j/protocol/eea/crypto/PrivateTransactionEncoder.java @@ -60,7 +60,6 @@ public static byte[] encode(final RawPrivateTransaction rawTransaction, final lo private static byte[] encode( final RawPrivateTransaction privateTransaction, final Sign.SignatureData signatureData) { - // final List values = asRlpValues(rawTransaction, signatureData); final List values = privateTransaction.getPrivateTransaction().asRlpValues(signatureData); final RlpList rlpList = new RlpList(values); From c254a72e5f0b1a547c52725589ea1ce5821c488f Mon Sep 17 00:00:00 2001 From: Nischal Sharma Date: Wed, 22 Nov 2023 11:25:28 +0530 Subject: [PATCH 7/7] added EIP1559 signed tx decoding --- .../eea/crypto/PrivateTransactionDecoder.java | 109 +++++++++++++----- .../crypto/SignedRawPrivateTransaction.java | 28 +++++ .../crypto/PrivateTransactionDecoderTest.java | 56 +++++++++ 3 files changed, 163 insertions(+), 30 deletions(-) diff --git a/eea/src/main/java/org/web3j/protocol/eea/crypto/PrivateTransactionDecoder.java b/eea/src/main/java/org/web3j/protocol/eea/crypto/PrivateTransactionDecoder.java index 1a21ec0f1..36167ab06 100644 --- a/eea/src/main/java/org/web3j/protocol/eea/crypto/PrivateTransactionDecoder.java +++ b/eea/src/main/java/org/web3j/protocol/eea/crypto/PrivateTransactionDecoder.java @@ -18,6 +18,7 @@ import java.util.stream.Collectors; import org.web3j.crypto.RawTransaction; +import org.web3j.crypto.Sign; import org.web3j.crypto.SignedRawTransaction; import org.web3j.crypto.TransactionDecoder; import org.web3j.crypto.transaction.type.TransactionType; @@ -69,37 +70,85 @@ private static RawPrivateTransaction decodePrivateTransaction1559(final byte[] t final String to = ((RlpString) temp.getValues().get(5)).asString(); final String data = ((RlpString) temp.getValues().get(7)).asString(); - final Base64String privateFrom = extractBase64(values.get(8)); - final Restriction restriction = extractRestriction(values.get(10)); - - if (values.get(9) instanceof RlpList) { - List privateForList = extractBase64List(values.get(9)); - return RawPrivateTransaction.createTransaction( - chainId, - nonce, - maxPriorityFeePerGas, - maxFeePerGas, - gasLimit, - to, - data, - privateFrom, - privateForList, - null, - restriction); + if (values.size() == 11) { + final Base64String privateFrom = extractBase64(values.get(8)); + final Restriction restriction = extractRestriction(values.get(10)); + + if (values.get(9) instanceof RlpList) { + List privateForList = extractBase64List(values.get(9)); + return RawPrivateTransaction.createTransaction( + chainId, + nonce, + maxPriorityFeePerGas, + maxFeePerGas, + gasLimit, + to, + data, + privateFrom, + privateForList, + null, + restriction); + } else { + Base64String privacyGroupId = extractBase64(values.get(9)); + return RawPrivateTransaction.createTransaction( + chainId, + nonce, + maxPriorityFeePerGas, + maxFeePerGas, + gasLimit, + to, + data, + privateFrom, + null, + privacyGroupId, + restriction); + } } else { - Base64String privacyGroupId = extractBase64(values.get(9)); - return RawPrivateTransaction.createTransaction( - chainId, - nonce, - maxPriorityFeePerGas, - maxFeePerGas, - gasLimit, - to, - data, - privateFrom, - null, - privacyGroupId, - restriction); + final Base64String privateFrom = extractBase64(values.get(11)); + final Restriction restriction = extractRestriction(values.get(13)); + + final byte[] v = + Sign.getVFromRecId( + Numeric.toBigInt(((RlpString) values.get(8)).getBytes()).intValue()); + final byte[] r = + Numeric.toBytesPadded( + Numeric.toBigInt(((RlpString) values.get(9)).getBytes()), 32); + final byte[] s = + Numeric.toBytesPadded( + Numeric.toBigInt(((RlpString) values.get(10)).getBytes()), 32); + final Sign.SignatureData signatureData = new Sign.SignatureData(v, r, s); + + if (values.get(12) instanceof RlpList) { + List privateForList = extractBase64List(values.get(12)); + return new SignedRawPrivateTransaction( + chainId, + nonce, + maxPriorityFeePerGas, + maxFeePerGas, + gasLimit, + to, + data, + signatureData, + privateFrom, + privateForList, + null, + restriction); + } else { + Base64String privacyGroupId = extractBase64(values.get(12)); + return new SignedRawPrivateTransaction( + chainId, + nonce, + maxPriorityFeePerGas, + maxFeePerGas, + gasLimit, + to, + data, + signatureData, + privateFrom, + null, + privacyGroupId, + restriction); + } } } diff --git a/eea/src/main/java/org/web3j/protocol/eea/crypto/SignedRawPrivateTransaction.java b/eea/src/main/java/org/web3j/protocol/eea/crypto/SignedRawPrivateTransaction.java index 109455933..7a056b279 100644 --- a/eea/src/main/java/org/web3j/protocol/eea/crypto/SignedRawPrivateTransaction.java +++ b/eea/src/main/java/org/web3j/protocol/eea/crypto/SignedRawPrivateTransaction.java @@ -86,6 +86,34 @@ public SignedRawPrivateTransaction( restriction); } + public SignedRawPrivateTransaction( + final long chainId, + final BigInteger nonce, + final BigInteger maxPriorityFeePerGas, + final BigInteger maxFeePerGas, + final BigInteger gasLimit, + final String to, + final String data, + final Sign.SignatureData signatureData, + final Base64String privateFrom, + final List privateFor, + final Base64String privacyGroupId, + final Restriction restriction) { + super( + chainId, + nonce, + maxPriorityFeePerGas, + maxFeePerGas, + gasLimit, + to, + data, + privateFrom, + privateFor, + privacyGroupId, + restriction); + this.signatureData = signatureData; + } + public Sign.SignatureData getSignatureData() { return signatureData; } diff --git a/eea/src/test/java/org/web3j/protocol/eea/crypto/PrivateTransactionDecoderTest.java b/eea/src/test/java/org/web3j/protocol/eea/crypto/PrivateTransactionDecoderTest.java index 3c5d35f0b..41a941ef2 100644 --- a/eea/src/test/java/org/web3j/protocol/eea/crypto/PrivateTransactionDecoderTest.java +++ b/eea/src/test/java/org/web3j/protocol/eea/crypto/PrivateTransactionDecoderTest.java @@ -187,6 +187,62 @@ public void testDecodingSigned() throws Exception { assertNull(signedResult.getChainId()); } + @Test + public void testDecodingSigned1559() throws Exception { + final BigInteger nonce = BigInteger.ZERO; + final long chainId = 2018; + final BigInteger gasLimit = BigInteger.TEN; + final BigInteger maxPriorityFeePerGas = BigInteger.ONE; + final BigInteger maxFeePerGas = BigInteger.ONE; + final String to = "0x0add5355"; + + final RawPrivateTransaction rawTransaction = + RawPrivateTransaction.createTransaction( + chainId, + nonce, + maxPriorityFeePerGas, + maxFeePerGas, + gasLimit, + to, + "", + MOCK_ENCLAVE_KEY, + MOCK_PRIVATE_FOR, + RESTRICTED); + final String privateKey = + "8f2a55949038a9610f50fb23b5883af3b4ecb3c3bb792cbcefbd1542c692be63"; + final Credentials credentials = Credentials.create(privateKey); + final byte[] encodedMessage = + PrivateTransactionEncoder.signMessage(rawTransaction, credentials); + final String hexMessage = Numeric.toHexString(encodedMessage); + + final RawPrivateTransaction result = PrivateTransactionDecoder.decode(hexMessage); + + final PrivateTransaction1559 result1559 = + (PrivateTransaction1559) result.getPrivateTransaction(); + assertNotNull(result1559); + assertEquals(nonce, result1559.getNonce()); + assertEquals(chainId, result1559.getChainId()); + assertEquals(maxPriorityFeePerGas, result1559.getMaxPriorityFeePerGas()); + assertEquals(maxFeePerGas, result1559.getMaxFeePerGas()); + assertEquals(gasLimit, result1559.getGasLimit()); + assertEquals(to, result1559.getTo()); + assertEquals("0x", result1559.getData()); + assertEquals(MOCK_ENCLAVE_KEY, result1559.getPrivateFrom()); + assertEquals(MOCK_PRIVATE_FOR, result1559.getPrivateFor().get()); + assertEquals(RESTRICTED, result1559.getRestriction()); + + assertTrue(result instanceof SignedRawPrivateTransaction); + final SignedRawPrivateTransaction signedResult = (SignedRawPrivateTransaction) result; + assertNotNull(signedResult.getSignatureData()); + Sign.SignatureData signatureData = signedResult.getSignatureData(); + final byte[] encodedTransaction = PrivateTransactionEncoder.encode(rawTransaction); + final BigInteger key = Sign.signedMessageToKey(encodedTransaction, signatureData); + assertEquals(key, credentials.getEcKeyPair().getPublicKey()); + assertEquals(credentials.getAddress(), signedResult.getFrom()); + signedResult.verify(credentials.getAddress()); + assertNull(signedResult.getChainId()); + } + @Test public void testDecodingSignedPrivacyGroup() throws Exception { final BigInteger nonce = BigInteger.ZERO;