diff --git a/ethereumj-core/src/main/java/org/ethereum/core/AccountState.java b/ethereumj-core/src/main/java/org/ethereum/core/AccountState.java index 29417ae4..a68d1b94 100644 --- a/ethereumj-core/src/main/java/org/ethereum/core/AccountState.java +++ b/ethereumj-core/src/main/java/org/ethereum/core/AccountState.java @@ -68,6 +68,10 @@ public class AccountState { this.nonce = nonce.add(BigInteger.ONE); } + public byte[] getCodeHash() { + return codeHash; + } + public void setCodeHash(byte[] codeHash){ rlpEncoded = null; this.codeHash = codeHash; diff --git a/ethereumj-core/src/main/java/org/ethereum/crypto/HashUtil.java b/ethereumj-core/src/main/java/org/ethereum/crypto/HashUtil.java index ee363ba3..91387a43 100644 --- a/ethereumj-core/src/main/java/org/ethereum/crypto/HashUtil.java +++ b/ethereumj-core/src/main/java/org/ethereum/crypto/HashUtil.java @@ -12,6 +12,8 @@ import org.spongycastle.util.encoders.Hex; public class HashUtil { + public static byte[] EMPTY_DATA_HASH = HashUtil.sha3(new byte[0]); + private static final MessageDigest sha256digest; static { diff --git a/ethereumj-core/src/main/java/org/ethereum/manager/WorldManager.java b/ethereumj-core/src/main/java/org/ethereum/manager/WorldManager.java index 43c6d482..d319469a 100644 --- a/ethereumj-core/src/main/java/org/ethereum/manager/WorldManager.java +++ b/ethereumj-core/src/main/java/org/ethereum/manager/WorldManager.java @@ -112,6 +112,10 @@ public class WorldManager { ProgramInvoke programInvoke = ProgramInvokeFactory.createProgramInvoke(tx, lastBlock); + if (logger.isInfoEnabled()) + logger.info("running the init for contract: addres={}" , + Hex.toHexString(tx.getContractAddress())); + VM vm = new VM(); Program program = new Program(initCode, programInvoke); vm.play(program); @@ -120,7 +124,7 @@ public class WorldManager { byte[] bodyCode = null; if (result.gethReturn() != null){ - result.gethReturn().array(); + bodyCode = result.gethReturn().array(); } // TODO: what if the body code is null , still submit ? @@ -128,17 +132,46 @@ public class WorldManager { if (bodyCode != null){ - byte[] key = HashUtil.sha3(bodyCode); - chainDB.put(key, bodyCode); + byte[] codeKey = HashUtil.sha3(bodyCode); + chainDB.put(codeKey, bodyCode); + receiverState.setCodeHash(codeKey); + worldState.update(tx.getContractAddress(), receiverState.getEncoded()); if (stateLogger.isInfoEnabled()) - stateLogger.info("saving code of the contract to the db: sha3(code)={} code={}", - Hex.toHexString(key), + stateLogger.info("saving code of the contract to the db:\n contract={} sha3(code)={} code={}", + Hex.toHexString(tx.getContractAddress()), + Hex.toHexString(codeKey), Hex.toHexString(bodyCode)); } } else { - // TODO: 2. check if the address is a contract, if it is perform contract call + + if (receiverState.getCodeHash() != HashUtil.EMPTY_DATA_HASH){ + + byte[] programCode = chainDB.get(receiverState.getCodeHash()); + if (programCode.length != 0){ + + Block lastBlock = + MainData.instance.getBlockchain().getLastBlock(); + + ProgramInvoke programInvoke = + ProgramInvokeFactory.createProgramInvoke(tx, lastBlock); + + if (logger.isInfoEnabled()) + logger.info("calling for existing contract: addres={}" , Hex.toHexString(tx.getReceiveAddress())); + + VM vm = new VM(); + Program program = new Program(programCode, programInvoke); + vm.play(program); + + ProgramResult result = program.getResult(); + + // TODO: (!!!!!) ALL THE CHECKS FOR THE PROGRAM RESULT + + + } + } + } pendingTransactions.put(Hex.toHexString(tx.getHash()), tx); }