Package org.ethereum.vm

Source Code of org.ethereum.vm.ProgramInvokeFactory

package org.ethereum.vm;

import org.ethereum.core.Block;
import org.ethereum.core.Transaction;
import org.ethereum.facade.Blockchain;
import org.ethereum.facade.Repository;
import org.ethereum.manager.WorldManager;
import org.ethereum.util.ByteUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.spongycastle.util.encoders.Hex;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.math.BigInteger;

/**
* www.ethereumJ.com
*
* @author: Roman Mandeleil
* Created on: 08/06/2014 09:59
*/
@Component
public class ProgramInvokeFactory {

    private static final Logger logger = LoggerFactory.getLogger("VM");

    @Autowired
    private Blockchain blockchain;

    /**
     * This attribute defines the number of recursive calls allowed in the EVM
     * Note: For the JVM to reach this level without a StackOverflow exception,
     * ethereumj may need to be started with a JVM argument to increase
     * the stack size. For example: -Xss10m
     */
    private static final int MAX_DEPTH = 1024;
   
        // Invocation by the wire tx
    public ProgramInvoke createProgramInvoke(Transaction tx, Block block, Repository repository) {

        // https://ethereum.etherpad.mozilla.org/26
        Block lastBlock = blockchain.getBestBlock();

        /***         ADDRESS op       ***/
        // YP: Get address of currently executing account.
        byte[] address  =  tx.isContractCreation() ? tx.getContractAddress(): tx.getReceiveAddress();

        /***         ORIGIN op       ***/
        // YP: This is the sender of original transaction; it is never a contract.
        byte[] origin  = tx.getSender();

        /***         CALLER op       ***/
        // YP: This is the address of the account that is directly responsible for this execution.
        byte[] caller = tx.getSender();

        /***         BALANCE op       ***/
        byte[] balance = repository.getBalance(address).toByteArray();

        /***         GASPRICE op       ***/
        byte[] gasPrice = tx.getGasPrice();

        /*** GAS op ***/
        byte[] gas = tx.getGasLimit();

        /***        CALLVALUE op      ***/
        byte[] callValue = tx.getValue() == null ? new byte[]{0} : tx.getValue();

        /***     CALLDATALOAD  op   ***/
        /***     CALLDATACOPY  op   ***/
        /***     CALLDATASIZE  op   ***/
        byte[] data = tx.getData() == null ? ByteUtil.EMPTY_BYTE_ARRAY : tx.getData();

        /***    PREVHASH  op  ***/
        byte[] lastHash = lastBlock.getHash();

        /***   COINBASE  op ***/
        byte[] coinbase = block.getCoinbase();

        /*** TIMESTAMP  op  ***/
        long timestamp = block.getTimestamp();

        /*** NUMBER  op  ***/
        long number = block.getNumber();

        /*** DIFFICULTY  op  ***/
        byte[] difficulty = block.getDifficulty();

        /*** GASLIMIT op ***/
        long gaslimit = block.getGasLimit();

        if (logger.isInfoEnabled()) {
            logger.info("Top level call: \n" +
                    "address={}\n" +
                    "origin={}\n"  +
                    "caller={}\n"  +
                    "balance={}\n" +
                    "gasPrice={}\n" +
                    "gas={}\n" +
                    "callValue={}\n" +
                    "data={}\n" +
                    "lastHash={}\n" +
                    "coinbase={}\n" +
                    "timestamp={}\n" +
                    "blockNumber={}\n" +
                    "difficulty={}\n" +
                    "gaslimit={}\n",

                    Hex.toHexString(address),
                    Hex.toHexString(origin),
                    Hex.toHexString(caller),
                    new BigInteger(balance).longValue(),
                    new BigInteger(gasPrice).longValue(),
                    new BigInteger(gas).longValue(),
                    new BigInteger(callValue).longValue(),
                    Hex.toHexString(data),
                    Hex.toHexString(lastHash),
                    Hex.toHexString(coinbase),
                    timestamp,
                    number,
                    Hex.toHexString(difficulty),
                    gaslimit);
        }

        ProgramInvoke programInvoke =
            new ProgramInvokeImpl(address, origin, caller, balance, gasPrice, gas, callValue, data,
                    lastHash,  coinbase,  timestamp,  number,  difficulty,  gaslimit,
                    repository);

        return programInvoke;
    }

    /**
     * This invocation created for contract call contract
     */
    public static ProgramInvoke createProgramInvoke(Program program, DataWord toAddress,
                                                    DataWord inValue, DataWord inGas,
                                                    BigInteger balanceInt,  byte[] dataIn,
                                                    Repository repository) {

        DataWord address = toAddress;
        DataWord origin = program.getOriginAddress();
        DataWord caller = program.getOwnerAddress();

        DataWord balance = new DataWord(balanceInt.toByteArray());
        DataWord gasPrice = program.getGasPrice();
        DataWord gas = inGas;
        DataWord callValue = inValue;

        byte[] data = dataIn;
        DataWord lastHash =  program.getPrevHash();
        DataWord coinbase =  program.getCoinbase();
        DataWord timestamp = program.getTimestamp();
        DataWord number =  program.getNumber();
        DataWord difficulty = program.getDifficulty();
        DataWord gasLimit = program.getGaslimit();

        if (logger.isInfoEnabled()) {
            logger.info("Internal call: \n" +
                            "address={}\n" +
                            "origin={}\n"  +
                            "caller={}\n"  +
                            "balance={}\n" +
                            "gasPrice={}\n" +
                            "gas={}\n" +
                            "callValue={}\n" +
                            "data={}\n" +
                            "lastHash={}\n" +
                            "coinbase={}\n" +
                            "timestamp={}\n" +
                            "blockNumber={}\n" +
                            "difficulty={}\n" +
                            "gaslimit={}\n",
                    Hex.toHexString(address.getLast20Bytes()),
                    Hex.toHexString(origin.getLast20Bytes()),
                    Hex.toHexString(caller.getLast20Bytes()),
                    balance.longValue(),
                    gasPrice.longValue(),
                    gas.longValue(),
                    callValue.longValue(),
                    data == null ? "": Hex.toHexString(data),
                    Hex.toHexString(lastHash.getData()),
                    Hex.toHexString(coinbase.getLast20Bytes()),
                    timestamp.longValue(),
                    number.longValue(),
                    Hex.toHexString(difficulty.getNoLeadZeroesData()),
                    gasLimit.longValue());
        }
       
        if (program.invokeData.getCallDeep() >= MAX_DEPTH)
          throw program.new OutOfGasException();

        return new ProgramInvokeImpl(address, origin, caller, balance, gasPrice, gas, callValue,
                data, lastHash, coinbase, timestamp, number, difficulty, gasLimit,
                repository, program.invokeData.getCallDeep()+1);
    }
}
TOP

Related Classes of org.ethereum.vm.ProgramInvokeFactory

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.