@Override
 public void setSender(ECKey senderPrivateKey) {
   txSender = senderPrivateKey;
   if (!getBlockchain().getRepository().isExist(senderPrivateKey.getAddress())) {
     Repository repository = getBlockchain().getRepository();
     Repository track = repository.startTracking();
     track.createAccount(senderPrivateKey.getAddress());
     track.commit();
   }
 }
Example #2
0
  @Test // CREATE magic
  public void test4() {

    /**
     * #The code will run ------------------
     *
     * <p>contract A: 77045e71a7a2c50903d88e564cd72fab11e82051 -----------
     *
     * <p>a = 0x7f60c860005461012c6020540000000000000000000000000000000000000000 b =
     * 0x0060005460206000f20000000000000000000000000000000000000000000000 create(100, 0 41)
     *
     * <p>contract B: (the contract to be created the addr will be defined to:
     * 8e45367623a2865132d9bf875d5cfa31b9a0cd94) ----------- a = 200 b = 300
     */

    // Set contract into Database
    byte[] caller_addr_bytes = Hex.decode("cd2a3d9f938e13cd947ec05abc7fe734df8dd826");

    byte[] contractA_addr_bytes = Hex.decode("77045e71a7a2c50903d88e564cd72fab11e82051");

    byte[] codeA =
        Hex.decode(
            "7f7f60c860005461012c602054000000000000"
                + "00000000000000000000000000006000547e60"
                + "005460206000f2000000000000000000000000"
                + "0000000000000000000000602054602960006064f0");

    ProgramInvokeMockImpl pi = new ProgramInvokeMockImpl();
    pi.setOwnerAddress(contractA_addr_bytes);

    Repository repository = pi.getRepository();

    repository.createAccount(contractA_addr_bytes);
    repository.saveCode(contractA_addr_bytes, codeA);

    repository.createAccount(caller_addr_bytes);

    // ****************** //
    //  Play the program  //
    // ****************** //
    VM vm = new VM();
    Program program = new Program(codeA, pi);

    try {
      while (!program.isStopped()) vm.step(program);
    } catch (RuntimeException e) {
      program.setRuntimeFailure(e);
    }

    logger.info("============ Results ============");

    System.out.println("*** Used gas: " + program.getResult().getGasUsed());
    // TODO: check that the value pushed after exec is the new address
    repository.close();
  }
Example #3
0
  // sha3_memSizeQuadraticCost32_zeroSize
  @Ignore // TODO #POC9
  @Test // contract call quadratic memory use
  public void test10() {

    int expectedGas = 313;

    DataWord key1 = new DataWord(999);
    DataWord value1 = new DataWord(3);

    // Set contract into Database
    String callerAddr = "cd1722f3947def4cf144679da39c4c32bdc35681";
    String contractAddr = "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6";
    String code = "600061040020600055";

    byte[] contractAddrB = Hex.decode(contractAddr);
    byte[] callerAddrB = Hex.decode(callerAddr);
    byte[] codeB = Hex.decode(code);

    byte[] codeKey = HashUtil.sha3(codeB);
    AccountState accountState = new AccountState(SystemProperties.getDefault());
    accountState.setCodeHash(codeKey);

    ProgramInvokeMockImpl pi = new ProgramInvokeMockImpl();
    pi.setOwnerAddress(contractAddrB);
    Repository repository = pi.getRepository();

    repository.createAccount(callerAddrB);
    repository.addBalance(
        callerAddrB,
        new BigInteger(
            "115792089237316195423570985008687907853269984665640564039457584007913129639935"));

    repository.createAccount(contractAddrB);
    repository.saveCode(contractAddrB, codeB);
    repository.addStorageRow(contractAddrB, key1, value1);

    // Play the program
    VM vm = new VM();
    Program program = new Program(codeB, pi);

    try {
      while (!program.isStopped()) vm.step(program);
    } catch (RuntimeException e) {
      program.setRuntimeFailure(e);
    }

    System.out.println();
    System.out.println("============ Results ============");

    BigInteger balance = repository.getBalance(callerAddrB);

    System.out.println("*** Used gas: " + program.getResult().getGasUsed());
    System.out.println("*** Contract Balance: " + balance);

    // todo: assert caller balance after contract exec

    repository.close();
    assertEquals(expectedGas, program.getResult().getGasUsed());
  }
  @Override
  public Block createForkBlock(Block parent) {
    try {
      List<Transaction> txes = new ArrayList<>();
      Map<ByteArrayWrapper, Long> nonces = new HashMap<>();
      Repository repoSnapshot =
          getBlockchain().getRepository().getSnapshotTo(parent.getStateRoot());
      for (PendingTx tx : submittedTxes) {
        ByteArrayWrapper senderW = new ByteArrayWrapper(tx.sender.getAddress());
        Long nonce = nonces.get(senderW);
        if (nonce == null) {
          BigInteger bcNonce = repoSnapshot.getNonce(tx.sender.getAddress());
          nonce = bcNonce.longValue();
        }
        nonces.put(senderW, nonce + 1);

        byte[] toAddress =
            tx.targetContract != null ? tx.targetContract.getAddress() : tx.toAddress;

        Transaction transaction =
            new Transaction(
                ByteUtil.longToBytesNoLeadZeroes(nonce),
                ByteUtil.longToBytesNoLeadZeroes(gasPrice),
                ByteUtil.longToBytesNoLeadZeroes(gasLimit),
                toAddress,
                ByteUtil.bigIntegerToBytes(tx.value),
                tx.data);
        transaction.sign(tx.sender.getPrivKeyBytes());
        if (tx.createdContract != null) {
          tx.createdContract.setAddress(transaction.getContractAddress());
        }
        txes.add(transaction);
      }
      Block b = getBlockchain().createNewBlock(parent, txes, Collections.EMPTY_LIST);
      Ethash.getForBlock(b.getNumber()).mineLight(b).get();
      ImportResult importResult = getBlockchain().tryToConnect(b);
      if (importResult != ImportResult.IMPORTED_BEST
          && importResult != ImportResult.IMPORTED_NOT_BEST) {
        throw new RuntimeException(
            "Invalid block import result " + importResult + " for block " + b);
      }
      submittedTxes.clear();
      return b;
    } catch (InterruptedException | ExecutionException e) {
      throw new RuntimeException(e);
    }
  }
    @Override
    public Object[] callConstFunction(Block callBlock, String functionName, Object... args) {

      Transaction tx =
          CallTransaction.createCallTransaction(
              0,
              0,
              100000000000000L,
              Hex.toHexString(getAddress()),
              0,
              contract.getByName(functionName),
              args);
      tx.sign(new byte[32]);

      Repository repository =
          getBlockchain().getRepository().getSnapshotTo(callBlock.getStateRoot()).startTracking();

      try {
        org.ethereum.core.TransactionExecutor executor =
            new org.ethereum.core.TransactionExecutor(
                    tx,
                    callBlock.getCoinbase(),
                    repository,
                    getBlockchain().getBlockStore(),
                    getBlockchain().getProgramInvokeFactory(),
                    callBlock)
                .setLocalCall(true);

        executor.init();
        executor.execute();
        executor.go();
        executor.finalization();

        return contract.getByName(functionName).decodeResult(executor.getResult().getHReturn());
      } finally {
        repository.rollback();
      }
    }
  private BlockchainImpl createBlockchain(Genesis genesis) {
    IndexedBlockStore blockStore = new IndexedBlockStore();
    blockStore.init(new HashMapDB(), new HashMapDB());

    Repository repository = new RepositoryImpl(new HashMapDB(), new HashMapDB());

    ProgramInvokeFactoryImpl programInvokeFactory = new ProgramInvokeFactoryImpl();
    EthereumListenerAdapter listener = new EthereumListenerAdapter();

    BlockchainImpl blockchain = new BlockchainImpl(blockStore, repository);
    blockchain.setParentHeaderValidator(new DependentBlockHeaderRuleAdapter());
    blockchain.setProgramInvokeFactory(programInvokeFactory);
    programInvokeFactory.setBlockchain(blockchain);

    blockchain.byTest = true;

    PendingStateImpl pendingState = new PendingStateImpl(listener, blockchain);

    pendingState.init();

    pendingState.setBlockchain(blockchain);
    blockchain.setPendingState(pendingState);

    Repository track = repository.startTracking();
    for (ByteArrayWrapper key : genesis.getPremine().keySet()) {
      track.createAccount(key.getData());
      track.addBalance(key.getData(), genesis.getPremine().get(key).getBalance());
    }
    for (Pair<byte[], BigInteger> acc : initialBallances) {
      track.createAccount(acc.getLeft());
      track.addBalance(acc.getLeft(), acc.getRight());
    }

    track.commit();

    blockStore.saveBlock(genesis, genesis.getCumulativeDifficulty(), true);

    blockchain.setBestBlock(genesis);
    blockchain.setTotalDifficulty(genesis.getCumulativeDifficulty());

    return blockchain;
  }
Example #7
0
  @Ignore // TODO #POC9
  @Test // contractB call contractA with data to storage
  public void test2() {

    /**
     * #The code will run ------------------
     *
     * <p>contract A: 77045e71a7a2c50903d88e564cd72fab11e82051 --------------- a = msg.data[0] b =
     * msg.data[1]
     *
     * <p>contract.storage[a] contract.storage[b]
     *
     * <p>contract B: 83c5541a6c8d2dbad642f385d8d06ca9b6c731ee ----------- a = msg((tx.gas / 10 *
     * 8), 0x77045e71a7a2c50903d88e564cd72fab11e82051, 0, [11, 22, 33], 3, 6)
     */
    long expectedVal_1 = 11;
    long expectedVal_2 = 22;

    // Set contract into Database
    String callerAddr = "cd2a3d9f938e13cd947ec05abc7fe734df8dd826";

    String contractA_addr = "77045e71a7a2c50903d88e564cd72fab11e82051";
    String contractB_addr = "83c5541a6c8d2dbad642f385d8d06ca9b6c731ee";

    String code_a = "60006020023560005260016020023560205260005160005560205160015500";
    String code_b =
        "6000601f5360e05960e05952600060c05901536060596020015980602001600b9052806040016016905280606001602190526080905260007377045e71a7a2c50903d88e564cd72fab11e820516103e8f1602060000260a00160200151600052";

    byte[] caller_addr_bytes = Hex.decode(callerAddr);

    byte[] contractA_addr_bytes = Hex.decode(contractA_addr);
    byte[] codeA = Hex.decode(code_a);

    byte[] contractB_addr_bytes = Hex.decode(contractB_addr);
    byte[] codeB = Hex.decode(code_b);

    ProgramInvokeMockImpl pi = new ProgramInvokeMockImpl();
    pi.setOwnerAddress(contractB_addr_bytes);
    Repository repository = pi.getRepository();

    repository.createAccount(contractA_addr_bytes);
    repository.saveCode(contractA_addr_bytes, codeA);

    repository.createAccount(contractB_addr_bytes);
    repository.saveCode(contractB_addr_bytes, codeB);

    repository.createAccount(caller_addr_bytes);
    repository.addBalance(caller_addr_bytes, new BigInteger("100000000000000000000"));

    // ****************** //
    //  Play the program  //
    // ****************** //
    VM vm = new VM();
    Program program = new Program(codeB, pi);

    try {
      while (!program.isStopped()) vm.step(program);
    } catch (RuntimeException e) {
      program.setRuntimeFailure(e);
    }

    System.out.println();
    System.out.println("============ Results ============");

    System.out.println("*** Used gas: " + program.getResult().getGasUsed());

    DataWord value_1 = repository.getStorageValue(contractA_addr_bytes, new DataWord(00));
    DataWord value_2 = repository.getStorageValue(contractA_addr_bytes, new DataWord(01));

    repository.close();
    assertEquals(expectedVal_1, value_1.longValue());
    assertEquals(expectedVal_2, value_2.longValue());

    // TODO: check that the value pushed after exec is 1
  }
Example #8
0
  @Ignore
  @Test // contractB call itself with code from contractA
  public void test6() {
    /**
     * #The code will run ------------------
     *
     * <p>contract A: 945304eb96065b2a98b57a48a06ae28d285a71b5 ---------------
     *
     * <p>PUSH1 0 CALLDATALOAD SLOAD NOT PUSH1 9 JUMPI STOP PUSH1 32 CALLDATALOAD PUSH1 0
     * CALLDATALOAD SSTORE
     *
     * <p>contract B: 0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6 ----------- { (MSTORE 0
     * 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) (MSTORE 32
     * 0xaaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaa) [[ 0 ]] (CALLSTATELESS
     * 1000000 0x945304eb96065b2a98b57a48a06ae28d285a71b5 23 0 64 64 0) }
     */

    // Set contract into Database
    byte[] caller_addr_bytes = Hex.decode("cd1722f3947def4cf144679da39c4c32bdc35681");

    byte[] contractA_addr_bytes = Hex.decode("945304eb96065b2a98b57a48a06ae28d285a71b5");
    byte[] contractB_addr_bytes = Hex.decode("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6");

    byte[] codeA = Hex.decode("60003554156009570060203560003555");
    byte[] codeB =
        Hex.decode(
            "7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6000527faaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaa6020526000604060406000601773945304eb96065b2a98b57a48a06ae28d285a71b5620f4240f3600055");

    ProgramInvokeMockImpl pi = new ProgramInvokeMockImpl();
    pi.setOwnerAddress(contractB_addr_bytes);
    pi.setGasLimit(10000000000000l);

    Repository repository = pi.getRepository();
    repository.createAccount(contractA_addr_bytes);
    repository.saveCode(contractA_addr_bytes, codeA);
    repository.addBalance(contractA_addr_bytes, BigInteger.valueOf(23));

    repository.createAccount(contractB_addr_bytes);
    repository.saveCode(contractB_addr_bytes, codeB);
    repository.addBalance(contractB_addr_bytes, new BigInteger("1000000000000000000"));

    repository.createAccount(caller_addr_bytes);
    repository.addBalance(caller_addr_bytes, new BigInteger("100000000000000000000"));

    // ****************** //
    //  Play the program  //
    // ****************** //
    VM vm = new VM();
    Program program = new Program(codeB, pi);

    try {
      while (!program.isStopped()) vm.step(program);
    } catch (RuntimeException e) {
      program.setRuntimeFailure(e);
    }

    System.out.println();
    System.out.println("============ Results ============");
    System.out.println("*** Used gas: " + program.getResult().getGasUsed());

    DataWord memValue1 = program.memoryLoad(new DataWord(0));
    DataWord memValue2 = program.memoryLoad(new DataWord(32));

    DataWord storeValue1 = repository.getStorageValue(contractB_addr_bytes, new DataWord(00));

    repository.close();

    assertEquals(
        "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", memValue1.toString());
    assertEquals(
        "aaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaa", memValue2.toString());

    assertEquals("0x1", storeValue1.shortHex());

    // TODO: check that the value pushed after exec is 1
  }
Example #9
0
  @Ignore // TODO #POC9
  @Test // contract call recursive
  public void test1() {

    /**
     * #The code will run ------------------
     *
     * <p>a = contract.storage[999] if a > 0: contract.storage[999] = a - 1
     *
     * <p># call to contract: 77045e71a7a2c50903d88e564cd72fab11e82051 send((tx.gas / 10 * 8),
     * 0x77045e71a7a2c50903d88e564cd72fab11e82051, 0) else: stop
     */
    int expectedGas = 436;

    DataWord key1 = new DataWord(999);
    DataWord value1 = new DataWord(3);

    // Set contract into Database
    String callerAddr = "cd2a3d9f938e13cd947ec05abc7fe734df8dd826";
    String contractAddr = "77045e71a7a2c50903d88e564cd72fab11e82051";
    String code =
        "6103e75460005260006000511115630000004c576001600051036103e755600060006000600060007377045e71a7a2c50903d88e564cd72fab11e820516008600a5a0402f1630000004c00565b00";

    byte[] contractAddrB = Hex.decode(contractAddr);
    byte[] callerAddrB = Hex.decode(callerAddr);
    byte[] codeB = Hex.decode(code);

    byte[] codeKey = HashUtil.sha3(codeB);
    AccountState accountState = new AccountState(SystemProperties.getDefault());
    accountState.setCodeHash(codeKey);

    ProgramInvokeMockImpl pi = new ProgramInvokeMockImpl();
    pi.setOwnerAddress(contractAddrB);
    Repository repository = pi.getRepository();

    repository.createAccount(callerAddrB);
    repository.addBalance(callerAddrB, new BigInteger("100000000000000000000"));

    repository.createAccount(contractAddrB);
    repository.saveCode(contractAddrB, codeB);
    repository.addStorageRow(contractAddrB, key1, value1);

    // Play the program
    VM vm = new VM();
    Program program = new Program(codeB, pi);

    try {
      while (!program.isStopped()) vm.step(program);
    } catch (RuntimeException e) {
      program.setRuntimeFailure(e);
    }

    System.out.println();
    System.out.println("============ Results ============");

    BigInteger balance = repository.getBalance(callerAddrB);

    System.out.println("*** Used gas: " + program.getResult().getGasUsed());
    System.out.println("*** Contract Balance: " + balance);

    // todo: assert caller balance after contract exec

    repository.close();
    assertEquals(expectedGas, program.getResult().getGasUsed());
  }
Example #10
0
  @Ignore
  @Test // contractB call contractA with return expectation
  public void test3() {

    /**
     * #The code will run ------------------
     *
     * <p>contract A: 77045e71a7a2c50903d88e564cd72fab11e82051 ---------------
     *
     * <p>a = 11 b = 22 c = 33 d = 44 e = 55 f = 66
     *
     * <p>[asm 192 0 RETURN asm]
     *
     * <p>contract B: 83c5541a6c8d2dbad642f385d8d06ca9b6c731ee ----------- a = msg((tx.gas / 10 *
     * 8), 0x77045e71a7a2c50903d88e564cd72fab11e82051, 0, [11, 22, 33], 3, 6)
     */
    long expectedVal_1 = 11;
    long expectedVal_2 = 22;
    long expectedVal_3 = 33;
    long expectedVal_4 = 44;
    long expectedVal_5 = 55;
    long expectedVal_6 = 66;

    // Set contract into Database
    byte[] caller_addr_bytes = Hex.decode("cd2a3d9f938e13cd947ec05abc7fe734df8dd826");

    byte[] contractA_addr_bytes = Hex.decode("77045e71a7a2c50903d88e564cd72fab11e82051");
    byte[] contractB_addr_bytes = Hex.decode("83c5541a6c8d2dbad642f385d8d06ca9b6c731ee");

    byte[] codeA =
        Hex.decode("600b60005260166020526021604052602c6060526037608052604260a05260c06000f2");
    byte[] codeB =
        Hex.decode(
            "6000601f5360e05960e05952600060c05901536060596020015980602001600b9052806040016016905280606001602190526080905260007377045e71a7a2c50903d88e564cd72fab11e820516103e8f1602060000260a00160200151600052");

    ProgramInvokeMockImpl pi = new ProgramInvokeMockImpl();
    pi.setOwnerAddress(contractB_addr_bytes);
    Repository repository = pi.getRepository();
    repository.createAccount(contractA_addr_bytes);
    repository.saveCode(contractA_addr_bytes, codeA);

    repository.createAccount(contractB_addr_bytes);
    repository.saveCode(contractB_addr_bytes, codeB);

    repository.createAccount(caller_addr_bytes);
    repository.addBalance(caller_addr_bytes, new BigInteger("100000000000000000000"));

    // ****************** //
    //  Play the program  //
    // ****************** //
    VM vm = new VM();
    Program program = new Program(codeB, pi);

    try {
      while (!program.isStopped()) vm.step(program);
    } catch (RuntimeException e) {
      program.setRuntimeFailure(e);
    }

    System.out.println();
    System.out.println("============ Results ============");
    System.out.println("*** Used gas: " + program.getResult().getGasUsed());

    DataWord value1 = program.memoryLoad(new DataWord(32));
    DataWord value2 = program.memoryLoad(new DataWord(64));
    DataWord value3 = program.memoryLoad(new DataWord(96));
    DataWord value4 = program.memoryLoad(new DataWord(128));
    DataWord value5 = program.memoryLoad(new DataWord(160));
    DataWord value6 = program.memoryLoad(new DataWord(192));

    repository.close();

    assertEquals(expectedVal_1, value1.longValue());
    assertEquals(expectedVal_2, value2.longValue());
    assertEquals(expectedVal_3, value3.longValue());
    assertEquals(expectedVal_4, value4.longValue());
    assertEquals(expectedVal_5, value5.longValue());
    assertEquals(expectedVal_6, value6.longValue());

    // TODO: check that the value pushed after exec is 1
  }