This repository has been archived by the owner on Dec 5, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'stage' of https://github.com/ethereum/ethereumj into stage
- Loading branch information
Showing
37 changed files
with
610 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,5 @@ | ||
sudo: false | ||
sudo: required | ||
dist: trusty | ||
|
||
language: java | ||
jdk: oraclejdk7 | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
148 changes: 148 additions & 0 deletions
148
ethereumj-core/src/main/java/org/ethereum/samples/CreateContractSample.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,148 @@ | ||
package org.ethereum.samples; | ||
|
||
import org.ethereum.core.Block; | ||
import org.ethereum.core.CallTransaction; | ||
import org.ethereum.core.Transaction; | ||
import org.ethereum.core.TransactionReceipt; | ||
import org.ethereum.db.ByteArrayWrapper; | ||
import org.ethereum.facade.EthereumFactory; | ||
import org.ethereum.listener.EthereumListenerAdapter; | ||
import org.ethereum.solidity.compiler.CompilationResult; | ||
import org.ethereum.solidity.compiler.SolidityCompiler; | ||
import org.ethereum.util.ByteUtil; | ||
import org.ethereum.vm.program.ProgramResult; | ||
import org.spongycastle.util.encoders.Hex; | ||
import org.springframework.context.annotation.Bean; | ||
|
||
import java.math.BigInteger; | ||
import java.util.*; | ||
|
||
/** | ||
* Created by Anton Nashatyrev on 03.03.2016. | ||
*/ | ||
public class CreateContractSample extends TestNetSample { | ||
String contract = | ||
"contract Sample {" + | ||
" int i;" + | ||
" function inc(int n) {" + | ||
" i = i + n;" + | ||
" }" + | ||
" function get() returns (int) {" + | ||
" return i;" + | ||
" }" + | ||
"}"; | ||
|
||
private Map<ByteArrayWrapper, TransactionReceipt> txWaiters = | ||
Collections.synchronizedMap(new HashMap<ByteArrayWrapper, TransactionReceipt>()); | ||
|
||
@Override | ||
public void onSyncDone() throws Exception { | ||
ethereum.addListener(new EthereumListenerAdapter() { | ||
// when block arrives look for our included transactions | ||
@Override | ||
public void onBlock(Block block, List<TransactionReceipt> receipts) { | ||
CreateContractSample.this.onBlock(block, receipts); | ||
} | ||
}); | ||
|
||
logger.info("Compiling contract..."); | ||
SolidityCompiler.Result result = SolidityCompiler.compile(contract.getBytes(), true, | ||
SolidityCompiler.Options.ABI, SolidityCompiler.Options.BIN); | ||
if (result.isFailed()) { | ||
throw new RuntimeException("Contract compilation failed:\n" + result.errors); | ||
} | ||
CompilationResult res = CompilationResult.parse(result.output); | ||
if (res.contracts.isEmpty()) { | ||
throw new RuntimeException("Compilation failed, no contracts returned:\n" + result.errors); | ||
} | ||
CompilationResult.ContractMetadata metadata = res.contracts.values().iterator().next(); | ||
if (metadata.bin == null || metadata.bin.isEmpty()) { | ||
throw new RuntimeException("Compilation failed, no binary returned:\n" + result.errors); | ||
} | ||
|
||
logger.info("Sending contract to net and waiting for inclusion"); | ||
TransactionReceipt receipt = sendTxAndWait(new byte[0], Hex.decode(metadata.bin)); | ||
|
||
byte[] contractAddress = receipt.getTransaction().getContractAddress(); | ||
logger.info("Contract created: " + Hex.toHexString(contractAddress)); | ||
|
||
logger.info("Calling the contract function 'inc'"); | ||
CallTransaction.Contract contract = new CallTransaction.Contract(metadata.abi); | ||
CallTransaction.Function inc = contract.getByName("inc"); | ||
byte[] functionCallBytes = inc.encode(777); | ||
TransactionReceipt receipt1 = sendTxAndWait(contractAddress, functionCallBytes); | ||
logger.info("Contract modified!"); | ||
|
||
ProgramResult r = ethereum.callConstantFunction(Hex.toHexString(contractAddress), | ||
contract.getByName("get")); | ||
Object[] ret = contract.getByName("get").decodeResult(r.getHReturn()); | ||
logger.info("Current contract data member value: " + ret[0]); | ||
} | ||
|
||
protected TransactionReceipt sendTxAndWait(byte[] receiveAddress, byte[] data) throws InterruptedException { | ||
BigInteger nonce = ethereum.getRepository().getNonce(senderAddress); | ||
Transaction tx = new Transaction( | ||
ByteUtil.bigIntegerToBytes(nonce), | ||
ByteUtil.longToBytesNoLeadZeroes(ethereum.getGasPrice()), | ||
ByteUtil.longToBytesNoLeadZeroes(3_000_000), | ||
receiveAddress, | ||
ByteUtil.longToBytesNoLeadZeroes(1), | ||
data); | ||
tx.sign(senderPrivateKey); | ||
logger.info("<=== Sending transaction: " + tx); | ||
ethereum.submitTransaction(tx); | ||
|
||
return waitForTx(tx.getHash()); | ||
} | ||
|
||
private void onBlock(Block block, List<TransactionReceipt> receipts) { | ||
for (TransactionReceipt receipt : receipts) { | ||
ByteArrayWrapper txHashW = new ByteArrayWrapper(receipt.getTransaction().getHash()); | ||
if (txWaiters.containsKey(txHashW)) { | ||
txWaiters.put(txHashW, receipt); | ||
synchronized (this) { | ||
notifyAll(); | ||
} | ||
} | ||
} | ||
} | ||
|
||
protected TransactionReceipt waitForTx(byte[] txHash) throws InterruptedException { | ||
ByteArrayWrapper txHashW = new ByteArrayWrapper(txHash); | ||
txWaiters.put(txHashW, null); | ||
long startBlock = ethereum.getBlockchain().getBestBlock().getNumber(); | ||
while(true) { | ||
TransactionReceipt receipt = txWaiters.get(txHashW); | ||
if (receipt != null) { | ||
return receipt; | ||
} else { | ||
long curBlock = ethereum.getBlockchain().getBestBlock().getNumber(); | ||
if (curBlock > startBlock + 16) { | ||
throw new RuntimeException("The transaction was not included during last 16 blocks: " + txHashW.toString().substring(0,8)); | ||
} else { | ||
logger.info("Waiting for block with transaction 0x" + txHashW.toString().substring(0,8) + | ||
" included (" + (curBlock - startBlock) + " blocks received so far) ..."); | ||
} | ||
} | ||
synchronized (this) { | ||
wait(20000); | ||
} | ||
} | ||
} | ||
|
||
public static void main(String[] args) throws Exception { | ||
sLogger.info("Starting EthereumJ!"); | ||
|
||
class Config extends TestNetConfig{ | ||
@Override | ||
@Bean | ||
public TestNetSample sampleBean() { | ||
return new CreateContractSample(); | ||
} | ||
} | ||
|
||
// Based on Config class the BasicSample would be created by Spring | ||
// and its springInit() method would be called as an entry point | ||
EthereumFactory.createEthereum(Config.class); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
34 changes: 34 additions & 0 deletions
34
ethereumj-core/src/main/java/org/ethereum/solidity/compiler/CompilationResult.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
package org.ethereum.solidity.compiler; | ||
|
||
import com.fasterxml.jackson.databind.ObjectMapper; | ||
import org.codehaus.jackson.annotate.JsonIgnoreProperties; | ||
import org.codehaus.jackson.annotate.JsonProperty; | ||
|
||
import java.io.IOException; | ||
import java.util.Map; | ||
|
||
@JsonIgnoreProperties(ignoreUnknown = true) | ||
public class CompilationResult { | ||
|
||
public Map<String, ContractMetadata> contracts; | ||
public String version; | ||
|
||
public static CompilationResult parse(String rawJson) throws IOException { | ||
return new ObjectMapper().readValue(rawJson, CompilationResult.class); | ||
} | ||
|
||
@JsonIgnoreProperties(ignoreUnknown = true) | ||
public static class ContractMetadata { | ||
public String abi; | ||
public String bin; | ||
public String solInterface; | ||
|
||
public String getInterface() { | ||
return solInterface; | ||
} | ||
|
||
public void setInterface(String solInterface) { | ||
this.solInterface = solInterface; | ||
} | ||
} | ||
} |
28 changes: 28 additions & 0 deletions
28
ethereumj-core/src/main/java/org/ethereum/solidity/compiler/ContractException.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
package org.ethereum.solidity.compiler; | ||
|
||
public class ContractException extends RuntimeException { | ||
|
||
public ContractException(String message) { | ||
super(message); | ||
} | ||
|
||
public static ContractException permissionError(String msg, Object... args) { | ||
return error("contract permission error", msg, args); | ||
} | ||
|
||
public static ContractException compilationError(String msg, Object... args) { | ||
return error("contract compilation error", msg, args); | ||
} | ||
|
||
public static ContractException validationError(String msg, Object... args) { | ||
return error("contract validation error", msg, args); | ||
} | ||
|
||
public static ContractException assembleError(String msg, Object... args) { | ||
return error("contract assemble error", msg, args); | ||
} | ||
|
||
private static ContractException error(String title, String message, Object... args) { | ||
return new ContractException(title + ": " + String.format(message, args)); | ||
} | ||
} |
66 changes: 66 additions & 0 deletions
66
ethereumj-core/src/main/java/org/ethereum/solidity/compiler/Solc.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
package org.ethereum.solidity.compiler; | ||
|
||
import java.io.File; | ||
import java.io.IOException; | ||
import java.io.InputStream; | ||
import java.nio.file.Files; | ||
import java.nio.file.StandardCopyOption; | ||
import java.util.Scanner; | ||
|
||
/** | ||
* Created by Anton Nashatyrev on 03.03.2016. | ||
*/ | ||
public class Solc { | ||
|
||
public static final Solc INSTANCE = new Solc(); | ||
|
||
private File solc = null; | ||
|
||
private Solc() { | ||
try { | ||
init(); | ||
} catch (IOException e) { | ||
throw new RuntimeException("Can't init solc compiler: ", e); | ||
} | ||
} | ||
|
||
private void init() throws IOException { | ||
File tmpDir = new File(System.getProperty("java.io.tmpdir"), "solc"); | ||
tmpDir.mkdirs(); | ||
|
||
InputStream is = getClass().getResourceAsStream("/native/" + getOS() + "/solc/file.list"); | ||
Scanner scanner = new Scanner(is); | ||
while (scanner.hasNext()) { | ||
String s = scanner.next(); | ||
File targetFile = new File(tmpDir, s); | ||
if (!targetFile.canRead()) { | ||
InputStream fis = getClass().getResourceAsStream("/native/" + getOS() + "/solc/" + s); | ||
Files.copy(fis, targetFile.toPath(), StandardCopyOption.REPLACE_EXISTING); | ||
} | ||
if (solc == null) { | ||
// first file in the list denotes executable | ||
solc = targetFile; | ||
solc.setExecutable(true); | ||
} | ||
targetFile.deleteOnExit(); | ||
} | ||
|
||
} | ||
|
||
private static String getOS() { | ||
String osName = System.getProperty("os.name").toLowerCase(); | ||
if (osName.contains("win")) { | ||
return "win"; | ||
} else if (osName.contains("linux")) { | ||
return "linux"; | ||
} else if (osName.contains("mac")) { | ||
return "mac"; | ||
} else { | ||
throw new RuntimeException("Can't find solc compiler: unrecognized OS: " + osName); | ||
} | ||
} | ||
|
||
public File getExecutable() { | ||
return solc; | ||
} | ||
} |
Oops, something went wrong.