Skip to content

Commit

Permalink
broadcast evm tx
Browse files Browse the repository at this point in the history
  • Loading branch information
sin3A committed Aug 17, 2023
1 parent d2e24d4 commit c84de6e
Show file tree
Hide file tree
Showing 10 changed files with 622 additions and 174 deletions.
49 changes: 45 additions & 4 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -174,14 +174,49 @@
</exclusion>
</exclusions>
</dependency>
<!-- <dependency>
<groupId>org.web3j</groupId>
<artifactId>crypto</artifactId>
<version>5.0.0</version>
<exclusions>
<exclusion>
<artifactId>bcprov-jdk15on</artifactId>
<groupId>org.bouncycastle</groupId>
</exclusion>
<exclusion>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</exclusion>
</exclusions>
</dependency>-->
<dependency>
<groupId>org.web3j</groupId>
<artifactId>crypto</artifactId>
<version>5.0.0</version>
<artifactId>core</artifactId>
<version>4.10.2</version>
<exclusions>
<exclusion>
<artifactId>bcprov-jdk15on</artifactId>
<groupId>org.bouncycastle</groupId>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
</exclusion>
<exclusion>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-stdlib-jdk8</artifactId>
</exclusion>
<exclusion>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</exclusion>
<exclusion>
<groupId>org.java-websocket</groupId>
<artifactId>Java-WebSocket</artifactId>
</exclusion>
<exclusion>
<artifactId>slf4j-api</artifactId>
<groupId>org.slf4j</groupId>
</exclusion>
<exclusion>
<groupId>org.java-websocket</groupId>
<artifactId>Java-WebSocket</artifactId>
</exclusion>
</exclusions>
</dependency>
Expand All @@ -195,6 +230,12 @@
<artifactId>Java-WebSocket</artifactId>
<version>1.5.2</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.8.11.6</version>
<scope>compile</scope>
</dependency>
</dependencies>

<build>
Expand Down
12 changes: 12 additions & 0 deletions src/main/java/irita/sdk/client/BaseClient.java
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
package irita.sdk.client;

import com.google.protobuf.Any;
import com.google.protobuf.ByteString;
import com.google.protobuf.GeneratedMessageV3;
import com.google.protobuf.InvalidProtocolBufferException;
import io.grpc.Channel;
import io.grpc.ManagedChannel;
import irita.sdk.config.ClientConfig;
import irita.sdk.config.OpbConfig;
import irita.sdk.constant.enums.BroadcastMode;
import irita.sdk.exception.IritaSDKException;
import irita.sdk.key.KeyInfo;
import irita.sdk.key.KeyManager;
Expand All @@ -23,6 +26,11 @@
import proto.cosmos.auth.v1beta1.Auth;
import proto.cosmos.auth.v1beta1.QueryGrpc;
import proto.cosmos.auth.v1beta1.QueryOuterClass;
import proto.cosmos.base.v1beta1.CoinOuterClass;
import proto.cosmos.tx.signing.v1beta1.Signing;
import proto.cosmos.tx.v1beta1.TxOuterClass;
import proto.ethermint.crypto.ethsecp256k1.Keys;
import proto.ethermint.evm.v1.Tx;

import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
Expand Down Expand Up @@ -81,6 +89,10 @@ public ResultTx buildAndSend(List<GeneratedMessageV3> msgs, BaseTx baseTx, Accou
return getRpcClient().broadcastTx(txBytes, baseTx.getMode());
}

public ResultTx buildAndSendEvm(byte[] txBytes, BroadcastMode mode) throws IOException {
return getRpcClient().broadcastTx(txBytes, mode);
}

public String buildTxHash(List<GeneratedMessageV3> msgs, BaseTx baseTx, Account account) {
if (account == null) {
account = queryAccount(baseTx);
Expand Down
11 changes: 11 additions & 0 deletions src/main/java/irita/sdk/client/IritaClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import irita.sdk.key.KeyManager;
import irita.sdk.module.bank.BankClient;
import irita.sdk.module.community_gov.CommunityGovClient;
import irita.sdk.module.evm.EvmClient;
import irita.sdk.module.feegrant.FeeGrantClient;
import irita.sdk.module.identity.IdentityClient;
import irita.sdk.module.mt.MtClient;
Expand All @@ -28,6 +29,7 @@ public class IritaClient {
private ServiceClient serviceClient;
private FeeGrantClient feeGrantClient;
private MtClient mtClient;
private EvmClient evmClient;

private IritaClient() {
}
Expand All @@ -46,6 +48,7 @@ public IritaClient(ClientConfig clientConfig, OpbConfig opbConfig, KeyManager km
this.serviceClient = new ServiceClient(baseClient);
this.feeGrantClient = new FeeGrantClient(baseClient);
this.mtClient = new MtClient(baseClient);
this.evmClient = new EvmClient(baseClient);
}

public BaseClient getBaseClient() {
Expand Down Expand Up @@ -154,4 +157,12 @@ public MtClient getMtClient() {
public void setMtClient(MtClient mtClient) {
this.mtClient = mtClient;
}

public EvmClient getEvmClient() {
return evmClient;
}

public void setEvmClient(EvmClient evmClient) {
this.evmClient = evmClient;
}
}
1 change: 1 addition & 0 deletions src/main/java/irita/sdk/constant/enums/MsgEnum.java
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ public enum MsgEnum {
MSG_LEGACY_TX("ethermint.evm.v1.LegacyTx", proto.ethermint.evm.v1.Tx.LegacyTx.class),
MSG_ACCESS_LIST_TX("ethermint.evm.v1.AccessListTx", proto.ethermint.evm.v1.Tx.AccessListTx.class),
MSG_DYNAMIC_FEE_TX("ethermint.evm.v1.DynamicFeeTx", proto.ethermint.evm.v1.Tx.DynamicFeeTx.class),
MSG_EXTENSION_OPTIONS_ETHERMINT_TX("ethermint.evm.v1.ExtensionOptionsEthereumTx", proto.ethermint.evm.v1.Tx.ExtensionOptionsEthereumTx.class),

;

Expand Down
119 changes: 119 additions & 0 deletions src/main/java/irita/sdk/crypto/eth/LegacyTransaction.java
Original file line number Diff line number Diff line change
@@ -1,20 +1,30 @@
package irita.sdk.crypto.eth;


import com.google.protobuf.ByteString;
import irita.sdk.util.Bech32Utils;
import org.apache.tuweni.bytes.Bytes;
import org.apache.tuweni.bytes.Bytes32;
import org.apache.tuweni.bytes.MutableBytes;
import org.apache.tuweni.units.bigints.UInt256;
import org.bouncycastle.asn1.sec.SECNamedCurves;
import org.bouncycastle.asn1.x9.X9ECParameters;
import org.bouncycastle.crypto.digests.SHA256Digest;
import org.bouncycastle.crypto.params.ECDomainParameters;
import org.bouncycastle.crypto.params.ECPrivateKeyParameters;
import org.bouncycastle.crypto.signers.ECDSASigner;
import org.bouncycastle.crypto.signers.HMacDSAKCalculator;
import org.jetbrains.annotations.NotNull;
import org.web3j.crypto.RawTransaction;
import org.web3j.crypto.Sign;
import org.web3j.crypto.SignedRawTransaction;
import org.web3j.rlp.*;
import org.web3j.utils.Numeric;
import proto.ethermint.evm.v1.Evm;
import proto.ethermint.evm.v1.Tx;

import java.math.BigInteger;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
Expand All @@ -26,6 +36,7 @@

public class LegacyTransaction {

private static RlpList rlpList;
public BigInteger curveOrder;

private long nonce;
Expand Down Expand Up @@ -56,6 +67,8 @@ public class LegacyTransaction {

private TransactionType transactionType;
private Optional<List<AccessListEntry>> maybeAccessList;
protected Optional<List<AccessListEntry>> accessList = Optional.empty();


private final SignatureAlgorithm instance = null;

Expand All @@ -67,6 +80,22 @@ public SignatureAlgorithm getInstance() {
return SignatureAlgorithmType.DEFAULT_SIGNATURE_ALGORITHM_TYPE.get();
}

public LegacyTransaction(long nonce,String gasPrice,long gasLimit,String to,String value,String data,BigInteger chainId) {
this.transactionType = TransactionType.FRONTIER;
this.nonce = nonce;
this.gasPrice = Optional.of(Wei.of(Long.parseLong(gasPrice)));
this.maxFeePerGas = Optional.empty();
this.gasLimit = gasLimit;
this.to = Optional.of(Address.fromHexString(to));
this.value = Wei.of(Long.parseLong(value));
//this.signature = getSignature(Numeric.toBigInt(legacyTx.getR().toByteArray()), Numeric.toBigInt(legacyTx.getS().toByteArray()), getV(legacyTx.getV().toByteArray()), getCurveOrder(curveOrder));
this.payload =Bytes.wrap(data.getBytes());
this.sender =null;
this.chainId = Optional.of(chainId);
//this.v =Optional.of(Numeric.toBigInt(legacyTx.getV().toByteArray()));
this.maxPriorityFeePerGas = Optional.empty();
}

public LegacyTransaction(Tx.LegacyTx legacyTx) {
this.transactionType = TransactionType.FRONTIER;
this.nonce = legacyTx.getNonce();
Expand Down Expand Up @@ -186,6 +215,39 @@ public String getSender() {
return Bech32Utils.hexToBech32("iaa",Numeric.cleanHexPrefix(addr));
}


public Bytes32 decodeTransaction(){
Bytes32 dataHash = computeSenderRecoveryHash(
transactionType,
nonce,
gasPrice.orElse(null),
maxPriorityFeePerGas.orElse(null),
maxFeePerGas.orElse(null),
gasLimit,
to,
value,
payload,
accessList,
chainId);
return dataHash;
}

/*public SECPSignature sign(final KeyPair keyPair){
Bytes32 dataHash = decodeTransaction();
final ECDSASigner signer = new ECDSASigner(new HMacDSAKCalculator(new SHA256Digest()));
X9ECParameters params = SECNamedCurves.getByName("secp256k1");
ECDomainParameters curve =new ECDomainParameters(params.getCurve(), params.getG(), params.getN(), params.getH());
final ECPrivateKeyParameters privKey =
new ECPrivateKeyParameters(
keyPair.getPrivateKey().getEncodedBytes().toUnsignedBigInteger(), curve);
signer.init(true, privKey);
final BigInteger[] components = signer.generateSignature(dataHash.toArrayUnsafe());
signature = getInstance().normaliseSignature(components[0], components[1], keyPair.getPublicKey(), dataHash);
return signature;
}*/

private Bytes32 getOrComputeSenderRecoveryHash() {
if (hashNoSignature == null) {
hashNoSignature =
Expand Down Expand Up @@ -390,4 +452,61 @@ public static void encodeAccessListInner(
] */
writeAccessList(rlpOutput, Optional.of(accessList));
}

public static LegacyTransaction decodeLegacyTransaction(String hexTransaction) {
byte[] transaction = Numeric.hexStringToByteArray(hexTransaction);
rlpList = RlpDecoder.decode(transaction);
RlpList values = (RlpList)rlpList.getValues().get(0);
BigInteger nonce = ((RlpString)values.getValues().get(0)).asPositiveBigInteger();
BigInteger gasPrice = ((RlpString)values.getValues().get(1)).asPositiveBigInteger();
BigInteger gasLimit = ((RlpString)values.getValues().get(2)).asPositiveBigInteger();
String to = ((RlpString)values.getValues().get(3)).asString();
BigInteger value = ((RlpString)values.getValues().get(4)).asPositiveBigInteger();
String data = ((RlpString)values.getValues().get(5)).asString();
Tx.LegacyTx legacyTx = Tx.LegacyTx.newBuilder()
.setData(ByteString.copyFrom(data.getBytes()))
.setGas(gasLimit.intValue())
.setNonce(nonce.intValue())
.setGasPrice(gasPrice.toString())
.setTo(to)
.setValue(value+"")
//.setGasPrice(8+"")
.setR(ByteString.copyFrom(((RlpString)values.getValues().get(7)).getBytes()))
.setS(ByteString.copyFrom(((RlpString)values.getValues().get(8)).getBytes()))
.setV(ByteString.copyFrom(((RlpString)values.getValues().get(6)).getBytes()))
.build();
return new LegacyTransaction(legacyTx);
}

public static byte[] encode(SECPSignature signatureData,long nonce,String gasPrice,long gasLimit,String to,String value,String data){
List<RlpType> result = new ArrayList<>();

result.add(RlpString.create(nonce));

result.add(RlpString.create(gasPrice));
result.add(RlpString.create(gasLimit));

// an empty to address (contract creation) should not be encoded as a numeric 0 value
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(value));

// value field will already be hex encoded, so we need to convert into binary first
byte[] data2 = Numeric.hexStringToByteArray(data);
result.add(RlpString.create(data2));
if (signatureData != null) {
result.add(RlpString.create(org.web3j.utils.Bytes.trimLeadingZeroes(new byte[0])));
result.add(RlpString.create(org.web3j.utils.Bytes.trimLeadingZeroes(signatureData.getR().toByteArray())));
result.add(RlpString.create(org.web3j.utils.Bytes.trimLeadingZeroes(signatureData.getS().toByteArray())));
}
RlpList rlpList = new RlpList(result);
return RlpEncoder.encode(rlpList);
}

}
Loading

0 comments on commit c84de6e

Please sign in to comment.