Skip to content

Commit

Permalink
refactoring Deploy helper and adding new helpers for:
Browse files Browse the repository at this point in the history
- Validator (AuctionBid, AuctionBidWithdraw, ValidatorDelegation and ValidatorDelegationWithdraw)
- Key (createRandom keys)
  • Loading branch information
AB3rtz committed Sep 14, 2022
1 parent 5418a43 commit 7ad8816
Show file tree
Hide file tree
Showing 7 changed files with 533 additions and 99 deletions.
21 changes: 21 additions & 0 deletions src/main/java/com/casper/sdk/helper/CasperConstants.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.casper.sdk.helper;

public enum CasperConstants {
DEFAULT_DEPLOY_TTL((long) 30 * 60 * 1000),
DEFAULT_GAS_PRICE(1),
DEPLOY_TTL_MS_MAX((long) 1000 * 60 * 60 * 24),
MAX_TRANSFER_ID(Long.MAX_VALUE),
MIN_TRANSFER_AMOUNT_MOTES(2500000000L),
STANDARD_PAYMENT_FOR_NATIVE_TRANSFERS((long) 1E8),
STANDARD_PAYMENT_FOR_DELEGATION((long) 5e9),
STANDARD_PAYMENT_FOR_DELEGATION_WITHDRAWAL((long) 5e9),
STANDARD_PAYMENT_FOR_AUCTION_BID((long) 5e9),
STANDARD_PAYMENT_FOR_AUCTION_BID_WITHDRAWAL((long) 5e9);

public final long value;

CasperConstants(long value) {
this.value = value;
}

}
161 changes: 71 additions & 90 deletions src/main/java/com/casper/sdk/helper/CasperDeployHelper.java
Original file line number Diff line number Diff line change
@@ -1,29 +1,22 @@
package com.casper.sdk.helper;

import com.casper.sdk.exception.NoSuchTypeException;
import com.casper.sdk.model.clvalue.CLValueOption;
import com.casper.sdk.model.clvalue.CLValuePublicKey;

import com.casper.sdk.model.clvalue.CLValueByteArray;
import com.casper.sdk.model.clvalue.CLValueU512;
import com.casper.sdk.model.clvalue.CLValueU64;
import com.casper.sdk.model.clvalue.cltype.CLTypeOption;
import com.casper.sdk.model.clvalue.cltype.CLTypePublicKey;
import com.casper.sdk.model.clvalue.cltype.CLTypeU512;
import com.casper.sdk.model.common.Digest;
import com.casper.sdk.model.common.Ttl;
import com.casper.sdk.model.deploy.Approval;
import com.casper.sdk.model.deploy.Deploy;
import com.casper.sdk.model.deploy.DeployHeader;
import com.casper.sdk.model.deploy.NamedArg;
import com.casper.sdk.model.deploy.*;
import com.casper.sdk.model.deploy.executabledeploy.ExecutableDeployItem;
import com.casper.sdk.model.deploy.executabledeploy.ModuleBytes;
import com.casper.sdk.model.deploy.executabledeploy.Transfer;
import com.casper.sdk.model.key.PublicKey;
import com.casper.sdk.model.key.Signature;
import com.syntifi.crypto.key.AbstractPrivateKey;
import com.syntifi.crypto.key.hash.Blake2b;
import dev.oak3.sbs4j.SerializerBuffer;
import dev.oak3.sbs4j.exception.ValueSerializationException;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import lombok.*;

import java.math.BigInteger;
import java.security.GeneralSecurityException;
Expand All @@ -39,113 +32,101 @@
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class CasperDeployHelper {

/**
* Method to generate a Transfer deploy
*
* @param fromPrivateKey sender private Key
* @param toPublicKey receiver public key
* @param amount amount to transfer
* @param chainName network name
* @return Deploy
* @throws NoSuchTypeException thrown if type not found
* @throws GeneralSecurityException thrown when an error occurs with cryptographic keys
*/
public static Deploy buildTransferDeploy(AbstractPrivateKey fromPrivateKey,
PublicKey toPublicKey, BigInteger amount, String chainName)
throws NoSuchTypeException, GeneralSecurityException, ValueSerializationException {
long id = Math.abs(new Random().nextInt());
BigInteger paymentAmount = BigInteger.valueOf(25000000000L);
long gasPrice = 1L;
Ttl ttl = Ttl
public static DeployHeader buildDeployHeader(PublicKey fromPublicKey, String chainName,
Long gasPrice, Ttl ttl, Date date,
List<Digest> dependencies, byte[] bodyHash) {
return DeployHeader
.builder()
.ttl("30m")
.account(fromPublicKey)
.ttl(ttl)
.timeStamp(date)
.gasPrice(gasPrice)
.bodyHash(Digest.digestFromBytes(bodyHash))
.chainName(chainName)
.dependencies(dependencies)
.build();
return CasperDeployHelper.buildTransferDeploy(fromPrivateKey,
toPublicKey, amount, chainName, id, paymentAmount,
gasPrice, ttl, new Date(), new ArrayList<>());
}

public static HashAndSignature signDeployHeader(AbstractPrivateKey privateKey, DeployHeader deployHeader)
throws GeneralSecurityException {
SerializerBuffer serializerBuffer = new SerializerBuffer();

/**
* @param fromPrivateKey private key of the sender
* @param toPublicKey public key of the receiver
* @param amount amount to transfer
* @param id id field in the request to tag the transaction
* @param paymentAmount, the number of motes paying to the execution engine
* @param gasPrice gasPrice for native transfers can be set to 1
* @param ttl time to live in milliseconds (default value is 1800000
* ms (30 minutes))
* @return Deploy
* @throws NoSuchTypeException thrown if type not found
* @throws GeneralSecurityException thrown when an error occurs with cryptographic keys
*/
public static Deploy buildTransferDeploy(AbstractPrivateKey fromPrivateKey, PublicKey toPublicKey,
BigInteger amount, String chainName, Long id, BigInteger paymentAmount,
Long gasPrice, Ttl ttl, Date date, List<Digest> dependencies)
throws NoSuchTypeException, GeneralSecurityException, ValueSerializationException {
deployHeader.serialize(serializerBuffer, true);
byte[] headerHash = Blake2b.digest(serializerBuffer.toByteArray(), 32);
Signature signature = Signature.sign(privateKey, headerHash);
return new HashAndSignature(headerHash, signature);
}

List<NamedArg<?>> transferArgs = new LinkedList<>();
NamedArg<CLTypeU512> amountNamedArg = new NamedArg<>("amount",
new CLValueU512(amount));
transferArgs.add(amountNamedArg);
NamedArg<CLTypePublicKey> publicKeyNamedArg = new NamedArg<>("target",
new CLValuePublicKey(toPublicKey));
transferArgs.add(publicKeyNamedArg);
CLValueOption idArg = new CLValueOption(Optional.of(
new CLValueU64(BigInteger.valueOf(682008))));
NamedArg<CLTypeOption> idNamedArg = new NamedArg<>("id", idArg);
transferArgs.add(idNamedArg);

Transfer session = Transfer
.builder()
.args(transferArgs)
.build();
public static byte[] getDeployItemAndModuleBytesHash(ExecutableDeployItem deployItem, ModuleBytes moduleBytes)
throws NoSuchTypeException, ValueSerializationException {
SerializerBuffer ser = new SerializerBuffer();
moduleBytes.serialize(ser, true);
deployItem.serialize(ser, true);
return Blake2b.digest(ser.toByteArray(), 32);
}

public static ModuleBytes getPaymentModuleBytes(BigInteger paymentAmount) {
List<NamedArg<?>> paymentArgs = new LinkedList<>();
NamedArg<CLTypeU512> paymentArg = new NamedArg<>("amount",
new CLValueU512(paymentAmount));
paymentArgs.add(paymentArg);

ModuleBytes payment = ModuleBytes
return ModuleBytes
.builder()
.args(paymentArgs)
.bytes("")
.bytes(new byte[]{})
.build();
SerializerBuffer ser = new SerializerBuffer();
payment.serialize(ser, true);
session.serialize(ser, true);
byte[] sessionAnPaymentHash = Blake2b.digest(ser.toByteArray(), 32);
ser.getBuffer().reset();
}

/**
* Core method to fully build a deploy
*
* @param fromPrivateKey private key of the sender
* @param chainName name of chain
* @param session item to deploy ExecutableDeployItems
* @param payment Module bytes as another ExecuteDeployItems
* @param gasPrice gasPrice for native transfers can be set to 1
* @param ttl time to live in milliseconds (default value is 1800000
* ms (30 minutes))
* @param date deploy date
* @param dependencies list of digest dependencies
* @return
* @throws NoSuchTypeException
* @throws GeneralSecurityException
* @throws ValueSerializationException
*/
public static Deploy buildDeploy(AbstractPrivateKey fromPrivateKey, String chainName,
ExecutableDeployItem session, ModuleBytes payment,
Long gasPrice, Ttl ttl, Date date, List<Digest> dependencies)
throws NoSuchTypeException, GeneralSecurityException, ValueSerializationException {

byte[] sessionAnPaymentHash = getDeployItemAndModuleBytesHash(session, payment);

PublicKey fromPublicKey = PublicKey.fromAbstractPublicKey(fromPrivateKey.derivePublicKey());

DeployHeader deployHeader = DeployHeader
.builder()
.account(fromPublicKey)
.ttl(ttl)
.timeStamp(date)
.gasPrice(gasPrice)
.bodyHash(Digest.digestFromBytes(sessionAnPaymentHash))
.chainName(chainName)
.dependencies(dependencies)
.build();
deployHeader.serialize(ser, true);
byte[] headerHash = Blake2b.digest(ser.toByteArray(), 32);
DeployHeader deployHeader = buildDeployHeader(fromPublicKey, chainName, gasPrice, ttl,
date, dependencies, sessionAnPaymentHash);

Signature signature = Signature.sign(fromPrivateKey, headerHash);
HashAndSignature hashAndSignature = signDeployHeader(fromPrivateKey, deployHeader);

List<Approval> approvals = new LinkedList<>();
approvals.add(Approval.builder()
.signer(PublicKey.fromAbstractPublicKey(fromPrivateKey.derivePublicKey()))
.signature(signature)
.signature(hashAndSignature.getSignature())
.build());

return Deploy.builder()
.hash(Digest.digestFromBytes(headerHash))
.hash(Digest.digestFromBytes(hashAndSignature.getHash()))
.header(deployHeader)
.payment(payment)
.session(session)
.approvals(approvals)
.build();
}

@Getter
@AllArgsConstructor
private static class HashAndSignature {
byte[] hash;
Signature signature;
}
}
3 changes: 1 addition & 2 deletions src/main/java/com/casper/sdk/helper/CasperKeyHelper.java
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
package com.casper.sdk.helper;

import com.casper.sdk.model.key.AlgorithmTag;
import com.syntifi.crypto.key.*;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;

import java.io.IOException;

/**
* Key service provides methods to easily work with private and public keys
* Key helper provides methods to easily work with private and public keys
*
* @author Alexandre Carvalho
* @author Andre Bertolace
Expand Down
106 changes: 106 additions & 0 deletions src/main/java/com/casper/sdk/helper/CasperTransferHelper.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
package com.casper.sdk.helper;

import com.casper.sdk.exception.NoSuchTypeException;
import com.casper.sdk.model.clvalue.CLValueOption;
import com.casper.sdk.model.clvalue.CLValuePublicKey;
import com.casper.sdk.model.clvalue.CLValueU512;
import com.casper.sdk.model.clvalue.CLValueU64;
import com.casper.sdk.model.clvalue.cltype.CLTypeOption;
import com.casper.sdk.model.clvalue.cltype.CLTypePublicKey;
import com.casper.sdk.model.clvalue.cltype.CLTypeU512;
import com.casper.sdk.model.common.Digest;
import com.casper.sdk.model.common.Ttl;
import com.casper.sdk.model.deploy.Deploy;
import com.casper.sdk.model.deploy.NamedArg;
import com.casper.sdk.model.deploy.executabledeploy.ModuleBytes;
import com.casper.sdk.model.deploy.executabledeploy.Transfer;
import com.casper.sdk.model.key.PublicKey;
import com.syntifi.crypto.key.AbstractPrivateKey;
import dev.oak3.sbs4j.exception.ValueSerializationException;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;

import java.math.BigInteger;
import java.security.GeneralSecurityException;
import java.util.*;

/**
* Transfer helper provides methods to easily transfer from/to purses
*
* @author Alexandre Carvalho
* @author Andre Bertolace
* @since 0.5.0
*/
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class CasperTransferHelper {
/**
* Helper method to create a Deploy for a Transfer
*
* @param from private key from sender
* @param to public key from signer
* @param amount amount to transfer
* @param chainName chain name
* @return a transfer deploy
* @throws NoSuchTypeException
* @throws GeneralSecurityException
* @throws ValueSerializationException
*/
public static Deploy buildTransferDeploy(AbstractPrivateKey from, PublicKey to,
BigInteger amount, String chainName)
throws NoSuchTypeException, GeneralSecurityException, ValueSerializationException {
long id = Math.abs(new Random().nextInt());
Ttl ttl = Ttl
.builder()
.ttl(CasperConstants.DEFAULT_DEPLOY_TTL.value / 60 / 1000 + "m")
.build();
BigInteger paymentAmount = BigInteger.valueOf(CasperConstants.STANDARD_PAYMENT_FOR_NATIVE_TRANSFERS.value);
return buildTransferDeploy(from, to, amount, chainName, id, paymentAmount,
CasperConstants.DEFAULT_GAS_PRICE.value, ttl, new Date(), new ArrayList<>());
}

/**
* Helper method to create a Deploy for a Transfer
*
* @param signer private key from sender
* @param to public key from signer
* @param amount amount to transfer
* @param chainName chain name
* @param id deploy id
* @param paymentAmount payment amount for processing transfers
* @param gasPrice gas price
* @param ttl time to live
* @param date execution date
* @param dependencies List of digest dependencies
* @return a transfer deploy
* @throws NoSuchTypeException
* @throws GeneralSecurityException
* @throws ValueSerializationException
*/
public static Deploy buildTransferDeploy(AbstractPrivateKey signer, PublicKey to, BigInteger amount,
String chainName, Long id, BigInteger paymentAmount,
Long gasPrice, Ttl ttl, Date date, List<Digest> dependencies)
throws NoSuchTypeException, GeneralSecurityException, ValueSerializationException {
List<NamedArg<?>> transferArgs = new LinkedList<>();
NamedArg<CLTypeU512> amountNamedArg = new NamedArg<>("amount",
new CLValueU512(amount));
transferArgs.add(amountNamedArg);
NamedArg<CLTypePublicKey> publicKeyNamedArg = new NamedArg<>("target",
new CLValuePublicKey(to));
transferArgs.add(publicKeyNamedArg);
CLValueOption idArg = new CLValueOption(Optional.of(
new CLValueU64(BigInteger.valueOf(id))));
NamedArg<CLTypeOption> idNamedArg = new NamedArg<>("id", idArg);
transferArgs.add(idNamedArg);

Transfer session = Transfer
.builder()
.args(transferArgs)
.build();
ModuleBytes payment = CasperDeployHelper.getPaymentModuleBytes(paymentAmount);

return CasperDeployHelper.buildDeploy(signer, chainName, session, payment, gasPrice, ttl,
date, dependencies);
}


}
Loading

0 comments on commit 7ad8816

Please sign in to comment.