java4ever is a Java 19 suite for smart-contracts development, testing & accessing DApps for Everscale blockchain network much like web3j for Ethereum and close to Truffle, Hardhat & locklift.
With java4ever you can connect your enterprise services on Java to most scalable smart-contract network. It is also suitable for any Everscale forks like GOSH or Venom.
With java4ever you get:
- Complete implementation of Everscale EVER-SDK JSON-RPC API
- All main Multisig Wallets variations support (easy deploy & calls)
- Pluggable EVER-SDK client library support (no rebuild needed, just plug-in SDK lib you like)
- Maven/Gradle support (deployed to Maven Central)
- TIP 3.2 Fungible Tokens helpers (easy deploy & calls)
- EverNodeSE Giver helpers (and you can polymorph to Multisig Givers with no code change or implement custom)
- Powerful auto-conversion between Java types & ABI expectations
- Transaction tree of a complex call can be accessed
java4ever uses blocking code (that is now a best practice due to Loom Structured Concurrency). Framework internally uses JSON-RPC connection to native EVER-SDK library binded to Java (java4ever-binding).
- Install JDK 19 or higher (link)
- Build EVER-SDK binary lib "ton_client"(.so/.dll) (or get precomiled one)
- Gradle
dependencies {
implementation 'tech.deplant.java4ever:java4ever-framework:1.6.2'
}- Maven
<dependency>
<groupId>tech.deplant.java4ever</groupId>
<artifactId>java4ever-framework</artifactId>
<version>1.6.2</version>
</dependency>You can add "ton_client" lib by multiple ways:
- Specify absolute path to your library in code:
varsdk1 = newSdkBuilder().create(newAbsolutePathLoader("c:/opt/sdk/ton_client.dll"));- Specify absolute path in system env variables:
varsdk2 = newSdkBuilder().create(AbsolutePathLoader.ofSystemEnv("TON_CLIENT_LIB_PATH"));- Place it in build current dir and specify filename in code:
varsdk3 = newSdkBuilder().create(AbsolutePathLoader.ofUserDir("ton_client.so"));- Use
-Djava.library.pathparameter to VM and then specify only lib name:
varsdk4 = newSdkBuilder().create(newJavaLibraryPathLoader("ton_client"));varsdkDev = newSdkBuilder()
.networkEndpoints("https://devnet-sandbox.evercloud.dev/graphql")
.create(JavaLibraryPathLoader.TON_CLIENT);varkeys = Credentials.RANDOM(sdk);
Stringsk = keys.secretKey();
Stringpk = keys.publicKey();varseed = Seed.RANDOM(sdk);
StringwordsPhrase = seed.phrase();
intwordsCount = seed.words();
varkeys = Credentials.ofSeed(sdk,seed);
Stringsk = keys.secretKey();
Stringpk = keys.publicKey();varkeysOfContract = newCredentials("1fae0df1eee24bc61fbb9230bdac07503b77ceac7700651bec8250df97b6f94f",
"8b55abc280dd0b741d78961b0f8f4d8d235f30f122bc5829b6e598e71331c01c");
OwnedContractmyContract = newOwnedContract(sdk,
newAddress("0:273642fe57e282432bda8f16c69ea19a94b13db05986e11585a5121bcfec3fe0"),
ContractAbi.ofFile("~/MyContract.abi.json"),
keysOfContract);Map<String, Object> functionInputs = Map.of();
Abi.FunctionHeaderheader = null;
myContract.runGetter("getOwner",functionInputs,header).get("value0");Map<String, Object> functionInputs = Map.of();
Abi.FunctionHeaderheader = null;
myContract.callExternal("getOwner",functionInputs,header).get("value0");Map<String, Object> functionInputs = Map.of();
Abi.FunctionHeaderheader = null;
Stringpayload = myContract.encodeInternalPayload("publishCustomTask",functionInputs,header);
varaddressOfMsig = newAddress("0:273642fe57e282432bda8f16c69ea19a94b13db05986e11585a5121bcfec3fe0");
varkeysOfMsig = newCredentials("1fae0df1eee24bc61fbb9230bdac07503b77ceac7700651bec8250df97b6f94f",
"8b55abc280dd0b741d78961b0f8f4d8d235f30f122bc5829b6e598e71331c01c");
BigIntegersendValue = EVER.amount();
Msigmsig = newMsig(sdk,addressOfMsig,keysOfMsig);
msig.send(myContract.address(),sendValue,true,0,payload); // sends internal message with payloadContractTemplatetemplate = newContractTemplate(ContractAbi.ofFile("~/MyContract.abi.json"),
ContractTvc.ofFile("~/MyContract.tvc"));
MsigTemplatesafeTemplate = MsigTemplate.SAFE(); // msig templates are includedCredentialskeys = Credentials.RANDOM(sdk);
Map<String, Object> initialData = Map.of("initDataParam1","helloWorld!"); // one static initData varMap<String, Object> constructorInputs = Map.of(); // no inputsOwnedContractcontract = template.deploy(sdk,0,initialData,keys,constructorInputs);MsigTemplatesafeTemplate = MsigTemplate.SAFE();
Givergiver = null;
if(isEverOsNet()){
giver = newEverOSGiver(SDK);
}else{
giver = Msig.ofSafe(SDK,
newAddress("0:bd7a935b78f85929bc870e466a948f5b9927ac17299f9e45213c598979b83bef"),
keysOfMsig);
}
safeTemplate.deploySingleSig(SDK,
Credentials.RANDOM(SDK),
giver,
EVER.amount());ContractAbiabi1 = template.abi();
ContractAbiabi2 = ContractAbi.ofFile("~/MyContract.abi.json");
booleanhasSend = abi1.hasFunction("sendTransaction");
StringabiType = abi2.functionOutputType("getBalance","value0").type();ContractTvctvc1 = template.tvc();
ContractTvctvc2 = ContractTvc.ofFile("~/MyContract.tvc");
Credentialskeys = Credentials.RANDOM(sdk);
Map<String, Object> initialData = Map.of("initDataParam1","helloWorld!"); // one static initData varContractTvctvc1update = tvc1.withUpdatedInitialData(sdk,template.abi(),initialData,keys.publicKey());java4ever-framework uses the JDK Platform Loggging (JEP 264: Platform Logging API and Service), so can be easily bridged to any logging framework.