mirror of
https://github.com/status-im/ethereumj-personal.git
synced 2025-02-26 18:50:28 +00:00
Overhaul crypto/hash, removed samples and switch to spongycastle
This commit is contained in:
parent
bd7ff7d470
commit
348ae7617a
@ -1,100 +1,63 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>EthereumJ</groupId>
|
||||
<artifactId>EthereumJ</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>repository.jboss.org</id>
|
||||
<name>JBoss Releases Repository</name>
|
||||
<url>http://repository.jboss.org/maven2</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
<pluginRepositories>
|
||||
<pluginRepository>
|
||||
<id>repository.jboss.org</id>
|
||||
<name>JBoss Releases Repository</name>
|
||||
<url>http://repository.jboss.org/maven2</url>
|
||||
</pluginRepository>
|
||||
</pluginRepositories>
|
||||
|
||||
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>4.10</version>
|
||||
</dependency>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.ethereum</groupId>
|
||||
<artifactId>EthereumJ</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<name>EthereumJ</name>
|
||||
<url>http://maven.apache.org</url>
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<!-- Third-party dependencies -->
|
||||
<junit.version>4.11</junit.version>
|
||||
<slf4j.version>1.7.7</slf4j.version>
|
||||
<leveldb.version>0.7</leveldb.version>
|
||||
<spongycastle.version>1.50.0.0</spongycastle.version>
|
||||
<generated.sourceDirectory>gen</generated.sourceDirectory>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>io.netty</groupId>
|
||||
<artifactId>netty-all</artifactId>
|
||||
<version>4.0.17.Final</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.bouncycastle</groupId>
|
||||
<artifactId>bcpg-jdk15on</artifactId>
|
||||
<version>1.49</version>
|
||||
<classifier>sources</classifier>
|
||||
</dependency>
|
||||
|
||||
|
||||
<dependency>
|
||||
<groupId>org.bouncycastle</groupId>
|
||||
<artifactId>bcprov-ext-jdk15on</artifactId>
|
||||
<version>1.49</version>
|
||||
<classifier>sources</classifier>
|
||||
</dependency>
|
||||
|
||||
|
||||
<dependency>
|
||||
<groupId>org.bouncycastle</groupId>
|
||||
<artifactId>bcprov-jdk15on</artifactId>
|
||||
<version>1.49</version>
|
||||
<classifier>sources</classifier>
|
||||
</dependency>
|
||||
|
||||
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>${junit.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<!-- Spongy Castle for SHA3 and SECP256K1 -->
|
||||
<dependency>
|
||||
<groupId>com.madgag.spongycastle</groupId>
|
||||
<artifactId>core</artifactId>
|
||||
<version>${spongycastle.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.fifesoft</groupId>
|
||||
<artifactId>rsyntaxtextarea</artifactId>
|
||||
<version>2.5.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.maxmind.geoip2</groupId>
|
||||
<artifactId>geoip2</artifactId>
|
||||
<version>0.6.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.maxmind.geoip</groupId>
|
||||
<artifactId>geoip-api</artifactId>
|
||||
<version>1.2.11</version>
|
||||
</dependency>
|
||||
|
||||
<!--
|
||||
<dependency>
|
||||
<groupId>org.antlr</groupId>
|
||||
<artifactId>antlr</artifactId>
|
||||
<version>3.5.2</version>
|
||||
</dependency>
|
||||
-->
|
||||
|
||||
<dependency>
|
||||
<groupId>org.antlr</groupId>
|
||||
<artifactId>antlr</artifactId>
|
||||
<version>3.1.3</version>
|
||||
<!-- <version>3.5.2</version> -->
|
||||
</dependency>
|
||||
|
||||
|
||||
<dependency>
|
||||
<groupId>org.antlr</groupId>
|
||||
<artifactId>stringtemplate</artifactId>
|
||||
@ -107,6 +70,20 @@
|
||||
<version>2.5.3</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Consumers are expected to provide their own SLF4J adapters
|
||||
such as logback, slf4j-log4j12, slf4j-jcl and so on see http://www.slf4j.org/faq.html -->
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-jdk14</artifactId>
|
||||
<version>${slf4j.version}</version>
|
||||
<scope>runtime</scope>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
<version>${slf4j.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<build>
|
||||
<plugins>
|
||||
|
661
ethereumj-core/src/main/java/org/ethereum/crypto/ECKey.java
Normal file
661
ethereumj-core/src/main/java/org/ethereum/crypto/ECKey.java
Normal file
@ -0,0 +1,661 @@
|
||||
package org.ethereum.crypto;
|
||||
/**
|
||||
* Copyright 2011 Google Inc.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static org.ethereum.util.ByteUtil.bigIntegerToBytes;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.math.BigInteger;
|
||||
import java.nio.charset.Charset;
|
||||
import java.security.SecureRandom;
|
||||
import java.security.SignatureException;
|
||||
import java.util.Arrays;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import org.ethereum.util.ByteUtil;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.spongycastle.asn1.sec.SECNamedCurves;
|
||||
import org.spongycastle.asn1.x9.X9ECParameters;
|
||||
import org.spongycastle.asn1.x9.X9IntegerConverter;
|
||||
import org.spongycastle.crypto.AsymmetricCipherKeyPair;
|
||||
import org.spongycastle.crypto.digests.SHA256Digest;
|
||||
import org.spongycastle.crypto.generators.ECKeyPairGenerator;
|
||||
import org.spongycastle.crypto.params.ECDomainParameters;
|
||||
import org.spongycastle.crypto.params.ECKeyGenerationParameters;
|
||||
import org.spongycastle.crypto.params.ECPrivateKeyParameters;
|
||||
import org.spongycastle.crypto.params.ECPublicKeyParameters;
|
||||
import org.spongycastle.crypto.signers.ECDSASigner;
|
||||
import org.spongycastle.crypto.signers.HMacDSAKCalculator;
|
||||
import org.spongycastle.math.ec.ECAlgorithms;
|
||||
import org.spongycastle.math.ec.ECCurve;
|
||||
import org.spongycastle.math.ec.ECPoint;
|
||||
import org.spongycastle.util.encoders.Base64;
|
||||
import org.spongycastle.util.encoders.Hex;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
|
||||
public class ECKey implements Serializable {
|
||||
private static final Logger log = LoggerFactory.getLogger(ECKey.class);
|
||||
|
||||
/** The parameters of the secp256k1 curve that Bitcoin uses. */
|
||||
public static final ECDomainParameters CURVE;
|
||||
|
||||
/**
|
||||
* Equal to CURVE.getN().shiftRight(1), used for canonicalising the S value of a signature. If you aren't
|
||||
* sure what this is about, you can ignore it.
|
||||
*/
|
||||
public static final BigInteger HALF_CURVE_ORDER;
|
||||
|
||||
private static final SecureRandom secureRandom;
|
||||
private static final long serialVersionUID = -728224901792295832L;
|
||||
|
||||
static {
|
||||
// All clients must agree on the curve to use by agreement. Bitcoin uses secp256k1.
|
||||
X9ECParameters params = SECNamedCurves.getByName("secp256k1");
|
||||
CURVE = new ECDomainParameters(params.getCurve(), params.getG(), params.getN(), params.getH());
|
||||
HALF_CURVE_ORDER = params.getN().shiftRight(1);
|
||||
secureRandom = new SecureRandom();
|
||||
}
|
||||
|
||||
// The two parts of the key. If "priv" is set, "pub" can always be calculated. If "pub" is set but not "priv", we
|
||||
// can only verify signatures not make them.
|
||||
// TODO: Redesign this class to use consistent internals and more efficient serialization.
|
||||
private BigInteger priv;
|
||||
protected final ECPoint pub;
|
||||
|
||||
// Transient because it's calculated on demand.
|
||||
transient private byte[] pubKeyHash;
|
||||
|
||||
/**
|
||||
* Generates an entirely new keypair. Point compression is used so the resulting public key will be 33 bytes
|
||||
* (32 for the co-ordinate and 1 byte to represent the y bit).
|
||||
*/
|
||||
public ECKey() {
|
||||
this(secureRandom);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates an entirely new keypair with the given {@link SecureRandom} object. Point compression is used so the
|
||||
* resulting public key will be 33 bytes (32 for the co-ordinate and 1 byte to represent the y bit).
|
||||
*/
|
||||
public ECKey(SecureRandom secureRandom) {
|
||||
ECKeyPairGenerator generator = new ECKeyPairGenerator();
|
||||
ECKeyGenerationParameters keygenParams = new ECKeyGenerationParameters(CURVE, secureRandom);
|
||||
generator.init(keygenParams);
|
||||
AsymmetricCipherKeyPair keypair = generator.generateKeyPair();
|
||||
ECPrivateKeyParameters privParams = (ECPrivateKeyParameters) keypair.getPrivate();
|
||||
ECPublicKeyParameters pubParams = (ECPublicKeyParameters) keypair.getPublic();
|
||||
priv = privParams.getD();
|
||||
pub = CURVE.getCurve().decodePoint(pubParams.getQ().getEncoded(true));
|
||||
}
|
||||
|
||||
protected ECKey(@Nullable BigInteger priv, ECPoint pub) {
|
||||
this.priv = priv;
|
||||
if(pub == null)
|
||||
throw new IllegalArgumentException("Public key may not be null");
|
||||
this.pub = pub;
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility for compressing an elliptic curve point. Returns the same point if it's already compressed.
|
||||
* See the ECKey class docs for a discussion of point compression.
|
||||
*/
|
||||
public static ECPoint compressPoint(ECPoint uncompressed) {
|
||||
return CURVE.getCurve().decodePoint(uncompressed.getEncoded(true));
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility for decompressing an elliptic curve point. Returns the same point if it's already compressed.
|
||||
* See the ECKey class docs for a discussion of point compression.
|
||||
*/
|
||||
public static ECPoint decompressPoint(ECPoint compressed) {
|
||||
return CURVE.getCurve().decodePoint(compressed.getEncoded(false));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an ECKey given the private key only. The public key is calculated from it (this is slow). Note that
|
||||
* the resulting public key is compressed.
|
||||
*/
|
||||
public static ECKey fromPrivate(BigInteger privKey) {
|
||||
return new ECKey(privKey, compressPoint(CURVE.getG().multiply(privKey)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an ECKey given the private key only. The public key is calculated from it (this is slow). The resulting
|
||||
* public key is compressed.
|
||||
*/
|
||||
public static ECKey fromPrivate(byte[] privKeyBytes) {
|
||||
return fromPrivate(new BigInteger(1, privKeyBytes));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an ECKey that simply trusts the caller to ensure that point is really the result of multiplying the
|
||||
* generator point by the private key. This is used to speed things up when you know you have the right values
|
||||
* already. The compression state of pub will be preserved.
|
||||
*/
|
||||
public static ECKey fromPrivateAndPrecalculatedPublic(BigInteger priv, ECPoint pub) {
|
||||
return new ECKey(priv, pub);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an ECKey that simply trusts the caller to ensure that point is really the result of multiplying the
|
||||
* generator point by the private key. This is used to speed things up when you know you have the right values
|
||||
* already. The compression state of the point will be preserved.
|
||||
*/
|
||||
public static ECKey fromPrivateAndPrecalculatedPublic(byte[] priv, byte[] pub) {
|
||||
checkNotNull(priv);
|
||||
checkNotNull(pub);
|
||||
return new ECKey(new BigInteger(1, priv), CURVE.getCurve().decodePoint(pub));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an ECKey that cannot be used for signing, only verifying signatures, from the given point. The
|
||||
* compression state of pub will be preserved.
|
||||
*/
|
||||
public static ECKey fromPublicOnly(ECPoint pub) {
|
||||
return new ECKey(null, pub);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an ECKey that cannot be used for signing, only verifying signatures, from the given encoded point.
|
||||
* The compression state of pub will be preserved.
|
||||
*/
|
||||
public static ECKey fromPublicOnly(byte[] pub) {
|
||||
return new ECKey(null, CURVE.getCurve().decodePoint(pub));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a copy of this key, but with the public point represented in uncompressed form. Normally you would
|
||||
* never need this: it's for specialised scenarios or when backwards compatibility in encoded form is necessary.
|
||||
*/
|
||||
public ECKey decompress() {
|
||||
if (!pub.isCompressed())
|
||||
return this;
|
||||
else
|
||||
return new ECKey(priv, decompressPoint(pub));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this key doesn't have access to private key bytes. This may be because it was never
|
||||
* given any private key bytes to begin with (a watching key).
|
||||
*/
|
||||
public boolean isPubKeyOnly() {
|
||||
return priv == null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this key has access to private key bytes. Does the opposite of
|
||||
* {@link #isPubKeyOnly()}.
|
||||
*/
|
||||
public boolean hasPrivKey() {
|
||||
return priv != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns public key bytes from the given private key. To convert a byte array into a BigInteger, use <tt>
|
||||
* new BigInteger(1, bytes);</tt>
|
||||
*/
|
||||
public static byte[] publicKeyFromPrivate(BigInteger privKey, boolean compressed) {
|
||||
ECPoint point = CURVE.getG().multiply(privKey);
|
||||
return point.getEncoded(compressed);
|
||||
}
|
||||
|
||||
/** Gets the hash160 form of the public key (as seen in addresses). */
|
||||
public byte[] getAddress() {
|
||||
if (pubKeyHash == null) {
|
||||
byte[] pubBytes = this.pub.getEncoded(false);
|
||||
pubKeyHash = HashUtil.sha3hash160(Arrays.copyOfRange(pubBytes, 1, pubBytes.length));
|
||||
}
|
||||
return pubKeyHash;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the raw public key value. This appears in transaction scriptSigs. Note that this is <b>not</b> the same
|
||||
* as the pubKeyHash/address.
|
||||
*/
|
||||
public byte[] getPubKey() {
|
||||
return pub.getEncoded();
|
||||
}
|
||||
|
||||
/** Gets the public key in the form of an elliptic curve point object from Bouncy Castle. */
|
||||
public ECPoint getPubKeyPoint() {
|
||||
return pub;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the private key in the form of an integer field element. The public key is derived by performing EC
|
||||
* point addition this number of times (i.e. point multiplying).
|
||||
*
|
||||
* @throws java.lang.IllegalStateException if the private key bytes are not available.
|
||||
*/
|
||||
public BigInteger getPrivKey() {
|
||||
if (priv == null)
|
||||
throw new MissingPrivateKeyException();
|
||||
return priv;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether this key is using the compressed form or not. Compressed pubkeys are only 33 bytes, not 64.
|
||||
*/
|
||||
public boolean isCompressed() {
|
||||
return pub.isCompressed();
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
StringBuilder b = new StringBuilder();
|
||||
b.append("pub:").append(Hex.toHexString(pub.getEncoded(false)));
|
||||
return b.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Produce a string rendering of the ECKey INCLUDING the private key.
|
||||
* Unless you absolutely need the private key it is better for security reasons to just use toString().
|
||||
*/
|
||||
public String toStringWithPrivate() {
|
||||
StringBuilder b = new StringBuilder();
|
||||
b.append(toString());
|
||||
if (priv != null) {
|
||||
b.append(" priv:").append(Hex.toHexString(priv.toByteArray()));
|
||||
}
|
||||
return b.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Groups the two components that make up a signature, and provides a way to encode to DER form, which is
|
||||
* how ECDSA signatures are represented when embedded in other data structures in the Bitcoin protocol. The raw
|
||||
* components can be useful for doing further EC maths on them.
|
||||
*/
|
||||
public static class ECDSASignature {
|
||||
/** The two components of the signature. */
|
||||
public final BigInteger r, s;
|
||||
public byte v;
|
||||
|
||||
/**
|
||||
* Constructs a signature with the given components. Does NOT automatically canonicalise the signature.
|
||||
*/
|
||||
public ECDSASignature(BigInteger r, BigInteger s) {
|
||||
this.r = r;
|
||||
this.s = s;
|
||||
}
|
||||
|
||||
public static ECDSASignature fromComponents(byte[] r, byte[] s) {
|
||||
return new ECDSASignature(new BigInteger(r), new BigInteger(s));
|
||||
}
|
||||
|
||||
/**
|
||||
* Will automatically adjust the S component to be less than or equal to half the curve order, if necessary.
|
||||
* This is required because for every signature (r,s) the signature (r, -s (mod N)) is a valid signature of
|
||||
* the same message. However, we dislike the ability to modify the bits of a Bitcoin transaction after it's
|
||||
* been signed, as that violates various assumed invariants. Thus in future only one of those forms will be
|
||||
* considered legal and the other will be banned.
|
||||
*/
|
||||
public ECDSASignature toCanonicalised() {
|
||||
if (s.compareTo(HALF_CURVE_ORDER) > 0) {
|
||||
// The order of the curve is the number of valid points that exist on that curve. If S is in the upper
|
||||
// half of the number of valid points, then bring it back to the lower half. Otherwise, imagine that
|
||||
// N = 10
|
||||
// s = 8, so (-8 % 10 == 2) thus both (r, 8) and (r, 2) are valid solutions.
|
||||
// 10 - 8 == 2, giving us always the latter solution, which is canonical.
|
||||
return new ECDSASignature(r, CURVE.getN().subtract(s));
|
||||
} else {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
public String toBase64() {
|
||||
byte[] sigData = new byte[65]; // 1 header + 32 bytes for R + 32 bytes for S
|
||||
sigData[0] = v;
|
||||
System.arraycopy(bigIntegerToBytes(this.r, 32), 0, sigData, 1, 32);
|
||||
System.arraycopy(bigIntegerToBytes(this.s, 32), 0, sigData, 33, 32);
|
||||
return new String(Base64.encode(sigData), Charset.forName("UTF-8"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
|
||||
ECDSASignature signature = (ECDSASignature) o;
|
||||
|
||||
if (!r.equals(signature.r)) return false;
|
||||
if (!s.equals(signature.s)) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = r.hashCode();
|
||||
result = 31 * result + s.hashCode();
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Signs the given hash and returns the R and S components as BigIntegers
|
||||
* and put them in ECDSASignature
|
||||
*
|
||||
* @param data to sign
|
||||
* @return ECDSASignature signature that contains the R and S components
|
||||
*/
|
||||
public ECDSASignature doSign(byte[] input) {
|
||||
// No decryption of private key required.
|
||||
if (priv == null)
|
||||
throw new MissingPrivateKeyException();
|
||||
checkNotNull(priv);
|
||||
ECDSASigner signer = new ECDSASigner(new HMacDSAKCalculator(new SHA256Digest()));
|
||||
ECPrivateKeyParameters privKey = new ECPrivateKeyParameters(priv, CURVE);
|
||||
signer.init(true, privKey);
|
||||
BigInteger[] components = signer.generateSignature(input);
|
||||
return new ECDSASignature(components[0], components[1]).toCanonicalised();
|
||||
}
|
||||
|
||||
/**
|
||||
* Signs a text message using the standard Bitcoin messaging signing format and returns the signature as a base64
|
||||
* encoded string.
|
||||
*
|
||||
* @throws IllegalStateException if this ECKey does not have the private part.
|
||||
*/
|
||||
public String signBitcoinMessage(String message) {
|
||||
byte[] data = ByteUtil.formatForBitcoinSigning(message);
|
||||
byte[] hash = HashUtil.doubleDigest(data);
|
||||
return sign(hash).toBase64();
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes the sha3 hash (32 bytes) of data and returns the ECDSA signature
|
||||
*
|
||||
* @throws IllegalStateException if this ECKey does not have the private part.
|
||||
*/
|
||||
public ECDSASignature sign(byte[] messageHash) {
|
||||
if (priv == null)
|
||||
throw new MissingPrivateKeyException();
|
||||
ECDSASignature sig = doSign(messageHash);
|
||||
// Now we have to work backwards to figure out the recId needed to recover the signature.
|
||||
int recId = -1;
|
||||
for (int i = 0; i < 4; i++) {
|
||||
ECKey k = ECKey.recoverFromSignature(i, sig, messageHash, isCompressed());
|
||||
if (k != null && k.pub.equals(pub)) {
|
||||
recId = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (recId == -1)
|
||||
throw new RuntimeException("Could not construct a recoverable key. This should never happen.");
|
||||
sig.v = (byte) (recId + 27 + (isCompressed() ? 4 : 0));
|
||||
return sig;
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a piece of text and a message signature encoded in base64, returns an ECKey
|
||||
* containing the public key that was used to sign it. This can then be compared to the expected public key to
|
||||
* determine if the signature was correct.
|
||||
*
|
||||
* @param message a piece of human readable text that was signed
|
||||
* @param signatureBase64 The Bitcoin-format message signature in base64
|
||||
* @throws SignatureException If the public key could not be recovered or if there was a signature format error.
|
||||
*/
|
||||
public static ECKey signedBitcoinMessageToKey(String message, String signatureBase64) throws SignatureException {
|
||||
byte[] messageBytes = ByteUtil.formatForBitcoinSigning(message);
|
||||
// Note that the C++ code doesn't actually seem to specify any character encoding. Presumably it's whatever
|
||||
// JSON-SPIRIT hands back. Assume UTF-8 for now.
|
||||
byte[] messageHash = HashUtil.doubleDigest(messageBytes);
|
||||
return signatureToKey(messageHash, signatureBase64);
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a piece of text and a message signature encoded in base64, returns an ECKey
|
||||
* containing the public key that was used to sign it. This can then be compared to the expected public key to
|
||||
* determine if the signature was correct.
|
||||
*
|
||||
* @param message a piece of human readable text that was signed
|
||||
* @param signatureBase64 The Bitcoin-format message signature in base64
|
||||
* @throws SignatureException If the public key could not be recovered or if there was a signature format error.
|
||||
*/
|
||||
public static ECKey signatureToKey(byte[] messageHash, String signatureBase64) throws SignatureException {
|
||||
byte[] signatureEncoded;
|
||||
try {
|
||||
signatureEncoded = Base64.decode(signatureBase64);
|
||||
} catch (RuntimeException e) {
|
||||
// This is what you get back from Bouncy Castle if base64 doesn't decode :(
|
||||
throw new SignatureException("Could not decode base64", e);
|
||||
}
|
||||
// Parse the signature bytes into r/s and the selector value.
|
||||
if (signatureEncoded.length < 65)
|
||||
throw new SignatureException("Signature truncated, expected 65 bytes and got " + signatureEncoded.length);
|
||||
int header = signatureEncoded[0] & 0xFF;
|
||||
// The header byte: 0x1B = first key with even y, 0x1C = first key with odd y,
|
||||
// 0x1D = second key with even y, 0x1E = second key with odd y
|
||||
if (header < 27 || header > 34)
|
||||
throw new SignatureException("Header byte out of range: " + header);
|
||||
BigInteger r = new BigInteger(1, Arrays.copyOfRange(signatureEncoded, 1, 33));
|
||||
BigInteger s = new BigInteger(1, Arrays.copyOfRange(signatureEncoded, 33, 65));
|
||||
ECDSASignature sig = new ECDSASignature(r, s);
|
||||
boolean compressed = false;
|
||||
if (header >= 31) {
|
||||
compressed = true;
|
||||
header -= 4;
|
||||
}
|
||||
int recId = header - 27;
|
||||
ECKey key = ECKey.recoverFromSignature(recId, sig, messageHash, compressed);
|
||||
if (key == null)
|
||||
throw new SignatureException("Could not recover public key from signature");
|
||||
return key;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Verifies the given ECDSA signature against the message bytes using the public key bytes.</p>
|
||||
*
|
||||
* <p>When using native ECDSA verification, data must be 32 bytes, and no element may be
|
||||
* larger than 520 bytes.</p>
|
||||
*
|
||||
* @param data Hash of the data to verify.
|
||||
* @param signature signature.
|
||||
* @param pub The public key bytes to use.
|
||||
*/
|
||||
public static boolean verify(byte[] data, ECDSASignature signature, byte[] pub) {
|
||||
ECDSASigner signer = new ECDSASigner();
|
||||
ECPublicKeyParameters params = new ECPublicKeyParameters(CURVE.getCurve().decodePoint(pub), CURVE);
|
||||
signer.init(false, params);
|
||||
try {
|
||||
return signer.verifySignature(data, signature.r, signature.s);
|
||||
} catch (NullPointerException e) {
|
||||
// Bouncy Castle contains a bug that can cause NPEs given specially crafted signatures. Those signatures
|
||||
// are inherently invalid/attack sigs so we just fail them here rather than crash the thread.
|
||||
log.error("Caught NPE inside bouncy castle");
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies the given ASN.1 encoded ECDSA signature against a hash using the public key.
|
||||
*
|
||||
* @param data Hash of the data to verify.
|
||||
* @param signature signature.
|
||||
* @param pub The public key bytes to use.
|
||||
*/
|
||||
public static boolean verify(byte[] data, byte[] signature, byte[] pub) {
|
||||
return verify(data, signature, pub);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies the given ASN.1 encoded ECDSA signature against a hash using the public key.
|
||||
*
|
||||
* @param data Hash of the data to verify.
|
||||
* @param signature signature.
|
||||
*/
|
||||
public boolean verify(byte[] data, byte[] signature) {
|
||||
return ECKey.verify(data, signature, getPubKey());
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies the given R/S pair (signature) against a hash using the public key.
|
||||
*/
|
||||
public boolean verify(byte[] sigHash, ECDSASignature signature) {
|
||||
return ECKey.verify(sigHash, signature, getPubKey());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this pubkey is canonical, i.e. the correct length taking into account compression.
|
||||
*/
|
||||
public boolean isPubKeyCanonical() {
|
||||
return isPubKeyCanonical(pub.getEncoded());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the given pubkey is canonical, i.e. the correct length taking into account compression.
|
||||
*/
|
||||
public static boolean isPubKeyCanonical(byte[] pubkey) {
|
||||
if (pubkey[0] == 0x04) {
|
||||
// Uncompressed pubkey
|
||||
if (pubkey.length != 65)
|
||||
return false;
|
||||
} else if (pubkey[0] == 0x02 || pubkey[0] == 0x03) {
|
||||
// Compressed pubkey
|
||||
if (pubkey.length != 33)
|
||||
return false;
|
||||
} else
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience wrapper around {@link ECKey#signedBitcoinMessageToKey(String, String)}. If the key derived from the
|
||||
* signature is not the same as this one, throws a SignatureException.
|
||||
*/
|
||||
public void verifyBitcoinMessage(String message, String signatureBase64) throws SignatureException {
|
||||
ECKey key = ECKey.signedBitcoinMessageToKey(message, signatureBase64);
|
||||
if (!key.pub.equals(pub))
|
||||
throw new SignatureException("Signature did not match for message");
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Given the components of a signature and a selector value, recover and return the public key
|
||||
* that generated the signature according to the algorithm in SEC1v2 section 4.1.6.</p>
|
||||
*
|
||||
* <p>The recId is an index from 0 to 3 which indicates which of the 4 possible keys is the correct one. Because
|
||||
* the key recovery operation yields multiple potential keys, the correct key must either be stored alongside the
|
||||
* signature, or you must be willing to try each recId in turn until you find one that outputs the key you are
|
||||
* expecting.</p>
|
||||
*
|
||||
* <p>If this method returns null it means recovery was not possible and recId should be iterated.</p>
|
||||
*
|
||||
* <p>Given the above two points, a correct usage of this method is inside a for loop from 0 to 3, and if the
|
||||
* output is null OR a key that is not the one you expect, you try again with the next recId.</p>
|
||||
*
|
||||
* @param recId Which possible key to recover.
|
||||
* @param sig the R and S components of the signature, wrapped.
|
||||
* @param messageHash Hash of the data that was signed.
|
||||
* @param compressed Whether or not the original pubkey was compressed.
|
||||
* @return An ECKey containing only the public part, or null if recovery wasn't possible.
|
||||
*/
|
||||
@Nullable
|
||||
public static ECKey recoverFromSignature(int recId, ECDSASignature sig, byte[] messageHash, boolean compressed) {
|
||||
Preconditions.checkArgument(recId >= 0, "recId must be positive");
|
||||
Preconditions.checkArgument(sig.r.signum() >= 0, "r must be positive");
|
||||
Preconditions.checkArgument(sig.s.signum() >= 0, "s must be positive");
|
||||
Preconditions.checkNotNull(messageHash);
|
||||
// 1.0 For j from 0 to h (h == recId here and the loop is outside this function)
|
||||
// 1.1 Let x = r + jn
|
||||
BigInteger n = CURVE.getN(); // Curve order.
|
||||
BigInteger i = BigInteger.valueOf((long) recId / 2);
|
||||
BigInteger x = sig.r.add(i.multiply(n));
|
||||
// 1.2. Convert the integer x to an octet string X of length mlen using the conversion routine
|
||||
// specified in Section 2.3.7, where mlen = ⌈(log2 p)/8⌉ or mlen = ⌈m/8⌉.
|
||||
// 1.3. Convert the octet string (16 set binary digits)||X to an elliptic curve point R using the
|
||||
// conversion routine specified in Section 2.3.4. If this conversion routine outputs “invalid”, then
|
||||
// do another iteration of Step 1.
|
||||
//
|
||||
// More concisely, what these points mean is to use X as a compressed public key.
|
||||
ECCurve.Fp curve = (ECCurve.Fp) CURVE.getCurve();
|
||||
BigInteger prime = curve.getQ(); // Bouncy Castle is not consistent about the letter it uses for the prime.
|
||||
if (x.compareTo(prime) >= 0) {
|
||||
// Cannot have point co-ordinates larger than this as everything takes place modulo Q.
|
||||
return null;
|
||||
}
|
||||
// Compressed keys require you to know an extra bit of data about the y-coord as there are two possibilities.
|
||||
// So it's encoded in the recId.
|
||||
ECPoint R = decompressKey(x, (recId & 1) == 1);
|
||||
// 1.4. If nR != point at infinity, then do another iteration of Step 1 (callers responsibility).
|
||||
if (!R.multiply(n).isInfinity())
|
||||
return null;
|
||||
// 1.5. Compute e from M using Steps 2 and 3 of ECDSA signature verification.
|
||||
BigInteger e = new BigInteger(1, messageHash);
|
||||
// 1.6. For k from 1 to 2 do the following. (loop is outside this function via iterating recId)
|
||||
// 1.6.1. Compute a candidate public key as:
|
||||
// Q = mi(r) * (sR - eG)
|
||||
//
|
||||
// Where mi(x) is the modular multiplicative inverse. We transform this into the following:
|
||||
// Q = (mi(r) * s ** R) + (mi(r) * -e ** G)
|
||||
// Where -e is the modular additive inverse of e, that is z such that z + e = 0 (mod n). In the above equation
|
||||
// ** is point multiplication and + is point addition (the EC group operator).
|
||||
//
|
||||
// We can find the additive inverse by subtracting e from zero then taking the mod. For example the additive
|
||||
// inverse of 3 modulo 11 is 8 because 3 + 8 mod 11 = 0, and -3 mod 11 = 8.
|
||||
BigInteger eInv = BigInteger.ZERO.subtract(e).mod(n);
|
||||
BigInteger rInv = sig.r.modInverse(n);
|
||||
BigInteger srInv = rInv.multiply(sig.s).mod(n);
|
||||
BigInteger eInvrInv = rInv.multiply(eInv).mod(n);
|
||||
ECPoint.Fp q = (ECPoint.Fp) ECAlgorithms.sumOfTwoMultiplies(CURVE.getG(), eInvrInv, R, srInv);
|
||||
return ECKey.fromPublicOnly(q.getEncoded(compressed));
|
||||
}
|
||||
|
||||
/** Decompress a compressed public key (x co-ord and low-bit of y-coord). */
|
||||
private static ECPoint decompressKey(BigInteger xBN, boolean yBit) {
|
||||
X9IntegerConverter x9 = new X9IntegerConverter();
|
||||
byte[] compEnc = x9.integerToBytes(xBN, 1 + x9.getByteLength(CURVE.getCurve()));
|
||||
compEnc[0] = (byte)(yBit ? 0x03 : 0x02);
|
||||
return CURVE.getCurve().decodePoint(compEnc);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a 32 byte array containing the private key, or null if the key is encrypted or public only
|
||||
*/
|
||||
@Nullable
|
||||
public byte[] getPrivKeyBytes() {
|
||||
return bigIntegerToBytes(priv, 32);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || !(o instanceof ECKey)) return false;
|
||||
|
||||
ECKey ecKey = (ECKey) o;
|
||||
|
||||
if (priv != null && !priv.equals(ecKey.priv)) return false;
|
||||
if (pub != null && !pub.equals(ecKey.pub)) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
// Public keys are random already so we can just use a part of them as the hashcode. Read from the start to
|
||||
// avoid picking up the type code (compressed vs uncompressed) which is tacked on the end.
|
||||
byte[] bits = getPubKey();
|
||||
return (bits[0] & 0xFF) | ((bits[1] & 0xFF) << 8) | ((bits[2] & 0xFF) << 16) | ((bits[3] & 0xFF) << 24);
|
||||
}
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public static class MissingPrivateKeyException extends RuntimeException {
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,61 @@
|
||||
package org.ethereum.crypto;
|
||||
|
||||
import static java.util.Arrays.copyOfRange;
|
||||
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
|
||||
import org.ethereum.util.ByteUtil;
|
||||
|
||||
public class HashUtil {
|
||||
|
||||
private static final MessageDigest sha256digest;
|
||||
|
||||
static {
|
||||
try {
|
||||
sha256digest = MessageDigest.getInstance("SHA-256");
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
throw new RuntimeException(e); // Can't happen.
|
||||
}
|
||||
}
|
||||
|
||||
public static byte[] sha256(byte[] input) {
|
||||
return sha256digest.digest(input);
|
||||
}
|
||||
|
||||
public static byte[] sha3(byte[] input) {
|
||||
return SHA3Helper.sha3(input);
|
||||
}
|
||||
|
||||
public static String sha3String(String input) {
|
||||
return SHA3Helper.sha3String(input);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates RIGTMOST160(SHA3(input)). This is used in address calculations.
|
||||
*/
|
||||
public static byte[] sha3hash160(byte[] input) {
|
||||
byte[] hash = sha3(input);
|
||||
return copyOfRange(hash, 12, hash.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* See {@link ByteUtil#doubleDigest(byte[], int, int)}.
|
||||
*/
|
||||
public static byte[] doubleDigest(byte[] input) {
|
||||
return doubleDigest(input, 0, input.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the SHA-256 hash of the given byte range, and then hashes the resulting hash again. This is
|
||||
* standard procedure in Bitcoin. The resulting hash is in big endian form.
|
||||
*/
|
||||
public static byte[] doubleDigest(byte[] input, int offset, int length) {
|
||||
synchronized (sha256digest) {
|
||||
sha256digest.reset();
|
||||
sha256digest.update(input, offset, length);
|
||||
byte[] first = sha256digest.digest();
|
||||
return sha256digest.digest(first);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
package org.ethereum.crypto;
|
||||
/**
|
||||
* <p>Exception to provide the following to {@link EncrypterDecrypterOpenSSL}:</p>
|
||||
* <ul>
|
||||
* <li>Provision of encryption / decryption exception</li>
|
||||
* </ul>
|
||||
* <p>This base exception acts as a general failure mode not attributable to a specific cause (other than
|
||||
* that reported in the exception message). Since this is in English, it may not be worth reporting directly
|
||||
* to the user other than as part of a "general failure to parse" response.</p>
|
||||
*/
|
||||
public class KeyCrypterException extends RuntimeException {
|
||||
private static final long serialVersionUID = -4441989608332681377L;
|
||||
|
||||
public KeyCrypterException(String s) {
|
||||
super(s);
|
||||
}
|
||||
|
||||
public KeyCrypterException(String s, Throwable throwable) {
|
||||
super(s, throwable);
|
||||
}
|
||||
}
|
@ -0,0 +1,96 @@
|
||||
package org.ethereum.crypto;
|
||||
|
||||
import java.math.BigInteger;
|
||||
|
||||
import org.spongycastle.crypto.digests.SHA3Digest;
|
||||
import org.spongycastle.util.encoders.Hex;
|
||||
|
||||
public class SHA3Helper {
|
||||
|
||||
private static SHA3Digest DEFAULT_DIGEST_256 = new SHA3Digest(256);
|
||||
|
||||
public static String sha3String(String message) {
|
||||
return sha3String(message, DEFAULT_DIGEST_256, true);
|
||||
}
|
||||
|
||||
public static String sha3String(byte[] message) {
|
||||
return sha3String(message, DEFAULT_DIGEST_256, true);
|
||||
}
|
||||
|
||||
public static byte[] sha3(String message) {
|
||||
return sha3(Hex.decode(message), DEFAULT_DIGEST_256, true);
|
||||
}
|
||||
|
||||
public static byte[] sha3(byte[] message) {
|
||||
return sha3(message, DEFAULT_DIGEST_256, true);
|
||||
}
|
||||
|
||||
protected static String sha3String(String message, Size bitSize) {
|
||||
SHA3Digest digest = new SHA3Digest(bitSize.bits);
|
||||
return sha3String(message, digest, true);
|
||||
}
|
||||
|
||||
protected static String sha3String(byte[] message, Size bitSize) {
|
||||
SHA3Digest digest = new SHA3Digest(bitSize.bits);
|
||||
return sha3String(message, digest, true);
|
||||
}
|
||||
|
||||
protected static String sha3String(String message, Size bitSize, boolean bouncyencoder) {
|
||||
SHA3Digest digest = new SHA3Digest(bitSize.bits);
|
||||
return sha3String(message, digest, bouncyencoder);
|
||||
}
|
||||
|
||||
protected static String sha3string(byte[] message, Size bitSize, boolean bouncyencoder) {
|
||||
SHA3Digest digest = new SHA3Digest(bitSize.bits);
|
||||
return sha3String(message, digest, bouncyencoder);
|
||||
}
|
||||
|
||||
private static String sha3String(String message, SHA3Digest digest, boolean bouncyencoder) {
|
||||
if (message != null) {
|
||||
return sha3String(Hex.decode(message), digest, bouncyencoder);
|
||||
}
|
||||
throw new NullPointerException("Can't hash a NULL value");
|
||||
}
|
||||
|
||||
private static String sha3String(byte[] message, SHA3Digest digest, boolean bouncyencoder) {
|
||||
byte[] hash = doSha3(message, digest, bouncyencoder);
|
||||
if (bouncyencoder) {
|
||||
return Hex.toHexString(hash);
|
||||
} else {
|
||||
BigInteger bigInt = new BigInteger(1, hash);
|
||||
return bigInt.toString(16);
|
||||
}
|
||||
}
|
||||
|
||||
private static byte[] sha3(byte[] message, SHA3Digest digest, boolean bouncyencoder) {
|
||||
return doSha3(message, digest, bouncyencoder);
|
||||
}
|
||||
|
||||
private static byte[] doSha3(byte[] message, SHA3Digest digest, boolean bouncyencoder) {
|
||||
byte[] hash = new byte[digest.getDigestSize()];
|
||||
|
||||
if (message.length != 0) {
|
||||
digest.update(message, 0, message.length);
|
||||
}
|
||||
digest.doFinal(hash, 0);
|
||||
return hash;
|
||||
}
|
||||
|
||||
public enum Size {
|
||||
|
||||
S224(224),
|
||||
S256(256),
|
||||
S384(384),
|
||||
S512(512);
|
||||
|
||||
int bits = 0;
|
||||
|
||||
Size(int bits) {
|
||||
this.bits = bits;
|
||||
}
|
||||
|
||||
public int getValue() {
|
||||
return this.bits;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,73 @@
|
||||
package org.ethereum.gui;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.table.DefaultTableCellRenderer;
|
||||
import javax.swing.table.TableCellRenderer;
|
||||
|
||||
import java.awt.*;
|
||||
|
||||
/**
|
||||
* www.ethereumJ.com
|
||||
* User: Roman Mandeleil
|
||||
* Created on: 25/04/14 07:11
|
||||
*/
|
||||
public class PeersTableMain extends JFrame{
|
||||
|
||||
// Instance attributes used in this example
|
||||
private JPanel topPanel;
|
||||
private JTable table;
|
||||
private JScrollPane scrollPane;
|
||||
|
||||
// Constructor of main frame
|
||||
public PeersTableMain() {
|
||||
// Set the frame characteristics
|
||||
setTitle("Ethereum Peers");
|
||||
setSize(355, 300);
|
||||
setLocation(815, 80);
|
||||
setBackground(Color.gray);
|
||||
|
||||
java.net.URL url = ClassLoader.getSystemResource("ethereum-icon.png");
|
||||
Toolkit kit = Toolkit.getDefaultToolkit();
|
||||
Image img = kit.createImage(url);
|
||||
this.setIconImage(img);
|
||||
|
||||
// Create a panel to hold all other components
|
||||
topPanel = new JPanel();
|
||||
topPanel.setLayout(new BorderLayout());
|
||||
getContentPane().add(topPanel);
|
||||
|
||||
// Create a new table instance
|
||||
table = new JTable();
|
||||
table.setModel(new PeersTableModel());
|
||||
|
||||
table.setFont(new Font("Courier New", Font.PLAIN, 18));
|
||||
table.setForeground(Color.GRAY);
|
||||
table.setTableHeader(null);
|
||||
|
||||
TableCellRenderer tcr = table.getDefaultRenderer(String.class);
|
||||
DefaultTableCellRenderer renderer = (DefaultTableCellRenderer) tcr;
|
||||
renderer.setHorizontalAlignment(SwingConstants.CENTER);
|
||||
|
||||
table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
|
||||
table.setCellSelectionEnabled(true);
|
||||
|
||||
table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
|
||||
table.getColumnModel().getColumn(0).setPreferredWidth(60);
|
||||
table.getColumnModel().getColumn(1).setPreferredWidth(200);
|
||||
table.getColumnModel().getColumn(2).setPreferredWidth(60);
|
||||
|
||||
table.setRowMargin(3);
|
||||
table.setRowHeight(50);
|
||||
|
||||
// Add the table to a scrolling pane
|
||||
scrollPane = new JScrollPane(table);
|
||||
topPanel.add(scrollPane, BorderLayout.CENTER);
|
||||
}
|
||||
|
||||
public static void main(String args[]) {
|
||||
|
||||
PeersTableMain mainFrame = new PeersTableMain();
|
||||
mainFrame.setVisible(true);
|
||||
mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||
}
|
||||
}
|
@ -1,8 +1,7 @@
|
||||
package org.ethereum.gui;
|
||||
|
||||
import samples.PeersTableMain;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
|
@ -6,7 +6,7 @@ import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.channel.ChannelInboundHandlerAdapter;
|
||||
import io.netty.channel.ChannelOption;
|
||||
import io.netty.channel.FixedRecvByteBufAllocator;
|
||||
import org.bouncycastle.util.encoders.Hex;
|
||||
import org.spongycastle.util.encoders.Hex;
|
||||
import org.ethereum.gui.PeerListener;
|
||||
import org.ethereum.manager.MainData;
|
||||
import org.ethereum.net.RLP;
|
||||
@ -83,8 +83,6 @@ public class EthereumProtocolHandler extends ChannelInboundHandlerAdapter {
|
||||
|
||||
System.out.println("No ping answer for [30 sec]");
|
||||
throw new Error("No ping return for 30 [sec]");
|
||||
|
||||
|
||||
// TODO: shutdown the handler
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
package org.ethereum.net.message;
|
||||
|
||||
import org.bouncycastle.util.encoders.Hex;
|
||||
import org.spongycastle.util.encoders.Hex;
|
||||
import org.ethereum.net.RLP;
|
||||
import org.ethereum.net.rlp.RLPItem;
|
||||
import org.ethereum.net.rlp.RLPList;
|
||||
|
@ -1,5 +1,6 @@
|
||||
package org.ethereum.net.vo;
|
||||
|
||||
import org.ethereum.crypto.HashUtil;
|
||||
import org.ethereum.net.rlp.RLPElement;
|
||||
import org.ethereum.net.rlp.RLPItem;
|
||||
import org.ethereum.net.rlp.RLPList;
|
||||
@ -56,11 +57,10 @@ public class BlockData {
|
||||
|
||||
}
|
||||
|
||||
|
||||
// [parent_hash, uncles_hash, coinbase, state_root, tx_list_hash, difficulty, timestamp, extradata, nonce]
|
||||
private void parseRLP(){
|
||||
|
||||
this.hash = Utils.sha3(rawData.getRLPData());
|
||||
this.hash = HashUtil.sha3(rawData.getRLPData());
|
||||
|
||||
List params = ((RLPList) rawData.getElement(0)).getList();
|
||||
|
||||
|
@ -1,11 +1,10 @@
|
||||
package org.ethereum.net.vo;
|
||||
|
||||
import org.bouncycastle.util.encoders.Hex;
|
||||
import org.spongycastle.util.encoders.Hex;
|
||||
import org.ethereum.net.rlp.RLPList;
|
||||
|
||||
import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* www.ethereumJ.com
|
||||
|
@ -1,5 +1,6 @@
|
||||
package org.ethereum.net.vo;
|
||||
|
||||
import org.ethereum.crypto.HashUtil;
|
||||
import org.ethereum.net.rlp.RLPItem;
|
||||
import org.ethereum.net.rlp.RLPList;
|
||||
import org.ethereum.util.Utils;
|
||||
@ -64,7 +65,7 @@ public class TransactionData {
|
||||
|
||||
if (rawData.size() == 9){ // Simple transaction
|
||||
|
||||
this.hash = Utils.sha3(rawData.getRLPData());
|
||||
this.hash = HashUtil.sha3(rawData.getRLPData());
|
||||
this.nonce = ((RLPItem) rawData.getElement(0)).getData();
|
||||
this.value = ((RLPItem) rawData.getElement(1)).getData();
|
||||
this.receiveAddress = ((RLPItem) rawData.getElement(2)).getData();
|
||||
@ -77,7 +78,7 @@ public class TransactionData {
|
||||
|
||||
} else if (rawData.size() == 10){ // Contract creation transaction
|
||||
|
||||
this.hash = Utils.sha3(rawData.getRLPData());
|
||||
this.hash = HashUtil.sha3(rawData.getRLPData());
|
||||
this.nonce = ((RLPItem) rawData.getElement(0)).getData();
|
||||
this.value = ((RLPItem) rawData.getElement(1)).getData();
|
||||
this.receiveAddress = ((RLPItem) rawData.getElement(2)).getData();
|
||||
|
127
ethereumj-core/src/main/java/org/ethereum/util/ByteUtil.java
Normal file
127
ethereumj-core/src/main/java/org/ethereum/util/ByteUtil.java
Normal file
@ -0,0 +1,127 @@
|
||||
package org.ethereum.util;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.math.BigInteger;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.Arrays;
|
||||
|
||||
import com.google.common.primitives.UnsignedInteger;
|
||||
import com.google.common.primitives.UnsignedLongs;
|
||||
|
||||
public class ByteUtil {
|
||||
|
||||
/** The string that prefixes all text messages signed using Bitcoin keys. */
|
||||
public static final String BITCOIN_SIGNED_MESSAGE_HEADER = "Bitcoin Signed Message:\n";
|
||||
public static final byte[] BITCOIN_SIGNED_MESSAGE_HEADER_BYTES = BITCOIN_SIGNED_MESSAGE_HEADER.getBytes();
|
||||
|
||||
/**
|
||||
* Creates a copy of bytes and appends b to the end of it
|
||||
*/
|
||||
public static byte[] appendByte(byte[] bytes, byte b) {
|
||||
byte[] result = Arrays.copyOf(bytes, bytes.length + 1);
|
||||
result[result.length - 1] = b;
|
||||
return result;
|
||||
}
|
||||
|
||||
// /**
|
||||
// * Returns the given byte array hex encoded.
|
||||
// */
|
||||
// public static String bytesToHexString(byte[] bytes) {
|
||||
// StringBuffer buf = new StringBuffer(bytes.length * 2);
|
||||
// for (byte b : bytes) {
|
||||
// String s = Integer.toString(0xFF & b, 16);
|
||||
// if (s.length() < 2)
|
||||
// buf.append('0');
|
||||
// buf.append(s);
|
||||
// }
|
||||
// return buf.toString();
|
||||
// }
|
||||
|
||||
/**
|
||||
* The regular {@link java.math.BigInteger#toByteArray()} method isn't quite what we often need: it appends a
|
||||
* leading zero to indicate that the number is positive and may need padding.
|
||||
*
|
||||
* @param b the integer to format into a byte array
|
||||
* @param numBytes the desired size of the resulting byte array
|
||||
* @return numBytes byte long array.
|
||||
*/
|
||||
public static byte[] bigIntegerToBytes(BigInteger b, int numBytes) {
|
||||
if (b == null) {
|
||||
return null;
|
||||
}
|
||||
byte[] bytes = new byte[numBytes];
|
||||
byte[] biBytes = b.toByteArray();
|
||||
int start = (biBytes.length == numBytes + 1) ? 1 : 0;
|
||||
int length = Math.min(biBytes.length, numBytes);
|
||||
System.arraycopy(biBytes, start, bytes, numBytes - length, length);
|
||||
return bytes;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Given a textual message, returns a byte buffer formatted as follows:</p>
|
||||
*
|
||||
* <tt><p>[24] "Bitcoin Signed Message:\n" [message.length as a varint] message</p></tt>
|
||||
*/
|
||||
public static byte[] formatForBitcoinSigning(String message) {
|
||||
try {
|
||||
ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
||||
bos.write(BITCOIN_SIGNED_MESSAGE_HEADER_BYTES.length);
|
||||
bos.write(BITCOIN_SIGNED_MESSAGE_HEADER_BYTES);
|
||||
byte[] messageBytes = message.getBytes(Charset.forName("UTF-8"));
|
||||
bos.write(encodeInt(messageBytes.length));
|
||||
bos.write(messageBytes);
|
||||
return bos.toByteArray();
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e); // Cannot happen.
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Given a textual message, returns a byte buffer formatted as follows:</p>
|
||||
*/
|
||||
public static byte[] formatForEthereumSigning(byte[] message) {
|
||||
try {
|
||||
ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
||||
bos.write(encodeInt(message.length));
|
||||
bos.write(message);
|
||||
return bos.toByteArray();
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e); // Cannot happen.
|
||||
}
|
||||
}
|
||||
|
||||
public static byte[] encodeInt(int value) {
|
||||
if (isLessThanUnsigned(value, 253)) {
|
||||
return new byte[]{(byte) value};
|
||||
} else if (isLessThanUnsigned(value, 65536)) {
|
||||
return new byte[]{(byte) 253, (byte) (value), (byte) (value >> 8)};
|
||||
} else if (isLessThanUnsigned(value, UnsignedInteger.MAX_VALUE.longValue())) {
|
||||
byte[] bytes = new byte[5];
|
||||
bytes[0] = (byte) 254;
|
||||
uint32ToByteArrayLE(value, bytes, 1);
|
||||
return bytes;
|
||||
} else {
|
||||
byte[] bytes = new byte[9];
|
||||
bytes[0] = (byte) 255;
|
||||
uint32ToByteArrayLE(value, bytes, 1);
|
||||
uint32ToByteArrayLE(value >>> 32, bytes, 5);
|
||||
return bytes;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Work around lack of unsigned types in Java.
|
||||
*/
|
||||
public static boolean isLessThanUnsigned(long n1, long n2) {
|
||||
return UnsignedLongs.compare(n1, n2) < 0;
|
||||
}
|
||||
|
||||
public static void uint32ToByteArrayLE(long val, byte[] out, int offset) {
|
||||
out[offset + 0] = (byte) (0xFF & (val >> 0));
|
||||
out[offset + 1] = (byte) (0xFF & (val >> 8));
|
||||
out[offset + 2] = (byte) (0xFF & (val >> 16));
|
||||
out[offset + 3] = (byte) (0xFF & (val >> 24));
|
||||
}
|
||||
|
||||
}
|
@ -1,20 +1,12 @@
|
||||
package org.ethereum.util;
|
||||
|
||||
import org.bouncycastle.asn1.sec.SECNamedCurves;
|
||||
import org.bouncycastle.asn1.x9.X9ECParameters;
|
||||
import org.bouncycastle.jce.provider.BouncyCastleProvider;
|
||||
import org.bouncycastle.math.ec.ECPoint;
|
||||
import org.bouncycastle.util.encoders.Hex;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.math.BigInteger;
|
||||
import java.net.URL;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.Security;
|
||||
import java.util.Arrays;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import static java.lang.System.exit;
|
||||
import javax.swing.ImageIcon;
|
||||
|
||||
import org.spongycastle.util.encoders.Hex;
|
||||
|
||||
/**
|
||||
* www.ethereumj.com
|
||||
@ -31,19 +23,14 @@ public class Utils {
|
||||
byte[] result = new byte[arrSize];
|
||||
|
||||
for (int i = 0; i < arrSize; ++i){
|
||||
|
||||
int digit1 = hexSymbols.indexOf( hexString.charAt(i * 3) );
|
||||
int digit2 = hexSymbols.indexOf( hexString.charAt(i * 3 + 1) );
|
||||
|
||||
result[i] = (byte) (digit1 * 16 + digit2);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
public static String toHexString(byte[] data){
|
||||
|
||||
if (data == null) return "null";
|
||||
else return Hex.toHexString(data);
|
||||
}
|
||||
@ -61,7 +48,6 @@ public class Utils {
|
||||
return (new BigInteger(1, numberBytes)).toString();
|
||||
}
|
||||
|
||||
|
||||
public static void printHexStringForByte(byte data){
|
||||
|
||||
System.out.print("[");
|
||||
@ -70,16 +56,11 @@ public class Utils {
|
||||
if (((int) data & 0xFF) < 16) {
|
||||
hexNum = "0" + hexNum;
|
||||
}
|
||||
|
||||
System.out.print( hexNum );
|
||||
|
||||
System.out.print("]");
|
||||
|
||||
System.out.println();
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static void printHexStringForByteArray(byte[] data){
|
||||
|
||||
System.out.print("[");
|
||||
@ -89,80 +70,17 @@ public class Utils {
|
||||
if (((int) data[i] & 0xFF) < 16) {
|
||||
hexNum = "0" + hexNum;
|
||||
}
|
||||
|
||||
System.out.print( hexNum );
|
||||
System.out.print(" ");
|
||||
}
|
||||
System.out.print("]");
|
||||
|
||||
System.out.println();
|
||||
}
|
||||
|
||||
private static MessageDigest sha3Digest = null;
|
||||
private static MessageDigest ripemd160Digest = null;
|
||||
static {
|
||||
|
||||
try{
|
||||
Security.addProvider(new BouncyCastleProvider());
|
||||
ripemd160Digest = MessageDigest.getInstance("RIPEMD160", "BC");
|
||||
sha3Digest = MessageDigest.getInstance("SHA3-256", "BC");
|
||||
} catch (Throwable th){
|
||||
|
||||
th.printStackTrace();
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
public static byte[] sha3(byte[] token){
|
||||
return sha3Digest.digest(token);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static byte[] ripemd160(byte[] token){
|
||||
|
||||
return ripemd160Digest.digest(token);
|
||||
}
|
||||
|
||||
|
||||
static X9ECParameters curvParams = SECNamedCurves.getByName("secp256k1");
|
||||
|
||||
public static byte[] privToAddress(byte[] priv){
|
||||
|
||||
/* address create howto
|
||||
|
||||
token = "cow"
|
||||
step1 = sha3(token) // generate 256 bit privkey
|
||||
step2 = privtopub(step1)[1:] // generate 512 bit pubkey with secp256k1
|
||||
step3 = sha3(step2)[12:]
|
||||
*/
|
||||
|
||||
// TODO: validity checks
|
||||
BigInteger privKey = new BigInteger(1, priv);
|
||||
|
||||
|
||||
ECPoint Q = curvParams.getG().multiply(privKey);
|
||||
byte[] pubKey = Q.getEncoded();
|
||||
|
||||
// TODO: find a performance improvement here - how to omit creation of new byte[]
|
||||
byte[] _pubKey = Arrays.copyOfRange(pubKey, 1, pubKey.length);
|
||||
|
||||
byte[] _addr = Utils.sha3(_pubKey);
|
||||
|
||||
// TODO: find a performance improvement here - how to omit creation of new byte[]
|
||||
byte[] addr = Arrays.copyOfRange(_addr, 12, _addr.length);
|
||||
|
||||
return addr;
|
||||
}
|
||||
|
||||
|
||||
public static ImageIcon getImageIcon(String resource){
|
||||
|
||||
URL imageURL = ClassLoader.getSystemResource(resource);
|
||||
ImageIcon image = new ImageIcon(imageURL);
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -1,439 +0,0 @@
|
||||
package samples;
|
||||
// ==================================================================
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import javax.crypto.Mac;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
|
||||
/**
|
||||
* Deterministic DSA signature generation. This is a sample
|
||||
* implementation designed to illustrate how deterministic DSA
|
||||
* chooses the pseudorandom value k when signing a given message.
|
||||
* This implementation was NOT optimized or hardened against
|
||||
* side-channel leaks.
|
||||
*
|
||||
* An instance is created with a hash function name, which must be
|
||||
* supported by the underlying Java virtual machine ("SHA-1" and
|
||||
* "SHA-256" should work everywhere). The data to sign is input
|
||||
* through the {@code update()} methods. The private key is set with
|
||||
* {@link #setPrivateKey}. The signature is obtained by calling
|
||||
* {@link #sign}; alternatively, {@link #signHash} can be used to
|
||||
* sign some data that has been externally hashed. The private key
|
||||
* MUST be set before generating the signature itself, but message
|
||||
* data can be input before setting the key.
|
||||
*
|
||||
* Instances are NOT thread-safe. However, once a signature has
|
||||
* been generated, the same instance can be used again for another
|
||||
* signature; {@link #setPrivateKey} need not be called again if the
|
||||
* private key has not changed. {@link #reset} can also be called to
|
||||
* cancel previously input data. Generating a signature with {@link
|
||||
* #sign} (not {@link #signHash}) also implicitly causes a
|
||||
* reset.
|
||||
*
|
||||
* ------------------------------------------------------------------
|
||||
* Copyright (c) 2013 IETF Trust and the persons identified as
|
||||
* authors of the code. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, is permitted pursuant to, and subject to the license
|
||||
* terms contained in, the Simplified BSD License set forth in Section
|
||||
* 4.c of the IETF Trust's Legal Provisions Relating to IETF Documents
|
||||
* (http://trustee.ietf.org/license-info).
|
||||
*
|
||||
* Technical remarks and questions can be addressed to:
|
||||
* pornin@bolet.org
|
||||
* ------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
public class DeterministicDSA {
|
||||
|
||||
private String macName;
|
||||
private MessageDigest dig;
|
||||
private Mac hmac;
|
||||
private BigInteger p, q, g, x;
|
||||
private int qlen, rlen, rolen, holen;
|
||||
private byte[] bx;
|
||||
|
||||
/**
|
||||
* Create an instance, using the specified hash function.
|
||||
* The name is used to obtain from the JVM an implementation
|
||||
* of the hash function and an implementation of HMAC.
|
||||
*
|
||||
* @param hashName the hash function name
|
||||
* @throws IllegalArgumentException on unsupported name
|
||||
*/
|
||||
public DeterministicDSA(String hashName)
|
||||
{
|
||||
try {
|
||||
dig = MessageDigest.getInstance(hashName);
|
||||
} catch (NoSuchAlgorithmException nsae) {
|
||||
throw new IllegalArgumentException(nsae);
|
||||
}
|
||||
if (hashName.indexOf('-') < 0) {
|
||||
macName = "Hmac" + hashName;
|
||||
} else {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("Hmac");
|
||||
int n = hashName.length();
|
||||
for (int i = 0; i < n; i ++) {
|
||||
char c = hashName.charAt(i);
|
||||
if (c != '-') {
|
||||
sb.append(c);
|
||||
}
|
||||
}
|
||||
macName = sb.toString();
|
||||
|
||||
}
|
||||
try {
|
||||
hmac = Mac.getInstance(macName);
|
||||
} catch (NoSuchAlgorithmException nsae) {
|
||||
throw new IllegalArgumentException(nsae);
|
||||
}
|
||||
holen = hmac.getMacLength();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the private key.
|
||||
*
|
||||
* @param p key parameter: field modulus
|
||||
* @param q key parameter: subgroup order
|
||||
* @param g key parameter: generator
|
||||
* @param x private key
|
||||
*/
|
||||
public void setPrivateKey(BigInteger p, BigInteger q,
|
||||
BigInteger g, BigInteger x)
|
||||
{
|
||||
/*
|
||||
* Perform some basic sanity checks. We do not
|
||||
* check primality of p or q because that would
|
||||
* be too expensive.
|
||||
*
|
||||
* We reject keys where q is longer than 999 bits,
|
||||
* because it would complicate signature encoding.
|
||||
* Normal DSA keys do not have a q longer than 256
|
||||
* bits anyway.
|
||||
*/
|
||||
if (p == null || q == null || g == null || x == null
|
||||
|| p.signum() <= 0 || q.signum() <= 0
|
||||
|| g.signum() <= 0 || x.signum() <= 0
|
||||
|| x.compareTo(q) >= 0 || q.compareTo(p) >= 0
|
||||
|| q.bitLength() > 999
|
||||
|| g.compareTo(p) >= 0 || g.bitLength() == 1
|
||||
|| g.modPow(q, p).bitLength() != 1) {
|
||||
throw new IllegalArgumentException(
|
||||
"invalid DSA private key");
|
||||
}
|
||||
this.p = p;
|
||||
this.q = q;
|
||||
this.g = g;
|
||||
this.x = x;
|
||||
qlen = q.bitLength();
|
||||
if (q.signum() <= 0 || qlen < 8) {
|
||||
throw new IllegalArgumentException(
|
||||
"bad group order: " + q);
|
||||
|
||||
|
||||
}
|
||||
rolen = (qlen + 7) >>> 3;
|
||||
rlen = rolen * 8;
|
||||
|
||||
/*
|
||||
* Convert the private exponent (x) into a sequence
|
||||
* of octets.
|
||||
*/
|
||||
bx = int2octets(x);
|
||||
}
|
||||
|
||||
private BigInteger bits2int(byte[] in)
|
||||
{
|
||||
BigInteger v = new BigInteger(1, in);
|
||||
int vlen = in.length * 8;
|
||||
if (vlen > qlen) {
|
||||
v = v.shiftRight(vlen - qlen);
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
private byte[] int2octets(BigInteger v)
|
||||
{
|
||||
byte[] out = v.toByteArray();
|
||||
if (out.length < rolen) {
|
||||
byte[] out2 = new byte[rolen];
|
||||
System.arraycopy(out, 0,
|
||||
out2, rolen - out.length,
|
||||
out.length);
|
||||
return out2;
|
||||
} else if (out.length > rolen) {
|
||||
byte[] out2 = new byte[rolen];
|
||||
System.arraycopy(out, out.length - rolen,
|
||||
out2, 0, rolen);
|
||||
return out2;
|
||||
} else {
|
||||
return out;
|
||||
}
|
||||
}
|
||||
|
||||
private byte[] bits2octets(byte[] in)
|
||||
{
|
||||
BigInteger z1 = bits2int(in);
|
||||
BigInteger z2 = z1.subtract(q);
|
||||
return int2octets(z2.signum() < 0 ? z1 : z2);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
|
||||
|
||||
Pornin Informational [Page 73]
|
||||
|
||||
RFC 6979 Deterministic DSA and ECDSA August 2013
|
||||
|
||||
|
||||
* Set (or reset) the secret key used for HMAC.
|
||||
*
|
||||
* @param K the new secret key
|
||||
*/
|
||||
private void setHmacKey(byte[] K)
|
||||
{
|
||||
try {
|
||||
hmac.init(new SecretKeySpec(K, macName));
|
||||
} catch (InvalidKeyException ike) {
|
||||
throw new IllegalArgumentException(ike);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute the pseudorandom k for signature generation,
|
||||
* using the process specified for deterministic DSA.
|
||||
*
|
||||
* @param h1 the hashed message
|
||||
* @return the pseudorandom k to use
|
||||
*/
|
||||
private BigInteger computek(byte[] h1)
|
||||
{
|
||||
/*
|
||||
* Convert hash value into an appropriately truncated
|
||||
* and/or expanded sequence of octets. The private
|
||||
* key was already processed (into field bx[]).
|
||||
*/
|
||||
byte[] bh = bits2octets(h1);
|
||||
|
||||
/*
|
||||
* HMAC is always used with K as key.
|
||||
* Whenever K is updated, we reset the
|
||||
* current HMAC key.
|
||||
*/
|
||||
|
||||
/* step b. */
|
||||
byte[] V = new byte[holen];
|
||||
for (int i = 0; i < holen; i ++) {
|
||||
V[i] = 0x01;
|
||||
}
|
||||
|
||||
/* step c. */
|
||||
byte[] K = new byte[holen];
|
||||
setHmacKey(K);
|
||||
|
||||
/* step d. */
|
||||
hmac.update(V);
|
||||
hmac.update((byte)0x00);
|
||||
hmac.update(bx);
|
||||
hmac.update(bh);
|
||||
K = hmac.doFinal();
|
||||
setHmacKey(K);
|
||||
|
||||
/* step e. */
|
||||
hmac.update(V);
|
||||
V = hmac.doFinal();
|
||||
|
||||
/* step f. */
|
||||
hmac.update(V);
|
||||
hmac.update((byte)0x01);
|
||||
hmac.update(bx);
|
||||
hmac.update(bh);
|
||||
K = hmac.doFinal();
|
||||
setHmacKey(K);
|
||||
|
||||
/* step g. */
|
||||
hmac.update(V);
|
||||
V = hmac.doFinal();
|
||||
|
||||
/* step h. */
|
||||
byte[] T = new byte[rolen];
|
||||
for (;;) {
|
||||
/*
|
||||
* We want qlen bits, but we support only
|
||||
* hash functions with an output length
|
||||
* multiple of 8;acd hence, we will gather
|
||||
* rlen bits, i.e., rolen octets.
|
||||
*/
|
||||
int toff = 0;
|
||||
while (toff < rolen) {
|
||||
hmac.update(V);
|
||||
V = hmac.doFinal();
|
||||
int cc = Math.min(V.length,
|
||||
T.length - toff);
|
||||
System.arraycopy(V, 0, T, toff, cc);
|
||||
toff += cc;
|
||||
}
|
||||
BigInteger k = bits2int(T);
|
||||
if (k.signum() > 0 && k.compareTo(q) < 0) {
|
||||
return k;
|
||||
}
|
||||
|
||||
/*
|
||||
* k is not in the proper range; update
|
||||
* K and V, and loop.
|
||||
*/
|
||||
|
||||
hmac.update(V);
|
||||
hmac.update((byte)0x00);
|
||||
K = hmac.doFinal();
|
||||
setHmacKey(K);
|
||||
hmac.update(V);
|
||||
V = hmac.doFinal();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Process one more byte of input data (message to sign).
|
||||
*
|
||||
* @param in the extra input byte
|
||||
*/
|
||||
public void update(byte in)
|
||||
{
|
||||
dig.update(in);
|
||||
}
|
||||
|
||||
/**
|
||||
* Process some extra bytes of input data (message to sign).
|
||||
*
|
||||
* @param in the extra input bytes
|
||||
*/
|
||||
public void update(byte[] in)
|
||||
{
|
||||
dig.update(in, 0, in.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Process some extra bytes of input data (message to sign).
|
||||
*
|
||||
* @param in the extra input buffer
|
||||
* @param off the extra input offset
|
||||
* @param len the extra input length (in bytes)
|
||||
*/
|
||||
public void update(byte[] in, int off, int len)
|
||||
{
|
||||
dig.update(in, off, len);
|
||||
}
|
||||
|
||||
/**
|
||||
* Produce the signature. {@link #setPrivateKey} MUST have
|
||||
* been called. The signature is computed over the data
|
||||
* that was input through the {@code update*()} methods.
|
||||
* This engine is then reset (made ready for a new
|
||||
* signature generation).
|
||||
*
|
||||
|
||||
|
||||
|
||||
Pornin Informational [Page 76]
|
||||
|
||||
RFC 6979 Deterministic DSA and ECDSA August 2013
|
||||
|
||||
|
||||
* @return the signature
|
||||
*/
|
||||
public byte[] sign()
|
||||
{
|
||||
return signHash(dig.digest());
|
||||
}
|
||||
|
||||
/**
|
||||
* Produce the signature. {@link #setPrivateKey} MUST
|
||||
* have been called. The signature is computed over the
|
||||
* provided hash value (data is assumed to have been hashed
|
||||
* externally). The data that was input through the
|
||||
* {@code update*()} methods is ignored, but kept.
|
||||
*
|
||||
* If the hash output is longer than the subgroup order
|
||||
* (the length of q, in bits, denoted 'qlen'), then the
|
||||
* provided value {@code h1} can be truncated, provided that
|
||||
* at least qlen leading bits are preserved. In other words,
|
||||
* bit values in {@code h1} beyond the first qlen bits are
|
||||
* ignored.
|
||||
*
|
||||
* @param h1 the hash value
|
||||
* @return the signature
|
||||
*/
|
||||
public byte[] signHash(byte[] h1)
|
||||
{
|
||||
if (p == null) {
|
||||
throw new IllegalStateException(
|
||||
"no private key set");
|
||||
}
|
||||
try {
|
||||
BigInteger k = computek(h1);
|
||||
BigInteger r = g.modPow(k, p).mod(q);
|
||||
BigInteger s = k.modInverse(q).multiply(
|
||||
bits2int(h1).add(x.multiply(r)))
|
||||
.mod(q);
|
||||
|
||||
/*
|
||||
* Signature encoding: ASN.1 SEQUENCE of
|
||||
* two INTEGERs. The conditions on q
|
||||
* imply that the encoded version of r and
|
||||
* s is no longer than 127 bytes for each,
|
||||
* including DER tag and length.
|
||||
*/
|
||||
byte[] br = r.toByteArray();
|
||||
byte[] bs = s.toByteArray();
|
||||
int ulen = br.length + bs.length + 4;
|
||||
int slen = ulen + (ulen >= 128 ? 3 : 2);
|
||||
|
||||
byte[] sig = new byte[slen];
|
||||
int i = 0;
|
||||
sig[i ++] = 0x30;
|
||||
if (ulen >= 128) {
|
||||
sig[i ++] = (byte)0x81;
|
||||
sig[i ++] = (byte)ulen;
|
||||
} else {
|
||||
sig[i ++] = (byte)ulen;
|
||||
}
|
||||
sig[i ++] = 0x02;
|
||||
sig[i ++] = (byte)br.length;
|
||||
System.arraycopy(br, 0, sig, i, br.length);
|
||||
i += br.length;
|
||||
sig[i ++] = 0x02;
|
||||
sig[i ++] = (byte)bs.length;
|
||||
System.arraycopy(bs, 0, sig, i, bs.length);
|
||||
return sig;
|
||||
|
||||
} catch (ArithmeticException ae) {
|
||||
throw new IllegalArgumentException(
|
||||
"DSA error (bad key ?)", ae);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset this engine. Data input through the {@code
|
||||
* update*()} methods is discarded. The current private key,
|
||||
* if one was set, is kept unchanged.
|
||||
*/
|
||||
public void reset()
|
||||
{
|
||||
dig.reset();
|
||||
}
|
||||
}
|
||||
|
||||
// ==================================================================
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -1,191 +0,0 @@
|
||||
package samples;
|
||||
|
||||
import com.maxmind.geoip.LookupService;
|
||||
import com.maxmind.geoip.Region;
|
||||
import com.maxmind.geoip.regionName;
|
||||
import com.maxmind.geoip2.exception.GeoIp2Exception;
|
||||
import org.ethereum.net.RLP;
|
||||
import org.ethereum.util.Utils;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.URL;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.channels.SocketChannel;
|
||||
import java.util.LinkedList;
|
||||
import java.util.Queue;
|
||||
|
||||
/**
|
||||
* www.openchain.info
|
||||
* User: Roman Mandeleil
|
||||
* Created on: 31/03/14 21:06
|
||||
*/
|
||||
public class Main1 {
|
||||
|
||||
public static void main(String args[]) throws IOException, GeoIp2Exception, URISyntaxException {
|
||||
|
||||
|
||||
try {
|
||||
|
||||
URL flagURL = ClassLoader.getSystemResource("GeoLiteCity.dat");
|
||||
File file = new File(flagURL.toURI());
|
||||
LookupService cl = new LookupService(file);
|
||||
System.out.println(cl.getLocation("110.77.217.185"));
|
||||
|
||||
|
||||
} catch (IOException e) {
|
||||
System.out.println("IO Exception");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
public static void main1(String args[]) throws IOException {
|
||||
|
||||
//22400891000000088400000043414243
|
||||
|
||||
String helloPacket = "22400891000000088400000043414243";
|
||||
String pingPacket = "224008910000000102";
|
||||
|
||||
System.out.println(helloPacket);
|
||||
|
||||
SocketChannel socketChannel = SocketChannel.open();
|
||||
socketChannel.connect(new InetSocketAddress("localhost", 20202));
|
||||
socketChannel.configureBlocking(false);
|
||||
|
||||
String helloString = "22 40 08 91 00 00 00 79 F8 77 80 0A 80 AD 45 74 " +
|
||||
"68 65 72 65 75 6D 28 2B 2B 29 2F 5A 65 72 6F 47 " +
|
||||
"6F 78 2F 76 30 2E 34 2E 31 2F 6E 63 75 72 73 65 " +
|
||||
"73 2F 4C 69 6E 75 78 2F 67 2B 2B 07 82 76 5F B8 " +
|
||||
"40 D8 D6 0C 25 80 FA 79 5C FC 03 13 EF DE BA 86 " +
|
||||
"9D 21 94 E7 9E 7C B2 B5 22 F7 82 FF A0 39 2C BB " +
|
||||
"AB 8D 1B AC 30 12 08 B1 37 E0 DE 49 98 33 4F 3B " +
|
||||
"CF 73 FA 11 7E F2 13 F8 74 17 08 9F EA F8 4C 21 " +
|
||||
"B0 22 40 08 91 00 00 00 02 C1 02 22 40 08 91 00 " +
|
||||
"00 00 26 E5 14 A0 AB 6B 9A 56 13 97 0F AA 77 1B " +
|
||||
"12 D4 49 B2 E9 BB 92 5A B7 A3 69 F0 A4 B8 6B 28 " +
|
||||
"6E 9D 54 00 99 CF 82 01 00 22 40 08 91 00 00 00 " +
|
||||
"02 C1 16 22 40 08 91 00 00 00 02 C1 01 ";
|
||||
|
||||
String getPeersString = "22 40 08 91 00 00 00 02 C1 10 ";
|
||||
|
||||
|
||||
byte[] helloBytes = hexStringToByteArr(helloString);
|
||||
|
||||
// Sending
|
||||
ByteBuffer outBuffer = ByteBuffer.allocate(helloBytes.length);
|
||||
|
||||
outBuffer.clear();
|
||||
outBuffer.put(helloBytes);
|
||||
outBuffer.flip();
|
||||
|
||||
while (outBuffer.hasRemaining()) {
|
||||
socketChannel.write(outBuffer);
|
||||
}
|
||||
|
||||
|
||||
outBuffer.clear();
|
||||
byte[] getPeersBytes = hexStringToByteArr(getPeersString);
|
||||
|
||||
// Sending
|
||||
outBuffer = ByteBuffer.allocate(getPeersBytes.length);
|
||||
|
||||
outBuffer.clear();
|
||||
outBuffer.put(getPeersBytes);
|
||||
outBuffer.flip();
|
||||
|
||||
while (outBuffer.hasRemaining()) {
|
||||
socketChannel.write(outBuffer);
|
||||
}
|
||||
|
||||
|
||||
ByteBuffer inBuffer = ByteBuffer.allocate(1);
|
||||
|
||||
int bytesRead = socketChannel.read(inBuffer); //read into buffer.
|
||||
while (bytesRead != -1) {
|
||||
|
||||
inBuffer.flip(); //make buffer ready for read
|
||||
|
||||
while (inBuffer.hasRemaining()) {
|
||||
|
||||
byte oneByte = inBuffer.get();
|
||||
|
||||
System.out.print(Integer.toHexString((int) oneByte & 0x00FF)); // read 1 byte at a time
|
||||
System.out.print(" ");
|
||||
}
|
||||
|
||||
|
||||
inBuffer.clear(); //make buffer ready for writing
|
||||
bytesRead = socketChannel.read(inBuffer);
|
||||
}
|
||||
|
||||
|
||||
// read 4 bytes sync token 0x22400891
|
||||
// read 4 bytes packet size token, translate to size
|
||||
|
||||
// read packet according the size
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
public static byte[] hexStringToByteArr(String hexString) {
|
||||
|
||||
String hexSymbols = "0123456789ABCDEF";
|
||||
|
||||
int arrSize = (int) (hexString.length() / 3);
|
||||
byte[] result = new byte[arrSize];
|
||||
|
||||
for (int i = 0; i < arrSize; ++i) {
|
||||
|
||||
int digit1 = hexSymbols.indexOf(hexString.charAt(i * 3));
|
||||
int digit2 = hexSymbols.indexOf(hexString.charAt(i * 3 + 1));
|
||||
|
||||
result[i] = (byte) (digit1 * 16 + digit2);
|
||||
}
|
||||
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
public static void main2(String args[]) {
|
||||
|
||||
String helloPacket =
|
||||
"F8 77 80 0B 80 AD 45 74 68 65 72 65 75 6D 28 2B 2B 29 " +
|
||||
"2F 5A 65 72 6F 47 6F 78 2F 76 30 2E 34 2E 32 2F " +
|
||||
"6E 63 75 72 73 65 73 2F 4C 69 6E 75 78 2F 67 2B " +
|
||||
"2B 07 82 76 5F B8 40 80 7D 3E D5 E7 7C BA 05 8D " +
|
||||
"C0 55 4A E0 90 98 9E FE EA 55 33 52 B3 1A DF DB " +
|
||||
"80 5E 2A 1A 7D F7 9D 14 FE 8D 9D 2C CE AA D8 E9 " +
|
||||
"4B 09 37 47 F1 33 C3 EE F3 98 83 96 20 1D 24 17 " +
|
||||
"93 83 5D 38 70 FF D4";
|
||||
|
||||
|
||||
String peersPacket = "F8 4E 11 F8 4B C5 36 81 " +
|
||||
"CC 0A 29 82 76 5F B8 40 D8 D6 0C 25 80 FA 79 5C " +
|
||||
"FC 03 13 EF DE BA 86 9D 21 94 E7 9E 7C B2 B5 22 " +
|
||||
"F7 82 FF A0 39 2C BB AB 8D 1B AC 30 12 08 B1 37 " +
|
||||
"E0 DE 49 98 33 4F 3B CF 73 FA 11 7E F2 13 F8 74 " +
|
||||
"17 08 9F EA F8 4C 21 B0";
|
||||
|
||||
|
||||
byte[] payload = Utils.hexStringToByteArr(peersPacket);
|
||||
|
||||
Utils.printHexStringForByteArray(payload);
|
||||
|
||||
Queue<Integer> index = new LinkedList<Integer>();
|
||||
RLP.fullTraverse(payload, 0, 0, payload.length, 1, index);
|
||||
|
||||
// for (Integer item : index) System.out.println("ind --> " + item);
|
||||
|
||||
|
||||
// Message newMessage = MessageFactory.createMessage(payload, index);
|
||||
// System.out.println(newMessage.toString());
|
||||
|
||||
|
||||
}
|
||||
}
|
@ -1,84 +0,0 @@
|
||||
package samples;
|
||||
|
||||
import org.ethereum.net.client.ClientPeer;
|
||||
|
||||
/**
|
||||
* www.ethereumJ.com
|
||||
* User: Roman Mandeleil
|
||||
* Created on: 10/04/14 12:50
|
||||
*/
|
||||
public class Main2 {
|
||||
|
||||
|
||||
public static void main(String args[]){
|
||||
|
||||
// 66.49.191.123
|
||||
// 54.204.10.41
|
||||
// 130.88.0.226
|
||||
// 85.65.126.45
|
||||
// 54.72.31.55
|
||||
|
||||
// new ClientPeer().connect("66.49.191.123", 30303);
|
||||
// new ClientPeer().connect("66.49.191.123", 30303);
|
||||
|
||||
// new ClientPeer().connect("54.72.31.55", 30303);
|
||||
|
||||
String ip_1 = "131.104.252.4";
|
||||
String ip_2 = "107.170.57.247";
|
||||
String ip_3 = "68.48.173.163";
|
||||
String ip_4 = "86.183.231.205";
|
||||
String ip_5 = "68.185.234.64";
|
||||
String ip_6 = "207.219.69.154";
|
||||
|
||||
|
||||
|
||||
|
||||
// new ClientPeer().connect("192.168.1.102", 30303);
|
||||
|
||||
|
||||
// new ClientPeer().connect("83.172.226.79", 30303);
|
||||
// new ClientPeer().connect("68.48.173.163", 31313);
|
||||
// new ClientPeer().connect("86.150.41.127", 30303);
|
||||
|
||||
// new ClientPeer().connect("82.217.72.169", 30303); nicksavers
|
||||
// new ClientPeer().connect("94.197.120.80", 30303); stephan (ursium)
|
||||
|
||||
|
||||
// new ClientPeer().connect("54.72.31.55", 30303); // peer discovery: capability = 4
|
||||
|
||||
new ClientPeer().connect("54.201.28.117", 30303); // poc-5
|
||||
// new ClientPeer().connect("94.210.200.192", 30303); // poc-5
|
||||
// new ClientPeer().connect("62.78.198.208", 30303); // poc-5 not stable
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/* POC - 5
|
||||
|
||||
Hello: [/206.223.168.190] Canada
|
||||
Hello: [/94.210.200.192] Netherlands
|
||||
Hello: [/88.69.198.198] Germany
|
||||
Hello: [/24.157.83.122] Canada
|
||||
Hello: [/71.202.162.40] United States
|
||||
Hello: [/64.231.10.208] Canada
|
||||
Hello: [/85.65.126.45] Israel
|
||||
Hello: [/62.78.198.208] Finland
|
||||
Hello: [/50.133.12.228] United States
|
||||
Hello: [/77.166.77.107] Netherlands
|
||||
Hello: [/110.77.217.185] Thailand
|
||||
Hello: [/64.231.9.30] Canada
|
||||
Hello: [/213.100.250.57] Sweden
|
||||
Hello: [/162.243.203.121] United States
|
||||
Hello: [/82.217.72.169] Netherlands
|
||||
Hello: [/99.231.80.166] Canada
|
||||
Hello: [/131.104.252.4] Canada
|
||||
Hello: [/54.204.10.41] United States
|
||||
Hello: [/54.201.28.117] United States
|
||||
Hello: [/67.204.1.162] Canada
|
||||
Hello: [/82.240.16.5] France
|
||||
Hello: [/74.79.23.119] United States
|
||||
*/
|
||||
|
||||
|
@ -1,48 +0,0 @@
|
||||
package samples;
|
||||
|
||||
|
||||
|
||||
import org.bouncycastle.jce.ECPointUtil;
|
||||
import org.bouncycastle.jce.provider.BouncyCastleProvider;
|
||||
import org.bouncycastle.jce.spec.ECParameterSpec;
|
||||
import org.bouncycastle.jce.spec.ECPrivateKeySpec;
|
||||
import org.bouncycastle.jce.spec.ECPublicKeySpec;
|
||||
import org.bouncycastle.util.encoders.Hex;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.math.BigInteger;
|
||||
import java.security.*;
|
||||
import java.security.spec.ECFieldF2m;
|
||||
import java.security.spec.EllipticCurve;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* www.ethereumJ.com
|
||||
* User: Roman Mandeleil
|
||||
* Created on: 17/04/14 09:37
|
||||
*/
|
||||
public class Main3 {
|
||||
|
||||
static private byte[] shortMsg = Hex.decode("54686520717569636B2062726F776E20666F78206A756D7073206F76657220746865206C617A7920646F67");
|
||||
|
||||
public static void main(String args[]) throws NoSuchProviderException, NoSuchAlgorithmException, IOException {
|
||||
|
||||
Security.addProvider(new BouncyCastleProvider());
|
||||
|
||||
MessageDigest digest = MessageDigest.getInstance("SHA3-256", "BC");
|
||||
byte[] result = digest.digest(shortMsg);
|
||||
|
||||
byte[] expected = Hex.decode("4D741B6F1EB29CB2A9B9911C82F56FA8D73B04959D3D9D222895DF6C0B28AA15");
|
||||
|
||||
if (Arrays.equals(expected, result)){
|
||||
|
||||
System.out.println("equal !!!");
|
||||
} else {
|
||||
|
||||
Hex.encode(result, System.out);
|
||||
System.out.flush();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
@ -1,64 +0,0 @@
|
||||
package samples;
|
||||
|
||||
|
||||
import org.bouncycastle.jce.ECPointUtil;
|
||||
import org.bouncycastle.jce.provider.BouncyCastleProvider;
|
||||
import org.bouncycastle.util.encoders.Hex;
|
||||
import org.ethereum.util.Utils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.math.BigInteger;
|
||||
import java.security.*;
|
||||
import java.security.spec.*;
|
||||
|
||||
/**
|
||||
* www.ethereumJ.com
|
||||
* User: Roman Mandeleil
|
||||
* Created on: 17/04/14 09:37
|
||||
*/
|
||||
public class Main4 {
|
||||
|
||||
static private byte[] shortMsg = Hex.decode("54686520717569636B2062726F776E20666F78206A756D7073206F76657220746865206C617A7920646F67");
|
||||
|
||||
public static void main(String args[]) throws NoSuchProviderException, NoSuchAlgorithmException, IOException, InvalidKeySpecException {
|
||||
|
||||
Security.addProvider(new BouncyCastleProvider());
|
||||
|
||||
|
||||
EllipticCurve curve = new EllipticCurve(
|
||||
new ECFieldF2m(239, // m
|
||||
new int[] { 36 }), // k
|
||||
new BigInteger("32010857077C5431123A46B808906756F543423E8D27877578125778AC76", 16), // a
|
||||
new BigInteger("790408F2EEDAF392B012EDEFB3392F30F4327C0CA3F31FC383C422AA8C16", 16)); // b
|
||||
|
||||
ECParameterSpec params = new ECParameterSpec(
|
||||
curve,
|
||||
ECPointUtil.decodePoint(curve,
|
||||
Hex.decode("0457927098FA932E7C0A96D3FD5B706EF7E5F5C156E16B7E7C86038552E91D61D8EE5077C33FECF6F1A16B268DE469C3C7744EA9A971649FC7A9616305")), // G
|
||||
new BigInteger("220855883097298041197912187592864814557886993776713230936715041207411783"), // n
|
||||
4); // h
|
||||
|
||||
ECPrivateKeySpec priKeySpec = new ECPrivateKeySpec(
|
||||
new BigInteger("145642755521911534651321230007534120304391871461646461466464667494947990"), // d
|
||||
params);
|
||||
|
||||
ECPublicKeySpec pubKeySpec = new ECPublicKeySpec(
|
||||
ECPointUtil.decodePoint(curve, Hex.decode("045894609CCECF9A92533F630DE713A958E96C97CCB8F5ABB5A688A238DEED6DC2D9D0C94EBFB7D526BA6A61764175B99CB6011E2047F9F067293F57F5")), // Q
|
||||
params);
|
||||
|
||||
Signature sgr = Signature.getInstance("ECDSA", "BC");
|
||||
KeyFactory f = KeyFactory.getInstance("ECDSA", "BC");
|
||||
PrivateKey sKey = f.generatePrivate(priKeySpec);
|
||||
PublicKey vKey = f.generatePublic(pubKeySpec);
|
||||
|
||||
// System.out.println(vKey);
|
||||
|
||||
|
||||
|
||||
System.out.println(Hex.toHexString(Utils.sha3("coinbase".getBytes())));
|
||||
|
||||
// toAddress(sha3("coinbase"));
|
||||
// toAddress(76ec948a9207fdea26dcba91086bcdd181920ff52a539b0d1eb28e73b4cd92af);
|
||||
|
||||
}
|
||||
}
|
@ -1,81 +0,0 @@
|
||||
package samples;
|
||||
|
||||
import org.ethereum.gui.PeersTableModel;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.table.DefaultTableCellRenderer;
|
||||
import javax.swing.table.TableCellRenderer;
|
||||
import java.awt.*;
|
||||
|
||||
/**
|
||||
* www.ethereumJ.com
|
||||
* User: Roman Mandeleil
|
||||
* Created on: 25/04/14 07:11
|
||||
*/
|
||||
public class PeersTableMain extends JFrame{
|
||||
|
||||
|
||||
|
||||
// Instance attributes used in this example
|
||||
private JPanel topPanel;
|
||||
private JTable table;
|
||||
private JScrollPane scrollPane;
|
||||
|
||||
// Constructor of main frame
|
||||
public PeersTableMain()
|
||||
{
|
||||
// Set the frame characteristics
|
||||
setTitle( "Ethereum Peers" );
|
||||
setSize( 355, 300 );
|
||||
setLocation(815, 80);
|
||||
setBackground( Color.gray );
|
||||
|
||||
java.net.URL url = ClassLoader.getSystemResource("ethereum-icon.png");
|
||||
Toolkit kit = Toolkit.getDefaultToolkit();
|
||||
Image img = kit.createImage(url);
|
||||
this.setIconImage(img);
|
||||
|
||||
|
||||
// Create a panel to hold all other components
|
||||
topPanel = new JPanel();
|
||||
topPanel.setLayout( new BorderLayout() );
|
||||
getContentPane().add( topPanel );
|
||||
|
||||
|
||||
// Create a new table instance
|
||||
table = new JTable( );
|
||||
table.setModel(new PeersTableModel());
|
||||
|
||||
table.setFont(new Font("Courier New", Font.PLAIN, 18));
|
||||
table.setForeground(Color.GRAY);
|
||||
table.setTableHeader(null);
|
||||
|
||||
|
||||
TableCellRenderer tcr = table.getDefaultRenderer(String.class);
|
||||
DefaultTableCellRenderer renderer = (DefaultTableCellRenderer)tcr;
|
||||
renderer.setHorizontalAlignment(SwingConstants.CENTER);
|
||||
|
||||
table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
|
||||
table.setCellSelectionEnabled(true);
|
||||
|
||||
table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
|
||||
table.getColumnModel().getColumn(0).setPreferredWidth(60);
|
||||
table.getColumnModel().getColumn(1).setPreferredWidth(200);
|
||||
table.getColumnModel().getColumn(2).setPreferredWidth(60);
|
||||
|
||||
table.setRowMargin(3);
|
||||
table.setRowHeight(50);
|
||||
|
||||
// Add the table to a scrolling pane
|
||||
scrollPane = new JScrollPane( table );
|
||||
topPanel.add( scrollPane, BorderLayout.CENTER );
|
||||
}
|
||||
|
||||
public static void main(String args[]){
|
||||
|
||||
PeersTableMain mainFrame = new PeersTableMain();
|
||||
mainFrame.setVisible( true );
|
||||
mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||
|
||||
}
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
package samples.antlr;
|
||||
|
||||
/**
|
||||
* www.ethereumJ.com
|
||||
* User: Roman Mandeleil
|
||||
* Created on: 25/04/14 17:06
|
||||
*/
|
||||
public class GenParser {
|
||||
|
||||
|
||||
public static void main(String args[]){
|
||||
|
||||
String userDir = System.getProperty("user.dir");
|
||||
String grammarFile = userDir + "\\src\\main\\java\\samples\\antlr\\Sample.g";
|
||||
org.antlr.Tool.main(new String[]{grammarFile});
|
||||
}
|
||||
}
|
@ -1,105 +0,0 @@
|
||||
grammar PyEsque;
|
||||
|
||||
options {
|
||||
language = Java;
|
||||
output = AST;
|
||||
//output=template;
|
||||
}
|
||||
|
||||
tokens {
|
||||
BLOCK;
|
||||
}
|
||||
|
||||
@header {
|
||||
package samples.antlr;
|
||||
}
|
||||
|
||||
@lexer::header {
|
||||
package samples.antlr;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@lexer::members {
|
||||
|
||||
private int previousIndents = -1;
|
||||
private int indentLevel = 0;
|
||||
java.util.Queue<Token> tokens = new java.util.LinkedList<Token>();
|
||||
|
||||
@Override
|
||||
public void emit(Token t) {
|
||||
state.token = t;
|
||||
tokens.offer(t);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Token nextToken() {
|
||||
super.nextToken();
|
||||
return tokens.isEmpty() ? getEOFToken() : tokens.poll();
|
||||
}
|
||||
|
||||
private void jump(int ttype) {
|
||||
indentLevel += (ttype == Dedent ? -1 : 1);
|
||||
emit(new CommonToken(ttype, "level=" + indentLevel));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
parse
|
||||
: block EOF -> block
|
||||
;
|
||||
|
||||
block
|
||||
: Indent block_atoms Dedent -> ^(BLOCK block_atoms)
|
||||
;
|
||||
|
||||
block_atoms
|
||||
: (Id | block)+
|
||||
;
|
||||
|
||||
NewLine
|
||||
: NL SP?
|
||||
{
|
||||
int n = $SP.text == null ? 0 : $SP.text.length();
|
||||
if(n > previousIndents) {
|
||||
jump(Indent);
|
||||
previousIndents = n;
|
||||
}
|
||||
else if(n < previousIndents) {
|
||||
jump(Dedent);
|
||||
previousIndents = n;
|
||||
}
|
||||
else if(input.LA(1) == EOF) {
|
||||
while(indentLevel > 0) {
|
||||
jump(Dedent);
|
||||
}
|
||||
}
|
||||
else {
|
||||
skip();
|
||||
}
|
||||
}
|
||||
;
|
||||
|
||||
|
||||
Id
|
||||
: ('a'..'z' | 'A'..'Z')+
|
||||
;
|
||||
|
||||
SpaceChars
|
||||
: SP {skip();}
|
||||
;
|
||||
|
||||
fragment NL : '\r'? '\n' | '\r';
|
||||
fragment SP : (' ' | '\t')+;
|
||||
fragment Indent : ;
|
||||
fragment Dedent : ;
|
||||
|
||||
|
||||
expression
|
||||
: INTEGER*
|
||||
;
|
||||
|
||||
|
||||
|
||||
fragment DIGIT : '0'..'9';
|
||||
INTEGER : DIGIT+ ;
|
@ -1,547 +0,0 @@
|
||||
// $ANTLR 3.5.2 E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\antlr\\PyEsque.g 2014-05-01 16:36:17
|
||||
|
||||
package samples.antlr;
|
||||
|
||||
|
||||
import org.antlr.runtime.*;
|
||||
import java.util.Stack;
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
|
||||
@SuppressWarnings("all")
|
||||
public class PyEsqueLexer extends Lexer {
|
||||
public static final int EOF=-1;
|
||||
public static final int BLOCK=4;
|
||||
public static final int DIGIT=5;
|
||||
public static final int Dedent=6;
|
||||
public static final int INTEGER=7;
|
||||
public static final int Id=8;
|
||||
public static final int Indent=9;
|
||||
public static final int NL=10;
|
||||
public static final int NewLine=11;
|
||||
public static final int SP=12;
|
||||
public static final int SpaceChars=13;
|
||||
|
||||
|
||||
private int previousIndents = -1;
|
||||
private int indentLevel = 0;
|
||||
java.util.Queue<Token> tokens = new java.util.LinkedList<Token>();
|
||||
|
||||
@Override
|
||||
public void emit(Token t) {
|
||||
state.token = t;
|
||||
tokens.offer(t);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Token nextToken() {
|
||||
super.nextToken();
|
||||
return tokens.isEmpty() ? getEOFToken() : tokens.poll();
|
||||
}
|
||||
|
||||
private void jump(int ttype) {
|
||||
indentLevel += (ttype == Dedent ? -1 : 1);
|
||||
emit(new CommonToken(ttype, "level=" + indentLevel));
|
||||
}
|
||||
|
||||
|
||||
// delegates
|
||||
// delegators
|
||||
public Lexer[] getDelegates() {
|
||||
return new Lexer[] {};
|
||||
}
|
||||
|
||||
public PyEsqueLexer() {}
|
||||
public PyEsqueLexer(CharStream input) {
|
||||
this(input, new RecognizerSharedState());
|
||||
}
|
||||
public PyEsqueLexer(CharStream input, RecognizerSharedState state) {
|
||||
super(input,state);
|
||||
}
|
||||
@Override public String getGrammarFileName() { return "E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\antlr\\PyEsque.g"; }
|
||||
|
||||
// $ANTLR start "NewLine"
|
||||
public final void mNewLine() throws RecognitionException {
|
||||
try {
|
||||
int _type = NewLine;
|
||||
int _channel = DEFAULT_TOKEN_CHANNEL;
|
||||
CommonToken SP1=null;
|
||||
|
||||
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\antlr\\PyEsque.g:61:2: ( NL ( SP )? )
|
||||
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\antlr\\PyEsque.g:61:4: NL ( SP )?
|
||||
{
|
||||
mNL();
|
||||
|
||||
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\antlr\\PyEsque.g:61:7: ( SP )?
|
||||
int alt1=2;
|
||||
int LA1_0 = input.LA(1);
|
||||
if ( (LA1_0=='\t'||LA1_0==' ') ) {
|
||||
alt1=1;
|
||||
}
|
||||
switch (alt1) {
|
||||
case 1 :
|
||||
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\antlr\\PyEsque.g:61:7: SP
|
||||
{
|
||||
int SP1Start39 = getCharIndex();
|
||||
int SP1StartLine39 = getLine();
|
||||
int SP1StartCharPos39 = getCharPositionInLine();
|
||||
mSP();
|
||||
SP1 = new CommonToken(input, Token.INVALID_TOKEN_TYPE, Token.DEFAULT_CHANNEL, SP1Start39, getCharIndex()-1);
|
||||
SP1.setLine(SP1StartLine39);
|
||||
SP1.setCharPositionInLine(SP1StartCharPos39);
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
|
||||
int n = (SP1!=null?SP1.getText():null) == null ? 0 : (SP1!=null?SP1.getText():null).length();
|
||||
if(n > previousIndents) {
|
||||
jump(Indent);
|
||||
previousIndents = n;
|
||||
}
|
||||
else if(n < previousIndents) {
|
||||
jump(Dedent);
|
||||
previousIndents = n;
|
||||
}
|
||||
else if(input.LA(1) == EOF) {
|
||||
while(indentLevel > 0) {
|
||||
jump(Dedent);
|
||||
}
|
||||
}
|
||||
else {
|
||||
skip();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
state.type = _type;
|
||||
state.channel = _channel;
|
||||
}
|
||||
finally {
|
||||
// do for sure before leaving
|
||||
}
|
||||
}
|
||||
// $ANTLR end "NewLine"
|
||||
|
||||
// $ANTLR start "Id"
|
||||
public final void mId() throws RecognitionException {
|
||||
try {
|
||||
int _type = Id;
|
||||
int _channel = DEFAULT_TOKEN_CHANNEL;
|
||||
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\antlr\\PyEsque.g:85:2: ( ( 'a' .. 'z' | 'A' .. 'Z' )+ )
|
||||
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\antlr\\PyEsque.g:85:4: ( 'a' .. 'z' | 'A' .. 'Z' )+
|
||||
{
|
||||
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\antlr\\PyEsque.g:85:4: ( 'a' .. 'z' | 'A' .. 'Z' )+
|
||||
int cnt2=0;
|
||||
loop2:
|
||||
while (true) {
|
||||
int alt2=2;
|
||||
int LA2_0 = input.LA(1);
|
||||
if ( ((LA2_0 >= 'A' && LA2_0 <= 'Z')||(LA2_0 >= 'a' && LA2_0 <= 'z')) ) {
|
||||
alt2=1;
|
||||
}
|
||||
|
||||
switch (alt2) {
|
||||
case 1 :
|
||||
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\antlr\\PyEsque.g:
|
||||
{
|
||||
if ( (input.LA(1) >= 'A' && input.LA(1) <= 'Z')||(input.LA(1) >= 'a' && input.LA(1) <= 'z') ) {
|
||||
input.consume();
|
||||
}
|
||||
else {
|
||||
MismatchedSetException mse = new MismatchedSetException(null,input);
|
||||
recover(mse);
|
||||
throw mse;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default :
|
||||
if ( cnt2 >= 1 ) break loop2;
|
||||
EarlyExitException eee = new EarlyExitException(2, input);
|
||||
throw eee;
|
||||
}
|
||||
cnt2++;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
state.type = _type;
|
||||
state.channel = _channel;
|
||||
}
|
||||
finally {
|
||||
// do for sure before leaving
|
||||
}
|
||||
}
|
||||
// $ANTLR end "Id"
|
||||
|
||||
// $ANTLR start "SpaceChars"
|
||||
public final void mSpaceChars() throws RecognitionException {
|
||||
try {
|
||||
int _type = SpaceChars;
|
||||
int _channel = DEFAULT_TOKEN_CHANNEL;
|
||||
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\antlr\\PyEsque.g:89:2: ( SP )
|
||||
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\antlr\\PyEsque.g:89:4: SP
|
||||
{
|
||||
mSP();
|
||||
|
||||
skip();
|
||||
}
|
||||
|
||||
state.type = _type;
|
||||
state.channel = _channel;
|
||||
}
|
||||
finally {
|
||||
// do for sure before leaving
|
||||
}
|
||||
}
|
||||
// $ANTLR end "SpaceChars"
|
||||
|
||||
// $ANTLR start "NL"
|
||||
public final void mNL() throws RecognitionException {
|
||||
try {
|
||||
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\antlr\\PyEsque.g:92:17: ( ( '\\r' )? '\\n' | '\\r' )
|
||||
int alt4=2;
|
||||
int LA4_0 = input.LA(1);
|
||||
if ( (LA4_0=='\r') ) {
|
||||
int LA4_1 = input.LA(2);
|
||||
if ( (LA4_1=='\n') ) {
|
||||
alt4=1;
|
||||
}
|
||||
|
||||
else {
|
||||
alt4=2;
|
||||
}
|
||||
|
||||
}
|
||||
else if ( (LA4_0=='\n') ) {
|
||||
alt4=1;
|
||||
}
|
||||
|
||||
else {
|
||||
NoViableAltException nvae =
|
||||
new NoViableAltException("", 4, 0, input);
|
||||
throw nvae;
|
||||
}
|
||||
|
||||
switch (alt4) {
|
||||
case 1 :
|
||||
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\antlr\\PyEsque.g:92:19: ( '\\r' )? '\\n'
|
||||
{
|
||||
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\antlr\\PyEsque.g:92:19: ( '\\r' )?
|
||||
int alt3=2;
|
||||
int LA3_0 = input.LA(1);
|
||||
if ( (LA3_0=='\r') ) {
|
||||
alt3=1;
|
||||
}
|
||||
switch (alt3) {
|
||||
case 1 :
|
||||
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\antlr\\PyEsque.g:92:19: '\\r'
|
||||
{
|
||||
match('\r');
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
match('\n');
|
||||
}
|
||||
break;
|
||||
case 2 :
|
||||
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\antlr\\PyEsque.g:92:32: '\\r'
|
||||
{
|
||||
match('\r');
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
finally {
|
||||
// do for sure before leaving
|
||||
}
|
||||
}
|
||||
// $ANTLR end "NL"
|
||||
|
||||
// $ANTLR start "SP"
|
||||
public final void mSP() throws RecognitionException {
|
||||
try {
|
||||
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\antlr\\PyEsque.g:93:17: ( ( ' ' | '\\t' )+ )
|
||||
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\antlr\\PyEsque.g:93:19: ( ' ' | '\\t' )+
|
||||
{
|
||||
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\antlr\\PyEsque.g:93:19: ( ' ' | '\\t' )+
|
||||
int cnt5=0;
|
||||
loop5:
|
||||
while (true) {
|
||||
int alt5=2;
|
||||
int LA5_0 = input.LA(1);
|
||||
if ( (LA5_0=='\t'||LA5_0==' ') ) {
|
||||
alt5=1;
|
||||
}
|
||||
|
||||
switch (alt5) {
|
||||
case 1 :
|
||||
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\antlr\\PyEsque.g:
|
||||
{
|
||||
if ( input.LA(1)=='\t'||input.LA(1)==' ' ) {
|
||||
input.consume();
|
||||
}
|
||||
else {
|
||||
MismatchedSetException mse = new MismatchedSetException(null,input);
|
||||
recover(mse);
|
||||
throw mse;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default :
|
||||
if ( cnt5 >= 1 ) break loop5;
|
||||
EarlyExitException eee = new EarlyExitException(5, input);
|
||||
throw eee;
|
||||
}
|
||||
cnt5++;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
finally {
|
||||
// do for sure before leaving
|
||||
}
|
||||
}
|
||||
// $ANTLR end "SP"
|
||||
|
||||
// $ANTLR start "Indent"
|
||||
public final void mIndent() throws RecognitionException {
|
||||
try {
|
||||
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\antlr\\PyEsque.g:94:17: ()
|
||||
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\antlr\\PyEsque.g:94:19:
|
||||
{
|
||||
}
|
||||
|
||||
}
|
||||
finally {
|
||||
// do for sure before leaving
|
||||
}
|
||||
}
|
||||
// $ANTLR end "Indent"
|
||||
|
||||
// $ANTLR start "Dedent"
|
||||
public final void mDedent() throws RecognitionException {
|
||||
try {
|
||||
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\antlr\\PyEsque.g:95:17: ()
|
||||
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\antlr\\PyEsque.g:95:19:
|
||||
{
|
||||
}
|
||||
|
||||
}
|
||||
finally {
|
||||
// do for sure before leaving
|
||||
}
|
||||
}
|
||||
// $ANTLR end "Dedent"
|
||||
|
||||
// $ANTLR start "DIGIT"
|
||||
public final void mDIGIT() throws RecognitionException {
|
||||
try {
|
||||
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\antlr\\PyEsque.g:104:16: ( '0' .. '9' )
|
||||
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\antlr\\PyEsque.g:
|
||||
{
|
||||
if ( (input.LA(1) >= '0' && input.LA(1) <= '9') ) {
|
||||
input.consume();
|
||||
}
|
||||
else {
|
||||
MismatchedSetException mse = new MismatchedSetException(null,input);
|
||||
recover(mse);
|
||||
throw mse;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
finally {
|
||||
// do for sure before leaving
|
||||
}
|
||||
}
|
||||
// $ANTLR end "DIGIT"
|
||||
|
||||
// $ANTLR start "INTEGER"
|
||||
public final void mINTEGER() throws RecognitionException {
|
||||
try {
|
||||
int _type = INTEGER;
|
||||
int _channel = DEFAULT_TOKEN_CHANNEL;
|
||||
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\antlr\\PyEsque.g:105:9: ( ( DIGIT )+ )
|
||||
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\antlr\\PyEsque.g:105:11: ( DIGIT )+
|
||||
{
|
||||
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\antlr\\PyEsque.g:105:11: ( DIGIT )+
|
||||
int cnt6=0;
|
||||
loop6:
|
||||
while (true) {
|
||||
int alt6=2;
|
||||
int LA6_0 = input.LA(1);
|
||||
if ( ((LA6_0 >= '0' && LA6_0 <= '9')) ) {
|
||||
alt6=1;
|
||||
}
|
||||
|
||||
switch (alt6) {
|
||||
case 1 :
|
||||
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\antlr\\PyEsque.g:
|
||||
{
|
||||
if ( (input.LA(1) >= '0' && input.LA(1) <= '9') ) {
|
||||
input.consume();
|
||||
}
|
||||
else {
|
||||
MismatchedSetException mse = new MismatchedSetException(null,input);
|
||||
recover(mse);
|
||||
throw mse;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default :
|
||||
if ( cnt6 >= 1 ) break loop6;
|
||||
EarlyExitException eee = new EarlyExitException(6, input);
|
||||
throw eee;
|
||||
}
|
||||
cnt6++;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
state.type = _type;
|
||||
state.channel = _channel;
|
||||
}
|
||||
finally {
|
||||
// do for sure before leaving
|
||||
}
|
||||
}
|
||||
// $ANTLR end "INTEGER"
|
||||
|
||||
@Override
|
||||
public void mTokens() throws RecognitionException {
|
||||
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\antlr\\PyEsque.g:1:8: ( NewLine | Id | SpaceChars | INTEGER )
|
||||
int alt7=4;
|
||||
switch ( input.LA(1) ) {
|
||||
case '\n':
|
||||
case '\r':
|
||||
{
|
||||
alt7=1;
|
||||
}
|
||||
break;
|
||||
case 'A':
|
||||
case 'B':
|
||||
case 'C':
|
||||
case 'D':
|
||||
case 'E':
|
||||
case 'F':
|
||||
case 'G':
|
||||
case 'H':
|
||||
case 'I':
|
||||
case 'J':
|
||||
case 'K':
|
||||
case 'L':
|
||||
case 'M':
|
||||
case 'N':
|
||||
case 'O':
|
||||
case 'P':
|
||||
case 'Q':
|
||||
case 'R':
|
||||
case 'S':
|
||||
case 'T':
|
||||
case 'U':
|
||||
case 'V':
|
||||
case 'W':
|
||||
case 'X':
|
||||
case 'Y':
|
||||
case 'Z':
|
||||
case 'a':
|
||||
case 'b':
|
||||
case 'c':
|
||||
case 'd':
|
||||
case 'e':
|
||||
case 'f':
|
||||
case 'g':
|
||||
case 'h':
|
||||
case 'i':
|
||||
case 'j':
|
||||
case 'k':
|
||||
case 'l':
|
||||
case 'm':
|
||||
case 'n':
|
||||
case 'o':
|
||||
case 'p':
|
||||
case 'q':
|
||||
case 'r':
|
||||
case 's':
|
||||
case 't':
|
||||
case 'u':
|
||||
case 'v':
|
||||
case 'w':
|
||||
case 'x':
|
||||
case 'y':
|
||||
case 'z':
|
||||
{
|
||||
alt7=2;
|
||||
}
|
||||
break;
|
||||
case '\t':
|
||||
case ' ':
|
||||
{
|
||||
alt7=3;
|
||||
}
|
||||
break;
|
||||
case '0':
|
||||
case '1':
|
||||
case '2':
|
||||
case '3':
|
||||
case '4':
|
||||
case '5':
|
||||
case '6':
|
||||
case '7':
|
||||
case '8':
|
||||
case '9':
|
||||
{
|
||||
alt7=4;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
NoViableAltException nvae =
|
||||
new NoViableAltException("", 7, 0, input);
|
||||
throw nvae;
|
||||
}
|
||||
switch (alt7) {
|
||||
case 1 :
|
||||
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\antlr\\PyEsque.g:1:10: NewLine
|
||||
{
|
||||
mNewLine();
|
||||
|
||||
}
|
||||
break;
|
||||
case 2 :
|
||||
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\antlr\\PyEsque.g:1:18: Id
|
||||
{
|
||||
mId();
|
||||
|
||||
}
|
||||
break;
|
||||
case 3 :
|
||||
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\antlr\\PyEsque.g:1:21: SpaceChars
|
||||
{
|
||||
mSpaceChars();
|
||||
|
||||
}
|
||||
break;
|
||||
case 4 :
|
||||
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\antlr\\PyEsque.g:1:32: INTEGER
|
||||
{
|
||||
mINTEGER();
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
@ -1,394 +0,0 @@
|
||||
// $ANTLR 3.5.2 E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\antlr\\PyEsque.g 2014-05-01 16:36:17
|
||||
|
||||
package samples.antlr;
|
||||
|
||||
|
||||
import org.antlr.runtime.*;
|
||||
import java.util.Stack;
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import org.antlr.runtime.tree.*;
|
||||
|
||||
|
||||
@SuppressWarnings("all")
|
||||
public class PyEsqueParser extends Parser {
|
||||
public static final String[] tokenNames = new String[] {
|
||||
"<invalid>", "<EOR>", "<DOWN>", "<UP>", "BLOCK", "DIGIT", "Dedent", "INTEGER",
|
||||
"Id", "Indent", "NL", "NewLine", "SP", "SpaceChars"
|
||||
};
|
||||
public static final int EOF=-1;
|
||||
public static final int BLOCK=4;
|
||||
public static final int DIGIT=5;
|
||||
public static final int Dedent=6;
|
||||
public static final int INTEGER=7;
|
||||
public static final int Id=8;
|
||||
public static final int Indent=9;
|
||||
public static final int NL=10;
|
||||
public static final int NewLine=11;
|
||||
public static final int SP=12;
|
||||
public static final int SpaceChars=13;
|
||||
|
||||
// delegates
|
||||
public Parser[] getDelegates() {
|
||||
return new Parser[] {};
|
||||
}
|
||||
|
||||
// delegators
|
||||
|
||||
|
||||
public PyEsqueParser(TokenStream input) {
|
||||
this(input, new RecognizerSharedState());
|
||||
}
|
||||
public PyEsqueParser(TokenStream input, RecognizerSharedState state) {
|
||||
super(input, state);
|
||||
}
|
||||
|
||||
protected TreeAdaptor adaptor = new CommonTreeAdaptor();
|
||||
|
||||
public void setTreeAdaptor(TreeAdaptor adaptor) {
|
||||
this.adaptor = adaptor;
|
||||
}
|
||||
public TreeAdaptor getTreeAdaptor() {
|
||||
return adaptor;
|
||||
}
|
||||
@Override public String[] getTokenNames() { return PyEsqueParser.tokenNames; }
|
||||
@Override public String getGrammarFileName() { return "E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\antlr\\PyEsque.g"; }
|
||||
|
||||
|
||||
public static class parse_return extends ParserRuleReturnScope {
|
||||
Object tree;
|
||||
@Override
|
||||
public Object getTree() { return tree; }
|
||||
};
|
||||
|
||||
|
||||
// $ANTLR start "parse"
|
||||
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\antlr\\PyEsque.g:48:1: parse : block EOF -> block ;
|
||||
public final parse_return parse() throws RecognitionException {
|
||||
parse_return retval = new parse_return();
|
||||
retval.start = input.LT(1);
|
||||
|
||||
Object root_0 = null;
|
||||
|
||||
Token EOF2=null;
|
||||
ParserRuleReturnScope block1 =null;
|
||||
|
||||
Object EOF2_tree=null;
|
||||
RewriteRuleTokenStream stream_EOF=new RewriteRuleTokenStream(adaptor,"token EOF");
|
||||
RewriteRuleSubtreeStream stream_block=new RewriteRuleSubtreeStream(adaptor,"rule block");
|
||||
|
||||
try {
|
||||
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\antlr\\PyEsque.g:49:2: ( block EOF -> block )
|
||||
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\antlr\\PyEsque.g:49:4: block EOF
|
||||
{
|
||||
pushFollow(FOLLOW_block_in_parse74);
|
||||
block1=block();
|
||||
state._fsp--;
|
||||
|
||||
stream_block.add(block1.getTree());
|
||||
EOF2=(Token)match(input,EOF,FOLLOW_EOF_in_parse76);
|
||||
stream_EOF.add(EOF2);
|
||||
|
||||
// AST REWRITE
|
||||
// elements: block
|
||||
// token labels:
|
||||
// rule labels: retval
|
||||
// token list labels:
|
||||
// rule list labels:
|
||||
// wildcard labels:
|
||||
retval.tree = root_0;
|
||||
RewriteRuleSubtreeStream stream_retval=new RewriteRuleSubtreeStream(adaptor,"rule retval",retval!=null?retval.getTree():null);
|
||||
|
||||
root_0 = (Object)adaptor.nil();
|
||||
// 49:14: -> block
|
||||
{
|
||||
adaptor.addChild(root_0, stream_block.nextTree());
|
||||
}
|
||||
|
||||
|
||||
retval.tree = root_0;
|
||||
|
||||
}
|
||||
|
||||
retval.stop = input.LT(-1);
|
||||
|
||||
retval.tree = (Object)adaptor.rulePostProcessing(root_0);
|
||||
adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop);
|
||||
|
||||
}
|
||||
catch (RecognitionException re) {
|
||||
reportError(re);
|
||||
recover(input,re);
|
||||
retval.tree = (Object)adaptor.errorNode(input, retval.start, input.LT(-1), re);
|
||||
}
|
||||
finally {
|
||||
// do for sure before leaving
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
// $ANTLR end "parse"
|
||||
|
||||
|
||||
public static class block_return extends ParserRuleReturnScope {
|
||||
Object tree;
|
||||
@Override
|
||||
public Object getTree() { return tree; }
|
||||
};
|
||||
|
||||
|
||||
// $ANTLR start "block"
|
||||
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\antlr\\PyEsque.g:52:1: block : Indent block_atoms Dedent -> ^( BLOCK block_atoms ) ;
|
||||
public final block_return block() throws RecognitionException {
|
||||
block_return retval = new block_return();
|
||||
retval.start = input.LT(1);
|
||||
|
||||
Object root_0 = null;
|
||||
|
||||
Token Indent3=null;
|
||||
Token Dedent5=null;
|
||||
ParserRuleReturnScope block_atoms4 =null;
|
||||
|
||||
Object Indent3_tree=null;
|
||||
Object Dedent5_tree=null;
|
||||
RewriteRuleTokenStream stream_Indent=new RewriteRuleTokenStream(adaptor,"token Indent");
|
||||
RewriteRuleTokenStream stream_Dedent=new RewriteRuleTokenStream(adaptor,"token Dedent");
|
||||
RewriteRuleSubtreeStream stream_block_atoms=new RewriteRuleSubtreeStream(adaptor,"rule block_atoms");
|
||||
|
||||
try {
|
||||
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\antlr\\PyEsque.g:53:2: ( Indent block_atoms Dedent -> ^( BLOCK block_atoms ) )
|
||||
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\antlr\\PyEsque.g:53:4: Indent block_atoms Dedent
|
||||
{
|
||||
Indent3=(Token)match(input,Indent,FOLLOW_Indent_in_block91);
|
||||
stream_Indent.add(Indent3);
|
||||
|
||||
pushFollow(FOLLOW_block_atoms_in_block93);
|
||||
block_atoms4=block_atoms();
|
||||
state._fsp--;
|
||||
|
||||
stream_block_atoms.add(block_atoms4.getTree());
|
||||
Dedent5=(Token)match(input,Dedent,FOLLOW_Dedent_in_block95);
|
||||
stream_Dedent.add(Dedent5);
|
||||
|
||||
// AST REWRITE
|
||||
// elements: block_atoms
|
||||
// token labels:
|
||||
// rule labels: retval
|
||||
// token list labels:
|
||||
// rule list labels:
|
||||
// wildcard labels:
|
||||
retval.tree = root_0;
|
||||
RewriteRuleSubtreeStream stream_retval=new RewriteRuleSubtreeStream(adaptor,"rule retval",retval!=null?retval.getTree():null);
|
||||
|
||||
root_0 = (Object)adaptor.nil();
|
||||
// 53:30: -> ^( BLOCK block_atoms )
|
||||
{
|
||||
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\antlr\\PyEsque.g:53:33: ^( BLOCK block_atoms )
|
||||
{
|
||||
Object root_1 = (Object)adaptor.nil();
|
||||
root_1 = (Object)adaptor.becomeRoot((Object)adaptor.create(BLOCK, "BLOCK"), root_1);
|
||||
adaptor.addChild(root_1, stream_block_atoms.nextTree());
|
||||
adaptor.addChild(root_0, root_1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
retval.tree = root_0;
|
||||
|
||||
}
|
||||
|
||||
retval.stop = input.LT(-1);
|
||||
|
||||
retval.tree = (Object)adaptor.rulePostProcessing(root_0);
|
||||
adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop);
|
||||
|
||||
}
|
||||
catch (RecognitionException re) {
|
||||
reportError(re);
|
||||
recover(input,re);
|
||||
retval.tree = (Object)adaptor.errorNode(input, retval.start, input.LT(-1), re);
|
||||
}
|
||||
finally {
|
||||
// do for sure before leaving
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
// $ANTLR end "block"
|
||||
|
||||
|
||||
public static class block_atoms_return extends ParserRuleReturnScope {
|
||||
Object tree;
|
||||
@Override
|
||||
public Object getTree() { return tree; }
|
||||
};
|
||||
|
||||
|
||||
// $ANTLR start "block_atoms"
|
||||
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\antlr\\PyEsque.g:56:1: block_atoms : ( Id | block )+ ;
|
||||
public final block_atoms_return block_atoms() throws RecognitionException {
|
||||
block_atoms_return retval = new block_atoms_return();
|
||||
retval.start = input.LT(1);
|
||||
|
||||
Object root_0 = null;
|
||||
|
||||
Token Id6=null;
|
||||
ParserRuleReturnScope block7 =null;
|
||||
|
||||
Object Id6_tree=null;
|
||||
|
||||
try {
|
||||
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\antlr\\PyEsque.g:57:2: ( ( Id | block )+ )
|
||||
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\antlr\\PyEsque.g:57:5: ( Id | block )+
|
||||
{
|
||||
root_0 = (Object)adaptor.nil();
|
||||
|
||||
|
||||
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\antlr\\PyEsque.g:57:5: ( Id | block )+
|
||||
int cnt1=0;
|
||||
loop1:
|
||||
while (true) {
|
||||
int alt1=3;
|
||||
int LA1_0 = input.LA(1);
|
||||
if ( (LA1_0==Id) ) {
|
||||
alt1=1;
|
||||
}
|
||||
else if ( (LA1_0==Indent) ) {
|
||||
alt1=2;
|
||||
}
|
||||
|
||||
switch (alt1) {
|
||||
case 1 :
|
||||
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\antlr\\PyEsque.g:57:6: Id
|
||||
{
|
||||
Id6=(Token)match(input,Id,FOLLOW_Id_in_block_atoms116);
|
||||
Id6_tree = (Object)adaptor.create(Id6);
|
||||
adaptor.addChild(root_0, Id6_tree);
|
||||
|
||||
}
|
||||
break;
|
||||
case 2 :
|
||||
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\antlr\\PyEsque.g:57:11: block
|
||||
{
|
||||
pushFollow(FOLLOW_block_in_block_atoms120);
|
||||
block7=block();
|
||||
state._fsp--;
|
||||
|
||||
adaptor.addChild(root_0, block7.getTree());
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
default :
|
||||
if ( cnt1 >= 1 ) break loop1;
|
||||
EarlyExitException eee = new EarlyExitException(1, input);
|
||||
throw eee;
|
||||
}
|
||||
cnt1++;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
retval.stop = input.LT(-1);
|
||||
|
||||
retval.tree = (Object)adaptor.rulePostProcessing(root_0);
|
||||
adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop);
|
||||
|
||||
}
|
||||
catch (RecognitionException re) {
|
||||
reportError(re);
|
||||
recover(input,re);
|
||||
retval.tree = (Object)adaptor.errorNode(input, retval.start, input.LT(-1), re);
|
||||
}
|
||||
finally {
|
||||
// do for sure before leaving
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
// $ANTLR end "block_atoms"
|
||||
|
||||
|
||||
public static class expression_return extends ParserRuleReturnScope {
|
||||
Object tree;
|
||||
@Override
|
||||
public Object getTree() { return tree; }
|
||||
};
|
||||
|
||||
|
||||
// $ANTLR start "expression"
|
||||
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\antlr\\PyEsque.g:98:1: expression : ( INTEGER )* ;
|
||||
public final expression_return expression() throws RecognitionException {
|
||||
expression_return retval = new expression_return();
|
||||
retval.start = input.LT(1);
|
||||
|
||||
Object root_0 = null;
|
||||
|
||||
Token INTEGER8=null;
|
||||
|
||||
Object INTEGER8_tree=null;
|
||||
|
||||
try {
|
||||
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\antlr\\PyEsque.g:99:2: ( ( INTEGER )* )
|
||||
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\antlr\\PyEsque.g:99:4: ( INTEGER )*
|
||||
{
|
||||
root_0 = (Object)adaptor.nil();
|
||||
|
||||
|
||||
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\antlr\\PyEsque.g:99:4: ( INTEGER )*
|
||||
loop2:
|
||||
while (true) {
|
||||
int alt2=2;
|
||||
int LA2_0 = input.LA(1);
|
||||
if ( (LA2_0==INTEGER) ) {
|
||||
alt2=1;
|
||||
}
|
||||
|
||||
switch (alt2) {
|
||||
case 1 :
|
||||
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\antlr\\PyEsque.g:99:4: INTEGER
|
||||
{
|
||||
INTEGER8=(Token)match(input,INTEGER,FOLLOW_INTEGER_in_expression246);
|
||||
INTEGER8_tree = (Object)adaptor.create(INTEGER8);
|
||||
adaptor.addChild(root_0, INTEGER8_tree);
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
default :
|
||||
break loop2;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
retval.stop = input.LT(-1);
|
||||
|
||||
retval.tree = (Object)adaptor.rulePostProcessing(root_0);
|
||||
adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop);
|
||||
|
||||
}
|
||||
catch (RecognitionException re) {
|
||||
reportError(re);
|
||||
recover(input,re);
|
||||
retval.tree = (Object)adaptor.errorNode(input, retval.start, input.LT(-1), re);
|
||||
}
|
||||
finally {
|
||||
// do for sure before leaving
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
// $ANTLR end "expression"
|
||||
|
||||
// Delegated rules
|
||||
|
||||
|
||||
|
||||
public static final BitSet FOLLOW_block_in_parse74 = new BitSet(new long[]{0x0000000000000000L});
|
||||
public static final BitSet FOLLOW_EOF_in_parse76 = new BitSet(new long[]{0x0000000000000002L});
|
||||
public static final BitSet FOLLOW_Indent_in_block91 = new BitSet(new long[]{0x0000000000000300L});
|
||||
public static final BitSet FOLLOW_block_atoms_in_block93 = new BitSet(new long[]{0x0000000000000040L});
|
||||
public static final BitSet FOLLOW_Dedent_in_block95 = new BitSet(new long[]{0x0000000000000002L});
|
||||
public static final BitSet FOLLOW_Id_in_block_atoms116 = new BitSet(new long[]{0x0000000000000302L});
|
||||
public static final BitSet FOLLOW_block_in_block_atoms120 = new BitSet(new long[]{0x0000000000000302L});
|
||||
public static final BitSet FOLLOW_INTEGER_in_expression246 = new BitSet(new long[]{0x0000000000000082L});
|
||||
}
|
@ -1,611 +0,0 @@
|
||||
/*
|
||||
[The 'BSD licence']
|
||||
Copyright (c) 2004 Terence Parr and Loring Craymer
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
3. The name of the author may not be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/** Python 2.3.3 Grammar
|
||||
*
|
||||
* Terence Parr and Loring Craymer
|
||||
* February 2004
|
||||
*
|
||||
* Converted to ANTLR v3 November 2005 by Terence Parr.
|
||||
*
|
||||
* This grammar was derived automatically from the Python 2.3.3
|
||||
* parser grammar to get a syntactically correct ANTLR grammar
|
||||
* for Python. Then Terence hand tweaked it to be semantically
|
||||
* correct; i.e., removed lookahead issues etc... It is LL(1)
|
||||
* except for the (sometimes optional) trailing commas and semi-colons.
|
||||
* It needs two symbols of lookahead in this case.
|
||||
*
|
||||
* Starting with Loring's preliminary lexer for Python, I modified it
|
||||
* to do my version of the whole nasty INDENT/DEDENT issue just so I
|
||||
* could understand the problem better. This grammar requires
|
||||
* PythonTokenStream.java to work. Also I used some rules from the
|
||||
* semi-formal grammar on the web for Python (automatically
|
||||
* translated to ANTLR format by an ANTLR grammar, naturally <grin>).
|
||||
* The lexical rules for python are particularly nasty and it took me
|
||||
* a long time to get it 'right'; i.e., think about it in the proper
|
||||
* way. Resist changing the lexer unless you've used ANTLR a lot. ;)
|
||||
*
|
||||
* I (Terence) tested this by running it on the jython-2.1/Lib
|
||||
* directory of 40k lines of Python.
|
||||
*
|
||||
* REQUIRES ANTLR v3
|
||||
*/
|
||||
grammar Python;
|
||||
|
||||
|
||||
tokens {
|
||||
INDENT;
|
||||
DEDENT;
|
||||
}
|
||||
|
||||
@lexer::members {
|
||||
/** Handles context-sensitive lexing of implicit line joining such as
|
||||
* the case where newline is ignored in cases like this:
|
||||
* a = [3,
|
||||
* 4]
|
||||
*/
|
||||
int implicitLineJoiningLevel = 0;
|
||||
int startPos=-1;
|
||||
}
|
||||
|
||||
@header {
|
||||
package org.ethereum.serpent;
|
||||
}
|
||||
|
||||
@lexer::header {
|
||||
package org.ethereum.serpent;
|
||||
}
|
||||
|
||||
|
||||
|
||||
single_input
|
||||
: NEWLINE
|
||||
| simple_stmt
|
||||
| compound_stmt NEWLINE
|
||||
;
|
||||
|
||||
file_input
|
||||
: (NEWLINE | stmt)*
|
||||
;
|
||||
|
||||
eval_input
|
||||
: (NEWLINE)* testlist (NEWLINE)*
|
||||
;
|
||||
|
||||
funcdef
|
||||
: 'def' NAME parameters COLON suite
|
||||
{System.out.println("found method def "+$NAME.text);}
|
||||
;
|
||||
|
||||
parameters
|
||||
: LPAREN (varargslist)? RPAREN
|
||||
;
|
||||
|
||||
varargslist
|
||||
: defparameter (options {greedy=true;}:COMMA defparameter)*
|
||||
(COMMA
|
||||
( STAR NAME (COMMA DOUBLESTAR NAME)?
|
||||
| DOUBLESTAR NAME
|
||||
)?
|
||||
)?
|
||||
| STAR NAME (COMMA DOUBLESTAR NAME)?
|
||||
| DOUBLESTAR NAME
|
||||
;
|
||||
|
||||
defparameter
|
||||
: fpdef (ASSIGN test)?
|
||||
;
|
||||
|
||||
fpdef
|
||||
: NAME
|
||||
| LPAREN fplist RPAREN
|
||||
;
|
||||
|
||||
fplist
|
||||
: fpdef (options {greedy=true;}:COMMA fpdef)* (COMMA)?
|
||||
;
|
||||
|
||||
|
||||
stmt: simple_stmt
|
||||
| compound_stmt
|
||||
;
|
||||
|
||||
simple_stmt
|
||||
: small_stmt (options {greedy=true;}:SEMI small_stmt)* (SEMI)? NEWLINE
|
||||
;
|
||||
|
||||
small_stmt: expr_stmt
|
||||
| print_stmt
|
||||
| del_stmt
|
||||
| pass_stmt
|
||||
| flow_stmt
|
||||
| import_stmt
|
||||
| global_stmt
|
||||
| exec_stmt
|
||||
| assert_stmt
|
||||
;
|
||||
|
||||
expr_stmt
|
||||
: testlist
|
||||
( augassign testlist
|
||||
| (ASSIGN testlist)+
|
||||
)?
|
||||
;
|
||||
|
||||
augassign
|
||||
: PLUSEQUAL
|
||||
| MINUSEQUAL
|
||||
| STAREQUAL
|
||||
| SLASHEQUAL
|
||||
| PERCENTEQUAL
|
||||
| AMPEREQUAL
|
||||
| VBAREQUAL
|
||||
| CIRCUMFLEXEQUAL
|
||||
| LEFTSHIFTEQUAL
|
||||
| RIGHTSHIFTEQUAL
|
||||
| DOUBLESTAREQUAL
|
||||
| DOUBLESLASHEQUAL
|
||||
;
|
||||
|
||||
print_stmt:
|
||||
'print'
|
||||
( testlist
|
||||
| RIGHTSHIFT testlist
|
||||
)?
|
||||
;
|
||||
|
||||
del_stmt: 'del' exprlist
|
||||
;
|
||||
|
||||
pass_stmt: 'pass'
|
||||
;
|
||||
|
||||
flow_stmt: break_stmt
|
||||
| continue_stmt
|
||||
| return_stmt
|
||||
| raise_stmt
|
||||
| yield_stmt
|
||||
;
|
||||
|
||||
break_stmt: 'break'
|
||||
;
|
||||
|
||||
continue_stmt: 'continue'
|
||||
;
|
||||
|
||||
return_stmt: 'return' (testlist)?
|
||||
;
|
||||
|
||||
yield_stmt: 'yield' testlist
|
||||
;
|
||||
|
||||
raise_stmt: 'raise' (test (COMMA test (COMMA test)?)?)?
|
||||
;
|
||||
|
||||
import_stmt
|
||||
: 'import' dotted_as_name (COMMA dotted_as_name)*
|
||||
| 'from' dotted_name 'import'
|
||||
(STAR | import_as_name (COMMA import_as_name)*)
|
||||
;
|
||||
|
||||
import_as_name
|
||||
: NAME (NAME NAME)?
|
||||
;
|
||||
|
||||
dotted_as_name: dotted_name (NAME NAME)?
|
||||
;
|
||||
|
||||
dotted_name: NAME (DOT NAME)*
|
||||
;
|
||||
|
||||
global_stmt: 'global' NAME (COMMA NAME)*
|
||||
;
|
||||
|
||||
exec_stmt: 'exec' expr ('in' test (COMMA test)?)?
|
||||
;
|
||||
|
||||
assert_stmt: 'assert' test (COMMA test)?
|
||||
;
|
||||
|
||||
|
||||
compound_stmt: if_stmt
|
||||
| while_stmt
|
||||
| for_stmt
|
||||
| try_stmt
|
||||
| funcdef
|
||||
| classdef
|
||||
;
|
||||
|
||||
if_stmt: 'if' test COLON suite ('elif' test COLON suite)* ('else' COLON suite)?
|
||||
;
|
||||
|
||||
while_stmt: 'while' test COLON suite ('else' COLON suite)?
|
||||
;
|
||||
|
||||
for_stmt: 'for' exprlist 'in' testlist COLON suite ('else' COLON suite)?
|
||||
;
|
||||
|
||||
try_stmt
|
||||
: 'try' COLON suite
|
||||
( (except_clause COLON suite)+ ('else' COLON suite)?
|
||||
| 'finally' COLON suite
|
||||
)
|
||||
;
|
||||
|
||||
except_clause: 'except' (test (COMMA test)?)?
|
||||
;
|
||||
|
||||
suite: simple_stmt
|
||||
| NEWLINE INDENT (stmt)+ DEDENT
|
||||
;
|
||||
|
||||
|
||||
test: and_test ('or' and_test)*
|
||||
| lambdef
|
||||
;
|
||||
|
||||
and_test
|
||||
: not_test ('and' not_test)*
|
||||
;
|
||||
|
||||
not_test
|
||||
: 'not' not_test
|
||||
| comparison
|
||||
;
|
||||
|
||||
comparison: expr (comp_op expr)*
|
||||
;
|
||||
|
||||
comp_op: LESS
|
||||
|GREATER
|
||||
|EQUAL
|
||||
|GREATEREQUAL
|
||||
|LESSEQUAL
|
||||
|ALT_NOTEQUAL
|
||||
|NOTEQUAL
|
||||
|'in'
|
||||
|'not' 'in'
|
||||
|'is'
|
||||
|'is' 'not'
|
||||
;
|
||||
|
||||
expr: xor_expr (VBAR xor_expr)*
|
||||
;
|
||||
|
||||
xor_expr: and_expr (CIRCUMFLEX and_expr)*
|
||||
;
|
||||
|
||||
and_expr: shift_expr (AMPER shift_expr)*
|
||||
;
|
||||
|
||||
shift_expr: arith_expr ((LEFTSHIFT|RIGHTSHIFT) arith_expr)*
|
||||
;
|
||||
|
||||
arith_expr: term ((PLUS|MINUS) term)*
|
||||
;
|
||||
|
||||
term: factor ((STAR | SLASH | PERCENT | DOUBLESLASH ) factor)*
|
||||
;
|
||||
|
||||
factor
|
||||
: (PLUS|MINUS|TILDE) factor
|
||||
| power
|
||||
;
|
||||
|
||||
power
|
||||
: atom (trailer)* (options {greedy=true;}:DOUBLESTAR factor)?
|
||||
;
|
||||
|
||||
atom: LPAREN (testlist)? RPAREN
|
||||
| LBRACK (listmaker)? RBRACK
|
||||
| LCURLY (dictmaker)? RCURLY
|
||||
| BACKQUOTE testlist BACKQUOTE
|
||||
| NAME
|
||||
| INT
|
||||
| LONGINT
|
||||
| FLOAT
|
||||
| COMPLEX
|
||||
| (STRING)+
|
||||
;
|
||||
|
||||
listmaker: test ( list_for | (options {greedy=true;}:COMMA test)* ) (COMMA)?
|
||||
;
|
||||
|
||||
lambdef: 'lambda' (varargslist)? COLON test
|
||||
;
|
||||
|
||||
trailer: LPAREN (arglist)? RPAREN
|
||||
| LBRACK subscriptlist RBRACK
|
||||
| DOT NAME
|
||||
;
|
||||
|
||||
subscriptlist
|
||||
: subscript (options {greedy=true;}:COMMA subscript)* (COMMA)?
|
||||
;
|
||||
|
||||
subscript
|
||||
: DOT DOT DOT
|
||||
| test (COLON (test)? (sliceop)?)?
|
||||
| COLON (test)? (sliceop)?
|
||||
;
|
||||
|
||||
sliceop: COLON (test)?
|
||||
;
|
||||
|
||||
exprlist
|
||||
: expr (options {k=2;}:COMMA expr)* (COMMA)?
|
||||
;
|
||||
|
||||
testlist
|
||||
: test (options {k=2;}: COMMA test)* (COMMA)?
|
||||
;
|
||||
|
||||
dictmaker
|
||||
: test COLON test
|
||||
(options {k=2;}:COMMA test COLON test)* (COMMA)?
|
||||
;
|
||||
|
||||
classdef: 'class' NAME (LPAREN testlist RPAREN)? COLON suite
|
||||
{System.out.println("found class def "+$NAME.text);}
|
||||
;
|
||||
|
||||
arglist: argument (COMMA argument)*
|
||||
( COMMA
|
||||
( STAR test (COMMA DOUBLESTAR test)?
|
||||
| DOUBLESTAR test
|
||||
)?
|
||||
)?
|
||||
| STAR test (COMMA DOUBLESTAR test)?
|
||||
| DOUBLESTAR test
|
||||
;
|
||||
|
||||
argument : test (ASSIGN test)?
|
||||
;
|
||||
|
||||
list_iter: list_for
|
||||
| list_if
|
||||
;
|
||||
|
||||
list_for: 'for' exprlist 'in' testlist (list_iter)?
|
||||
;
|
||||
|
||||
list_if: 'if' test (list_iter)?
|
||||
;
|
||||
|
||||
LPAREN : '(' {implicitLineJoiningLevel++;} ;
|
||||
|
||||
RPAREN : ')' {implicitLineJoiningLevel--;} ;
|
||||
|
||||
LBRACK : '[' {implicitLineJoiningLevel++;} ;
|
||||
|
||||
RBRACK : ']' {implicitLineJoiningLevel--;} ;
|
||||
|
||||
COLON : ':' ;
|
||||
|
||||
COMMA : ',' ;
|
||||
|
||||
SEMI : ';' ;
|
||||
|
||||
PLUS : '+' ;
|
||||
|
||||
MINUS : '-' ;
|
||||
|
||||
STAR : '*' ;
|
||||
|
||||
SLASH : '/' ;
|
||||
|
||||
VBAR : '|' ;
|
||||
|
||||
AMPER : '&' ;
|
||||
|
||||
LESS : '<' ;
|
||||
|
||||
GREATER : '>' ;
|
||||
|
||||
ASSIGN : '=' ;
|
||||
|
||||
PERCENT : '%' ;
|
||||
|
||||
BACKQUOTE : '`' ;
|
||||
|
||||
LCURLY : '{' {implicitLineJoiningLevel++;} ;
|
||||
|
||||
RCURLY : '}' {implicitLineJoiningLevel--;} ;
|
||||
|
||||
CIRCUMFLEX : '^' ;
|
||||
|
||||
TILDE : '~' ;
|
||||
|
||||
EQUAL : '==' ;
|
||||
|
||||
NOTEQUAL : '!=' ;
|
||||
|
||||
ALT_NOTEQUAL: '<>' ;
|
||||
|
||||
LESSEQUAL : '<=' ;
|
||||
|
||||
LEFTSHIFT : '<<' ;
|
||||
|
||||
GREATEREQUAL : '>=' ;
|
||||
|
||||
RIGHTSHIFT : '>>' ;
|
||||
|
||||
PLUSEQUAL : '+=' ;
|
||||
|
||||
MINUSEQUAL : '-=' ;
|
||||
|
||||
DOUBLESTAR : '**' ;
|
||||
|
||||
STAREQUAL : '*=' ;
|
||||
|
||||
DOUBLESLASH : '//' ;
|
||||
|
||||
SLASHEQUAL : '/=' ;
|
||||
|
||||
VBAREQUAL : '|=' ;
|
||||
|
||||
PERCENTEQUAL : '%=' ;
|
||||
|
||||
AMPEREQUAL : '&=' ;
|
||||
|
||||
CIRCUMFLEXEQUAL : '^=' ;
|
||||
|
||||
LEFTSHIFTEQUAL : '<<=' ;
|
||||
|
||||
RIGHTSHIFTEQUAL : '>>=' ;
|
||||
|
||||
DOUBLESTAREQUAL : '**=' ;
|
||||
|
||||
DOUBLESLASHEQUAL : '//=' ;
|
||||
|
||||
DOT : '.' ;
|
||||
|
||||
FLOAT
|
||||
: '.' DIGITS (Exponent)?
|
||||
| DIGITS ('.' (DIGITS (Exponent)?)? | Exponent)
|
||||
;
|
||||
|
||||
LONGINT
|
||||
: INT ('l'|'L')
|
||||
;
|
||||
|
||||
fragment
|
||||
Exponent
|
||||
: ('e' | 'E') ( '+' | '-' )? DIGITS
|
||||
;
|
||||
|
||||
INT : // Hex
|
||||
'0' ('x' | 'X') ( '0' .. '9' | 'a' .. 'f' | 'A' .. 'F' )+
|
||||
('l' | 'L')?
|
||||
| // Octal
|
||||
'0' DIGITS*
|
||||
| '1'..'9' DIGITS*
|
||||
;
|
||||
|
||||
COMPLEX
|
||||
: INT ('j'|'J')
|
||||
| FLOAT ('j'|'J')
|
||||
;
|
||||
|
||||
fragment
|
||||
DIGITS : ( '0' .. '9' )+ ;
|
||||
|
||||
NAME: ( 'a' .. 'z' | 'A' .. 'Z' | '_')
|
||||
( 'a' .. 'z' | 'A' .. 'Z' | '_' | '0' .. '9' )*
|
||||
;
|
||||
|
||||
/** Match various string types. Note that greedy=false implies '''
|
||||
* should make us exit loop not continue.
|
||||
*/
|
||||
STRING
|
||||
: ('r'|'u'|'ur')?
|
||||
( '\'\'\'' (options {greedy=false;}:.)* '\'\'\''
|
||||
| '"""' (options {greedy=false;}:.)* '"""'
|
||||
| '"' (ESC|~('\\'|'\n'|'"'))* '"'
|
||||
| '\'' (ESC|~('\\'|'\n'|'\''))* '\''
|
||||
)
|
||||
;
|
||||
|
||||
fragment
|
||||
ESC
|
||||
: '\\' .
|
||||
;
|
||||
|
||||
/** Consume a newline and any whitespace at start of next line */
|
||||
CONTINUED_LINE
|
||||
: '\\' ('\r')? '\n' (' '|'\t')* { $channel=HIDDEN; }
|
||||
;
|
||||
|
||||
/** Treat a sequence of blank lines as a single blank line. If
|
||||
* nested within a (..), {..}, or [..], then ignore newlines.
|
||||
* If the first newline starts in column one, they are to be ignored.
|
||||
*/
|
||||
NEWLINE
|
||||
: (('\r')? '\n' )+
|
||||
{if ( startPos==0 || implicitLineJoiningLevel>0 )
|
||||
$channel=HIDDEN;
|
||||
}
|
||||
;
|
||||
|
||||
WS : {startPos>0}?=> (' '|'\t')+ {$channel=HIDDEN;}
|
||||
;
|
||||
|
||||
/** Grab everything before a real symbol. Then if newline, kill it
|
||||
* as this is a blank line. If whitespace followed by comment, kill it
|
||||
* as it's a comment on a line by itself.
|
||||
*
|
||||
* Ignore leading whitespace when nested in [..], (..), {..}.
|
||||
*/
|
||||
LEADING_WS
|
||||
@init {
|
||||
int spaces = 0;
|
||||
}
|
||||
: {startPos==0}?=>
|
||||
( {implicitLineJoiningLevel>0}? ( ' ' | '\t' )+ {$channel=HIDDEN;}
|
||||
| ( ' ' { spaces++; }
|
||||
| '\t' { spaces += 8; spaces -= (spaces \% 8); }
|
||||
)+
|
||||
{
|
||||
// make a string of n spaces where n is column number - 1
|
||||
char[] indentation = new char[spaces];
|
||||
for (int i=0; i<spaces; i++) {
|
||||
indentation[i] = ' ';
|
||||
}
|
||||
String s = new String(indentation);
|
||||
emit(new ClassicToken(LEADING_WS,new String(indentation)));
|
||||
}
|
||||
// kill trailing newline if present and then ignore
|
||||
( ('\r')? '\n' {if (state.token!=null) state.token.setChannel(HIDDEN); else $channel=HIDDEN;})*
|
||||
// {token.setChannel(99); }
|
||||
)
|
||||
;
|
||||
|
||||
/** Comments not on line by themselves are turned into newlines.
|
||||
|
||||
b = a # end of line comment
|
||||
|
||||
or
|
||||
|
||||
a = [1, # weird
|
||||
2]
|
||||
|
||||
This rule is invoked directly by nextToken when the comment is in
|
||||
first column or when comment is on end of nonwhitespace line.
|
||||
|
||||
Only match \n here if we didn't start on left edge; let NEWLINE return that.
|
||||
Kill if newlines if we live on a line by ourselves
|
||||
|
||||
Consume any leading whitespace if it starts on left edge.
|
||||
*/
|
||||
COMMENT
|
||||
@init {
|
||||
$channel=HIDDEN;
|
||||
}
|
||||
: {startPos==0}?=> (' '|'\t')* '#' (~'\n')* '\n'+
|
||||
| {startPos>0}?=> '#' (~'\n')* // let NEWLINE handle \n unless char pos==0 for '#'
|
||||
;
|
@ -1,201 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2009 Scott Stanchfield
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*******************************************************************************/
|
||||
grammar Sample;
|
||||
|
||||
options {
|
||||
language = Java;
|
||||
output = AST;
|
||||
output=template;
|
||||
}
|
||||
|
||||
@header {
|
||||
package samples.antlr;
|
||||
}
|
||||
|
||||
@lexer::header {
|
||||
package samples.antlr;
|
||||
}
|
||||
|
||||
program
|
||||
: 'program' IDENT '='
|
||||
(constant | variable | function | procedure | typeDecl)*
|
||||
'begin'
|
||||
statement*
|
||||
'end' IDENT '.'
|
||||
;
|
||||
|
||||
constant
|
||||
: 'constant' IDENT ':' type ':=' expression ';'
|
||||
;
|
||||
|
||||
variable
|
||||
: 'var' IDENT (',' IDENT)* ':' type (':=' expression)? ';'
|
||||
;
|
||||
|
||||
type
|
||||
: 'Integer'
|
||||
| 'Boolean'
|
||||
| 'String'
|
||||
| 'Char'
|
||||
| IDENT
|
||||
| typeSpec
|
||||
;
|
||||
|
||||
typeDecl
|
||||
: 'type' IDENT '=' typeSpec ';'
|
||||
;
|
||||
|
||||
typeSpec
|
||||
: arrayType
|
||||
| recordType
|
||||
| enumType
|
||||
;
|
||||
|
||||
arrayType
|
||||
: 'array' '[' INTEGER '..' INTEGER ']' 'of' type
|
||||
;
|
||||
|
||||
recordType
|
||||
: 'record' field* 'end' 'record'
|
||||
;
|
||||
|
||||
field
|
||||
: IDENT ':' type ';'
|
||||
;
|
||||
|
||||
enumType
|
||||
: '<' IDENT (',' IDENT)* '>'
|
||||
;
|
||||
|
||||
statement
|
||||
: assignmentStatement
|
||||
| ifStatement
|
||||
| loopStatement
|
||||
| whileStatement
|
||||
| procedureCallStatement
|
||||
;
|
||||
|
||||
procedureCallStatement
|
||||
: IDENT '(' actualParameters? ')' ';'
|
||||
;
|
||||
|
||||
actualParameters
|
||||
: expression (',' expression)*
|
||||
;
|
||||
|
||||
ifStatement
|
||||
: 'if' expression 'then' statement+
|
||||
('elsif' expression 'then' statement+)*
|
||||
('else' statement+)?
|
||||
'end' 'if' ';'
|
||||
;
|
||||
|
||||
assignmentStatement
|
||||
: IDENT ':=' expression ';'
|
||||
;
|
||||
|
||||
exitStatement
|
||||
: 'exit' 'when' expression ';'
|
||||
;
|
||||
|
||||
whileStatement
|
||||
: 'while' expression 'loop'
|
||||
(statement|exitStatement)*
|
||||
'end' 'loop' ';'
|
||||
;
|
||||
|
||||
loopStatement
|
||||
: 'loop' (statement|exitStatement)* 'end' 'loop' ';'
|
||||
;
|
||||
|
||||
returnStatement
|
||||
: 'return' expression ';'
|
||||
;
|
||||
|
||||
procedure
|
||||
: 'procedure' IDENT '(' parameters? ')' '='
|
||||
(constant | variable)*
|
||||
'begin'
|
||||
statement*
|
||||
'end' IDENT '.'
|
||||
;
|
||||
function
|
||||
: 'function' IDENT '(' parameters? ')' ':' type '='
|
||||
(constant | variable)*
|
||||
'begin'
|
||||
(statement|returnStatement)*
|
||||
'end' IDENT '.'
|
||||
;
|
||||
|
||||
parameters
|
||||
: parameter (',' parameter)*
|
||||
;
|
||||
|
||||
parameter
|
||||
: 'var'? IDENT ':' type
|
||||
;
|
||||
|
||||
|
||||
// expressions -- fun time!
|
||||
|
||||
term
|
||||
: IDENT
|
||||
| '(' expression ')'
|
||||
| INTEGER
|
||||
| STRING_LITERAL
|
||||
| CHAR_LITERAL
|
||||
| IDENT '(' actualParameters ')'
|
||||
;
|
||||
|
||||
negation
|
||||
: 'not'* term
|
||||
;
|
||||
|
||||
unary
|
||||
: ('+' | '-')* negation
|
||||
;
|
||||
|
||||
mult
|
||||
: unary (('*' | '/' | 'mod') unary)*
|
||||
;
|
||||
|
||||
add
|
||||
: mult (('+' | '-') mult)*
|
||||
;
|
||||
|
||||
relation
|
||||
: add (('=' | '/=' | '<' | '<=' | '>=' | '>') add)*
|
||||
;
|
||||
|
||||
expression
|
||||
: relation (('and' | 'or') relation)*
|
||||
;
|
||||
|
||||
|
||||
MULTILINE_COMMENT : '/*' .* '*/' {$channel = HIDDEN;} ;
|
||||
|
||||
STRING_LITERAL
|
||||
: '"'
|
||||
{ StringBuilder b = new StringBuilder(); }
|
||||
( '"' '"' { b.appendCodePoint('"');}
|
||||
| c=~('"'|'\r'|'\n') { b.appendCodePoint(c);}
|
||||
)*
|
||||
'"'
|
||||
{ setText(b.toString()); }
|
||||
;
|
||||
|
||||
CHAR_LITERAL
|
||||
: '\'' . '\'' {setText(getText().substring(1,2));}
|
||||
;
|
||||
|
||||
fragment LETTER : ('a'..'z' | 'A'..'Z') ;
|
||||
fragment DIGIT : '0'..'9';
|
||||
INTEGER : DIGIT+ ;
|
||||
IDENT : LETTER (LETTER | DIGIT)*;
|
||||
WS : (' ' | '\t' | '\n' | '\r' | '\f')+ {$channel = HIDDEN;};
|
||||
COMMENT : '//' .* ('\n'|'\r') {$channel = HIDDEN;};
|
@ -1,10 +0,0 @@
|
||||
|
||||
/** https://github.com/rollxx/antlr-php-runtime/blob/master/examples/cminus/Bytecode.stg */
|
||||
|
||||
|
||||
|
||||
variable(type,name) ::= ".var is <name> <type><\n>"
|
||||
|
||||
type_int() ::= "I"
|
||||
|
||||
type_char() ::= "C"
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,81 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2009 Scott Stanchfield
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*******************************************************************************/
|
||||
package samples.antlr;
|
||||
|
||||
import org.antlr.runtime.*;
|
||||
import org.antlr.runtime.tree.CommonTree;
|
||||
import org.antlr.runtime.tree.DOTTreeGenerator;
|
||||
import org.antlr.stringtemplate.StringTemplate;
|
||||
import org.antlr.stringtemplate.StringTemplateGroup;
|
||||
|
||||
|
||||
|
||||
public class Test1 {
|
||||
public static void main(String[] args) throws RecognitionException {
|
||||
CharStream stream =
|
||||
new ANTLRStringStream("program XLSample1 =\r\n" +
|
||||
"/*\r\n" +
|
||||
" constant one : Integer := 1;\r\n" +
|
||||
" constant two : Integer := 2 * 3;\r\n" +
|
||||
" var x, y, z : Integer := 42;\r\n" +
|
||||
"*/\r\n" +
|
||||
"\r\n" +
|
||||
" procedure foo() =\r\n" +
|
||||
" var x : Integer := 2;\r\n" +
|
||||
" begin\r\n" +
|
||||
" end foo.\r\n" +
|
||||
" procedure fee(y : Integer) =\r\n" +
|
||||
" var x : Integer := 2;\r\n" +
|
||||
" begin\r\n" +
|
||||
" end fee.\r\n" +
|
||||
" function fie(y : Integer) : Integer =\r\n" +
|
||||
" var x : Integer := 2;\r\n" +
|
||||
" begin\r\n" +
|
||||
" return y;\r\n" +
|
||||
" end fie.\r\n" +
|
||||
"begin\r\n" +
|
||||
"end XLSample1.");
|
||||
SampleLexer lexer = new SampleLexer(stream);
|
||||
TokenStream tokenStream = new CommonTokenStream(lexer);
|
||||
SampleParser parser = new SampleParser(tokenStream);
|
||||
CommonTree astTree = (CommonTree) parser.program().getTree();
|
||||
|
||||
DOTTreeGenerator gen = new DOTTreeGenerator();
|
||||
StringTemplate st = gen.toDOT(astTree);
|
||||
|
||||
|
||||
String userDir = System.getProperty("user.dir");
|
||||
|
||||
String stgFile = userDir + "\\src\\main\\java\\samples\\antlr\\Sample2Asm.stg";
|
||||
|
||||
|
||||
|
||||
StringTemplateGroup stg = new StringTemplateGroup(stgFile);
|
||||
|
||||
parser.setTemplateLib(stg);
|
||||
|
||||
RuleReturnScope r = parser.program();
|
||||
// System.out.println(r.getTemplate().toString());
|
||||
|
||||
|
||||
|
||||
// System.out.println(st);
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
Lexical Analysis (scanning)
|
||||
Semantic Analysis (parsing)
|
||||
Tree Generation ==> Abstract Syntax Tree (AST)
|
||||
Code Generation ==> using stg file
|
||||
Interpretation
|
||||
*/
|
||||
System.out.println("ok");
|
||||
}
|
||||
}
|
@ -1,51 +0,0 @@
|
||||
package samples.netty;
|
||||
|
||||
import io.netty.bootstrap.Bootstrap;
|
||||
import io.netty.channel.ChannelFuture;
|
||||
import io.netty.channel.ChannelInitializer;
|
||||
import io.netty.channel.ChannelOption;
|
||||
import io.netty.channel.EventLoopGroup;
|
||||
import io.netty.channel.nio.NioEventLoopGroup;
|
||||
import io.netty.channel.socket.nio.NioSocketChannel;
|
||||
|
||||
import java.nio.channels.SocketChannel;
|
||||
|
||||
/**
|
||||
* www.ethereumJ.com
|
||||
* User: Roman Mandeleil
|
||||
* Created on: 10/04/14 08:20
|
||||
*/
|
||||
public class Client {
|
||||
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
|
||||
String host = "85.65.126.45";
|
||||
int port = 10101;
|
||||
|
||||
EventLoopGroup workerGroup = new NioEventLoopGroup();
|
||||
|
||||
try {
|
||||
|
||||
Bootstrap b = new Bootstrap();
|
||||
b.group(workerGroup);
|
||||
b.channel(NioSocketChannel.class);
|
||||
|
||||
b.option(ChannelOption.SO_KEEPALIVE, true);
|
||||
b.handler(new ChannelInitializer<NioSocketChannel>() {
|
||||
@Override
|
||||
public void initChannel(NioSocketChannel ch) throws Exception {
|
||||
ch.pipeline().addLast(new ClientMessageHandler());
|
||||
}
|
||||
});
|
||||
|
||||
// Start the client.
|
||||
ChannelFuture f = b.connect(host, port).sync(); // (5)
|
||||
|
||||
// Wait until the connection is closed.
|
||||
f.channel().closeFuture().sync();
|
||||
} finally {
|
||||
workerGroup.shutdownGracefully();
|
||||
}
|
||||
}
|
||||
}
|
@ -1,70 +0,0 @@
|
||||
package samples.netty;
|
||||
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.channel.ChannelFuture;
|
||||
import io.netty.channel.ChannelFutureListener;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.channel.ChannelInboundHandlerAdapter;
|
||||
import io.netty.util.ReferenceCountUtil;
|
||||
|
||||
/**
|
||||
* www.ethereumJ.com
|
||||
* User: Roman Mandeleil
|
||||
* Created on: 10/04/14 08:19
|
||||
*/
|
||||
public class ClientMessageHandler extends ChannelInboundHandlerAdapter {
|
||||
|
||||
|
||||
@Override
|
||||
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
|
||||
|
||||
|
||||
ByteBuf input = ((ByteBuf)msg);
|
||||
|
||||
try {
|
||||
|
||||
int inputSize = input.readableBytes();
|
||||
byte[] payload = new byte[inputSize];
|
||||
input.readBytes(payload);
|
||||
|
||||
if (payload.length < 5){
|
||||
System.out.println("Not a Roman server disconnect");
|
||||
ctx.close();
|
||||
}
|
||||
|
||||
String prefix = new String(payload, 0, 5);
|
||||
|
||||
if (!prefix.equals("9191-")){
|
||||
System.out.println("Not a Roman server disconnect");
|
||||
ctx.close();
|
||||
}
|
||||
|
||||
|
||||
String newMessage = new String(payload);
|
||||
System.out.println(newMessage);
|
||||
|
||||
Thread.sleep(1000);
|
||||
|
||||
String answer = RomanProtocol.getAnswer(newMessage);
|
||||
final ByteBuf buffer = ctx.alloc().buffer(answer.length());
|
||||
buffer.writeBytes(answer.getBytes());
|
||||
ctx.writeAndFlush(buffer);
|
||||
|
||||
// String answer2 = "cool sir 2!!!";
|
||||
// final ByteBuf helloMessage2 = ctx.alloc().buffer(answer2.length());
|
||||
// helloMessage2.writeBytes(answer2.getBytes());
|
||||
// ctx.writeAndFlush(helloMessage2);
|
||||
|
||||
|
||||
} finally {
|
||||
ReferenceCountUtil.release(input);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
|
||||
cause.printStackTrace();
|
||||
ctx.close();
|
||||
}
|
||||
}
|
@ -1,47 +0,0 @@
|
||||
package samples.netty;
|
||||
|
||||
/**
|
||||
* www.ethereumJ.com
|
||||
* User: Roman Mandeleil
|
||||
* Created on: 10/04/14 11:19
|
||||
*/
|
||||
public class RomanProtocol {
|
||||
|
||||
|
||||
public static String getAnswer(String msg){
|
||||
|
||||
if (msg.equals("9191-Hello"))
|
||||
return ("9191-Good day sir");
|
||||
|
||||
if (msg.equals("9191-Good day sir"))
|
||||
return ("9191-What is you name");
|
||||
|
||||
if (msg.equals("9191-What is you name"))
|
||||
return ("9191-My Name is Ethereum");
|
||||
|
||||
if (msg.matches("9191-My Name is ([\\w])*")) {
|
||||
|
||||
String name = msg.substring(16);
|
||||
|
||||
return ("9191-Good to see you: " + name);
|
||||
}
|
||||
|
||||
if (msg.matches("9191-Good to see you: ([\\w])*")) {
|
||||
|
||||
return ("9191-Hello");
|
||||
}
|
||||
|
||||
|
||||
return "9191-Sorry I don't understand you";
|
||||
}
|
||||
|
||||
public static void main(String args[]){
|
||||
|
||||
System.out.println(getAnswer("9191-My Name is Vasia"));
|
||||
|
||||
|
||||
// 1800-0770-77
|
||||
|
||||
|
||||
}
|
||||
}
|
@ -1,69 +0,0 @@
|
||||
package samples.netty;
|
||||
|
||||
import io.netty.bootstrap.ServerBootstrap;
|
||||
import io.netty.channel.ChannelFuture;
|
||||
import io.netty.channel.ChannelInitializer;
|
||||
import io.netty.channel.ChannelOption;
|
||||
import io.netty.channel.EventLoopGroup;
|
||||
import io.netty.channel.nio.NioEventLoopGroup;
|
||||
import io.netty.channel.socket.nio.NioServerSocketChannel;
|
||||
import io.netty.channel.socket.nio.NioSocketChannel;
|
||||
|
||||
/**
|
||||
* www.ethereumJ.com
|
||||
* User: Roman Mandeleil
|
||||
* Created on: 10/04/14 08:20
|
||||
*/
|
||||
public class Server {
|
||||
|
||||
int port;
|
||||
|
||||
|
||||
public Server(int port) {
|
||||
this.port = port;
|
||||
}
|
||||
|
||||
|
||||
public void start(){
|
||||
|
||||
EventLoopGroup bossGroup = new NioEventLoopGroup();
|
||||
EventLoopGroup workerGroup = new NioEventLoopGroup();
|
||||
|
||||
|
||||
ServerBootstrap bootstrap = new ServerBootstrap();
|
||||
bootstrap.group(bossGroup, workerGroup)
|
||||
.channel(NioServerSocketChannel.class)
|
||||
.childHandler(new ChannelInitializer<NioSocketChannel>() {
|
||||
|
||||
public void initChannel(NioSocketChannel channel){
|
||||
|
||||
channel.pipeline().addLast(new ServerMessageHandler());
|
||||
|
||||
};
|
||||
|
||||
}).option(ChannelOption.SO_BACKLOG, 128)
|
||||
.childOption(ChannelOption.SO_KEEPALIVE, true);
|
||||
|
||||
try {
|
||||
|
||||
System.out.println("Server started");
|
||||
ChannelFuture future = bootstrap.bind(port).sync();
|
||||
|
||||
future.channel().closeFuture().sync();
|
||||
|
||||
|
||||
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
workerGroup.shutdownGracefully();
|
||||
bossGroup.shutdownGracefully();
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String args[]){
|
||||
|
||||
new Server(10101).start();
|
||||
|
||||
}
|
||||
}
|
@ -1,65 +0,0 @@
|
||||
package samples.netty;
|
||||
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.channel.*;
|
||||
import io.netty.util.ReferenceCountUtil;
|
||||
|
||||
/**
|
||||
* www.ethereumJ.com
|
||||
* User: Roman Mandeleil
|
||||
* Created on: 10/04/14 08:19
|
||||
*/
|
||||
public class ServerMessageHandler extends ChannelInboundHandlerAdapter {
|
||||
|
||||
|
||||
@Override
|
||||
public void channelActive(final ChannelHandlerContext ctx) {
|
||||
|
||||
String helloString = "9191-Hello";
|
||||
|
||||
final ByteBuf helloMessage = ctx.alloc().buffer(helloString.length());
|
||||
helloMessage.writeBytes(helloString.getBytes());
|
||||
|
||||
final ChannelFuture channelFuture = ctx.writeAndFlush(helloMessage);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
|
||||
|
||||
|
||||
ByteBuf input = ((ByteBuf)msg);
|
||||
|
||||
try {
|
||||
|
||||
int inputSize = input.readableBytes();
|
||||
byte[] payload = new byte[inputSize];
|
||||
input.readBytes(payload);
|
||||
|
||||
String newMessage = new String(payload);
|
||||
System.out.println(newMessage);
|
||||
|
||||
Thread.sleep(1000);
|
||||
|
||||
String answer = RomanProtocol.getAnswer(newMessage);
|
||||
final ByteBuf buffer = ctx.alloc().buffer(answer.length());
|
||||
buffer.writeBytes(answer.getBytes());
|
||||
ctx.writeAndFlush(buffer);
|
||||
|
||||
|
||||
|
||||
|
||||
} finally {
|
||||
ReferenceCountUtil.release(input);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
|
||||
|
||||
System.out.println("Client disconnected");
|
||||
// cause.printStackTrace();
|
||||
ctx.close();
|
||||
}
|
||||
}
|
@ -1,18 +0,0 @@
|
||||
package samples.niotut;
|
||||
|
||||
import java.nio.channels.SocketChannel;
|
||||
|
||||
public class ChangeRequest {
|
||||
public static final int REGISTER = 1;
|
||||
public static final int CHANGEOPS = 2;
|
||||
|
||||
public SocketChannel socket;
|
||||
public int type;
|
||||
public int ops;
|
||||
|
||||
public ChangeRequest(SocketChannel socket, int type, int ops) {
|
||||
this.socket = socket;
|
||||
this.type = type;
|
||||
this.ops = ops;
|
||||
}
|
||||
}
|
@ -1,38 +0,0 @@
|
||||
package samples.niotut;
|
||||
|
||||
import java.nio.channels.SocketChannel;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
public class EchoWorker implements Runnable {
|
||||
private List queue = new LinkedList();
|
||||
|
||||
public void processData(NioServer server, SocketChannel socket, byte[] data, int count) {
|
||||
byte[] dataCopy = new byte[count];
|
||||
System.arraycopy(data, 0, dataCopy, 0, count);
|
||||
synchronized(queue) {
|
||||
queue.add(new ServerDataEvent(server, socket, dataCopy));
|
||||
queue.notify();
|
||||
}
|
||||
}
|
||||
|
||||
public void run() {
|
||||
ServerDataEvent dataEvent;
|
||||
|
||||
while(true) {
|
||||
// Wait for data to become available
|
||||
synchronized(queue) {
|
||||
while(queue.isEmpty()) {
|
||||
try {
|
||||
queue.wait();
|
||||
} catch (InterruptedException e) {
|
||||
}
|
||||
}
|
||||
dataEvent = (ServerDataEvent) queue.remove(0);
|
||||
}
|
||||
|
||||
// Return to sender
|
||||
dataEvent.server.send(dataEvent.socket, dataEvent.data);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,403 +0,0 @@
|
||||
package samples.niotut;
|
||||
|
||||
|
||||
/* BASED ON: http://rox-xmlrpc.sourceforge.net/niotut/#The client */
|
||||
|
||||
import org.ethereum.util.Utils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.InetAddress;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.channels.SelectionKey;
|
||||
import java.nio.channels.Selector;
|
||||
import java.nio.channels.SocketChannel;
|
||||
import java.nio.channels.spi.SelectorProvider;
|
||||
import java.util.*;
|
||||
|
||||
public class NioClient implements Runnable {
|
||||
// The host:port combination to connect to
|
||||
private InetAddress hostAddress;
|
||||
private int port;
|
||||
|
||||
// The selector we'll be monitoring
|
||||
private Selector selector;
|
||||
|
||||
// The buffer into which we'll read data when it's available
|
||||
private ByteBuffer readBuffer = ByteBuffer.allocate(8192);
|
||||
|
||||
// A list of PendingChange instances
|
||||
private List pendingChanges = new LinkedList();
|
||||
|
||||
// Maps a SocketChannel to a list of ByteBuffer instances
|
||||
private Map pendingData = new HashMap();
|
||||
|
||||
// Maps a SocketChannel to a RspHandler
|
||||
private Map rspHandlers = Collections.synchronizedMap(new HashMap());
|
||||
|
||||
public SocketChannel socket;
|
||||
public RspHandler handler;
|
||||
|
||||
|
||||
public static final String helloString = "22 40 08 91 00 00 00 79 F8 77 80 0B 80 AD 45 74 " +
|
||||
"68 65 72 65 75 6D 28 2B 2B 29 2F 5A 65 72 6F 47 " +
|
||||
"6F 78 2F 76 30 2E 34 2E 31 2F 6E 63 75 72 73 65 " +
|
||||
"73 2F 4C 69 6E 75 78 2F 67 2B 2B 07 82 76 5F B8 " +
|
||||
"40 D8 D6 0C 25 80 FA 79 5C FC 03 13 EF DE BA 86 " +
|
||||
"9D 21 94 E7 9E 7C B2 B5 22 F7 82 FF A0 39 2C BB " +
|
||||
"AB 8D 1B AC 30 12 08 B1 37 E0 DE 49 98 33 4F 3B " +
|
||||
"CF 73 FA 11 7E F2 13 F8 74 17 08 9F EA F8 4C 21 " +
|
||||
"B0 ";
|
||||
|
||||
public static final String pingString = "22 40 08 91 00 00 00 02 C1 02 ";
|
||||
public static final String pongString = "22 40 08 91 00 00 00 02 C1 03 ";
|
||||
|
||||
public static final String getPeersString = "22 40 08 91 00 00 00 02 C1 10 ";
|
||||
|
||||
public static final String getTransactions = "22 40 08 91 00 00 00 02 C1 16 ";
|
||||
|
||||
public static final String getChain = "22 40 08 91 00 00 00 26 F8 24 14 " +
|
||||
"AB 6B 9A 56 13 97 0F AA 77 1B 12 D4 49 B2 E9 BB 92 5A B7 A3 69 F0 A4 B8 6B 28 6E 9D 54 00 99 CF " +
|
||||
"82 01 00 ";
|
||||
|
||||
public static final String getTxString = "22 40 08 91 00 00 00 02 C1 16 ";
|
||||
|
||||
|
||||
|
||||
public NioClient(InetAddress hostAddress, int port) throws IOException {
|
||||
this.hostAddress = hostAddress;
|
||||
this.port = port;
|
||||
this.selector = this.initSelector();
|
||||
|
||||
// Start a new connection
|
||||
this.socket = this.initiateConnection();
|
||||
|
||||
// Register the response handler
|
||||
this.handler = new RspHandler();
|
||||
this.rspHandlers.put(socket, handler);
|
||||
|
||||
}
|
||||
|
||||
public void send(byte[] data) throws IOException {
|
||||
|
||||
// And queue the data we want written
|
||||
synchronized (this.pendingData) {
|
||||
List queue = (List) this.pendingData.get(socket);
|
||||
if (queue == null) {
|
||||
queue = new ArrayList();
|
||||
this.pendingData.put(socket, queue);
|
||||
}
|
||||
queue.add(ByteBuffer.wrap(data));
|
||||
}
|
||||
|
||||
// Finally, wake up our selecting thread so it can make the required changes
|
||||
this.selector.wakeup();
|
||||
}
|
||||
|
||||
public void run() {
|
||||
|
||||
|
||||
while (true) {
|
||||
try {
|
||||
// Process any pending changes
|
||||
synchronized (this.pendingChanges) {
|
||||
Iterator changes = this.pendingChanges.iterator();
|
||||
while (changes.hasNext()) {
|
||||
ChangeRequest change = (ChangeRequest) changes.next();
|
||||
|
||||
switch (change.type) {
|
||||
case ChangeRequest.CHANGEOPS:
|
||||
SelectionKey key = change.socket.keyFor(this.selector);
|
||||
key.interestOps(change.ops);
|
||||
break;
|
||||
case ChangeRequest.REGISTER:
|
||||
change.socket.register(this.selector, change.ops);
|
||||
break;
|
||||
}
|
||||
}
|
||||
this.pendingChanges.clear();
|
||||
}
|
||||
|
||||
// Wait for an event one of the registered channels
|
||||
// THIS ONE ACTUALLY BLOCKS AND SHOULD AWAKE WHEN SOME I/O HAPPENS
|
||||
this.selector.select();
|
||||
|
||||
// Iterate over the set of keys for which events are available
|
||||
Iterator selectedKeys = this.selector.selectedKeys().iterator();
|
||||
while (selectedKeys.hasNext()) {
|
||||
SelectionKey key = (SelectionKey) selectedKeys.next();
|
||||
selectedKeys.remove();
|
||||
|
||||
if (!key.isValid()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check what event is available and deal with it
|
||||
if (key.isConnectable()) {
|
||||
this.establishConnection(key);
|
||||
} else if (key.isReadable()) {
|
||||
this.read(key);
|
||||
} else if (key.isWritable()) {
|
||||
this.write(key);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void read(SelectionKey key) throws IOException {
|
||||
SocketChannel socketChannel = (SocketChannel) key.channel();
|
||||
|
||||
// Clear out our read buffer so it's ready for new data
|
||||
this.readBuffer.clear();
|
||||
|
||||
// Attempt to read off the channel
|
||||
int numRead;
|
||||
try {
|
||||
|
||||
numRead = socketChannel.read(this.readBuffer);
|
||||
System.out.println("reading: " + numRead);
|
||||
// key.interestOps(SelectionKey.OP_WRITE);
|
||||
|
||||
} catch (IOException e) {
|
||||
// The remote forcibly closed the connection, cancel
|
||||
// the selection key and close the channel.
|
||||
key.cancel();
|
||||
socketChannel.close();
|
||||
return;
|
||||
}
|
||||
|
||||
if (numRead == -1) {
|
||||
// Remote entity shut the socket down cleanly. Do the
|
||||
// same from our end and cancel the channel.
|
||||
// key.channel().close();
|
||||
// key.cancel();
|
||||
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Handle the response
|
||||
|
||||
|
||||
this.handleResponse(socketChannel, this.readBuffer.array(), numRead);
|
||||
}
|
||||
|
||||
private void handleResponse(SocketChannel socketChannel, byte[] data, int numRead) throws IOException {
|
||||
|
||||
// Make a correctly sized copy of the data before handing it
|
||||
// to the client
|
||||
byte[] rspData = new byte[numRead];
|
||||
System.arraycopy(data, 0, rspData, 0, numRead);
|
||||
|
||||
|
||||
|
||||
// Look up the handler for this channel
|
||||
RspHandler handler = (RspHandler) this.rspHandlers.get(socketChannel);
|
||||
|
||||
// And pass the response to it
|
||||
if (handler.handleResponse(rspData)) {
|
||||
// The handler has seen enough, close the connection
|
||||
// socketChannel.close();
|
||||
// socketChannel.keyFor(this.selector).cancel();
|
||||
}
|
||||
}
|
||||
|
||||
private void write(SelectionKey key) throws IOException {
|
||||
SocketChannel socketChannel = (SocketChannel) key.channel();
|
||||
|
||||
synchronized (this.pendingData) {
|
||||
List queue = (List) this.pendingData.get(socketChannel);
|
||||
|
||||
|
||||
// Write until there's not more data ...
|
||||
while (queue != null && !queue.isEmpty()) {
|
||||
ByteBuffer buf = (ByteBuffer) queue.get(0);
|
||||
byte[] packet = buf.array();
|
||||
|
||||
System.out.print("write: ");
|
||||
Utils.printHexStringForByteArray(packet);
|
||||
|
||||
socketChannel.write(buf);
|
||||
|
||||
if (buf.remaining() > 0) {
|
||||
// ... or the socket's buffer fills up
|
||||
break;
|
||||
}
|
||||
queue.remove(0);
|
||||
}
|
||||
// key.interestOps(SelectionKey.OP_READ);
|
||||
|
||||
if (queue == null || queue.isEmpty()) {
|
||||
// We wrote away all data, so we're no longer interested
|
||||
// in writing on this socket. Switch back to waiting for
|
||||
// data.
|
||||
key.interestOps(SelectionKey.OP_READ);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void establishConnection(SelectionKey key) throws IOException {
|
||||
SocketChannel socketChannel = (SocketChannel) key.channel();
|
||||
|
||||
// Finish the connection. If the connection operation failed
|
||||
// this will raise an IOException.
|
||||
try {
|
||||
socketChannel.finishConnect();
|
||||
} catch (IOException e) {
|
||||
// Cancel the channel's registration with our selector
|
||||
System.out.println(e);
|
||||
key.cancel();
|
||||
return;
|
||||
}
|
||||
|
||||
// Register an interest in writing on this channel
|
||||
key.interestOps(SelectionKey.OP_WRITE);
|
||||
}
|
||||
|
||||
private SocketChannel initiateConnection() throws IOException {
|
||||
// Create a non-blocking socket channel
|
||||
SocketChannel socketChannel = SocketChannel.open();
|
||||
socketChannel.configureBlocking(false);
|
||||
|
||||
// Kick off connection establishment
|
||||
socketChannel.connect(new InetSocketAddress(this.hostAddress, this.port));
|
||||
|
||||
// Queue a channel registration since the caller is not the
|
||||
// selecting thread. As part of the registration we'll register
|
||||
// an interest in connection events. These are raised when a channel
|
||||
// is ready to complete connection establishment.
|
||||
synchronized(this.pendingChanges) {
|
||||
this.pendingChanges.add(new ChangeRequest(socketChannel,
|
||||
ChangeRequest.REGISTER, SelectionKey.OP_CONNECT));
|
||||
}
|
||||
|
||||
return socketChannel;
|
||||
}
|
||||
|
||||
private Selector initSelector() throws IOException {
|
||||
// Create a new selector
|
||||
return SelectorProvider.provider().openSelector();
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
try {
|
||||
|
||||
NioClient client = new NioClient(InetAddress.getByName("localhost"), 20202);
|
||||
Thread t = new Thread(client, "ClientThread");
|
||||
t.setDaemon(true);
|
||||
t.start();
|
||||
|
||||
// client.send(new byte[0]);
|
||||
// client.handler.waitForResponse();
|
||||
Thread.sleep(2000);
|
||||
|
||||
|
||||
System.out.println("\nsending HELLO");
|
||||
client.enableWriting();
|
||||
// client.send(hexStringToByteArr(helloString));
|
||||
Thread.sleep(100);
|
||||
|
||||
System.out.println("\nsending PONG");
|
||||
// client.enableWriting();
|
||||
// client.send(hexStringToByteArr(pongString));
|
||||
|
||||
Thread.sleep(100);
|
||||
System.out.println("\nsending GETCHAIN");
|
||||
// client.enableWriting();
|
||||
// client.send(hexStringToByteArr(getChain));
|
||||
|
||||
|
||||
|
||||
|
||||
// System.out.println("\nsending PING");
|
||||
// client.send(hexStringToByteArr(pingString));
|
||||
// client.handler.waitForResponse();
|
||||
|
||||
|
||||
System.out.println("SLEEPING");
|
||||
Thread.sleep(5000);
|
||||
|
||||
client.handler.waitForResponse();
|
||||
|
||||
// System.out.println("\nsending GETCHAIN");
|
||||
// client.send(hexStringToByteArr(getChain));
|
||||
// client.handler.waitForResponse();
|
||||
|
||||
|
||||
// System.out.println("\nsending GETPEERS");
|
||||
// client.send(hexStringToByteArr(getPeersString));
|
||||
// client.handler.waitForResponse();
|
||||
// client.handler.waitForResponse();
|
||||
|
||||
// System.out.println("\nsending GETTRANSACTIONS");
|
||||
// client.send(hexStringToByteArr(getTransactions));
|
||||
|
||||
|
||||
System.out.println("\nsleeping 5 secs before death");
|
||||
|
||||
|
||||
Thread.sleep(5000);
|
||||
|
||||
client.socket.close();
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
client.send(hexStringToByteArr(helloString));
|
||||
client.handler.waitForResponse();
|
||||
|
||||
|
||||
System.out.println("");
|
||||
client.send(hexStringToByteArr(getPeersString));
|
||||
client.handler.waitForResponse();
|
||||
|
||||
|
||||
System.out.println("");
|
||||
client.handler.waitForResponse();
|
||||
|
||||
System.out.println("");
|
||||
client.handler.waitForResponse();
|
||||
*/
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static byte[] hexStringToByteArr(String hexString){
|
||||
|
||||
String hexSymbols = "0123456789ABCDEF";
|
||||
|
||||
int arrSize = (int) (hexString.length() / 3);
|
||||
byte[] result = new byte[arrSize];
|
||||
|
||||
for (int i = 0; i < arrSize; ++i){
|
||||
|
||||
int digit1 = hexSymbols.indexOf( hexString.charAt(i * 3) );
|
||||
int digit2 = hexSymbols.indexOf( hexString.charAt(i * 3 + 1) );
|
||||
|
||||
result[i] = (byte) (digit1 * 16 + digit2);
|
||||
}
|
||||
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
public void enableWriting(){
|
||||
SelectionKey key = this.socket.keyFor(this.selector);
|
||||
key.interestOps(SelectionKey.OP_WRITE | SelectionKey.OP_READ);
|
||||
}
|
||||
|
||||
public void enableOnlyReading(){
|
||||
SelectionKey key = this.socket.keyFor(this.selector);
|
||||
key.interestOps(SelectionKey.OP_READ);
|
||||
}
|
||||
|
||||
}
|
@ -1,213 +0,0 @@
|
||||
package samples.niotut;
|
||||
|
||||
|
||||
/* BASED ON: http://rox-xmlrpc.sourceforge.net/niotut/#The client */
|
||||
import java.io.IOException;
|
||||
import java.net.InetAddress;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.Socket;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.channels.SelectionKey;
|
||||
import java.nio.channels.Selector;
|
||||
import java.nio.channels.ServerSocketChannel;
|
||||
import java.nio.channels.SocketChannel;
|
||||
import java.nio.channels.spi.SelectorProvider;
|
||||
import java.util.*;
|
||||
|
||||
public class NioServer implements Runnable {
|
||||
// The host:port combination to listen on
|
||||
private InetAddress hostAddress;
|
||||
private int port;
|
||||
|
||||
// The channel on which we'll accept connections
|
||||
private ServerSocketChannel serverChannel;
|
||||
|
||||
// The selector we'll be monitoring
|
||||
private Selector selector;
|
||||
|
||||
// The buffer into which we'll read data when it's available
|
||||
private ByteBuffer readBuffer = ByteBuffer.allocate(8192);
|
||||
|
||||
private EchoWorker worker;
|
||||
|
||||
// A list of PendingChange instances
|
||||
private List pendingChanges = new LinkedList();
|
||||
|
||||
// Maps a SocketChannel to a list of ByteBuffer instances
|
||||
private Map pendingData = new HashMap();
|
||||
|
||||
public NioServer(InetAddress hostAddress, int port, EchoWorker worker) throws IOException {
|
||||
this.hostAddress = hostAddress;
|
||||
this.port = port;
|
||||
this.selector = this.initSelector();
|
||||
this.worker = worker;
|
||||
}
|
||||
|
||||
public void send(SocketChannel socket, byte[] data) {
|
||||
synchronized (this.pendingChanges) {
|
||||
// Indicate we want the interest ops set changed
|
||||
this.pendingChanges.add(new ChangeRequest(socket, ChangeRequest.CHANGEOPS, SelectionKey.OP_WRITE));
|
||||
|
||||
// And queue the data we want written
|
||||
synchronized (this.pendingData) {
|
||||
List queue = (List) this.pendingData.get(socket);
|
||||
if (queue == null) {
|
||||
queue = new ArrayList();
|
||||
this.pendingData.put(socket, queue);
|
||||
}
|
||||
queue.add(ByteBuffer.wrap(data));
|
||||
}
|
||||
}
|
||||
|
||||
// Finally, wake up our selecting thread so it can make the required changes
|
||||
this.selector.wakeup();
|
||||
}
|
||||
|
||||
public void run() {
|
||||
while (true) {
|
||||
try {
|
||||
// Process any pending changes
|
||||
synchronized (this.pendingChanges) {
|
||||
Iterator changes = this.pendingChanges.iterator();
|
||||
while (changes.hasNext()) {
|
||||
ChangeRequest change = (ChangeRequest) changes.next();
|
||||
switch (change.type) {
|
||||
case ChangeRequest.CHANGEOPS:
|
||||
SelectionKey key = change.socket.keyFor(this.selector);
|
||||
key.interestOps(change.ops);
|
||||
}
|
||||
}
|
||||
this.pendingChanges.clear();
|
||||
}
|
||||
|
||||
// Wait for an event one of the registered channels
|
||||
System.out.println("accepting");
|
||||
this.selector.select();
|
||||
|
||||
// Iterate over the set of keys for which events are available
|
||||
Iterator selectedKeys = this.selector.selectedKeys().iterator();
|
||||
while (selectedKeys.hasNext()) {
|
||||
SelectionKey key = (SelectionKey) selectedKeys.next();
|
||||
selectedKeys.remove();
|
||||
|
||||
if (!key.isValid()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check what event is available and deal with it
|
||||
if (key.isAcceptable()) {
|
||||
System.out.println("new channel");
|
||||
this.accept(key);
|
||||
} else if (key.isReadable()) {
|
||||
System.out.println("reading");
|
||||
this.read(key);
|
||||
} else if (key.isWritable()) {
|
||||
System.out.println("writing");
|
||||
this.write(key);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void accept(SelectionKey key) throws IOException {
|
||||
// For an accept to be pending the channel must be a server socket channel.
|
||||
ServerSocketChannel serverSocketChannel = (ServerSocketChannel) key.channel();
|
||||
|
||||
// Accept the connection and make it non-blocking
|
||||
SocketChannel socketChannel = serverSocketChannel.accept();
|
||||
Socket socket = socketChannel.socket();
|
||||
socketChannel.configureBlocking(false);
|
||||
|
||||
// Register the new SocketChannel with our Selector, indicating
|
||||
// we'd like to be notified when there's data waiting to be read
|
||||
socketChannel.register(this.selector, SelectionKey.OP_READ);
|
||||
}
|
||||
|
||||
private void read(SelectionKey key) throws IOException {
|
||||
SocketChannel socketChannel = (SocketChannel) key.channel();
|
||||
|
||||
// Clear out our read buffer so it's ready for new data
|
||||
this.readBuffer.clear();
|
||||
|
||||
// Attempt to read off the channel
|
||||
int numRead;
|
||||
try {
|
||||
numRead = socketChannel.read(this.readBuffer);
|
||||
} catch (IOException e) {
|
||||
// The remote forcibly closed the connection, cancel
|
||||
// the selection key and close the channel.
|
||||
key.cancel();
|
||||
socketChannel.close();
|
||||
return;
|
||||
}
|
||||
|
||||
if (numRead == -1) {
|
||||
// Remote entity shut the socket down cleanly. Do the
|
||||
// same from our end and cancel the channel.
|
||||
key.channel().close();
|
||||
key.cancel();
|
||||
return;
|
||||
}
|
||||
|
||||
// Hand the data off to our worker thread
|
||||
this.worker.processData(this, socketChannel, this.readBuffer.array(), numRead);
|
||||
}
|
||||
|
||||
private void write(SelectionKey key) throws IOException {
|
||||
SocketChannel socketChannel = (SocketChannel) key.channel();
|
||||
|
||||
synchronized (this.pendingData) {
|
||||
List queue = (List) this.pendingData.get(socketChannel);
|
||||
|
||||
// Write until there's not more data ...
|
||||
while (!queue.isEmpty()) {
|
||||
ByteBuffer buf = (ByteBuffer) queue.get(0);
|
||||
socketChannel.write(buf);
|
||||
if (buf.remaining() > 0) {
|
||||
// ... or the socket's buffer fills up
|
||||
break;
|
||||
}
|
||||
queue.remove(0);
|
||||
}
|
||||
|
||||
if (queue.isEmpty()) {
|
||||
// We wrote away all data, so we're no longer interested
|
||||
// in writing on this socket. Switch back to waiting for
|
||||
// data.
|
||||
key.interestOps(SelectionKey.OP_READ);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Selector initSelector() throws IOException {
|
||||
// Create a new selector
|
||||
Selector socketSelector = SelectorProvider.provider().openSelector();
|
||||
|
||||
// Create a new non-blocking server socket channel
|
||||
this.serverChannel = ServerSocketChannel.open();
|
||||
serverChannel.configureBlocking(false);
|
||||
|
||||
// Bind the server socket to the specified address and port
|
||||
InetSocketAddress isa = new InetSocketAddress(this.hostAddress, this.port);
|
||||
serverChannel.socket().bind(isa);
|
||||
|
||||
// Register the server socket channel, indicating an interest in
|
||||
// accepting new connections
|
||||
serverChannel.register(socketSelector, SelectionKey.OP_ACCEPT);
|
||||
|
||||
return socketSelector;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
try {
|
||||
EchoWorker worker = new EchoWorker();
|
||||
new Thread(worker).start();
|
||||
new Thread(new NioServer(null, 9090, worker)).start();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
@ -1,107 +0,0 @@
|
||||
package samples.niotut;
|
||||
|
||||
import org.ethereum.net.RLP;
|
||||
import org.ethereum.util.Utils;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.Queue;
|
||||
|
||||
public class RspHandler {
|
||||
|
||||
public Queue<byte[]> packetsRecived = new LinkedList<byte[]>();
|
||||
|
||||
|
||||
public synchronized boolean handleResponse(byte[] rsp) {
|
||||
|
||||
packetsRecived.add(rsp);
|
||||
this.notify();
|
||||
return true;
|
||||
}
|
||||
|
||||
public synchronized void waitForResponse() {
|
||||
|
||||
|
||||
while(packetsRecived.isEmpty()) {
|
||||
try {
|
||||
this.wait();
|
||||
} catch (InterruptedException e) {
|
||||
}
|
||||
}
|
||||
|
||||
while (!packetsRecived.isEmpty()) {
|
||||
|
||||
byte[] rsp = packetsRecived.remove();
|
||||
Utils.printHexStringForByteArray(rsp);
|
||||
|
||||
|
||||
if (rsp.length < 9){
|
||||
// Can't be any ether packet
|
||||
}
|
||||
|
||||
boolean noMoreMessages = false;
|
||||
|
||||
|
||||
// 22 40 08 91 - magic packet
|
||||
if ((rsp[0] & 0xFF) == 0x22 &&
|
||||
(rsp[1] & 0xFF) == 0x40 &&
|
||||
(rsp[2] & 0xFF) == 0x08 &&
|
||||
(rsp[3] & 0xFF) == 0x91 ){
|
||||
|
||||
|
||||
// Got ethereum message
|
||||
}
|
||||
|
||||
|
||||
int numMessages = 0;
|
||||
// count number of messages in the packet
|
||||
for (int i = 0; i < rsp.length - 3; ++i){
|
||||
|
||||
if ( (rsp[i + 0] & 0xFF) == 0x22 &&
|
||||
(rsp[i + 1] & 0xFF) == 0x40 &&
|
||||
(rsp[i + 2] & 0xFF) == 0x08 &&
|
||||
(rsp[i + 3] & 0xFF) == 0x91 ){
|
||||
|
||||
++numMessages;
|
||||
}
|
||||
}
|
||||
|
||||
System.out.println("This packet contains: " + numMessages + " messages");
|
||||
|
||||
for (int i = 0; i < numMessages; ++i){
|
||||
|
||||
// Callc message length
|
||||
int messageLength = ((rsp[4] & 0xFF) << 24) +
|
||||
((rsp[5] & 0xFF) << 16) +
|
||||
((rsp[6] & 0xFF) << 8) +
|
||||
((rsp[7] & 0xFF));
|
||||
|
||||
byte[] msgPayload = new byte[messageLength];
|
||||
|
||||
System.out.println("payload size: " + msgPayload.length );
|
||||
System.out.println("packet size: " + messageLength );
|
||||
System.arraycopy(rsp, 8, msgPayload, 0, messageLength);
|
||||
|
||||
Utils.printHexStringForByteArray(msgPayload);
|
||||
|
||||
|
||||
|
||||
|
||||
Queue<Integer> index = new LinkedList<Integer>();
|
||||
|
||||
RLP.fullTraverse(msgPayload, 0, 0, msgPayload.length, 1, index);
|
||||
|
||||
// Message msg = MessageFactory.createMessage(msgPayload, index);
|
||||
// System.out.println("msg: " + msg);
|
||||
|
||||
// shift next message to the start of the packet array
|
||||
if (i + 1 < numMessages){
|
||||
|
||||
System.arraycopy(rsp, msgPayload.length + 8, rsp, 0, rsp.length - msgPayload.length - 8);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
System.out.println();
|
||||
}
|
||||
}
|
||||
}
|
@ -1,16 +0,0 @@
|
||||
|
||||
package samples.niotut;
|
||||
|
||||
import java.nio.channels.SocketChannel;
|
||||
|
||||
class ServerDataEvent {
|
||||
public NioServer server;
|
||||
public SocketChannel socket;
|
||||
public byte[] data;
|
||||
|
||||
public ServerDataEvent(NioServer server, SocketChannel socket, byte[] data) {
|
||||
this.server = server;
|
||||
this.socket = socket;
|
||||
this.data = data;
|
||||
}
|
||||
}
|
@ -1,74 +0,0 @@
|
||||
group Bytecode;
|
||||
|
||||
program(globals,functions) ::= <<
|
||||
.class public Wrapper
|
||||
.super java/lang/Object
|
||||
<globals>
|
||||
<functions>
|
||||
>>
|
||||
|
||||
variable(type,name) ::= ".var is <name> <type><\n>"
|
||||
|
||||
globalVariable(type,name) ::= ".field <name> <type><\n>"
|
||||
|
||||
function(type,name,args,locals,stats) ::= <<
|
||||
.method <name>(<args:{<it.type>}>)<type>
|
||||
<locals>
|
||||
<stats; separator="\n">
|
||||
return
|
||||
.end method
|
||||
>>
|
||||
|
||||
type_int() ::= "I"
|
||||
|
||||
type_char() ::= "C"
|
||||
|
||||
type_user_object(name) ::= "L<name>;"
|
||||
|
||||
parameter(type,name) ::= "<type> <name>"
|
||||
|
||||
statement(expr) ::= "<expr>"
|
||||
|
||||
statementList(locals,stats) ::= <<
|
||||
<locals>
|
||||
<stats; separator="\n">
|
||||
>>
|
||||
|
||||
forLoop(e1,e2,e3,locals,stats) ::= <<
|
||||
<e1>
|
||||
start:
|
||||
<e2>
|
||||
bf exit
|
||||
<locals>
|
||||
<stats; separator="\n">
|
||||
<e3>
|
||||
goto start
|
||||
exit:
|
||||
>>
|
||||
|
||||
assign(lhs,rhs) ::= <<
|
||||
<rhs>
|
||||
store <lhs>
|
||||
>>
|
||||
|
||||
|
||||
equals(left,right) ::= <<
|
||||
<left>
|
||||
<right>
|
||||
equals
|
||||
>>
|
||||
|
||||
lessThan(left,right) ::= <<
|
||||
<left>
|
||||
<right>
|
||||
lt
|
||||
>>
|
||||
|
||||
add(left,right) ::= <<
|
||||
<left>
|
||||
<right>
|
||||
add
|
||||
>>
|
||||
|
||||
refVar(id) ::= "push <id>"
|
||||
iconst(value) ::= "iconst <value>"
|
@ -1,152 +0,0 @@
|
||||
grammar CMinus;
|
||||
options {output=template;}
|
||||
|
||||
scope slist {
|
||||
List locals; // must be defined one per semicolon
|
||||
List stats;
|
||||
}
|
||||
|
||||
/*
|
||||
@slist::init {
|
||||
locals = new ArrayList();
|
||||
stats = new ArrayList();
|
||||
}
|
||||
*/
|
||||
|
||||
@header {
|
||||
package samples.stg;
|
||||
import org.antlr.stringtemplate.*;
|
||||
}
|
||||
|
||||
@lexer::header {
|
||||
package samples.stg;
|
||||
}
|
||||
|
||||
|
||||
program
|
||||
scope {
|
||||
List globals;
|
||||
List functions;
|
||||
}
|
||||
@init {
|
||||
$program::globals = new ArrayList();
|
||||
$program::functions = new ArrayList();
|
||||
}
|
||||
: declaration+
|
||||
-> program(globals={$program::globals},functions={$program::functions})
|
||||
;
|
||||
|
||||
declaration
|
||||
: variable {$program::globals.add($variable.st);}
|
||||
| f=function {$program::functions.add($f.st);}
|
||||
;
|
||||
|
||||
// ack is $function.st ambig? It can mean the rule's dyn scope or
|
||||
// the ref in this rule. Ack.
|
||||
|
||||
variable
|
||||
: type declarator ';'
|
||||
-> {$function.size()>0 && $function::name==null}?
|
||||
globalVariable(type={$type.st},name={$declarator.st})
|
||||
-> variable(type={$type.st},name={$declarator.st})
|
||||
;
|
||||
|
||||
declarator
|
||||
: ID -> {new StringTemplate($ID.text)}
|
||||
;
|
||||
|
||||
function
|
||||
scope {
|
||||
String name;
|
||||
}
|
||||
scope slist;
|
||||
@init {
|
||||
$slist::locals = new ArrayList();
|
||||
$slist::stats = new ArrayList();
|
||||
}
|
||||
: type ID {$function::name=$ID.text;}
|
||||
'(' ( p+=formalParameter ( ',' p+=formalParameter )* )? ')'
|
||||
block
|
||||
-> function(type={$type.st}, name={$function::name},
|
||||
locals={$slist::locals},
|
||||
stats={$slist::stats},
|
||||
args={$p})
|
||||
;
|
||||
|
||||
formalParameter
|
||||
: type declarator
|
||||
-> parameter(type={$type.st},name={$declarator.st})
|
||||
;
|
||||
|
||||
type
|
||||
: 'int' -> type_int()
|
||||
| 'char' -> type_char()
|
||||
| ID -> type_user_object(name={$ID.text})
|
||||
;
|
||||
|
||||
block
|
||||
: '{'
|
||||
( variable {$slist::locals.add($variable.st);} )*
|
||||
( stat {$slist::stats.add($stat.st);})*
|
||||
'}'
|
||||
;
|
||||
|
||||
stat
|
||||
scope slist;
|
||||
@init {
|
||||
$slist::locals = new ArrayList();
|
||||
$slist::stats = new ArrayList();
|
||||
}
|
||||
: forStat -> {$forStat.st}
|
||||
| expr ';' -> statement(expr={$expr.st})
|
||||
| block -> statementList(locals={$slist::locals}, stats={$slist::stats})
|
||||
| assignStat ';' -> {$assignStat.st}
|
||||
| ';' -> {new StringTemplate(";")}
|
||||
;
|
||||
|
||||
forStat
|
||||
scope slist;
|
||||
@init {
|
||||
$slist::locals = new ArrayList();
|
||||
$slist::stats = new ArrayList();
|
||||
}
|
||||
: 'for' '(' e1=assignStat ';' e2=expr ';' e3=assignStat ')' block
|
||||
-> forLoop(e1={$e1.st},e2={$e2.st},e3={$e3.st},
|
||||
locals={$slist::locals}, stats={$slist::stats})
|
||||
;
|
||||
|
||||
assignStat
|
||||
: ID '=' expr -> assign(lhs={$ID.text}, rhs={$expr.st})
|
||||
;
|
||||
|
||||
expr: condExpr -> {$condExpr.st}
|
||||
;
|
||||
|
||||
condExpr
|
||||
: a=aexpr
|
||||
( ( '==' b=aexpr -> equals(left={$a.st},right={$b.st})
|
||||
| '<' b=aexpr -> lessThan(left={$a.st},right={$b.st})
|
||||
)
|
||||
| -> {$a.st} // else just aexpr
|
||||
)
|
||||
;
|
||||
|
||||
aexpr
|
||||
: (a=atom -> {$a.st})
|
||||
( '+' b=atom -> add(left={$aexpr.st}, right={$b.st}) )*
|
||||
;
|
||||
|
||||
atom
|
||||
: ID -> refVar(id={$ID.text})
|
||||
| INT -> iconst(value={$INT.text})
|
||||
| '(' expr ')' -> {$expr.st}
|
||||
;
|
||||
|
||||
ID : ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'0'..'9'|'_')*
|
||||
;
|
||||
|
||||
INT : ('0'..'9')+
|
||||
;
|
||||
|
||||
WS : (' ' | '\t' | '\r' | '\n')+ {$channel=HIDDEN;}
|
||||
;
|
@ -1,824 +0,0 @@
|
||||
// $ANTLR 3.5.2 E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\stg\\CMinus.g 2014-04-27 13:24:16
|
||||
|
||||
package samples.stg;
|
||||
|
||||
|
||||
import org.antlr.runtime.*;
|
||||
import java.util.Stack;
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
|
||||
@SuppressWarnings("all")
|
||||
public class CMinusLexer extends Lexer {
|
||||
public static final int EOF=-1;
|
||||
public static final int T__7=7;
|
||||
public static final int T__8=8;
|
||||
public static final int T__9=9;
|
||||
public static final int T__10=10;
|
||||
public static final int T__11=11;
|
||||
public static final int T__12=12;
|
||||
public static final int T__13=13;
|
||||
public static final int T__14=14;
|
||||
public static final int T__15=15;
|
||||
public static final int T__16=16;
|
||||
public static final int T__17=17;
|
||||
public static final int T__18=18;
|
||||
public static final int T__19=19;
|
||||
public static final int ID=4;
|
||||
public static final int INT=5;
|
||||
public static final int WS=6;
|
||||
|
||||
// delegates
|
||||
// delegators
|
||||
public Lexer[] getDelegates() {
|
||||
return new Lexer[] {};
|
||||
}
|
||||
|
||||
public CMinusLexer() {}
|
||||
public CMinusLexer(CharStream input) {
|
||||
this(input, new RecognizerSharedState());
|
||||
}
|
||||
public CMinusLexer(CharStream input, RecognizerSharedState state) {
|
||||
super(input,state);
|
||||
}
|
||||
@Override public String getGrammarFileName() { return "E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\stg\\CMinus.g"; }
|
||||
|
||||
// $ANTLR start "T__7"
|
||||
public final void mT__7() throws RecognitionException {
|
||||
try {
|
||||
int _type = T__7;
|
||||
int _channel = DEFAULT_TOKEN_CHANNEL;
|
||||
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\stg\\CMinus.g:6:6: ( '(' )
|
||||
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\stg\\CMinus.g:6:8: '('
|
||||
{
|
||||
match('(');
|
||||
}
|
||||
|
||||
state.type = _type;
|
||||
state.channel = _channel;
|
||||
}
|
||||
finally {
|
||||
// do for sure before leaving
|
||||
}
|
||||
}
|
||||
// $ANTLR end "T__7"
|
||||
|
||||
// $ANTLR start "T__8"
|
||||
public final void mT__8() throws RecognitionException {
|
||||
try {
|
||||
int _type = T__8;
|
||||
int _channel = DEFAULT_TOKEN_CHANNEL;
|
||||
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\stg\\CMinus.g:7:6: ( ')' )
|
||||
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\stg\\CMinus.g:7:8: ')'
|
||||
{
|
||||
match(')');
|
||||
}
|
||||
|
||||
state.type = _type;
|
||||
state.channel = _channel;
|
||||
}
|
||||
finally {
|
||||
// do for sure before leaving
|
||||
}
|
||||
}
|
||||
// $ANTLR end "T__8"
|
||||
|
||||
// $ANTLR start "T__9"
|
||||
public final void mT__9() throws RecognitionException {
|
||||
try {
|
||||
int _type = T__9;
|
||||
int _channel = DEFAULT_TOKEN_CHANNEL;
|
||||
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\stg\\CMinus.g:8:6: ( '+' )
|
||||
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\stg\\CMinus.g:8:8: '+'
|
||||
{
|
||||
match('+');
|
||||
}
|
||||
|
||||
state.type = _type;
|
||||
state.channel = _channel;
|
||||
}
|
||||
finally {
|
||||
// do for sure before leaving
|
||||
}
|
||||
}
|
||||
// $ANTLR end "T__9"
|
||||
|
||||
// $ANTLR start "T__10"
|
||||
public final void mT__10() throws RecognitionException {
|
||||
try {
|
||||
int _type = T__10;
|
||||
int _channel = DEFAULT_TOKEN_CHANNEL;
|
||||
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\stg\\CMinus.g:9:7: ( ',' )
|
||||
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\stg\\CMinus.g:9:9: ','
|
||||
{
|
||||
match(',');
|
||||
}
|
||||
|
||||
state.type = _type;
|
||||
state.channel = _channel;
|
||||
}
|
||||
finally {
|
||||
// do for sure before leaving
|
||||
}
|
||||
}
|
||||
// $ANTLR end "T__10"
|
||||
|
||||
// $ANTLR start "T__11"
|
||||
public final void mT__11() throws RecognitionException {
|
||||
try {
|
||||
int _type = T__11;
|
||||
int _channel = DEFAULT_TOKEN_CHANNEL;
|
||||
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\stg\\CMinus.g:10:7: ( ';' )
|
||||
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\stg\\CMinus.g:10:9: ';'
|
||||
{
|
||||
match(';');
|
||||
}
|
||||
|
||||
state.type = _type;
|
||||
state.channel = _channel;
|
||||
}
|
||||
finally {
|
||||
// do for sure before leaving
|
||||
}
|
||||
}
|
||||
// $ANTLR end "T__11"
|
||||
|
||||
// $ANTLR start "T__12"
|
||||
public final void mT__12() throws RecognitionException {
|
||||
try {
|
||||
int _type = T__12;
|
||||
int _channel = DEFAULT_TOKEN_CHANNEL;
|
||||
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\stg\\CMinus.g:11:7: ( '<' )
|
||||
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\stg\\CMinus.g:11:9: '<'
|
||||
{
|
||||
match('<');
|
||||
}
|
||||
|
||||
state.type = _type;
|
||||
state.channel = _channel;
|
||||
}
|
||||
finally {
|
||||
// do for sure before leaving
|
||||
}
|
||||
}
|
||||
// $ANTLR end "T__12"
|
||||
|
||||
// $ANTLR start "T__13"
|
||||
public final void mT__13() throws RecognitionException {
|
||||
try {
|
||||
int _type = T__13;
|
||||
int _channel = DEFAULT_TOKEN_CHANNEL;
|
||||
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\stg\\CMinus.g:12:7: ( '=' )
|
||||
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\stg\\CMinus.g:12:9: '='
|
||||
{
|
||||
match('=');
|
||||
}
|
||||
|
||||
state.type = _type;
|
||||
state.channel = _channel;
|
||||
}
|
||||
finally {
|
||||
// do for sure before leaving
|
||||
}
|
||||
}
|
||||
// $ANTLR end "T__13"
|
||||
|
||||
// $ANTLR start "T__14"
|
||||
public final void mT__14() throws RecognitionException {
|
||||
try {
|
||||
int _type = T__14;
|
||||
int _channel = DEFAULT_TOKEN_CHANNEL;
|
||||
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\stg\\CMinus.g:13:7: ( '==' )
|
||||
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\stg\\CMinus.g:13:9: '=='
|
||||
{
|
||||
match("==");
|
||||
|
||||
}
|
||||
|
||||
state.type = _type;
|
||||
state.channel = _channel;
|
||||
}
|
||||
finally {
|
||||
// do for sure before leaving
|
||||
}
|
||||
}
|
||||
// $ANTLR end "T__14"
|
||||
|
||||
// $ANTLR start "T__15"
|
||||
public final void mT__15() throws RecognitionException {
|
||||
try {
|
||||
int _type = T__15;
|
||||
int _channel = DEFAULT_TOKEN_CHANNEL;
|
||||
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\stg\\CMinus.g:14:7: ( 'char' )
|
||||
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\stg\\CMinus.g:14:9: 'char'
|
||||
{
|
||||
match("char");
|
||||
|
||||
}
|
||||
|
||||
state.type = _type;
|
||||
state.channel = _channel;
|
||||
}
|
||||
finally {
|
||||
// do for sure before leaving
|
||||
}
|
||||
}
|
||||
// $ANTLR end "T__15"
|
||||
|
||||
// $ANTLR start "T__16"
|
||||
public final void mT__16() throws RecognitionException {
|
||||
try {
|
||||
int _type = T__16;
|
||||
int _channel = DEFAULT_TOKEN_CHANNEL;
|
||||
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\stg\\CMinus.g:15:7: ( 'for' )
|
||||
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\stg\\CMinus.g:15:9: 'for'
|
||||
{
|
||||
match("for");
|
||||
|
||||
}
|
||||
|
||||
state.type = _type;
|
||||
state.channel = _channel;
|
||||
}
|
||||
finally {
|
||||
// do for sure before leaving
|
||||
}
|
||||
}
|
||||
// $ANTLR end "T__16"
|
||||
|
||||
// $ANTLR start "T__17"
|
||||
public final void mT__17() throws RecognitionException {
|
||||
try {
|
||||
int _type = T__17;
|
||||
int _channel = DEFAULT_TOKEN_CHANNEL;
|
||||
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\stg\\CMinus.g:16:7: ( 'int' )
|
||||
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\stg\\CMinus.g:16:9: 'int'
|
||||
{
|
||||
match("int");
|
||||
|
||||
}
|
||||
|
||||
state.type = _type;
|
||||
state.channel = _channel;
|
||||
}
|
||||
finally {
|
||||
// do for sure before leaving
|
||||
}
|
||||
}
|
||||
// $ANTLR end "T__17"
|
||||
|
||||
// $ANTLR start "T__18"
|
||||
public final void mT__18() throws RecognitionException {
|
||||
try {
|
||||
int _type = T__18;
|
||||
int _channel = DEFAULT_TOKEN_CHANNEL;
|
||||
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\stg\\CMinus.g:17:7: ( '{' )
|
||||
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\stg\\CMinus.g:17:9: '{'
|
||||
{
|
||||
match('{');
|
||||
}
|
||||
|
||||
state.type = _type;
|
||||
state.channel = _channel;
|
||||
}
|
||||
finally {
|
||||
// do for sure before leaving
|
||||
}
|
||||
}
|
||||
// $ANTLR end "T__18"
|
||||
|
||||
// $ANTLR start "T__19"
|
||||
public final void mT__19() throws RecognitionException {
|
||||
try {
|
||||
int _type = T__19;
|
||||
int _channel = DEFAULT_TOKEN_CHANNEL;
|
||||
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\stg\\CMinus.g:18:7: ( '}' )
|
||||
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\stg\\CMinus.g:18:9: '}'
|
||||
{
|
||||
match('}');
|
||||
}
|
||||
|
||||
state.type = _type;
|
||||
state.channel = _channel;
|
||||
}
|
||||
finally {
|
||||
// do for sure before leaving
|
||||
}
|
||||
}
|
||||
// $ANTLR end "T__19"
|
||||
|
||||
// $ANTLR start "ID"
|
||||
public final void mID() throws RecognitionException {
|
||||
try {
|
||||
int _type = ID;
|
||||
int _channel = DEFAULT_TOKEN_CHANNEL;
|
||||
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\stg\\CMinus.g:145:5: ( ( 'a' .. 'z' | 'A' .. 'Z' | '_' ) ( 'a' .. 'z' | 'A' .. 'Z' | '0' .. '9' | '_' )* )
|
||||
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\stg\\CMinus.g:145:9: ( 'a' .. 'z' | 'A' .. 'Z' | '_' ) ( 'a' .. 'z' | 'A' .. 'Z' | '0' .. '9' | '_' )*
|
||||
{
|
||||
if ( (input.LA(1) >= 'A' && input.LA(1) <= 'Z')||input.LA(1)=='_'||(input.LA(1) >= 'a' && input.LA(1) <= 'z') ) {
|
||||
input.consume();
|
||||
}
|
||||
else {
|
||||
MismatchedSetException mse = new MismatchedSetException(null,input);
|
||||
recover(mse);
|
||||
throw mse;
|
||||
}
|
||||
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\stg\\CMinus.g:145:33: ( 'a' .. 'z' | 'A' .. 'Z' | '0' .. '9' | '_' )*
|
||||
loop1:
|
||||
while (true) {
|
||||
int alt1=2;
|
||||
int LA1_0 = input.LA(1);
|
||||
if ( ((LA1_0 >= '0' && LA1_0 <= '9')||(LA1_0 >= 'A' && LA1_0 <= 'Z')||LA1_0=='_'||(LA1_0 >= 'a' && LA1_0 <= 'z')) ) {
|
||||
alt1=1;
|
||||
}
|
||||
|
||||
switch (alt1) {
|
||||
case 1 :
|
||||
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\stg\\CMinus.g:
|
||||
{
|
||||
if ( (input.LA(1) >= '0' && input.LA(1) <= '9')||(input.LA(1) >= 'A' && input.LA(1) <= 'Z')||input.LA(1)=='_'||(input.LA(1) >= 'a' && input.LA(1) <= 'z') ) {
|
||||
input.consume();
|
||||
}
|
||||
else {
|
||||
MismatchedSetException mse = new MismatchedSetException(null,input);
|
||||
recover(mse);
|
||||
throw mse;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default :
|
||||
break loop1;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
state.type = _type;
|
||||
state.channel = _channel;
|
||||
}
|
||||
finally {
|
||||
// do for sure before leaving
|
||||
}
|
||||
}
|
||||
// $ANTLR end "ID"
|
||||
|
||||
// $ANTLR start "INT"
|
||||
public final void mINT() throws RecognitionException {
|
||||
try {
|
||||
int _type = INT;
|
||||
int _channel = DEFAULT_TOKEN_CHANNEL;
|
||||
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\stg\\CMinus.g:148:5: ( ( '0' .. '9' )+ )
|
||||
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\stg\\CMinus.g:148:7: ( '0' .. '9' )+
|
||||
{
|
||||
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\stg\\CMinus.g:148:7: ( '0' .. '9' )+
|
||||
int cnt2=0;
|
||||
loop2:
|
||||
while (true) {
|
||||
int alt2=2;
|
||||
int LA2_0 = input.LA(1);
|
||||
if ( ((LA2_0 >= '0' && LA2_0 <= '9')) ) {
|
||||
alt2=1;
|
||||
}
|
||||
|
||||
switch (alt2) {
|
||||
case 1 :
|
||||
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\stg\\CMinus.g:
|
||||
{
|
||||
if ( (input.LA(1) >= '0' && input.LA(1) <= '9') ) {
|
||||
input.consume();
|
||||
}
|
||||
else {
|
||||
MismatchedSetException mse = new MismatchedSetException(null,input);
|
||||
recover(mse);
|
||||
throw mse;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default :
|
||||
if ( cnt2 >= 1 ) break loop2;
|
||||
EarlyExitException eee = new EarlyExitException(2, input);
|
||||
throw eee;
|
||||
}
|
||||
cnt2++;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
state.type = _type;
|
||||
state.channel = _channel;
|
||||
}
|
||||
finally {
|
||||
// do for sure before leaving
|
||||
}
|
||||
}
|
||||
// $ANTLR end "INT"
|
||||
|
||||
// $ANTLR start "WS"
|
||||
public final void mWS() throws RecognitionException {
|
||||
try {
|
||||
int _type = WS;
|
||||
int _channel = DEFAULT_TOKEN_CHANNEL;
|
||||
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\stg\\CMinus.g:151:5: ( ( ' ' | '\\t' | '\\r' | '\\n' )+ )
|
||||
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\stg\\CMinus.g:151:9: ( ' ' | '\\t' | '\\r' | '\\n' )+
|
||||
{
|
||||
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\stg\\CMinus.g:151:9: ( ' ' | '\\t' | '\\r' | '\\n' )+
|
||||
int cnt3=0;
|
||||
loop3:
|
||||
while (true) {
|
||||
int alt3=2;
|
||||
int LA3_0 = input.LA(1);
|
||||
if ( ((LA3_0 >= '\t' && LA3_0 <= '\n')||LA3_0=='\r'||LA3_0==' ') ) {
|
||||
alt3=1;
|
||||
}
|
||||
|
||||
switch (alt3) {
|
||||
case 1 :
|
||||
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\stg\\CMinus.g:
|
||||
{
|
||||
if ( (input.LA(1) >= '\t' && input.LA(1) <= '\n')||input.LA(1)=='\r'||input.LA(1)==' ' ) {
|
||||
input.consume();
|
||||
}
|
||||
else {
|
||||
MismatchedSetException mse = new MismatchedSetException(null,input);
|
||||
recover(mse);
|
||||
throw mse;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default :
|
||||
if ( cnt3 >= 1 ) break loop3;
|
||||
EarlyExitException eee = new EarlyExitException(3, input);
|
||||
throw eee;
|
||||
}
|
||||
cnt3++;
|
||||
}
|
||||
|
||||
_channel=HIDDEN;
|
||||
}
|
||||
|
||||
state.type = _type;
|
||||
state.channel = _channel;
|
||||
}
|
||||
finally {
|
||||
// do for sure before leaving
|
||||
}
|
||||
}
|
||||
// $ANTLR end "WS"
|
||||
|
||||
@Override
|
||||
public void mTokens() throws RecognitionException {
|
||||
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\stg\\CMinus.g:1:8: ( T__7 | T__8 | T__9 | T__10 | T__11 | T__12 | T__13 | T__14 | T__15 | T__16 | T__17 | T__18 | T__19 | ID | INT | WS )
|
||||
int alt4=16;
|
||||
switch ( input.LA(1) ) {
|
||||
case '(':
|
||||
{
|
||||
alt4=1;
|
||||
}
|
||||
break;
|
||||
case ')':
|
||||
{
|
||||
alt4=2;
|
||||
}
|
||||
break;
|
||||
case '+':
|
||||
{
|
||||
alt4=3;
|
||||
}
|
||||
break;
|
||||
case ',':
|
||||
{
|
||||
alt4=4;
|
||||
}
|
||||
break;
|
||||
case ';':
|
||||
{
|
||||
alt4=5;
|
||||
}
|
||||
break;
|
||||
case '<':
|
||||
{
|
||||
alt4=6;
|
||||
}
|
||||
break;
|
||||
case '=':
|
||||
{
|
||||
int LA4_7 = input.LA(2);
|
||||
if ( (LA4_7=='=') ) {
|
||||
alt4=8;
|
||||
}
|
||||
|
||||
else {
|
||||
alt4=7;
|
||||
}
|
||||
|
||||
}
|
||||
break;
|
||||
case 'c':
|
||||
{
|
||||
int LA4_8 = input.LA(2);
|
||||
if ( (LA4_8=='h') ) {
|
||||
int LA4_18 = input.LA(3);
|
||||
if ( (LA4_18=='a') ) {
|
||||
int LA4_21 = input.LA(4);
|
||||
if ( (LA4_21=='r') ) {
|
||||
int LA4_24 = input.LA(5);
|
||||
if ( ((LA4_24 >= '0' && LA4_24 <= '9')||(LA4_24 >= 'A' && LA4_24 <= 'Z')||LA4_24=='_'||(LA4_24 >= 'a' && LA4_24 <= 'z')) ) {
|
||||
alt4=14;
|
||||
}
|
||||
|
||||
else {
|
||||
alt4=9;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
else {
|
||||
alt4=14;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
else {
|
||||
alt4=14;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
else {
|
||||
alt4=14;
|
||||
}
|
||||
|
||||
}
|
||||
break;
|
||||
case 'f':
|
||||
{
|
||||
int LA4_9 = input.LA(2);
|
||||
if ( (LA4_9=='o') ) {
|
||||
int LA4_19 = input.LA(3);
|
||||
if ( (LA4_19=='r') ) {
|
||||
int LA4_22 = input.LA(4);
|
||||
if ( ((LA4_22 >= '0' && LA4_22 <= '9')||(LA4_22 >= 'A' && LA4_22 <= 'Z')||LA4_22=='_'||(LA4_22 >= 'a' && LA4_22 <= 'z')) ) {
|
||||
alt4=14;
|
||||
}
|
||||
|
||||
else {
|
||||
alt4=10;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
else {
|
||||
alt4=14;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
else {
|
||||
alt4=14;
|
||||
}
|
||||
|
||||
}
|
||||
break;
|
||||
case 'i':
|
||||
{
|
||||
int LA4_10 = input.LA(2);
|
||||
if ( (LA4_10=='n') ) {
|
||||
int LA4_20 = input.LA(3);
|
||||
if ( (LA4_20=='t') ) {
|
||||
int LA4_23 = input.LA(4);
|
||||
if ( ((LA4_23 >= '0' && LA4_23 <= '9')||(LA4_23 >= 'A' && LA4_23 <= 'Z')||LA4_23=='_'||(LA4_23 >= 'a' && LA4_23 <= 'z')) ) {
|
||||
alt4=14;
|
||||
}
|
||||
|
||||
else {
|
||||
alt4=11;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
else {
|
||||
alt4=14;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
else {
|
||||
alt4=14;
|
||||
}
|
||||
|
||||
}
|
||||
break;
|
||||
case '{':
|
||||
{
|
||||
alt4=12;
|
||||
}
|
||||
break;
|
||||
case '}':
|
||||
{
|
||||
alt4=13;
|
||||
}
|
||||
break;
|
||||
case 'A':
|
||||
case 'B':
|
||||
case 'C':
|
||||
case 'D':
|
||||
case 'E':
|
||||
case 'F':
|
||||
case 'G':
|
||||
case 'H':
|
||||
case 'I':
|
||||
case 'J':
|
||||
case 'K':
|
||||
case 'L':
|
||||
case 'M':
|
||||
case 'N':
|
||||
case 'O':
|
||||
case 'P':
|
||||
case 'Q':
|
||||
case 'R':
|
||||
case 'S':
|
||||
case 'T':
|
||||
case 'U':
|
||||
case 'V':
|
||||
case 'W':
|
||||
case 'X':
|
||||
case 'Y':
|
||||
case 'Z':
|
||||
case '_':
|
||||
case 'a':
|
||||
case 'b':
|
||||
case 'd':
|
||||
case 'e':
|
||||
case 'g':
|
||||
case 'h':
|
||||
case 'j':
|
||||
case 'k':
|
||||
case 'l':
|
||||
case 'm':
|
||||
case 'n':
|
||||
case 'o':
|
||||
case 'p':
|
||||
case 'q':
|
||||
case 'r':
|
||||
case 's':
|
||||
case 't':
|
||||
case 'u':
|
||||
case 'v':
|
||||
case 'w':
|
||||
case 'x':
|
||||
case 'y':
|
||||
case 'z':
|
||||
{
|
||||
alt4=14;
|
||||
}
|
||||
break;
|
||||
case '0':
|
||||
case '1':
|
||||
case '2':
|
||||
case '3':
|
||||
case '4':
|
||||
case '5':
|
||||
case '6':
|
||||
case '7':
|
||||
case '8':
|
||||
case '9':
|
||||
{
|
||||
alt4=15;
|
||||
}
|
||||
break;
|
||||
case '\t':
|
||||
case '\n':
|
||||
case '\r':
|
||||
case ' ':
|
||||
{
|
||||
alt4=16;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
NoViableAltException nvae =
|
||||
new NoViableAltException("", 4, 0, input);
|
||||
throw nvae;
|
||||
}
|
||||
switch (alt4) {
|
||||
case 1 :
|
||||
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\stg\\CMinus.g:1:10: T__7
|
||||
{
|
||||
mT__7();
|
||||
|
||||
}
|
||||
break;
|
||||
case 2 :
|
||||
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\stg\\CMinus.g:1:15: T__8
|
||||
{
|
||||
mT__8();
|
||||
|
||||
}
|
||||
break;
|
||||
case 3 :
|
||||
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\stg\\CMinus.g:1:20: T__9
|
||||
{
|
||||
mT__9();
|
||||
|
||||
}
|
||||
break;
|
||||
case 4 :
|
||||
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\stg\\CMinus.g:1:25: T__10
|
||||
{
|
||||
mT__10();
|
||||
|
||||
}
|
||||
break;
|
||||
case 5 :
|
||||
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\stg\\CMinus.g:1:31: T__11
|
||||
{
|
||||
mT__11();
|
||||
|
||||
}
|
||||
break;
|
||||
case 6 :
|
||||
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\stg\\CMinus.g:1:37: T__12
|
||||
{
|
||||
mT__12();
|
||||
|
||||
}
|
||||
break;
|
||||
case 7 :
|
||||
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\stg\\CMinus.g:1:43: T__13
|
||||
{
|
||||
mT__13();
|
||||
|
||||
}
|
||||
break;
|
||||
case 8 :
|
||||
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\stg\\CMinus.g:1:49: T__14
|
||||
{
|
||||
mT__14();
|
||||
|
||||
}
|
||||
break;
|
||||
case 9 :
|
||||
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\stg\\CMinus.g:1:55: T__15
|
||||
{
|
||||
mT__15();
|
||||
|
||||
}
|
||||
break;
|
||||
case 10 :
|
||||
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\stg\\CMinus.g:1:61: T__16
|
||||
{
|
||||
mT__16();
|
||||
|
||||
}
|
||||
break;
|
||||
case 11 :
|
||||
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\stg\\CMinus.g:1:67: T__17
|
||||
{
|
||||
mT__17();
|
||||
|
||||
}
|
||||
break;
|
||||
case 12 :
|
||||
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\stg\\CMinus.g:1:73: T__18
|
||||
{
|
||||
mT__18();
|
||||
|
||||
}
|
||||
break;
|
||||
case 13 :
|
||||
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\stg\\CMinus.g:1:79: T__19
|
||||
{
|
||||
mT__19();
|
||||
|
||||
}
|
||||
break;
|
||||
case 14 :
|
||||
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\stg\\CMinus.g:1:85: ID
|
||||
{
|
||||
mID();
|
||||
|
||||
}
|
||||
break;
|
||||
case 15 :
|
||||
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\stg\\CMinus.g:1:88: INT
|
||||
{
|
||||
mINT();
|
||||
|
||||
}
|
||||
break;
|
||||
case 16 :
|
||||
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\stg\\CMinus.g:1:92: WS
|
||||
{
|
||||
mWS();
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -1,17 +0,0 @@
|
||||
package samples.stg;
|
||||
|
||||
/**
|
||||
* www.ethereumJ.com
|
||||
* User: Roman Mandeleil
|
||||
* Created on: 25/04/14 17:06
|
||||
*/
|
||||
public class GenParser {
|
||||
|
||||
|
||||
public static void main(String args[]){
|
||||
|
||||
String userDir = System.getProperty("user.dir");
|
||||
org.antlr.Tool.main(new String[]{userDir + "\\src\\main\\java\\samples\\stg\\CMinus.g"});
|
||||
|
||||
}
|
||||
}
|
@ -1,55 +0,0 @@
|
||||
group Java;
|
||||
|
||||
program(globals,functions) ::= <<
|
||||
class Wrapper {
|
||||
<globals; separator="\n">
|
||||
<functions; separator="\n">
|
||||
}
|
||||
>>
|
||||
|
||||
variable(type,name) ::= "<type> <name>;"
|
||||
|
||||
globalVariable ::= variable
|
||||
|
||||
function(type,name,args,locals,stats) ::= <<
|
||||
<type> <name>(<args; separator=", ">) {
|
||||
<locals; separator="\n">
|
||||
<stats; separator="\n">
|
||||
}
|
||||
>>
|
||||
|
||||
type_int() ::= "int"
|
||||
|
||||
type_char() ::= "char"
|
||||
|
||||
type_user_object(name) ::= "<name>"
|
||||
|
||||
parameter(type,name) ::= "<type> <name>"
|
||||
|
||||
statement(expr) ::= "<expr>;"
|
||||
|
||||
statementList(locals,stats) ::= <<
|
||||
{
|
||||
<locals; separator="\n">
|
||||
<stats; separator="\n">
|
||||
}<\n>
|
||||
>>
|
||||
|
||||
forLoop(e1,e2,e3,locals,stats) ::= <<
|
||||
for (<e1> <e2>; <e3>) {
|
||||
<locals; separator="\n">
|
||||
<stats; separator="\n">
|
||||
}
|
||||
>>
|
||||
|
||||
assign(lhs,rhs) ::= "<lhs> = <rhs>;"
|
||||
|
||||
equals(left,right) ::= "<left> == <right>"
|
||||
|
||||
lessThan(left,right) ::= "<left> \< <right>"
|
||||
|
||||
add(left,right) ::= "<left> + <right>"
|
||||
|
||||
refVar(id) ::= "<id>"
|
||||
|
||||
iconst(value) ::= "<value>"
|
@ -1,30 +0,0 @@
|
||||
|
||||
package samples.stg;
|
||||
import java.io.*;
|
||||
import org.antlr.runtime.*;
|
||||
import org.antlr.stringtemplate.*;
|
||||
import org.antlr.stringtemplate.language.*;
|
||||
|
||||
public class Main {
|
||||
public static StringTemplateGroup templates;
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
String templateFileName;
|
||||
|
||||
String userDir = System.getProperty("user.dir");
|
||||
|
||||
templateFileName = userDir + "\\src\\main\\java\\samples\\stg\\Bytecode.stg";
|
||||
templates = new StringTemplateGroup(new FileReader(templateFileName),
|
||||
AngleBracketTemplateLexer.class);
|
||||
|
||||
String srcFile = userDir + "\\src\\main\\java\\samples\\stg\\input";
|
||||
|
||||
CharStream input = new ANTLRFileStream(srcFile);
|
||||
CMinusLexer lexer = new CMinusLexer(input);
|
||||
CommonTokenStream tokens = new CommonTokenStream(lexer);
|
||||
CMinusParser parser = new CMinusParser(tokens);
|
||||
parser.setTemplateLib(templates);
|
||||
RuleReturnScope r = parser.program();
|
||||
System.out.println(r.getTemplate().toString());
|
||||
}
|
||||
}
|
@ -1,48 +0,0 @@
|
||||
group Python;
|
||||
|
||||
program(globals,functions) ::= <<
|
||||
<functions; separator="\n">
|
||||
>>
|
||||
|
||||
variable(type,name) ::= " "
|
||||
|
||||
globalVariable ::= variable
|
||||
|
||||
function(type,name,args,locals,stats) ::= <<
|
||||
def <name>(<args; separator=", ">):
|
||||
<stats>
|
||||
>>
|
||||
|
||||
type_int() ::= "int"
|
||||
|
||||
type_char() ::= "char"
|
||||
|
||||
type_user_object(name) ::= "<name>"
|
||||
|
||||
parameter(type,name) ::= "<name>"
|
||||
|
||||
statement(expr) ::= "<expr>"
|
||||
|
||||
statementList(locals,stats) ::= <<
|
||||
<stats; separator="\n">
|
||||
>>
|
||||
|
||||
// python has a weird FOR, use a WHILE. :)
|
||||
forLoop(e1,e2,e3,locals,stats) ::= <<
|
||||
<e1>
|
||||
while ( <e2> ):
|
||||
<stats; separator="\n">
|
||||
<e3>
|
||||
>>
|
||||
|
||||
assign(lhs,rhs) ::= "<lhs> = <rhs>"
|
||||
|
||||
equals(left,right) ::= "<left> == <right>"
|
||||
|
||||
lessThan(left,right) ::= "<left> \< <right>"
|
||||
|
||||
add(left,right) ::= "<left> + <right>"
|
||||
|
||||
refVar(id) ::= "<id>"
|
||||
|
||||
iconst(value) ::= "<value>"
|
@ -1,7 +0,0 @@
|
||||
Java.stg
|
||||
Bytecode.stg
|
||||
Python.stg
|
||||
Main.java
|
||||
CMinus.g
|
||||
input
|
||||
output
|
@ -1,9 +0,0 @@
|
||||
char c;
|
||||
int x;
|
||||
int foo(int y, char d) {
|
||||
int i;
|
||||
for (i=0; i<3; i=i+1) {
|
||||
x=3;
|
||||
y=5;
|
||||
}
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
class Wrapper {
|
||||
char c;
|
||||
int x;
|
||||
int foo(int y, char d) {
|
||||
int i;
|
||||
for (i = 0; i < 3; i = i + 1;) {
|
||||
x = 3;
|
||||
y = 5;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,20 +1,15 @@
|
||||
package org.ethereum.block;
|
||||
|
||||
import org.bouncycastle.util.encoders.Hex;
|
||||
import org.spongycastle.util.encoders.Hex;
|
||||
import org.ethereum.crypto.HashUtil;
|
||||
import org.ethereum.net.RLP;
|
||||
import org.ethereum.net.rlp.RLPList;
|
||||
import org.ethereum.net.vo.BlockData;
|
||||
import org.ethereum.util.Utils;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.math.BigInteger;
|
||||
|
||||
/**
|
||||
* www.ethereumJ.com
|
||||
* User: Roman Mandeleil
|
||||
* Created on: 19/04/14 13:30
|
||||
*/
|
||||
public class BlockTest {
|
||||
|
||||
@Test /* Creating genesis hash not ready yet */
|
||||
@ -37,8 +32,6 @@ public class BlockTest {
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
|
||||
( 0(256) - parentHash
|
||||
SHA3(RLP(emptyList)) - hashes of transactions
|
||||
0(160) - coinbase
|
||||
@ -56,15 +49,10 @@ public class BlockTest {
|
||||
block.appendRaw(RLPEmptyList);
|
||||
block.appendRaw(RLPEmptyList);
|
||||
|
||||
|
||||
*/
|
||||
|
||||
|
||||
// gennesis hash
|
||||
//ab6b9a5613970faa771b12d449b2e9bb925ab7a369f0a4b86b286e9d540099cf
|
||||
|
||||
|
||||
|
||||
/* 1 */ byte[] prevHash =
|
||||
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
@ -72,7 +60,7 @@ public class BlockTest {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||
prevHash = RLP.encodeElement(prevHash);
|
||||
|
||||
/* 2 */ byte[] uncleList = RLP.encodeElement(Utils.sha3(RLP.encodeList(new byte[]{})));
|
||||
/* 2 */ byte[] uncleList = RLP.encodeElement(HashUtil.sha3(RLP.encodeList(new byte[]{})));
|
||||
|
||||
/* 3 */ byte[] coinbase =
|
||||
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
@ -86,7 +74,7 @@ public class BlockTest {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||
rootState = RLP.encodeElement(rootState);
|
||||
|
||||
/* 5 */ byte[] transactionsRoot = RLP.encodeElement(Utils.sha3(RLP.encodeList(new byte[]{})));
|
||||
/* 5 */ byte[] transactionsRoot = RLP.encodeElement(HashUtil.sha3(RLP.encodeList(new byte[]{})));
|
||||
|
||||
/* 6 */ BigInteger difficulty = new BigInteger("2");
|
||||
difficulty = difficulty.pow(22);
|
||||
@ -99,9 +87,7 @@ public class BlockTest {
|
||||
extradata = RLP.encodeElement(extradata);
|
||||
|
||||
/* 9 */ byte[] nonce = {42};
|
||||
nonce = RLP.encodeElement( Utils.sha3(nonce) );
|
||||
|
||||
|
||||
nonce = RLP.encodeElement(HashUtil.sha3(nonce));
|
||||
|
||||
byte[] header = RLP.encodeList( prevHash,
|
||||
uncleList,
|
||||
@ -115,14 +101,13 @@ public class BlockTest {
|
||||
|
||||
// block.appendList(9) << h256() << sha3EmptyList << h160() << stateRoot << sha3EmptyList << c_genesisDifficulty << (uint)0 << string() << sha3(bytes(1, 42));
|
||||
|
||||
|
||||
byte[] txList = RLP.encodeList(new byte[]{});
|
||||
byte[] unclesList = RLP.encodeList(new byte[]{});
|
||||
|
||||
byte[] genesis = RLP.encodeList(header, txList, unclesList);
|
||||
System.out.println(Hex.toHexString(genesis));
|
||||
|
||||
byte[] hash = Utils.sha3(genesis);
|
||||
byte[] hash = HashUtil.sha3(genesis);
|
||||
|
||||
System.out.println(Hex.toHexString(hash));
|
||||
|
||||
@ -133,10 +118,9 @@ public class BlockTest {
|
||||
public void test2(){
|
||||
|
||||
byte[] goGenesisBytes = Hex.decode("f8a4f8a0a00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794000000000000000000000000000000000000000080a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347834000008080a004994f67dc55b09e814ab7ffc8df3686b4afb2bb53e60eae97ef043fe03fb829c0c0");
|
||||
System.out.println( Hex.toHexString( Utils.sha3(goGenesisBytes) ) );
|
||||
System.out.println( Hex.toHexString( HashUtil.sha3(goGenesisBytes) ) );
|
||||
}
|
||||
|
||||
|
||||
@Test /* create BlockData from part of real RLP BLOCKS message */
|
||||
public void test3(){
|
||||
|
||||
@ -148,14 +132,10 @@ public class BlockTest {
|
||||
RLP.parseObjects(payload, rlpList);
|
||||
|
||||
BlockData blockData = new BlockData(rlpList);
|
||||
|
||||
RLPList.recursivePrint(rlpList);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
[[ab6b9a5613970faa771b12d449b2e9bb925ab7a369f0a4b86b286e9d540099cf, 1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347, 3854aaf203ba5f8d49b1ec221329c7aebcf050d3, 990dc3b5acbee04124361d958fe51acb582593613fc290683940a0769549d3ed, 9bfe4817d274ea3eb8672e9fe848c3885b53bbbd1d7c26e6039f90fb96b942b0, 3ff000, 533f16b7, null, 00000000000000000000000000000000000000000000000077377adff6c227db, ]
|
||||
[
|
||||
|
@ -1,109 +1,78 @@
|
||||
package org.ethereum.crypto;
|
||||
|
||||
import junit.framework.Assert;
|
||||
import org.bouncycastle.util.encoders.Hex;
|
||||
import org.spongycastle.util.encoders.Hex;
|
||||
import org.ethereum.util.Utils;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.math.BigInteger;
|
||||
|
||||
/**
|
||||
* www.ethereumJ.com
|
||||
* User: Roman Mandeleil
|
||||
* Created on: 17/04/14 15:02
|
||||
*/
|
||||
|
||||
public class CryptoTest {
|
||||
|
||||
|
||||
|
||||
@Test
|
||||
public void test1(){
|
||||
|
||||
byte[] result = Utils.sha3("horse".getBytes());
|
||||
byte[] result = HashUtil.sha3("horse".getBytes());
|
||||
|
||||
Assert.assertEquals("c87f65ff3f271bf5dc8643484f66b200109caffe4bf98c4cb393dc35740b28c0",
|
||||
assertEquals("c87f65ff3f271bf5dc8643484f66b200109caffe4bf98c4cb393dc35740b28c0",
|
||||
Hex.toHexString(result));
|
||||
|
||||
result = Utils.sha3("cow".getBytes());
|
||||
result = HashUtil.sha3("cow".getBytes());
|
||||
|
||||
Assert.assertEquals("c85ef7d79691fe79573b1a7064c19c1a9819ebdbd1faaab1a8ec92344438aaf4",
|
||||
assertEquals("c85ef7d79691fe79573b1a7064c19c1a9819ebdbd1faaab1a8ec92344438aaf4",
|
||||
Hex.toHexString(result));
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test2(){
|
||||
|
||||
byte[] result = Utils.ripemd160("c87f65ff3f271bf5dc8643484f66b200109caffe4bf98c4cb393dc35740b28c0".getBytes());
|
||||
|
||||
|
||||
System.out.println(Hex.toHexString(result));
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void test3(){
|
||||
|
||||
BigInteger privKey = new BigInteger("cd244b3015703ddf545595da06ada5516628c5feadbf49dc66049c4b370cc5d8", 16);
|
||||
byte[] addr = Utils.privToAddress(privKey.toByteArray());
|
||||
Assert.assertEquals("89b44e4d3c81ede05d0f5de8d1a68f754d73d997", Hex.toHexString(addr));
|
||||
byte[] addr = ECKey.fromPrivate(privKey).getAddress();
|
||||
assertEquals("89b44e4d3c81ede05d0f5de8d1a68f754d73d997", Hex.toHexString(addr));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test4(){
|
||||
|
||||
byte[] cowBytes = Utils.sha3("cow".getBytes());
|
||||
|
||||
byte[] addr = Utils.privToAddress(cowBytes);
|
||||
Assert.assertEquals("CD2A3D9F938E13CD947EC05ABC7FE734DF8DD826", Hex.toHexString(addr).toUpperCase());
|
||||
byte[] cowBytes = HashUtil.sha3("cow".getBytes());
|
||||
byte[] addr = ECKey.fromPrivate(cowBytes).getAddress();
|
||||
assertEquals("CD2A3D9F938E13CD947EC05ABC7FE734DF8DD826", Hex.toHexString(addr).toUpperCase());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test5(){
|
||||
|
||||
byte[] horseBytes = Utils.sha3("horse".getBytes());
|
||||
|
||||
byte[] addr = Utils.privToAddress(horseBytes);
|
||||
Assert.assertEquals("13978AEE95F38490E9769C39B2773ED763D9CD5F", Hex.toHexString(addr).toUpperCase());
|
||||
byte[] horseBytes = HashUtil.sha3("horse".getBytes());
|
||||
byte[] addr = ECKey.fromPrivate(horseBytes).getAddress();
|
||||
assertEquals("13978AEE95F38490E9769C39B2773ED763D9CD5F", Hex.toHexString(addr).toUpperCase());
|
||||
}
|
||||
|
||||
|
||||
@Test /* performance test */
|
||||
public void test6(){
|
||||
|
||||
|
||||
long firstTime = System.currentTimeMillis();
|
||||
System.out.println(firstTime);
|
||||
for (int i = 0; i < 1000; ++i){
|
||||
|
||||
byte[] horseBytes = Utils.sha3("horse".getBytes());
|
||||
|
||||
byte[] addr = Utils.privToAddress(horseBytes);
|
||||
Assert.assertEquals("13978AEE95F38490E9769C39B2773ED763D9CD5F", Hex.toHexString(addr).toUpperCase());
|
||||
byte[] horseBytes = HashUtil.sha3("horse".getBytes());
|
||||
byte[] addr = ECKey.fromPrivate(horseBytes).getAddress();
|
||||
assertEquals("13978AEE95F38490E9769C39B2773ED763D9CD5F", Hex.toHexString(addr).toUpperCase());
|
||||
}
|
||||
long secondTime = System.currentTimeMillis();
|
||||
System.out.println(secondTime);
|
||||
|
||||
System.out.println(secondTime - firstTime + " millisec");
|
||||
|
||||
// 1) result: ~52 address calculation every second
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Test /* real tx hash calc */
|
||||
public void test7(){
|
||||
|
||||
String txRaw = "F89D80809400000000000000000000000000000000000000008609184E72A000822710B3606956330C0D630000003359366000530A0D630000003359602060005301356000533557604060005301600054630000000C5884336069571CA07F6EB94576346488C6253197BDE6A7E59DDC36F2773672C849402AA9C402C3C4A06D254E662BF7450DD8D835160CBB053463FED0B53F2CDD7F3EA8731919C8E8CC";
|
||||
|
||||
byte[] txHashB = Utils.sha3(Hex.decode(txRaw));
|
||||
byte[] txHashB = HashUtil.sha3(Hex.decode(txRaw));
|
||||
String txHash = Utils.toHexString(txHashB);
|
||||
|
||||
Assert.assertEquals("4b7d9670a92bf120d5b43400543b69304a14d767cf836a7f6abff4edde092895", txHash);
|
||||
|
||||
assertEquals("4b7d9670a92bf120d5b43400543b69304a14d767cf836a7f6abff4edde092895", txHash);
|
||||
}
|
||||
|
||||
@Test /* real block hash calc */
|
||||
@ -111,23 +80,14 @@ public class CryptoTest {
|
||||
|
||||
String blockRaw = "F885F8818080A01DCC4DE8DEC75D7AAB85B567B6CCD41AD312451B948A7413F0A142FD40D49347940000000000000000000000000000000000000000A0BCDDD284BF396739C224DBA0411566C891C32115FEB998A3E2B4E61F3F35582AA01DCC4DE8DEC75D7AAB85B567B6CCD41AD312451B948A7413F0A142FD40D4934783800000808080C0C0";
|
||||
|
||||
byte[] blockHashB = Utils.sha3(Hex.decode(blockRaw));
|
||||
byte[] blockHashB = HashUtil.sha3(Hex.decode(blockRaw));
|
||||
String blockHash = Utils.toHexString(blockHashB);
|
||||
|
||||
System.out.println(blockHash);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void test9(){
|
||||
|
||||
// todo: https://tools.ietf.org/html/rfc6979#section-2.2
|
||||
// todo: https://github.com/bcgit/bc-java/blob/master/core/src/main/java/org/bouncycastle/crypto/signers/ECDSASigner.java
|
||||
|
||||
|
||||
}
|
||||
|
||||
//
|
||||
}
|
||||
|
292
ethereumj-core/src/test/java/org/ethereum/crypto/ECKeyTest.java
Normal file
292
ethereumj-core/src/test/java/org/ethereum/crypto/ECKeyTest.java
Normal file
@ -0,0 +1,292 @@
|
||||
package org.ethereum.crypto;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.math.BigInteger;
|
||||
import java.security.SignatureException;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
import org.ethereum.crypto.ECKey.ECDSASignature;
|
||||
import org.junit.Test;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.spongycastle.util.encoders.Hex;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.util.concurrent.Futures;
|
||||
import com.google.common.util.concurrent.ListenableFuture;
|
||||
import com.google.common.util.concurrent.ListeningExecutorService;
|
||||
import com.google.common.util.concurrent.MoreExecutors;
|
||||
|
||||
public class ECKeyTest {
|
||||
private static final Logger log = LoggerFactory.getLogger(ECKeyTest.class);
|
||||
|
||||
private String privString = "3ecb44df2159c26e0f995712d4f39b6f6e499b40749b1cf1246c37f9516cb6a4";
|
||||
private BigInteger privateKey = new BigInteger(Hex.decode(privString));
|
||||
|
||||
private String pubString = "0497466f2b32bc3bb76d4741ae51cd1d8578b48d3f1e68da206d47321aec267ce78549b514e4453d74ef11b0cd5e4e4c364effddac8b51bcfc8de80682f952896f";
|
||||
private String compressedPubString = "0397466f2b32bc3bb76d4741ae51cd1d8578b48d3f1e68da206d47321aec267ce7";
|
||||
private byte[] pubKey = Hex.decode(pubString);
|
||||
private byte[] compressedPubKey = Hex.decode(compressedPubString);
|
||||
private String address = "8a40bfaa73256b60764c1bf40675a99083efb075";
|
||||
|
||||
private String exampleMessage = new String("This is an example of a signed message.");
|
||||
private String bitcoinSigBase64 = "HIb1Pb2tCwt/f15R9c/nlCgQrFTAxIt7TooOqG4B8ODNSaUdTtcW1N2E9bH+mF9HGjfd88H8QOyG0sPZtp2uaCQ=";
|
||||
private String ethereumSigBase64 = "HD5AsBr4wuH6UU9tXuSJhUvgfGayfwoY0cKT03sFUjnpQsupHznd/3mCIRfLuNHlRCVGdAyHecdyM8IVZMtc1I8=";
|
||||
|
||||
@Test
|
||||
public void testHashCode() {
|
||||
fail("Not yet implemented");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testECKey() {
|
||||
ECKey key = new ECKey();
|
||||
assertTrue(key.isPubKeyCanonical());
|
||||
assertNotNull(key.getPubKey());
|
||||
assertNotNull(key.getPrivKeyBytes());
|
||||
log.debug(Hex.toHexString(key.getPrivKeyBytes()) + " :Generated privkey");
|
||||
log.debug(Hex.toHexString(key.getPubKey()) + " :Generated pubkey");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFromPrivateKey() {
|
||||
ECKey key = ECKey.fromPrivate(privateKey).decompress();
|
||||
assertTrue(key.isPubKeyCanonical());
|
||||
assertTrue(key.hasPrivKey());
|
||||
assertArrayEquals(pubKey, key.getPubKey());
|
||||
}
|
||||
|
||||
@Test(expected=IllegalArgumentException.class)
|
||||
public void testPrivatePublicKeyBytesNoArg() {
|
||||
new ECKey(null, null);
|
||||
fail("Expecting an IllegalArgumentException for using only null-parameters");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsPubKeyOnly() {
|
||||
ECKey key = ECKey.fromPublicOnly(pubKey);
|
||||
assertTrue(key.isPubKeyCanonical());
|
||||
assertTrue(key.isPubKeyOnly());
|
||||
assertArrayEquals(key.getPubKey(), pubKey);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPublicKeyFromPrivate() {
|
||||
byte[] pubFromPriv = ECKey.publicKeyFromPrivate(privateKey, false);
|
||||
assertArrayEquals(pubKey, pubFromPriv);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPublicKeyFromPrivateCompressed() {
|
||||
byte[] pubFromPriv = ECKey.publicKeyFromPrivate(privateKey, true);
|
||||
assertArrayEquals(compressedPubKey, pubFromPriv);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetAddress() {
|
||||
ECKey key = ECKey.fromPublicOnly(pubKey);
|
||||
assertArrayEquals(Hex.decode(address), key.getAddress());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testToString() {
|
||||
ECKey key = ECKey.fromPrivate(BigInteger.TEN); // An example private key.
|
||||
assertEquals("pub:04a0434d9e47f3c86235477c7b1ae6ae5d3442d49b1943c2b752a68e2a47e247c7893aba425419bc27a3b6c7e693a24c696f794c2ed877a1593cbee53b037368d7", key.toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSignBitcoin() throws IOException {
|
||||
// TODO: Understand why key must be decompressed for this to work
|
||||
ECKey key = ECKey.fromPrivate(privateKey).decompress();
|
||||
System.out.println("Secret: " + Hex.toHexString(key.getPrivKeyBytes()));
|
||||
System.out.println("Pubkey: " + Hex.toHexString(key.getPubKey()));
|
||||
String output = key.signBitcoinMessage(exampleMessage);
|
||||
|
||||
System.out.println("Signtr: " + output + " (Base64) - length: " + output.length());
|
||||
|
||||
assertEquals(bitcoinSigBase64, output);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEthereumSign() throws IOException {
|
||||
// TODO: Understand why key must be decompressed for this to work
|
||||
ECKey key = ECKey.fromPrivate(privateKey).decompress();
|
||||
System.out.println("Secret\t: " + Hex.toHexString(key.getPrivKeyBytes()));
|
||||
System.out.println("Pubkey\t: " + Hex.toHexString(key.getPubKey()));
|
||||
System.out.println("Data\t: " + exampleMessage);
|
||||
byte[] messageHash = HashUtil.sha3(exampleMessage.getBytes());
|
||||
ECDSASignature signature = key.sign(messageHash);
|
||||
String output = signature.toBase64();
|
||||
System.out.println("Signtr\t: " + output + " (Base64, length: " + output.length() + ")");
|
||||
assertEquals(ethereumSigBase64, output);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testVerifySignature1() {
|
||||
ECKey key = ECKey.fromPublicOnly(pubKey);
|
||||
BigInteger r = new BigInteger("28157690258821599598544026901946453245423343069728565040002908283498585537001");
|
||||
BigInteger s = new BigInteger("30212485197630673222315826773656074299979444367665131281281249560925428307087");
|
||||
ECDSASignature sig = ECDSASignature.fromComponents(r.toByteArray(), s.toByteArray());
|
||||
sig.v = 28;
|
||||
key.verify(HashUtil.sha3(exampleMessage.getBytes()), sig);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testVerifySignature2() {
|
||||
BigInteger r = new BigInteger("c52c114d4f5a3ba904a9b3036e5e118fe0dbb987fe3955da20f2cd8f6c21ab9c", 16);
|
||||
BigInteger s = new BigInteger("6ba4c2874299a55ad947dbc98a25ee895aabf6b625c26c435e84bfd70edf2f69", 16);
|
||||
ECDSASignature sig = ECDSASignature.fromComponents(r.toByteArray(), s.toByteArray());
|
||||
sig.v = 0x1b;
|
||||
byte[] rawtx = Hex.decode("f82804881bc16d674ec8000094cd2a3d9f938e13cd947ec05abc7fe734df8dd8268609184e72a0006480");
|
||||
try {
|
||||
ECKey key = ECKey.signatureToKey(HashUtil.sha3(rawtx), sig.toBase64());
|
||||
System.out.println("Signature public key\t: " + Hex.toHexString(key.getPubKey()));
|
||||
System.out.println("Sender is\t\t: " + Hex.toHexString(key.getAddress()));
|
||||
assertEquals("cd2a3d9f938e13cd947ec05abc7fe734df8dd826", Hex.toHexString(key.getAddress()));
|
||||
key.verify(HashUtil.sha3(rawtx), sig);
|
||||
} catch (SignatureException e) {
|
||||
fail();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testVerifyBitcoinMessage() {
|
||||
ECKey key = ECKey.fromPublicOnly(pubKey);
|
||||
try {
|
||||
key.verifyBitcoinMessage(exampleMessage, bitcoinSigBase64);
|
||||
} catch (SignatureException e) {
|
||||
fail();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSValue() throws Exception {
|
||||
// Check that we never generate an S value that is larger than half the curve order. This avoids a malleability
|
||||
// issue that can allow someone to change a transaction [hash] without invalidating the signature.
|
||||
final int ITERATIONS = 10;
|
||||
ListeningExecutorService executor = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(ITERATIONS));
|
||||
List<ListenableFuture<ECKey.ECDSASignature>> sigFutures = Lists.newArrayList();
|
||||
final ECKey key = new ECKey();
|
||||
for (byte i = 0; i < ITERATIONS; i++) {
|
||||
final byte[] hash = HashUtil.sha3(new byte[]{i});
|
||||
sigFutures.add(executor.submit(new Callable<ECKey.ECDSASignature>() {
|
||||
@Override
|
||||
public ECKey.ECDSASignature call() throws Exception {
|
||||
return key.doSign(hash);
|
||||
}
|
||||
}));
|
||||
}
|
||||
List<ECKey.ECDSASignature> sigs = Futures.allAsList(sigFutures).get();
|
||||
for (ECKey.ECDSASignature signature : sigs) {
|
||||
assertTrue(signature.s.compareTo(ECKey.HALF_CURVE_ORDER) <= 0);
|
||||
}
|
||||
final ECKey.ECDSASignature duplicate = new ECKey.ECDSASignature(sigs.get(0).r, sigs.get(0).s);
|
||||
assertEquals(sigs.get(0), duplicate);
|
||||
assertEquals(sigs.get(0).hashCode(), duplicate.hashCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSignVerify() {
|
||||
ECKey key = ECKey.fromPrivate(privateKey);
|
||||
String message = new String("This is an example of a signed message.");
|
||||
ECDSASignature output = key.doSign(message.getBytes());
|
||||
assertTrue(key.verify(message.getBytes(), output));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsPubKeyCanonicalCorect() {
|
||||
// Test correct prefix 4, right length 65
|
||||
byte[] canonicalPubkey1 = new byte[65]; canonicalPubkey1[0] = 0x04;
|
||||
assertTrue(ECKey.isPubKeyCanonical(canonicalPubkey1));
|
||||
// Test correct prefix 2, right length 33
|
||||
byte[] canonicalPubkey2 = new byte[33]; canonicalPubkey2[0] = 0x02;
|
||||
assertTrue(ECKey.isPubKeyCanonical(canonicalPubkey2));
|
||||
// Test correct prefix 3, right length 33
|
||||
byte[] canonicalPubkey3 = new byte[33]; canonicalPubkey3[0] = 0x03;
|
||||
assertTrue(ECKey.isPubKeyCanonical(canonicalPubkey3));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsPubKeyCanonicalWrongLength() {
|
||||
// Test correct prefix 4, but wrong length !65
|
||||
byte[] nonCanonicalPubkey1 = new byte[64]; nonCanonicalPubkey1[0] = 0x04;
|
||||
assertFalse(ECKey.isPubKeyCanonical(nonCanonicalPubkey1));
|
||||
// Test correct prefix 2, but wrong length !33
|
||||
byte[] nonCanonicalPubkey2 = new byte[32]; nonCanonicalPubkey2[0] = 0x02;
|
||||
assertFalse(ECKey.isPubKeyCanonical(nonCanonicalPubkey2));
|
||||
// Test correct prefix 3, but wrong length !33
|
||||
byte[] nonCanonicalPubkey3 = new byte[32]; nonCanonicalPubkey3[0] = 0x03;
|
||||
assertFalse(ECKey.isPubKeyCanonical(nonCanonicalPubkey3));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsPubKeyCanonicalWrongPrefix() {
|
||||
// Test wrong prefix 4, right length 65
|
||||
byte[] nonCanonicalPubkey4 = new byte[65];
|
||||
assertFalse(ECKey.isPubKeyCanonical(nonCanonicalPubkey4));
|
||||
// Test wrong prefix 2, right length 33
|
||||
byte[] nonCanonicalPubkey5 = new byte[33];
|
||||
assertFalse(ECKey.isPubKeyCanonical(nonCanonicalPubkey5));
|
||||
// Test wrong prefix 3, right length 33
|
||||
byte[] nonCanonicalPubkey6 = new byte[33];
|
||||
assertFalse(ECKey.isPubKeyCanonical(nonCanonicalPubkey6));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void keyRecovery() throws Exception {
|
||||
ECKey key = new ECKey();
|
||||
String message = "Hello World!";
|
||||
byte[] hash = HashUtil.sha256(message.getBytes());
|
||||
ECKey.ECDSASignature sig = key.doSign(hash);
|
||||
key = ECKey.fromPublicOnly(key.getPubKeyPoint());
|
||||
boolean found = false;
|
||||
for (int i = 0; i < 4; i++) {
|
||||
ECKey key2 = ECKey.recoverFromSignature(i, sig, hash, true);
|
||||
checkNotNull(key2);
|
||||
if (key.equals(key2)) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
assertTrue(found);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSignedBitcoinMessageToKey() throws SignatureException {
|
||||
ECKey key = ECKey.signedBitcoinMessageToKey("This is an example of a signed message.", bitcoinSigBase64);
|
||||
assertNotNull(key);
|
||||
assertArrayEquals(pubKey, key.getPubKey());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSignedMessageToKey() throws SignatureException {
|
||||
byte[] messageHash = HashUtil.sha3(exampleMessage.getBytes());
|
||||
ECKey key = ECKey.signatureToKey(messageHash, ethereumSigBase64);
|
||||
assertNotNull(key);
|
||||
assertArrayEquals(pubKey, key.getPubKey());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testGetPrivKeyBytes() {
|
||||
ECKey key = new ECKey();
|
||||
assertNotNull(key.getPrivKeyBytes());
|
||||
assertEquals(32, key.getPrivKeyBytes().length);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEqualsObject() {
|
||||
ECKey key0 = new ECKey();
|
||||
ECKey key1 = ECKey.fromPrivate(privateKey);
|
||||
ECKey key2 = ECKey.fromPrivate(privateKey);
|
||||
|
||||
assertFalse(key0.equals(key1));
|
||||
assertTrue(key1.equals(key1));
|
||||
assertTrue(key1.equals(key2));
|
||||
}
|
||||
}
|
@ -1,7 +1,6 @@
|
||||
package org.ethereum.net;
|
||||
|
||||
import junit.framework.Assert;
|
||||
import org.bouncycastle.util.encoders.Hex;
|
||||
import org.spongycastle.util.encoders.Hex;
|
||||
import org.ethereum.net.message.*;
|
||||
import org.ethereum.net.rlp.RLPList;
|
||||
import org.ethereum.net.vo.BlockData;
|
||||
@ -11,17 +10,10 @@ import org.ethereum.util.Utils;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Queue;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* www.ethereumJ.com
|
||||
* User: Roman Mandeleil
|
||||
* Created on: 07/04/14 12:57
|
||||
*/
|
||||
public class MessagesTest {
|
||||
|
||||
/* HELLO_MESSAGE */
|
||||
@ -46,12 +38,12 @@ public class MessagesTest {
|
||||
System.out.println(helloMessage);
|
||||
|
||||
|
||||
Assert.assertEquals(12, helloMessage.getProtocolVersion());
|
||||
Assert.assertEquals(0, helloMessage.getNetworkId());
|
||||
Assert.assertEquals("Ethereum(++)/ZeroGox/v0.5.1/ncurses/Linux/g++", helloMessage.getClientId());
|
||||
Assert.assertEquals(7, helloMessage.getCapabilities());
|
||||
Assert.assertEquals(30303, helloMessage.getPeerPort());
|
||||
Assert.assertEquals(
|
||||
assertEquals(12, helloMessage.getProtocolVersion());
|
||||
assertEquals(0, helloMessage.getNetworkId());
|
||||
assertEquals("Ethereum(++)/ZeroGox/v0.5.1/ncurses/Linux/g++", helloMessage.getClientId());
|
||||
assertEquals(7, helloMessage.getCapabilities());
|
||||
assertEquals(30303, helloMessage.getPeerPort());
|
||||
assertEquals(
|
||||
"D8833B83560E0B12170E9169DC43784223A59842DE2359E6D03DB34C30A966C2DE3B4B2552FB0D7595A185D558F2E669B595674F5217C996EE148884828BE0FD",
|
||||
Utils.toHexString(helloMessage.getPeerId()).toUpperCase() );
|
||||
}
|
||||
@ -68,12 +60,12 @@ public class MessagesTest {
|
||||
helloMessage.parseRLP();
|
||||
System.out.println(helloMessage);
|
||||
|
||||
Assert.assertEquals(11, helloMessage.getProtocolVersion());
|
||||
Assert.assertEquals(0, helloMessage.getNetworkId());
|
||||
Assert.assertEquals("Ethereum(++)/v0.4.3/ETH_BUILD_TYPE/ETH_BUILD_PLATFORM", helloMessage.getClientId());
|
||||
Assert.assertEquals(7, helloMessage.getCapabilities());
|
||||
Assert.assertEquals(30303, helloMessage.getPeerPort());
|
||||
Assert.assertEquals(
|
||||
assertEquals(11, helloMessage.getProtocolVersion());
|
||||
assertEquals(0, helloMessage.getNetworkId());
|
||||
assertEquals("Ethereum(++)/v0.4.3/ETH_BUILD_TYPE/ETH_BUILD_PLATFORM", helloMessage.getClientId());
|
||||
assertEquals(7, helloMessage.getCapabilities());
|
||||
assertEquals(30303, helloMessage.getPeerPort());
|
||||
assertEquals(
|
||||
"E02B18FBA6B887FB9258469C3AF8E445CC9AE2B5386CAC5F60C4170F822086224E3876555C745A7EC8AC181C7F9701776D94A779604EA12651DE5F4A748D29E1",
|
||||
Utils.toHexString(helloMessage.getPeerId()).toUpperCase() );
|
||||
}
|
||||
@ -92,7 +84,7 @@ public class MessagesTest {
|
||||
DisconnectMessage disconnectMessage = new DisconnectMessage(rlpList);
|
||||
System.out.println(disconnectMessage);
|
||||
|
||||
Assert.assertEquals(disconnectMessage.getReason(),
|
||||
assertEquals(disconnectMessage.getReason(),
|
||||
DisconnectMessage.REASON_DISCONNECT_REQUESTED);
|
||||
}
|
||||
|
||||
@ -107,7 +99,7 @@ public class MessagesTest {
|
||||
DisconnectMessage disconnectMessage = new DisconnectMessage(rlpList);
|
||||
System.out.println(disconnectMessage);
|
||||
|
||||
Assert.assertEquals(disconnectMessage.getReason(),
|
||||
assertEquals(disconnectMessage.getReason(),
|
||||
DisconnectMessage.REASON_TCP_ERROR);
|
||||
}
|
||||
|
||||
@ -125,13 +117,13 @@ public class MessagesTest {
|
||||
PeersMessage peersMessage= new PeersMessage(rlpList);
|
||||
System.out.println(peersMessage);
|
||||
|
||||
Assert.assertEquals(9, peersMessage.getPeers().size());
|
||||
assertEquals(9, peersMessage.getPeers().size());
|
||||
|
||||
PeerData peerData = peersMessage.getPeers().get(3);
|
||||
|
||||
Assert.assertEquals("/85.65.126.45", peerData.getInetAddress().toString());
|
||||
Assert.assertEquals(30303, peerData.getPort());
|
||||
Assert.assertEquals("82A8A5831D3B4FB76CF130CDC8A2B162A85D005D82A1DCC9B73239035EADE6347EDE2FFC86571ABE348EA38699CE886AA3D425FE58182C433434AB4CFD7B5B88",
|
||||
assertEquals("/85.65.126.45", peerData.getInetAddress().toString());
|
||||
assertEquals(30303, peerData.getPort());
|
||||
assertEquals("82A8A5831D3B4FB76CF130CDC8A2B162A85D005D82A1DCC9B73239035EADE6347EDE2FFC86571ABE348EA38699CE886AA3D425FE58182C433434AB4CFD7B5B88",
|
||||
Utils.toHexString( peerData.getPeerId() ).toUpperCase());
|
||||
|
||||
}
|
||||
@ -147,20 +139,20 @@ public class MessagesTest {
|
||||
PeersMessage peersMessage= new PeersMessage(rlpList);
|
||||
System.out.println(peersMessage);
|
||||
|
||||
Assert.assertEquals(77, peersMessage.getPeers().size());
|
||||
assertEquals(77, peersMessage.getPeers().size());
|
||||
|
||||
PeerData peerData = peersMessage.getPeers().get(7);
|
||||
|
||||
Assert.assertEquals("/191.234.57.55", peerData.getInetAddress().toString());
|
||||
Assert.assertEquals(30303, peerData.getPort());
|
||||
Assert.assertEquals("21780C55B47DB4B11467B5F55B0B555E0887CE36FBD975E224B1C70EAC7AB8E8C2DB37F0A48B90FFDD5A379ADA99B6A0F6429C4A53C25558191A682636AEF4F2",
|
||||
assertEquals("/191.234.57.55", peerData.getInetAddress().toString());
|
||||
assertEquals(30303, peerData.getPort());
|
||||
assertEquals("21780C55B47DB4B11467B5F55B0B555E0887CE36FBD975E224B1C70EAC7AB8E8C2DB37F0A48B90FFDD5A379ADA99B6A0F6429C4A53C25558191A682636AEF4F2",
|
||||
Utils.toHexString( peerData.getPeerId() ).toUpperCase());
|
||||
|
||||
peerData = peersMessage.getPeers().get(75);
|
||||
|
||||
Assert.assertEquals("/86.124.82.254", peerData.getInetAddress().toString());
|
||||
Assert.assertEquals(30303, peerData.getPort());
|
||||
Assert.assertEquals("F6155F1A60143B7D9D5D1A440D7D52FE6809F69E0C6F1E0024457E0D71DD88ADE3B13AAA940C89AC0610952B48BD832C42E343A13E61FFDB06010CFFC345E053",
|
||||
assertEquals("/86.124.82.254", peerData.getInetAddress().toString());
|
||||
assertEquals(30303, peerData.getPort());
|
||||
assertEquals("F6155F1A60143B7D9D5D1A440D7D52FE6809F69E0C6F1E0024457E0D71DD88ADE3B13AAA940C89AC0610952B48BD832C42E343A13E61FFDB06010CFFC345E053",
|
||||
Utils.toHexString( peerData.getPeerId() ).toUpperCase());
|
||||
|
||||
}
|
||||
@ -200,42 +192,42 @@ public class MessagesTest {
|
||||
TransactionsMessage transactionsMessage = new TransactionsMessage(rlpList);
|
||||
System.out.println(transactionsMessage);
|
||||
|
||||
Assert.assertEquals(1, transactionsMessage.getTransactions().size());
|
||||
assertEquals(1, transactionsMessage.getTransactions().size());
|
||||
|
||||
TransactionData tx =
|
||||
transactionsMessage.getTransactions().get(0);
|
||||
|
||||
Assert.assertEquals("558A3797E0DD3FBFAF761F1ADD6749C7D5DB313FDAC5CBA59F40E28AF7BBACD1",
|
||||
assertEquals("558A3797E0DD3FBFAF761F1ADD6749C7D5DB313FDAC5CBA59F40E28AF7BBACD1",
|
||||
Utils.toHexString( tx.getHash() ).toUpperCase());
|
||||
|
||||
Assert.assertEquals("04",
|
||||
assertEquals("04",
|
||||
Utils.toHexString( tx.getNonce() ).toUpperCase());
|
||||
|
||||
Assert.assertEquals("1BC16D674EC80000",
|
||||
assertEquals("1BC16D674EC80000",
|
||||
Utils.toHexString( tx.getValue() ).toUpperCase());
|
||||
|
||||
Assert.assertEquals("CD2A3D9F938E13CD947EC05ABC7FE734DF8DD826",
|
||||
assertEquals("CD2A3D9F938E13CD947EC05ABC7FE734DF8DD826",
|
||||
Utils.toHexString( tx.getReceiveAddress() ).toUpperCase());
|
||||
|
||||
Assert.assertEquals("09184E72A000",
|
||||
assertEquals("09184E72A000",
|
||||
Utils.toHexString( tx.getGasPrice() ).toUpperCase());
|
||||
|
||||
Assert.assertEquals("64",
|
||||
assertEquals("64",
|
||||
Utils.toHexString( tx.getGas() ).toUpperCase());
|
||||
|
||||
Assert.assertEquals("NULL",
|
||||
assertEquals("NULL",
|
||||
Utils.toHexString( tx.getData() ).toUpperCase());
|
||||
|
||||
Assert.assertEquals("NULL",
|
||||
assertEquals("NULL",
|
||||
Utils.toHexString( tx.getInit() ).toUpperCase());
|
||||
|
||||
Assert.assertEquals("1B",
|
||||
assertEquals("1B",
|
||||
Utils.toHexString( new byte[] {tx.getSignatureV()} ).toUpperCase());
|
||||
|
||||
Assert.assertEquals("5E3868194605F1647593B842725818CCFA6A38651A728715133A8E97CDCFAC54",
|
||||
assertEquals("5E3868194605F1647593B842725818CCFA6A38651A728715133A8E97CDCFAC54",
|
||||
Utils.toHexString( tx.getSignatureR() ).toUpperCase());
|
||||
|
||||
Assert.assertEquals("0FF91628D04B215EBCCFD5F4FC34CC1B45DF32F6B4609FBB0DE42E8522264467",
|
||||
assertEquals("0FF91628D04B215EBCCFD5F4FC34CC1B45DF32F6B4609FBB0DE42E8522264467",
|
||||
Utils.toHexString( tx.getSignatureS() ).toUpperCase());
|
||||
|
||||
}
|
||||
@ -253,79 +245,79 @@ public class MessagesTest {
|
||||
TransactionsMessage transactionsMessage = new TransactionsMessage(rlpList);
|
||||
System.out.println(transactionsMessage);
|
||||
|
||||
Assert.assertEquals(3, transactionsMessage.getTransactions().size());
|
||||
assertEquals(3, transactionsMessage.getTransactions().size());
|
||||
|
||||
TransactionData tx =
|
||||
transactionsMessage.getTransactions().get(0);
|
||||
|
||||
Assert.assertEquals("4B7D9670A92BF120D5B43400543B69304A14D767CF836A7F6ABFF4EDDE092895",
|
||||
assertEquals("4B7D9670A92BF120D5B43400543B69304A14D767CF836A7F6ABFF4EDDE092895",
|
||||
Utils.toHexString( tx.getHash() ).toUpperCase());
|
||||
|
||||
Assert.assertEquals("NULL",
|
||||
assertEquals("NULL",
|
||||
Utils.toHexString( tx.getNonce() ).toUpperCase());
|
||||
|
||||
Assert.assertEquals("NULL",
|
||||
assertEquals("NULL",
|
||||
Utils.toHexString( tx.getValue() ).toUpperCase());
|
||||
|
||||
Assert.assertEquals("0000000000000000000000000000000000000000",
|
||||
assertEquals("0000000000000000000000000000000000000000",
|
||||
Utils.toHexString( tx.getReceiveAddress() ).toUpperCase());
|
||||
|
||||
Assert.assertEquals("09184E72A000",
|
||||
assertEquals("09184E72A000",
|
||||
Utils.toHexString( tx.getGasPrice() ).toUpperCase());
|
||||
|
||||
Assert.assertEquals("2710",
|
||||
assertEquals("2710",
|
||||
Utils.toHexString( tx.getGas() ).toUpperCase());
|
||||
|
||||
Assert.assertEquals("606956330C0D630000003359366000530A0D630000003359602060005301356000533557604060005301600054630000000C58",
|
||||
assertEquals("606956330C0D630000003359366000530A0D630000003359602060005301356000533557604060005301600054630000000C58",
|
||||
Utils.toHexString( tx.getData() ).toUpperCase());
|
||||
|
||||
Assert.assertEquals("33606957",
|
||||
assertEquals("33606957",
|
||||
Utils.toHexString( tx.getInit() ).toUpperCase());
|
||||
|
||||
Assert.assertEquals("1C",
|
||||
assertEquals("1C",
|
||||
Utils.toHexString( new byte[] {tx.getSignatureV()} ).toUpperCase());
|
||||
|
||||
Assert.assertEquals("7F6EB94576346488C6253197BDE6A7E59DDC36F2773672C849402AA9C402C3C4",
|
||||
assertEquals("7F6EB94576346488C6253197BDE6A7E59DDC36F2773672C849402AA9C402C3C4",
|
||||
Utils.toHexString( tx.getSignatureR() ).toUpperCase());
|
||||
|
||||
Assert.assertEquals("6D254E662BF7450DD8D835160CBB053463FED0B53F2CDD7F3EA8731919C8E8CC",
|
||||
assertEquals("6D254E662BF7450DD8D835160CBB053463FED0B53F2CDD7F3EA8731919C8E8CC",
|
||||
Utils.toHexString( tx.getSignatureS() ).toUpperCase());
|
||||
|
||||
|
||||
tx =
|
||||
transactionsMessage.getTransactions().get(2);
|
||||
|
||||
Assert.assertEquals("B0251A1BB20B44459DB5B5444AB53EDD9E12C46D0BA07FA401A797BEB967D53C",
|
||||
assertEquals("B0251A1BB20B44459DB5B5444AB53EDD9E12C46D0BA07FA401A797BEB967D53C",
|
||||
Utils.toHexString( tx.getHash() ).toUpperCase());
|
||||
|
||||
Assert.assertEquals("02",
|
||||
assertEquals("02",
|
||||
Utils.toHexString( tx.getNonce() ).toUpperCase());
|
||||
|
||||
Assert.assertEquals("NULL",
|
||||
assertEquals("NULL",
|
||||
Utils.toHexString( tx.getValue() ).toUpperCase());
|
||||
|
||||
Assert.assertEquals("CCDEAC59D35627B7DE09332E819D5159E7BB7250",
|
||||
assertEquals("CCDEAC59D35627B7DE09332E819D5159E7BB7250",
|
||||
Utils.toHexString( tx.getReceiveAddress() ).toUpperCase());
|
||||
|
||||
Assert.assertEquals("09184E72A000",
|
||||
assertEquals("09184E72A000",
|
||||
Utils.toHexString( tx.getGasPrice() ).toUpperCase());
|
||||
|
||||
Assert.assertEquals("2710",
|
||||
assertEquals("2710",
|
||||
Utils.toHexString( tx.getGas() ).toUpperCase());
|
||||
|
||||
Assert.assertEquals("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000002D0ACEEE7E5AB874E22CCF8D1A649F59106D74E8",
|
||||
assertEquals("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000002D0ACEEE7E5AB874E22CCF8D1A649F59106D74E8",
|
||||
Utils.toHexString( tx.getData() ).toUpperCase());
|
||||
|
||||
Assert.assertEquals("NULL",
|
||||
assertEquals("NULL",
|
||||
Utils.toHexString( tx.getInit() ).toUpperCase());
|
||||
|
||||
Assert.assertEquals("1B",
|
||||
assertEquals("1B",
|
||||
Utils.toHexString( new byte[] {tx.getSignatureV()} ).toUpperCase());
|
||||
|
||||
Assert.assertEquals("D05887574456C6DE8F7A0D172342C2CBDD4CF7AFE15D9DBB8B75B748BA6791C9",
|
||||
assertEquals("D05887574456C6DE8F7A0D172342C2CBDD4CF7AFE15D9DBB8B75B748BA6791C9",
|
||||
Utils.toHexString( tx.getSignatureR() ).toUpperCase());
|
||||
|
||||
Assert.assertEquals("1E87172A861F6C37B5A9E3A5D0D7393152A7FBE41530E5BB8AC8F35433E5931B",
|
||||
assertEquals("1E87172A861F6C37B5A9E3A5D0D7393152A7FBE41530E5BB8AC8F35433E5931B",
|
||||
Utils.toHexString(tx.getSignatureS()).toUpperCase());
|
||||
|
||||
}
|
||||
@ -347,7 +339,7 @@ public class MessagesTest {
|
||||
List<BlockData> list = blocksMessage.getBlockDataList();
|
||||
System.out.println(blocksMessage);
|
||||
|
||||
Assert.assertEquals(1, list.size());
|
||||
assertEquals(1, list.size());
|
||||
|
||||
BlockData block = list.get(0);
|
||||
|
||||
@ -393,7 +385,7 @@ public class MessagesTest {
|
||||
System.out.println(blocksMessage);
|
||||
|
||||
|
||||
Assert.assertEquals(32, list.size());
|
||||
assertEquals(32, list.size());
|
||||
|
||||
BlockData block = list.get(31);
|
||||
|
||||
@ -474,7 +466,7 @@ public class MessagesTest {
|
||||
NotInChainMessage notInChainMessage = new NotInChainMessage(rlpList);
|
||||
System.out.println(notInChainMessage);
|
||||
|
||||
Assert.assertEquals("E5E441F0877116011CCDECE2501A50B40C40418377037E16D0282B2B5E347138",
|
||||
assertEquals("E5E441F0877116011CCDECE2501A50B40C40418377037E16D0282B2B5E347138",
|
||||
Utils.toHexString(notInChainMessage.getHash()).toUpperCase());
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
package org.ethereum.net;
|
||||
|
||||
import org.bouncycastle.util.encoders.Hex;
|
||||
import org.spongycastle.util.encoders.Hex;
|
||||
import org.ethereum.crypto.HashUtil;
|
||||
import org.ethereum.net.rlp.RLPList;
|
||||
import org.ethereum.util.Utils;
|
||||
import org.junit.Assert;
|
||||
@ -15,11 +16,6 @@ import java.util.Queue;
|
||||
import static org.junit.Assert.assertArrayEquals;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
/**
|
||||
* www.ethereumJ.com
|
||||
* User: Roman Mandeleil
|
||||
* Created on: 07/04/14 12:57
|
||||
*/
|
||||
public class RLPTest {
|
||||
|
||||
@Test
|
||||
@ -235,7 +231,7 @@ public class RLPTest {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||
prevHash = RLP.encodeElement(prevHash);
|
||||
|
||||
/* 2 */ byte[] uncleList = Utils.sha3(RLP.encodeList(new byte[]{}));
|
||||
/* 2 */ byte[] uncleList = HashUtil.sha3(RLP.encodeList(new byte[]{}));
|
||||
|
||||
/* 3 */ byte[] coinbase =
|
||||
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
|
@ -1,31 +1,21 @@
|
||||
package org.ethereum.serpent;
|
||||
|
||||
import junit.framework.Assert;
|
||||
import org.antlr.runtime.ANTLRStringStream;
|
||||
import org.antlr.runtime.CharStream;
|
||||
import org.antlr.runtime.CommonTokenStream;
|
||||
import org.antlr.runtime.RecognitionException;
|
||||
import org.antlr.stringtemplate.StringTemplateGroup;
|
||||
import org.antlr.stringtemplate.language.AngleBracketTemplateLexer;
|
||||
import org.bouncycastle.util.encoders.Hex;
|
||||
import org.ethereum.util.Utils;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileReader;
|
||||
import java.math.BigInteger;
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedList;
|
||||
import java.util.Queue;
|
||||
|
||||
/**
|
||||
* www.ethereumJ.com
|
||||
* User: Roman Mandeleil
|
||||
* Created on: 27/04/14 14:35
|
||||
*/
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
public class TestCompile {
|
||||
|
||||
|
||||
/* bin_expr
|
||||
['+', 2, 1, ['<1>', '<0>', 'ADD']], V
|
||||
['-', 2, 1, ['<1>', '<0>', 'SUB']], V
|
||||
@ -40,9 +30,7 @@ public class TestCompile {
|
||||
@Test /* Test one symbol */
|
||||
public void test0() throws FileNotFoundException, RecognitionException {
|
||||
|
||||
CharStream stream =
|
||||
new ANTLRStringStream("" +
|
||||
"A");
|
||||
CharStream stream = new ANTLRStringStream("" + "A");
|
||||
|
||||
SerpentLexer lex = new SerpentLexer(stream);
|
||||
CommonTokenStream tokens = new CommonTokenStream(lex);
|
||||
@ -58,12 +46,9 @@ public class TestCompile {
|
||||
|
||||
SerpentParser.bin_expr_return retVal = parser.bin_expr();
|
||||
|
||||
Assert.assertEquals("A", retVal.getTemplate().toString());
|
||||
|
||||
assertEquals("A", retVal.getTemplate().toString());
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Test /* Test ADD 1*/
|
||||
public void test1() throws FileNotFoundException, RecognitionException {
|
||||
|
||||
@ -85,8 +70,7 @@ public class TestCompile {
|
||||
|
||||
SerpentParser.bin_expr_return retVal = parser.bin_expr();
|
||||
|
||||
Assert.assertEquals("A B ADD", retVal.getTemplate().toString());
|
||||
|
||||
assertEquals("A B ADD", retVal.getTemplate().toString());
|
||||
}
|
||||
|
||||
@Test /* Test ADD 2*/
|
||||
@ -110,8 +94,7 @@ public class TestCompile {
|
||||
|
||||
SerpentParser.bin_expr_return retVal = parser.bin_expr();
|
||||
|
||||
Assert.assertEquals("A B ADD C1 ADD", retVal.getTemplate().toString());
|
||||
|
||||
assertEquals("A B ADD C1 ADD", retVal.getTemplate().toString());
|
||||
}
|
||||
|
||||
@Test /* Test SUB 1*/
|
||||
@ -135,8 +118,7 @@ public class TestCompile {
|
||||
|
||||
SerpentParser.bin_expr_return retVal = parser.bin_expr();
|
||||
|
||||
Assert.assertEquals("A B SUB", retVal.getTemplate().toString());
|
||||
|
||||
assertEquals("A B SUB", retVal.getTemplate().toString());
|
||||
}
|
||||
|
||||
@Test /* Test MUL 1*/
|
||||
@ -150,7 +132,6 @@ public class TestCompile {
|
||||
CommonTokenStream tokens = new CommonTokenStream(lex);
|
||||
SerpentParser parser = new SerpentParser(tokens);
|
||||
|
||||
|
||||
String userDir = System.getProperty("user.dir");
|
||||
String templateFileName = userDir + "\\src\\main\\java\\org\\ethereum\\serpent\\Serpent2Asm.stg";
|
||||
|
||||
@ -160,8 +141,7 @@ public class TestCompile {
|
||||
|
||||
SerpentParser.bin_expr_return retVal = parser.bin_expr();
|
||||
|
||||
Assert.assertEquals("A B MUL", retVal.getTemplate().toString());
|
||||
|
||||
assertEquals("A B MUL", retVal.getTemplate().toString());
|
||||
}
|
||||
|
||||
|
||||
@ -176,7 +156,6 @@ public class TestCompile {
|
||||
CommonTokenStream tokens = new CommonTokenStream(lex);
|
||||
SerpentParser parser = new SerpentParser(tokens);
|
||||
|
||||
|
||||
String userDir = System.getProperty("user.dir");
|
||||
String templateFileName = userDir + "\\src\\main\\java\\org\\ethereum\\serpent\\Serpent2Asm.stg";
|
||||
|
||||
@ -186,7 +165,7 @@ public class TestCompile {
|
||||
|
||||
SerpentParser.bin_expr_return retVal = parser.bin_expr();
|
||||
|
||||
Assert.assertEquals("A B DIV", retVal.getTemplate().toString());
|
||||
assertEquals("A B DIV", retVal.getTemplate().toString());
|
||||
|
||||
}
|
||||
|
||||
@ -211,7 +190,7 @@ public class TestCompile {
|
||||
|
||||
SerpentParser.bin_expr_return retVal = parser.bin_expr();
|
||||
|
||||
Assert.assertEquals("A B EXP", retVal.getTemplate().toString());
|
||||
assertEquals("A B EXP", retVal.getTemplate().toString());
|
||||
|
||||
}
|
||||
|
||||
@ -236,7 +215,9 @@ public class TestCompile {
|
||||
|
||||
SerpentParser.bin_expr_return retVal = parser.bin_expr();
|
||||
|
||||
Assert.assertEquals("A B MOD", retVal.getTemplate().toString());
|
||||
|
||||
|
||||
assertEquals("A B MOD", retVal.getTemplate().toString());
|
||||
}
|
||||
|
||||
@Test /* Test SDIV 1*/
|
||||
@ -260,7 +241,7 @@ public class TestCompile {
|
||||
|
||||
SerpentParser.bin_expr_return retVal = parser.bin_expr();
|
||||
|
||||
Assert.assertEquals("A B SDIV", retVal.getTemplate().toString());
|
||||
assertEquals("A B SDIV", retVal.getTemplate().toString());
|
||||
|
||||
}
|
||||
|
||||
@ -285,7 +266,7 @@ public class TestCompile {
|
||||
|
||||
SerpentParser.bin_expr_return retVal = parser.bin_expr();
|
||||
|
||||
Assert.assertEquals("A B SMOD", retVal.getTemplate().toString());
|
||||
assertEquals("A B SMOD", retVal.getTemplate().toString());
|
||||
|
||||
}
|
||||
|
||||
@ -311,7 +292,7 @@ public class TestCompile {
|
||||
|
||||
SerpentParser.bin_expr_return retVal = parser.bin_expr();
|
||||
|
||||
Assert.assertEquals("A B DIV C SUB D ADD ET MUL", retVal.getTemplate().toString());
|
||||
assertEquals("A B DIV C SUB D ADD ET MUL", retVal.getTemplate().toString());
|
||||
|
||||
}
|
||||
|
||||
@ -336,7 +317,7 @@ public class TestCompile {
|
||||
|
||||
SerpentParser.bin_expr_return retVal = parser.bin_expr();
|
||||
|
||||
Assert.assertEquals("A B DIV C SUB D ADD ET MUL ET2 MOD RO EXP RO2 ADD COOL SDIV HOT SMOD",
|
||||
assertEquals("A B DIV C SUB D ADD ET MUL ET2 MOD RO EXP RO2 ADD COOL SDIV HOT SMOD",
|
||||
retVal.getTemplate().toString());
|
||||
|
||||
}
|
||||
@ -372,7 +353,7 @@ public class TestCompile {
|
||||
|
||||
SerpentParser.cond_expr_return retVal = parser.cond_expr();
|
||||
|
||||
Assert.assertEquals("A B ADD B A ADD EQ",
|
||||
assertEquals("A B ADD B A ADD EQ",
|
||||
retVal.getTemplate().toString());
|
||||
|
||||
}
|
||||
@ -398,7 +379,7 @@ public class TestCompile {
|
||||
|
||||
SerpentParser.cond_expr_return retVal = parser.cond_expr();
|
||||
|
||||
Assert.assertEquals("A C ADD C A ADD LT",
|
||||
assertEquals("A C ADD C A ADD LT",
|
||||
retVal.getTemplate().toString());
|
||||
|
||||
}
|
||||
@ -424,7 +405,7 @@ public class TestCompile {
|
||||
|
||||
SerpentParser.cond_expr_return retVal = parser.cond_expr();
|
||||
|
||||
Assert.assertEquals("A C ADD C A ADD GT NOT",
|
||||
assertEquals("A C ADD C A ADD GT NOT",
|
||||
retVal.getTemplate().toString());
|
||||
|
||||
}
|
||||
@ -451,7 +432,7 @@ public class TestCompile {
|
||||
|
||||
SerpentParser.cond_expr_return retVal = parser.cond_expr();
|
||||
|
||||
Assert.assertEquals("A C ADD C A ADD GT",
|
||||
assertEquals("A C ADD C A ADD GT",
|
||||
retVal.getTemplate().toString());
|
||||
|
||||
}
|
||||
@ -478,7 +459,7 @@ public class TestCompile {
|
||||
|
||||
SerpentParser.cond_expr_return retVal = parser.cond_expr();
|
||||
|
||||
Assert.assertEquals("A C ADD C A ADD LT NOT",
|
||||
assertEquals("A C ADD C A ADD LT NOT",
|
||||
retVal.getTemplate().toString());
|
||||
|
||||
}
|
||||
@ -504,7 +485,7 @@ public class TestCompile {
|
||||
|
||||
SerpentParser.unr_expr_return retVal = parser.unr_expr();
|
||||
|
||||
Assert.assertEquals("A NOT",
|
||||
assertEquals("A NOT",
|
||||
retVal.getTemplate().toString());
|
||||
|
||||
}
|
||||
@ -531,7 +512,7 @@ public class TestCompile {
|
||||
|
||||
SerpentParser.unr_expr_return retVal = parser.unr_expr();
|
||||
|
||||
Assert.assertEquals("A NOT NOT",
|
||||
assertEquals("A NOT NOT",
|
||||
retVal.getTemplate().toString());
|
||||
|
||||
}
|
||||
@ -557,7 +538,7 @@ public class TestCompile {
|
||||
|
||||
SerpentParser.unr_expr_return retVal = parser.unr_expr();
|
||||
|
||||
Assert.assertEquals("A NOT NOT",
|
||||
assertEquals("A NOT NOT",
|
||||
retVal.getTemplate().toString());
|
||||
|
||||
}
|
||||
@ -583,7 +564,7 @@ public class TestCompile {
|
||||
|
||||
SerpentParser.unr_expr_return retVal = parser.unr_expr();
|
||||
|
||||
Assert.assertEquals("A NOT",
|
||||
assertEquals("A NOT",
|
||||
retVal.getTemplate().toString());
|
||||
|
||||
}
|
||||
@ -610,7 +591,7 @@ public class TestCompile {
|
||||
|
||||
SerpentParser.program_return retVal = parser.program();
|
||||
|
||||
Assert.assertEquals("10 0 MSTORE 20 32 MSTORE 30 64 MSTORE",
|
||||
assertEquals("10 0 MSTORE 20 32 MSTORE 30 64 MSTORE",
|
||||
retVal.getTemplate().toString().trim());
|
||||
|
||||
}
|
||||
@ -636,7 +617,7 @@ public class TestCompile {
|
||||
|
||||
SerpentParser.program_return retVal = parser.program();
|
||||
|
||||
Assert.assertEquals("10 0 MSTORE 20 32 MSTORE 30 0 MSTORE 40 32 MSTORE",
|
||||
assertEquals("10 0 MSTORE 20 32 MSTORE 30 0 MSTORE 40 32 MSTORE",
|
||||
retVal.getTemplate().toString().trim());
|
||||
|
||||
}
|
||||
@ -662,7 +643,7 @@ public class TestCompile {
|
||||
|
||||
SerpentParser.if_else_stmt_return retVal = parser.if_else_stmt();
|
||||
|
||||
Assert.assertEquals("",
|
||||
assertEquals("",
|
||||
retVal.getTemplate().toString().trim());
|
||||
|
||||
}
|
||||
@ -688,7 +669,7 @@ public class TestCompile {
|
||||
|
||||
SerpentParser.storage_load_return retVal = parser.storage_load();
|
||||
|
||||
Assert.assertEquals("0 SLOAD",
|
||||
assertEquals("0 SLOAD",
|
||||
retVal.getTemplate().toString().trim());
|
||||
}
|
||||
|
||||
@ -713,7 +694,7 @@ public class TestCompile {
|
||||
|
||||
SerpentParser.storage_load_return retVal = parser.storage_load();
|
||||
|
||||
Assert.assertEquals("100 SLOAD",
|
||||
assertEquals("100 SLOAD",
|
||||
retVal.getTemplate().toString().trim());
|
||||
}
|
||||
|
||||
@ -738,7 +719,7 @@ public class TestCompile {
|
||||
|
||||
SerpentParser.storage_save_return retVal = parser.storage_save();
|
||||
|
||||
Assert.assertEquals("200 100 SSTORE",
|
||||
assertEquals("200 100 SSTORE",
|
||||
retVal.getTemplate().toString().trim());
|
||||
}
|
||||
|
||||
@ -763,7 +744,7 @@ public class TestCompile {
|
||||
|
||||
SerpentParser.storage_save_return retVal = parser.storage_save();
|
||||
|
||||
Assert.assertEquals("200 3 4 ADD SSTORE",
|
||||
assertEquals("200 3 4 ADD SSTORE",
|
||||
retVal.getTemplate().toString().trim());
|
||||
}
|
||||
|
||||
@ -789,7 +770,7 @@ public class TestCompile {
|
||||
|
||||
SerpentParser.storage_save_return retVal = parser.storage_save();
|
||||
|
||||
Assert.assertEquals("200 100 ADD 100 SSTORE", // todo: have to optimize it somewhere in the future
|
||||
assertEquals("200 100 ADD 100 SSTORE", // todo: have to optimize it somewhere in the future
|
||||
retVal.getTemplate().toString().trim());
|
||||
}
|
||||
|
||||
@ -814,7 +795,7 @@ public class TestCompile {
|
||||
|
||||
SerpentParser.msg_load_return retVal = parser.msg_load();
|
||||
|
||||
Assert.assertEquals("0 32 MULL CALLDATALOAD",
|
||||
assertEquals("0 32 MULL CALLDATALOAD",
|
||||
retVal.getTemplate().toString().trim());
|
||||
}
|
||||
|
||||
@ -839,7 +820,7 @@ public class TestCompile {
|
||||
|
||||
SerpentParser.msg_load_return retVal = parser.msg_load();
|
||||
|
||||
Assert.assertEquals("10 20 ADD 32 MUL CALLDATALOAD",
|
||||
assertEquals("10 20 ADD 32 MUL CALLDATALOAD",
|
||||
retVal.getTemplate().toString().trim());
|
||||
}
|
||||
|
||||
@ -864,7 +845,7 @@ public class TestCompile {
|
||||
|
||||
SerpentParser.bin_expr_return retVal = parser.bin_expr();
|
||||
|
||||
Assert.assertEquals("0 32 MUL CALLDATALOAD 2 32 MUL CALLDATALOAD ADD",
|
||||
assertEquals("0 32 MUL CALLDATALOAD 2 32 MUL CALLDATALOAD ADD",
|
||||
retVal.getTemplate().toString().trim());
|
||||
}
|
||||
|
||||
@ -891,7 +872,7 @@ public class TestCompile {
|
||||
|
||||
SerpentParser.storage_save_return retVal = parser.storage_save();
|
||||
|
||||
Assert.assertEquals("1 32 MUL CALLDATALOAD 0 32 MUL CALLDATALOAD SSTORE",
|
||||
assertEquals("1 32 MUL CALLDATALOAD 0 32 MUL CALLDATALOAD SSTORE",
|
||||
retVal.getTemplate().toString().trim());
|
||||
}
|
||||
|
||||
@ -916,7 +897,7 @@ public class TestCompile {
|
||||
|
||||
SerpentParser.unr_expr_return retVal = parser.unr_expr();
|
||||
|
||||
Assert.assertEquals("0 32 MUL CALLDATALOAD SLOAD NOT",
|
||||
assertEquals("0 32 MUL CALLDATALOAD SLOAD NOT",
|
||||
retVal.getTemplate().toString().trim());
|
||||
}
|
||||
|
||||
@ -941,7 +922,7 @@ public class TestCompile {
|
||||
|
||||
SerpentParser.test_1_return retVal = parser.test_1();
|
||||
|
||||
Assert.assertEquals("20 0 MSTORE 20 32 MSTORE 32 MLOAD",
|
||||
assertEquals("20 0 MSTORE 20 32 MSTORE 32 MLOAD",
|
||||
retVal.getTemplate().toString().trim());
|
||||
}
|
||||
|
||||
@ -966,7 +947,7 @@ public class TestCompile {
|
||||
|
||||
SerpentParser.test_1_return retVal = parser.test_1();
|
||||
|
||||
Assert.assertEquals("20 0 MSTORE 20 32 MSTORE 20 64 MSTORE 64 MLOAD",
|
||||
assertEquals("20 0 MSTORE 20 32 MSTORE 20 64 MSTORE 64 MLOAD",
|
||||
retVal.getTemplate().toString().trim());
|
||||
}
|
||||
|
||||
@ -996,7 +977,7 @@ public class TestCompile {
|
||||
|
||||
SerpentParser.if_else_stmt_return retVal = parser.if_else_stmt();
|
||||
|
||||
Assert.assertEquals("",
|
||||
assertEquals("",
|
||||
retVal.getTemplate().toString().trim());
|
||||
}
|
||||
|
||||
@ -1038,7 +1019,7 @@ public class TestCompile {
|
||||
|
||||
SerpentParser.gen_body_return retVal = parser.gen_body();
|
||||
|
||||
Assert.assertEquals("",
|
||||
assertEquals("",
|
||||
retVal.getTemplate().toString().trim());
|
||||
}
|
||||
|
||||
@ -1065,16 +1046,7 @@ public class TestCompile {
|
||||
|
||||
SerpentParser.hex_num_return retVal = parser.hex_num();
|
||||
|
||||
Assert.assertEquals(Utils.hexStringToDecimalString(hexNum),
|
||||
assertEquals(Utils.hexStringToDecimalString(hexNum),
|
||||
retVal.getTemplate().toString().trim());
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
@ -1,114 +1,44 @@
|
||||
package org.ethereum.transaction;
|
||||
|
||||
import org.bouncycastle.asn1.sec.SECNamedCurves;
|
||||
import org.bouncycastle.asn1.x9.X9ECParameters;
|
||||
import org.bouncycastle.util.encoders.Hex;
|
||||
import org.ethereum.util.Utils;
|
||||
import org.junit.Test;
|
||||
|
||||
import javax.crypto.Mac;
|
||||
import javax.crypto.SecretKey;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.math.BigInteger;
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.NoSuchProviderException;
|
||||
|
||||
/**
|
||||
* www.ethereumJ.com
|
||||
* User: Roman Mandeleil
|
||||
* Created on: 20/04/14 14:21
|
||||
*/
|
||||
import org.ethereum.crypto.ECKey;
|
||||
import org.ethereum.crypto.HashUtil;
|
||||
import org.junit.Test;
|
||||
import org.spongycastle.util.encoders.Hex;
|
||||
|
||||
public class TransactionTest {
|
||||
|
||||
|
||||
|
||||
@Test /* sign transaction https://tools.ietf.org/html/rfc6979 */
|
||||
public void test1() throws NoSuchProviderException, NoSuchAlgorithmException, InvalidKeyException, IOException {
|
||||
|
||||
//python taken exact data
|
||||
String txRLPRawData = "a9e880872386f26fc1000085e8d4a510008203e89413978aee95f38490e9769c39b2773ed763d9cd5f80";
|
||||
// String txRLPRawData = "f82804881bc16d674ec8000094cd2a3d9f938e13cd947ec05abc7fe734df8dd8268609184e72a0006480";
|
||||
|
||||
// String txRLPRawData = "f82804881bc16d674ec8000094cd2a3d9f938e13cd947ec05abc7fe734df8dd8268609184e72a0006480";
|
||||
String cowPrivKey = "c85ef7d79691fe79573b1a7064c19c1a9819ebdbd1faaab1a8ec92344438aaf4";
|
||||
byte[] cowPrivKey = Hex.decode("c85ef7d79691fe79573b1a7064c19c1a9819ebdbd1faaab1a8ec92344438aaf4");
|
||||
ECKey key = ECKey.fromPrivate(cowPrivKey);
|
||||
|
||||
byte[] data = Hex.decode(txRLPRawData);
|
||||
byte[] privKey = Hex.decode(cowPrivKey);
|
||||
|
||||
// step 1: serialize + RLP encode
|
||||
// step 2: hash = sha3(step1)
|
||||
byte[] txHash = Utils.sha3(data);
|
||||
|
||||
X9ECParameters curvParams = SECNamedCurves.getByName("secp256k1");
|
||||
|
||||
// z = hash_to_int(msghash)
|
||||
// k = deterministic_generate_k(msghash,priv)
|
||||
BigInteger txHashInt = new BigInteger(1, txHash );
|
||||
|
||||
/*
|
||||
v = '\x01' * 32
|
||||
k = '\x00' * 32
|
||||
priv = encode_privkey(priv,'bin')
|
||||
msghash = encode(hash_to_int(msghash),256,32)
|
||||
k = hmac.new(k, v+'\x00'+priv+msghash, hashlib.sha256).digest()
|
||||
v = hmac.new(k, v, hashlib.sha256).digest()
|
||||
k = hmac.new(k, v+'\x01'+priv+msghash, hashlib.sha256).digest()
|
||||
v = hmac.new(k, v, hashlib.sha256).digest()
|
||||
return decode(hmac.new(k, v, hashlib.sha256).digest(),256)
|
||||
*/
|
||||
byte[] v = {
|
||||
0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
|
||||
0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
|
||||
0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
|
||||
0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01
|
||||
};
|
||||
|
||||
byte[] k = {
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
|
||||
};
|
||||
|
||||
Mac hmac = Mac.getInstance("HMac-SHA256", "BC");
|
||||
|
||||
SecretKey secretKey = new SecretKeySpec(k, "HMac-SHA256");
|
||||
|
||||
hmac.init(secretKey);
|
||||
hmac.reset();
|
||||
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream(v.length + 1 + privKey.length + txHash.length);
|
||||
baos.write(v);
|
||||
baos.write(new byte[]{00});
|
||||
baos.write(privKey);
|
||||
baos.write(txHash);
|
||||
|
||||
hmac.update(baos.toByteArray());
|
||||
byte[] k_ = hmac.doFinal(secretKey.getEncoded());
|
||||
|
||||
|
||||
System.out.println(Hex.toHexString(k_));
|
||||
|
||||
|
||||
byte[] txHash = HashUtil.sha3(data);
|
||||
|
||||
String signature = key.doSign(txHash).toBase64();
|
||||
System.out.println(signature);
|
||||
}
|
||||
|
||||
@Test /* achieve public key of the sender */
|
||||
public void test2(){
|
||||
|
||||
// http://etherchain.org/#/tx/558a3797e0dd3fbfaf761f1add6749c7d5db313fdac5cba59f40e28af7bbacd1
|
||||
// f86b04881bc16d674ec8000094cd2a3d9f938e13cd947ec05abc7fe734df8dd8268609184e72a00064801ba05e3868194605f1647593b842725818ccfa6a38651a728715133a8e97cdcfac54a00ff91628d04b215ebccfd5f4fc34cc1b45df32f6b4609fbb0de42e8522264467
|
||||
|
||||
// [ 0x12, [ 0x4, 0x1BC16D674EC80000, 0xCD2A3D9F938E13CD947EC05ABC7FE734DF8DD826, 0x9184E72A000, 0x64, 0x0,
|
||||
// 0x1B, 0x5E3868194605F1647593B842725818CCFA6A38651A728715133A8E97CDCFAC54, 0xFF91628D04B215EBCCFD5F4FC34CC1B45DF32F6B4609FBB0DE42E8522264467 ] ]
|
||||
// sender: d4bfbf8d0f435c2ee2b4e3680018f1892fc1fba6
|
||||
|
||||
String rawTX = "F86B04881BC16D674EC8000094CD2A3D9F938E13CD947EC05ABC7FE734DF8DD8268609184E72A00064801BA05E3868194605F1647593B842725818CCFA6A38651A728715133A8E97CDCFAC54A00FF91628D04B215EBCCFD5F4FC34CC1B45DF32F6B4609FBB0DE42E8522264467";
|
||||
byte[] rawTxBytes = Hex.decode(rawTX);
|
||||
|
||||
String txHash = Hex.toHexString(Utils.sha3(rawTxBytes));
|
||||
String txHash = Hex.toHexString(HashUtil.sha3(rawTxBytes));
|
||||
System.out.println(txHash);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user