Java
Get Started
Prerequisite and Requirements
$ java -version
java 17.0.1 2021-10-19 LTS
Java(TM) SE Runtime Environment (build 17.0.1+12-LTS-39)
Java HotSpot(TM) 64-Bit Server VM (build 17.0.1+12-LTS-39, mixed mode, sharing)
$ javac -version
javac 17.0.1
Installation
mitum-java-util-4.1.1-jdk17.jar
.implementation files('./lib/mitum-java-util-4.1.1-jdk17.jar')
Make Your First Operation
create an account
by mitum-java-util.Get Available Account
1. pairs of (public key, weight); aka `keys`
- public key has suffix `mpu`
- The range of each weight should be in 1 <= weight <= 100
- If an account have single public key, the account is called 'single-sig account', or it's called 'multi-sig account'
2. threshold
- The range of threshold should be in 1 <= threshold <= 100
- The sum of all weights of the account should be over or equal to threshold
sender
.Create Generator
Generator
.Generator.currency
.Generator
, network id
should be provided.network id
is up to each network.mitum
./*
import org.mitumc.sdk.Generator
*/
String id = "mitum";
Generator generator = Generator.get(id);
Generator
, go to Major Classes and refer to Generator.Create Operation Item
sender
, token
, etc…1. The keys and threshold of the account will be,
- keys(public key, weight): (kpYjRwq6gQrjvzeqQ91MNiCcR9Beb9sD67SuhQ6frPGwmpu, 50), (pWoFhRP3C7ocebSRPxTPfeaJZpnyKpEkxQqi6fAD4SHompu, 50)
- threshold: 100
2. The initial balance of the account will be,
- balance(currency id, amount): (MCC, 10000), (PEN, 20000)
/*
import org.mitumc.sdk.key.*;
import org.mitumc.sdk.operation.Amount;
import org.mitumc.sdk.operation.currency.*;
*/
Key key1 = Key.get("kpYjRwq6gQrjvzeqQ91MNiCcR9Beb9sD67SuhQ6frPGwmpu", 50);
Key key2 = Key.get("pWoFhRP3C7ocebSRPxTPfeaJZpnyKpEkxQqi6fAD4SHompu", 50);
Keys keys = Keys.get(new Key[]{ key1, key2 }, 100);
Amount amount1 = Amount.get("MCC", "10000");
Amount amount2 = Amount.get("PEN", "20000");
CreateAccountsItem item = generator.currency.getCreateAccountsItem(keys, new Amount[]{ amount1, amount2 }); // newCreateAccountsItem(keys, amount list)
First, create each key by
Key.get(public key, weight)
.Second, combine all keys with account threshold by
Keys.get(key list, threshold)
.Third, create each amount by
Amount.get(currencyId, amount)
.Finally, create an item by
Generator.currency.getCreateAccountsItem(keys, amount list)
- `Keys` created by `keys` can contain up to 10 key pairs.
- `Amount list` s.t each amount created by `amounts` can contain up to 10 in one item.
- Moreover, a `fact` can contain multiple items. The number of items in a fact is up to 10, either.
Create Operation Fact
items
, sender
, token
, and fact hash
.token
and fact hash
because they will be filled automatically by SDK.items
and sender
.sender
.1. The account which has been created already.
2. The account which has sufficient balance of currencies in items.
3. The account that you(or owners of the account) know its private keys corresponding account public keys.
/*
import org.mitumc.sdk.operation.currency.*;
*/
String senderAddress = "CY1pkxsqQK6XMbnK4ssDNbDR2K7mitSwdS27DwBjd3Gcmca"; // sender's account address; replace with your address
CreateAccountsFact fact = generator.currency.getCreateAccountsFact(senderAddress, new CreateAccountsItem[]{ item }); // newCreateAccountsFact(sender address, item list)
Generator.currency.getCreateAccountsFact(sender's address, item list)
as an array.Create Operation
fact_signs
as a fact signature.fact_signs
should exceed or be equal to the sender
’s threshold.memo
in operation but it is not necessary. You can enter something if you need, but be careful because that memo
also affects the operation hash
.sender
is a single-sig account which means only a single key exists in the sender’s account.sender
is a multi-sig account, you may add multiple signatures to fact_signs
./*
import org.mitumc.sdk.operation.Operation;
*/
String senderPrivateKey = "KxD8T82nfwsUmQu3iMXENm93YTTatGFp1AYDPqTo5e6ycvY1xNXpmpr";
Operation operation = generator.getOperation(fact);
operation.sign(senderPrivateKey);
Generator.getOperation(fact, memo)
for create operations, not Generator.currency.newOperation(fact, memo)
.Create Seal
operation
itself is enough to create an account.String signKey = "KzafpyGojcN44yme25UMGvZvKWdMuFv1SwEhsZn8iF8szUz16jskmpr";
HashMap<String, Object> seal = gn.getSeal(signKey, new Operation[]{ operation }); // getSeal(sign key, operation list)
getOperation
, use Generator.getSeal(signer, operation list)
.Support Operations
Model |
Support Operations |
---|---|
Currency |
create account, key updater, transfer |
Currency Extension |
create contract account, withdraw |
Document |
create document, update document, (sign document) |
Feefi |
pool register, pool policy updater, pool deposit, pool withdraw |
NFT |
collection register, collection policy updater, mint, transfer, burn, sign, approve, delegate |
Currency
Create Account
create-account
have been already explained but it’ll be re-introduced in one code-block.The information of the new account: account keys as pairs of (public key, weight), threshold, initial balance as pairs of (currency id, amount).
Sender’s account that has existed already - especially sender’s account address and private keys.
/*
import org.mitumc.sdk.key.*;
import org.mitumc.sdk.Generator;
import org.mitumc.sdk.operation.*;
import org.mitumc.sdk.operation.currency.*;
*/
String senderPrivateKey = "KzafpyGojcN44yme25UMGvZvKWdMuFv1SwEhsZn8iF8szUz16jskmpr";
String senderAddress = "FcLfoPNCYjSMnxLPiQJQFGTV15ecHn3xY4J2HNCrqbCfmca";
Generator gn = Generator.get("mitum"); // network id: mitum
Key key = Key.get("knW2wVXH399P9Xg8aVjAGuMkk3uTBZwcSpcy4aR3UjiAmpu", 100);
Keys keys = Keys.get(new Key[]{ key }, 100); // becomes single-sig account
Amount amount = Amount.get("MCC", "1000");
CreateAccountsItem item = gn.currency.getCreateAccountsItem(keys, new Amount[]{ amount });
CreateAccountsFact fact = gn.currency.getCreateAccountsFact(senderAddress, new CreateAccountsItem[]{ item });
Operation createAccount = gn.getOperation(fact);
createAccount.sign(senderPrivateKey);
Key Updater
- I have an single sig account with keys: (kpYjRwq6gQrjvzeqQ91MNiCcR9Beb9sD67SuhQ6frPGwmpu, 100), threshold: 100
- But I want to replace keys of the account with keys: (22ndFZw57ax28ydC3ZxzLJMNX9oMSqAfgauyWhC17pxDpmpu, 50), (22wD5RWsRFAr8mHkYmmyUDzKf6VBNgjHcgc3YhKxCvrZDmpu, 50), threshold: 100
- Then you can use key-updater operation to reach the goal!
The account(target) information you want to change the keys - account address and private keys; what private keys need is up to threshold and key weights.
New keys: pairs of (public key, weights) and threshold
Sufficient balance in a currency id to pay a fee.
create-account
and transfer
need item
to create an operation but key-updater
don’t need any item for it./*
import org.mitumc.sdk.key.*;
import org.mitumc.sdk.Generator;
import org.mitumc.sdk.operation.*;
import org.mitumc.sdk.operation.currency.*;
*/
Generator gn = Generator.get("mitum"); // network id: mitum
String targetPrivateKey = "KzejtzpPZFdLUXo2hHouamwLoYoPtoffKo5zwoJXsBakKzSvTdbzmpr";
String targetAddress = "JDhSSB3CpRjwM8aF2XX23nTpauv9fLhxTjWsQRm9cJ7umca";
Key key1 = Key.get("22ndFZw57ax28ydC3ZxzLJMNX9oMSqAfgauyWhC17pxDpmpu", 50);
Key key2 = Key.get("22wD5RWsRFAr8mHkYmmyUDzKf6VBNgjHcgc3YhKxCvrZDmpu", 50);
Keys newKeys = Keys.get(new Key[]{ key1, key2 }, 100);
KeyUpdaterFact fact = gn.currency.getKeyUpdaterFact(targetAddress, "MCC", newKeys);
Operation keyUpdater = gn.getOperation(fact);
keyUpdater.sign(targetPrivateKey);
After updating keys of the account, the keys used before become useless. You should sign operation with private keys of new keypairs of the account.
So record new private keysthreshold somewhere else before sending a key-updater operation to the network.
Transfer
Sender’s account information - account address, and private keys
Pairs of (currency id, amount) to transfer
create-account
, you must create item before making fact.1000000 MCC token
15000 PEN token
CY1pkxsqQK6XMbnK4ssDNbDR2K7mitSwdS27DwBjd3Gcmca
/*
import org.mitumc.sdk.Generator;
import org.mitumc.sdk.operation.*;
import org.mitumc.sdk.operation.currency.*;
*/
Generator gn = Generator.get("mitum"); // network id: mitum
String senderPrivateKey = "KzdeJMr8e2fbquuZwr9SEd9e1ZWGmZEj96NuAwHnz7jnfJ7FqHQBmpr";
String senderAddress = "2D5vAb2X3Rs6ZKPjVsK6UHcnGxGfUuXDR1ED1hcvUHqsmca";
String receiverAddress = "CY1pkxsqQK6XMbnK4ssDNbDR2K7mitSwdS27DwBjd3Gcmca";
Amount amount1 = Amount.get("MCC", "100000")
Amount amount2 = Amount.get("PEN", "15000")
TransfersItem item = gn.currency.getTransfersItem(receiverAddress, new Amount[]{ amount1, amount2 }); // getTransfersItem(receiver address, amount list)
TransfersFact fact = gn.currency.getTransfersFact(senderAddress, new TransfersItem[]{ item }); // getTransfersFact(sender address, item list)
Operation transfer = gn.getOperation(fact);
transfer.sign(senderPrivateKey); // suppose sender is single-sig
Currency Extension
Create Contract Account
/*
import org.mitumc.sdk.key.*;
import org.mitumc.sdk.Generator;
import org.mitumc.sdk.operation.*;
import org.mitumc.sdk.operation.currency.*;
import org.mitumc.sdk.operation.currency.extension.*;
*/
String senderPrivateKey = "KzafpyGojcN44yme25UMGvZvKWdMuFv1SwEhsZn8iF8szUz16jskmpr";
String senderAddress = "FcLfoPNCYjSMnxLPiQJQFGTV15ecHn3xY4J2HNCrqbCfmca";
Generator gn = Generator.get("mitum"); // network id: mitum
Key key = Key.get("knW2wVXH399P9Xg8aVjAGuMkk3uTBZwcSpcy4aR3UjiAmpu", 100);
Keys keys = Keys.get(new Key[]{ key }, 100); // becomes single-sig account
Amount amount = Amount.get("MCC", "1000");
CreateContractAccountsItem item = gn.currency.extension.getCreateContractAccountsItem(keys, new Amount[]{ amount });
CreateContractAccountsFact fact = gn.currency.extension.getCreateContractAccountsFact(senderAddress, new CreateContractAccountsItem[]{ item });
Operation createContractAccount = gn.getOperation(fact);
createContractAccount.sign(senderPrivateKey);
Withdraw
/*
import org.mitumc.sdk.Generator;
import org.mitumc.sdk.operation.*;
import org.mitumc.sdk.operation.currency.*;
import org.mitumc.sdk.operation.currency.extension.*;
*/
Generator gn = Generator.get("mitum"); // network id: mitum
String senderPrivateKey = "KzdeJMr8e2fbquuZwr9SEd9e1ZWGmZEj96NuAwHnz7jnfJ7FqHQBmpr";
String senderAddress = "2D5vAb2X3Rs6ZKPjVsK6UHcnGxGfUuXDR1ED1hcvUHqsmca";
String targetAddress = "CY1pkxsqQK6XMbnK4ssDNbDR2K7mitSwdS27DwBjd3Gcmca";
Amount amount1 = Amount.get("MCC", "1000000");
Amount amount2 = Amount.get("PEN", "15000");
WithdrawsItem item = gn.currency.extension.getWithdrawsItem(targetAddress, new Amount[]{ amount1, amount2 }); // getTransfersItem(receiver address, amount list)
WithdrawsFact fact = gn.currency.extension.getWithdrawsFact(senderAddress, new WithdrawsItem[]{ item }); // getTransfersFact(sender address, item list)
Operation withdraws = gn.getOperation(fact);
withdraws.sign(senderPrivateKey);
Sign
Has every signature been signed by the private key of the account?
Is the sum of every weight for each signer greater than or equal to the account threshold?
(pub1, 30)
(pub2, 30)
(pub3, 30)
threshold: 50
CASE1: fact signatures signed by pub1’s private key and pub2’s private key
the sum of pub1’s weight and pub2’s weight: 60
the sum of weights = 60 > threshold = 50
So the operation with these two fact signatures is available
CASE2: fact signatures signed by pub2’s private key and pub3’s private key
the sum of pub2’s weight and pub3’s weight: 60
the sum of weights = 60 > threshold = 50
So the operation with these two fact signatures is available
CASE3: fact signatures signed by pub1’s private key and pub3’s private key
the sum of pub1’s weight and pub3’s weight: 60
the sum of weights = 60 > threshold = 50
So the operation with these two fact signatures is available
CASE4: fact signatures signed by pub1’s private key, pub2’s private key, pub3’s private key
the sum of pub1’s weight, pub2’s weight and pub3’s weight: 90
the sum of weights = 90 > threshold = 50
So the operation with these two fact signatures is available
Operation.addSign(private key)
)Add Fact Sign to Operation
Private key to sign - it should be that of the sender of the operation.
Operation as JsonObject, or external JSON file.
Network ID
Signer
with network id
like Generator
./*
import org.mitumc.sdk.Signer;
import org.mitumc.sdk.JSONParser;
*/
String id = "mitum";
String key = "KzafpyGojcN44yme25UMGvZvKWdMuFv1SwEhsZn8iF8szUz16jskmpr";
Signer signer = Signer.get(id, key);
HashMap<String, Object> signed = signer.addSignToOperation("operation.json"); // or JsonObject from Operation JSON instead
Operation
object of mitum-java-util. It’s just a HashMap object.Signer
.Details
Get Mitum Keypair
Account Address:
mca
Private Key:
mpr
Public Key:
mpu
Account Address:
9XyYKpjad2MSPxR4wfQHvdWrZnk9f5s2zc9Rkdy2KT1gmca
Private Key:
L11mKUECzKouwvXwh3eyECsCnvQx5REureuujGBjRuYXbMswFkMxmpr
Public Key:
28Hhy6jwkEHx75bNLmG66RQu1LWiZ1vodwRTURtBJhtPWmpu
Just Create New Keypair
Keypar.create()
./*
import org.mitumc.sdk.key.Keypair;
*/
Keypair kp = Keypair.random();
kp.getPrivateKey(); // returns private key of the keypair
kp.getPublicKey(); // returns public key of the keypair
Get Keypair From Your Private Key
/*
import org.mitumc.sdk.key.Keypair;
*/
String key = "KzafpyGojcN44yme25UMGvZvKWdMuFv1SwEhsZn8iF8szUz16jskmpr";
Keypair pkp = Keypair.fromPrivateKey(key);
Get Keypair From Your Seed
/*
import org.mitumc.sdk.key.Keypair;
*/
String seed = "Thisisaseedfortheexample;Keypair.fromSeed()";
Keypair skp = Keypair.fromSeed(seed);
// or... -----------------------------//
// byte[] bseed = seed.getBytes();
// Keypair skp = Keypair.fromSeed(bseed);
Get Account Address with Keys
key1: (vmk1iprMrs8V1NkA9DsSL3XQNnUW9SmFL5RCVJC24oFYmpu, 40)
key2: (29BQ8gcVfJd5hPZCKj335WSe4cyDe7TGrjam7fTrkYNunmpu, 30)
key3: (uJKiGLBeXF3BdaDMzKSqJ4g7L5kAukJJtW3uuMaP1NLumpu, 30)
threshold: 100
/*
import org.mitumc.key.Key
import org.mitumc.key.Keys
*/
Key key1 = Key.get("vmk1iprMrs8V1NkA9DsSL3XQNnUW9SmFL5RCVJC24oFYmpu", 40);
Key key2 = Key.get("29BQ8gcVfJd5hPZCKj335WSe4cyDe7TGrjam7fTrkYNunmpu", 30);
Key key3 = Key.get("uJKiGLBeXF3BdaDMzKSqJ4g7L5kAukJJtW3uuMaP1NLumpu", 30);
Keys keys = Keys.get(new Key[]{ key1, key2, key3 }, 100);
String address = keys.getAddress(); // This is the goal!
Major Classes
Generator
Generator
is the class that helps generate operations for Mitum Currency.Generator
, network id
must be set.For Mitum Currency, use
Generator.currency
.For Mitum Currency Extension, use
Generator.currency.extension
.For Mitum Document, use
Generator.document
.For Mitum Feefi, use
Generator.feefi
.For Mitum NFT, use
Generator.nft
.
/*
import org.mitumc.sdk.Generator;
*/
String id = "mitum";
Generator generator = Generator.get(id);
CurrencyGenerator cgn = generator.currency; // org.mitumc.sdk.operation.currency.CurrencyGenerator;
ExtensionGenerator egn = generator.currency.extension; // org.mitumc.sdk.operation.currency.extension.ExtensionGenerator;
DocumentGenerator dgn = generator.document; // org.mitumc.sdk.operation.document.DocumentGenerator;
FeefiGenerator fgn = generator.feefi; // org.mitumc.sdk.operation.feefi.FeefiGenerator;
NFTGenerator ngn = generator.nft; // org.mitumc.sdk.operation.nft.NFTGenerator;
Generator
provides are,/* For Mitum Currency */
CreateAccountsItem getCreateAccountsItem(Keys keys, Amount[] amounts);
TransfersItem getTransfersItem(String receiver, Amount[] amounts);
CreateAccountsFact getCreateAccountsFact(String sender, CreateAccountsItem[] items);
KeyUpdaterFact getKeyUpdaterFact(String target, String currency, Keys keys);
TransfersFact getTransfersFact(String sender, TransfersItem[] items);
/* For Mitum Currency Extension */
CreateContractAccountsItem getCreateContractAccountsItem(Keys keys, Amount[] amounts);
WithdrawsItem getWithdrawsItem(String target, Amount[] amounts);
CreateContractAccountsFact getCreateContractAccountsFact(String sender, CreateContractAccountsItem[] items);
WithdrawsFact getWithdrawsFact(String sender, WithdrawsItem[] items);
/* For Mitum Document */
Generator.document.getCreateDocumentsItem(Document document, String currencyId);
Generator.document.getUpdateDocumentsItem(Document document, String currencyId);
Generator.document.getCreateDocumentsFact(String sender, CreateDocumentsItem[] items);
Generator.document.getUpdateDocumentsFact(String sender, UpdateDocumentsItem[] items);
/* For Blocksign */
Generator.document.blocksign.user(String address, String signCode, boolean signed);
Generator.document.blocksign.document(String documentId, String owner, String fileHash, BlockSignUser creator, String title, String size, BlockSignUser[] signers);
Generator.document.blocksign.getSignDocumentsItem(String documentId, String owner, String currencyId);
Generator.document.blocksign.getSignDocumentsFact(String sender, SignDocumentsItem[] items);DocumentsFact(String sender, BlockCityItem<T>[] items);
/* For Blockcity */
Candidate candidate(String address, String nickname, String manifest, int count);
UserStatistics userStatistics(int hp, int strength, int agility, int dexterity, int charisma, int intelligence, int vital);
Document userDocument(String documentId, String owner, int gold, int bankGold, UserStatistics statistics);
Document landDocument(String documentId, String owner, String address, String area, String renter, String account, String rentDate, int period);
Document voteDocument(String documentId, String owner, int round, String endTime, Candidate[] candidates, String bossName, String account, String office);
Document historyDocument(String documentId, String owner, String name, String account, String date, String usage, String app);
/* For Mitum Feefi */
PoolRegisterFact getPoolRegisterFact(String sender, String target, Amount initialFee, String incomingCid, String outgoingCid, String currency);
PoolPolicyUpdaterFact getPoolPolicyUpdaterFact(String sender, String target, Amount fee, String poolId, String currency);
PoolDepositsFact getPoolDepositsFact(String sender, String pool, String poolId, Amount amount);
PoolWithdrawFact getPoolWithdrawFact(String sender, String pool, String poolId, Amount[] amounts);
/* For Mitum NFT */
NFTSigner signer(String account, int share, boolean signed);
NFTSigners signers(int total, NFTSigner[] signers);
CollectionRegisterForm collectionRegisterForm(String target, String symbol, String name, int royalty, String uri, String[] whites);
CollectionPolicy collectionPolicy(String name, int royalty, String uri, String[] whites);
MintForm mintForm(String hash, String uri, NFTSigners creators, NFTSigners copyrighters);
MintItem getMintItem(String collection, MintForm form, String currency);
NFTTransferItem getTransferItem(String receiver, NFTID nid, String currency);
BurnItem getBurnItem(NFTID nid, String currency);
NFTSignItem getSignItem(String qualification, NFTID nid, String currency);
ApproveItem getApproveItem(String approved, NFTID nid, String currency);
DelegateItem getDelegateItem(String collection, String agent, String mode, String currency);
CollectionRegisterFact getCollectionRegisterFact(String sender, CollectionRegisterForm form, String currency);
CollectionPolicyUpdaterFact getCollectionPolicyUpdaterFact(String sender, String collection, CollectionPolicy policy, String currency);
MintFact getMintFact(String sender, MintItem[] items);
NFTTransferFact getTransferFact(String sender, NFTTransferItem[] items);
BurnFact getBurnFact(String sender, BurnItem[] items);
NFTSignFact getSignFact(String sender, NFTSignItem[] items);
ApproveFact getApproveFact(String sender, ApproveItem[] items);
DelegateFact getDelegateFact(String sender, DelegateItem[] items);
/* Common */
Operation getOperation(OperationFact fact);
Operation getOperation(OperationFact fact, String memo);
HashMap<String, Object> getSeal(String signKey, Operation[] operations);
HashMap<String, Object> getSeal(String signKey, JsonObject[] operations);
HashMap<String, Object> randomKeys();
HashMap<String, Object> randomKeys(int numOfKeys);
Signer
Signer
is the class for adding new fact signature to already create operations.Generator
, network id
must be set.Signer
provides only one method, that is,HashMap<String, Object> addSignToOperation(JsonObject operation);
HashMap<String, Object> addSignToOperation(String operationPath);
Signer
, go back to Make Your First Operation - Sign.JSONParser
Operation
to file or to print it in JSON format, you don’t need to use JSONParser
of mitum-java-util.JsonObject getObjectFromJsonFile(String fpName);
JsonObject getObjectFromHashMap(HashMap<String, Object> target);
void writeJsonFileFromJsonObject(JsonObject target, String fpName);
void writeJsonFileFromHashMap(HashMap target, String fpName);
HashMap<String, Object> mergeOperations(JsonObject[] operations);
HashMap<String, Object> mergeOperations(HashMap<String, Object>[] operations);
/*
import org.mitumc.sdk.JSONParser;
*/
// ... omitted
// ... create operations
// ... refer to above `Make Your First Operation`
// ... suppose you have already made operations - createAccount, keyUpdater, transfer and a seal - seal
JSONParser.writeJsonFileFromHashMap(createAccount.toDict(), 'createAccount.json'); // writeJsonFileFromHashMap(HashMap, filePath)
JSONParser.writeJsonFileFromHashMap(keyUpdater.toDict(), 'keyUpdater.json');
JSONParser.writeJsonFileFromHashMap(transfer.toDict(), 'transfer.json');
JSONParser.writeJsonFileFromHashMap(seal, 'seal.json');