Skip to content

Commit

Permalink
initial version of Blockchain module;
Browse files Browse the repository at this point in the history
for convenience added:
isDeployed(Address address)
waitForDeployment(Address address, int timeoutSeconds)
waitForBalanceChange(Address address, int timeoutSeconds)
to Tonlib;
  • Loading branch information
neodix42 committed Oct 28, 2024
1 parent 4529648 commit 14fc1d2
Show file tree
Hide file tree
Showing 15 changed files with 1,005 additions and 495 deletions.
38 changes: 38 additions & 0 deletions blockchain/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
target/
!.mvn/wrapper/maven-wrapper.jar
!**/src/main/**/target/
!**/src/test/**/target/

### IntelliJ IDEA ###
.idea/modules.xml
.idea/jarRepositories.xml
.idea/compiler.xml
.idea/libraries/
*.iws
*.iml
*.ipr

### Eclipse ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache

### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
build/
!**/src/main/**/build/
!**/src/test/**/build/

### VS Code ###
.vscode/

### Mac OS ###
.DS_Store
136 changes: 136 additions & 0 deletions blockchain/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
<?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>
<parent>
<groupId>io.github.neodix42</groupId>
<artifactId>top</artifactId>
<version>0.7.1</version>
</parent>

<artifactId>blockchain</artifactId>
<name>TON Java Blockchain</name>

<description>The comprehensive Java TON development framework.</description>

<url>https://github.com/neodiX42/ton4j</url>

<licenses>
<license>
<name>GNU General Public License v3.0</name>
<url>https://www.gnu.org/licenses/gpl-3.0.html</url>
</license>
</licenses>

<developers>
<developer>
<name>neodiX</name>
<email>[email protected]</email>
</developer>
</developers>

<scm>
<connection>scm:git:git://github.com/neodiX42/ton4j.git</connection>
<developerConnection>scm:git:ssh://github.com/neodiX42/ton4j.git</developerConnection>
<url>https://github.com/neodiX42/ton4j/tree/main</url>
</scm>

<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>

<dependencies>
<dependency>
<groupId>io.github.neodix42</groupId>
<artifactId>smartcontract</artifactId>
<version>${project.parent.version}</version>
</dependency>
<dependency>
<groupId>io.github.neodix42</groupId>
<artifactId>emulator</artifactId>
<version>${project.parent.version}</version>
</dependency>
<dependency>
<groupId>io.github.neodix42</groupId>
<artifactId>utils</artifactId>
<version>${project.parent.version}</version>
</dependency>
<dependency>
<groupId>io.github.neodix42</groupId>
<artifactId>func</artifactId>
<version>${project.parent.version}</version>
</dependency>
<dependency>
<groupId>io.github.neodix42</groupId>
<artifactId>fift</artifactId>
<version>${project.parent.version}</version>
</dependency>
<dependency>
<groupId>io.github.neodix42</groupId>
<artifactId>tonconnect</artifactId>
<version>${project.parent.version}</version>
</dependency>
<dependency>
<groupId>io.github.neodix42</groupId>
<artifactId>tonlib</artifactId>
<version>${project.parent.version}</version>
</dependency>
<dependency>
<groupId>io.github.neodix42</groupId>
<artifactId>bitstring</artifactId>
<version>${project.parent.version}</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>${commons-io.version}</version>
</dependency>
<!-- recompiled from source with Java 8 -->
<dependency>
<groupId>io.github.neodix42</groupId>
<artifactId>tweetnacl-java-8</artifactId>
<version>0.4.7</version>
<scope>compile</scope>
</dependency>
<!-- test -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.vmlens</groupId>
<artifactId>concurrent-junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
</dependency>
</dependencies>

</project>
203 changes: 203 additions & 0 deletions blockchain/src/main/java/org/ton/java/Blockchain.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,203 @@
package org.ton.java;

import static java.util.Objects.isNull;
import static java.util.Objects.nonNull;

import java.math.BigInteger;
import lombok.Builder;
import lombok.extern.slf4j.Slf4j;
import org.ton.java.address.Address;
import org.ton.java.emulator.tvm.TvmEmulator;
import org.ton.java.emulator.tvm.TvmVerbosityLevel;
import org.ton.java.emulator.tx.TxEmulator;
import org.ton.java.emulator.tx.TxEmulatorConfig;
import org.ton.java.emulator.tx.TxVerbosityLevel;
import org.ton.java.fift.FiftRunner;
import org.ton.java.func.FuncRunner;
import org.ton.java.smartcontract.SmartContractCompiler;
import org.ton.java.smartcontract.faucet.TestnetFaucet;
import org.ton.java.smartcontract.wallet.Contract;
import org.ton.java.tlb.types.Message;
import org.ton.java.tonlib.Tonlib;
import org.ton.java.tonlib.types.ExtMessageInfo;
import org.ton.java.utils.Utils;

@Slf4j
@Builder
public class Blockchain {

private FuncRunner funcRunner;
private FiftRunner fiftRunner;
private Tonlib tonlib;
private Network network;
TxEmulatorConfig txEmulatorConfig;
TxVerbosityLevel txVerbosityLevel;
TvmVerbosityLevel tvmVerbosityLevel;
Contract standardContract;
String customContractPath;
String customContractAsResource;
private static SmartContractCompiler smartContractCompiler;
private static TxEmulator txEmulator;
private static TvmEmulator tvmEmulator;

public static class BlockchainBuilder {}

public static BlockchainBuilder builder() {
return new CustomBlockchainBuilder();
}

private static class CustomBlockchainBuilder extends BlockchainBuilder {
@Override
public Blockchain build() {
try {

smartContractCompiler =
SmartContractCompiler.builder()
.fiftRunner(super.fiftRunner)
.funcRunner(super.funcRunner)
.build();

if (isNull(super.tonlib)) {
if (super.network == Network.MAINNET) {
super.tonlib = Tonlib.builder().testnet(false).ignoreCache(false).build();
} else if (super.network == Network.TESTNET) {
super.tonlib = Tonlib.builder().testnet(true).ignoreCache(false).build();
}
}

if (super.network == Network.EMULATOR) {
tvmEmulator =
TvmEmulator.builder()
.codeBoc("a")
.dataBoc("a")
.verbosityLevel(super.tvmVerbosityLevel)
.build();

txEmulator = TxEmulator.builder().verbosityLevel(super.txVerbosityLevel).build();
}
if (isNull(super.funcRunner)) {
super.funcRunner = FuncRunner.builder().build();
}

if (isNull(super.fiftRunner)) {
super.fiftRunner = FiftRunner.builder().build();
}

if (super.network == Network.EMULATOR) {
log.info(
String.format(
"\nJava Blockchain configuration:\n"
+ "Target network: %s\n"
+ "Emulator location: %s, configType: %s, txVerbosity: %s, tvmVerbosity: %s\n"
+ "Tonlib location: %s\n"
+ "Tonlib global config: %s\n"
+ "Func location: %s\n"
+ "Fift location: %s, FIFTPATH=%s\n"
+ "Contract: %s\n",
super.network,
txEmulator.pathToEmulatorSharedLib,
super.txEmulatorConfig,
super.txVerbosityLevel,
super.tvmVerbosityLevel,
super.tonlib.pathToTonlibSharedLib,
super.tonlib.pathToGlobalConfig,
super.funcRunner.funcExecutablePath,
super.fiftRunner.fiftExecutablePath,
super.fiftRunner.getLibsPath(),
nonNull(super.standardContract)
? "standard contract"
: isNull(super.customContractPath)
? "integrated resource: " + super.customContractAsResource
: super.customContractPath));
} else {
log.info(
String.format(
"Java Blockchain configuration:\n"
+ "Target network: %s\n"
+ "Emulator not used\n"
+ "Tonlib location: %s\n"
+ "Tonlib global config: %s\n"
+ "Func location: %s\n"
+ "Fift location: %s, FIFTPATH=%s\n"
+ "Contract: %s\n",
super.network,
super.tonlib.pathToTonlibSharedLib,
super.tonlib.pathToGlobalConfig,
super.funcRunner.getFuncPath(),
super.fiftRunner.getFiftPath(),
super.fiftRunner.getLibsPath(),
nonNull(super.standardContract)
? "standard contract " + super.standardContract.getName()
: isNull(super.customContractPath)
? "integrated resource at " + super.customContractAsResource
: super.customContractPath));
}
} catch (Exception e) {
throw new RuntimeException("Error creating blockchain instance: " + e.getMessage());
}
return super.build();
}
}

public void deploy(int waitForDeploymentSeconds) {
log.info("deploying on {}", network);
try {
Address address = standardContract.getAddress();
String nonBounceableAddress;
if (nonNull(standardContract)) {
standardContract.getTonlib();
if (network == Network.MAINNET || network == Network.TESTNET) {
ExtMessageInfo result;

if (waitForDeploymentSeconds != 0) {
if (network == Network.MAINNET) {

nonBounceableAddress = address.toNonBounceable();
log.info(
"waiting {}s for toncoins to be deposited to address {}",
waitForDeploymentSeconds,
nonBounceableAddress);
tonlib.waitForBalanceChange(address, waitForDeploymentSeconds);
log.info("now sending external message with deploy instructions...");
Message msg = standardContract.prepareDeployMsg();
result = tonlib.sendRawMessage(msg.toCell().toBase64());
assert result.getError().getCode() != 0;
tonlib.waitForDeployment(address, waitForDeploymentSeconds);
log.info(
"{} deployed at address {}", standardContract.getName(), nonBounceableAddress);
} else {
nonBounceableAddress = address.toNonBounceableTestnet();
log.info("topping up {} with 0.1 toncoin from TestnetFaucet", nonBounceableAddress);
BigInteger newBalance =
TestnetFaucet.topUpContract(
tonlib, Address.of(standardContract.getAddress()), Utils.toNano(0.1));
log.info("topped up successfully, new balance {}", Utils.formatNanoValue(newBalance));
log.info("now sending external message with deploy instructions...");
Message msg = standardContract.prepareDeployMsg();
result = tonlib.sendRawMessage(msg.toCell().toBase64());
if (result.getError().getCode() != 0) {
throw new Error(
"Cannot send external message. Error: " + result.getError().getMessage());
}

tonlib.waitForDeployment(address, waitForDeploymentSeconds);
log.info(
"{} deployed at address {}", standardContract.getName(), nonBounceableAddress);
}
}
} else {
tvmEmulator =
TvmEmulator.builder()
.codeBoc(standardContract.createCodeCell().toBase64())
.dataBoc(standardContract.createDataCell().toBase64())
.verbosityLevel(tvmVerbosityLevel)
.build();

txEmulator = TxEmulator.builder().verbosityLevel(txVerbosityLevel).build();
}
}
} catch (Exception e) {
throw new Error("Cannot deploy the contract on " + network + ". Error " + e.getMessage());
}
}
}
7 changes: 7 additions & 0 deletions blockchain/src/main/java/org/ton/java/Network.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package org.ton.java;

public enum Network {
MAINNET,
TESTNET,
EMULATOR;
}
Loading

0 comments on commit 14fc1d2

Please sign in to comment.