Klaytn Docs Archive
Getting StartedBuild a dAppNode OperationDeveloper Hub
  • Klaytn Docs
  • -
    • Klaytn Overview
      • Why Klaytn
      • Klaytn Design
        • Consensus Mechanism
        • Accounts
        • Transactions
          • Basic
          • Fee Delegation
          • Partial Fee Delegation
          • Ethereum
        • Computation
          • Klaytn Smart Contract
          • Execution Model
          • Computation Cost
            • Computation Cost (Previous docs)
          • Klaytn Virtual Machine
            • Klaytn Virtual Machine (Previous docs)
        • Storage
          • State Migration
          • StateDB Live Pruning
        • Transaction Fees
          • Transaction Fees (Previous docs)
        • Klaytn native coin - KLAY
        • Token Economy
        • Governance
        • Multi-Channel
        • KNI
      • Scaling Solutions
    • Getting Started
      • Deploying Smart Contract Using Foundry
      • Deploying Smart Contract Using Hardhat
      • Deploying Smart Contract Using Thirdweb
      • Deploying Smart Contract Using KEN
        • Launch an Endpoint Node
        • Top up your Account
        • Install Development Tools
        • Deploy a Smart Contract
        • Check the Deployment
        • Account Management
          • Creating Accounts
          • Managing Accounts
      • Development Environment
      • Getting KLAY
    • Smart Contract
      • Solidity - Smart Contract Language
      • Precompiled Contracts
        • Precompiled Contracts (Previous docs)
      • IDE and Tools
        • Truffle
      • Sample Contracts
        • KlaytnGreeter
        • ERC-20
          • 1. Writing ERC-20 Smart Contract
          • 2. Deploying Smart Contract
          • 3. Interacting with ERC-20 token from Klaytn Wallet
        • ERC-721
          • 1. Writing ERC-721 Smart Contract
          • 2. Deploying Smart Contract
      • Testing Guide
      • Deployment Guide
      • Klaytn Compatible Tokens
      • Porting Ethereum Contract
    • Run a Node
      • Deployment
        • Endpoint Node
          • System Requirements
          • Installation Guide
            • Download
            • Installation Guide
            • Configuration
            • Startup the EN
            • Testing the Installation
          • ken CLI commands
          • JSON-RPC APIs
        • Core Cell
          • System Requirements
          • Network Configuration
          • Installation Guide
            • Download
            • Before You Install
            • Consensus Node Setup
              • Installation Guide
              • Configuration
              • Startup the CN
            • Proxy Node Setup
              • Installation Guide
              • Configuration
              • Startup the PN
            • Testing the Core Cell
          • Monitoring Setup
          • H/A Setup
        • Service Chain
          • Getting Started
            • Setting up a 4-node Service Chain
            • Connecting to Baobab
            • Cross-Chain Value Transfer
            • HA(High Availability) for ServiceChain
            • Nested ServiceChain
            • Value Transfer between Sibling ServiceChains
          • Reference Manuals
            • System Requirements
            • Download
            • SCN User Guide
              • Installation
              • Configuration
              • Starting/Stopping SCN
              • Checking Node Status
              • kscn commands
              • homi commands
            • SPN/SEN User Guide
              • Installation
              • Configuration
              • Starting/Stopping Node
              • Checking Node Status
            • Bridge Configuration
            • Anchoring
            • KAS Anchoring
            • Value Transfer
            • Configuration Files
            • Log Files
            • Genesis JSON
            • Upgrade & Hard Fork
          • How-To Guides
        • Download Node Packages
          • v1.12.0
          • v1.11.1
          • v1.11.0
          • v1.10.2
          • v1.10.1
          • v1.10.0
          • v1.9.1
          • v1.9.0
          • v1.8.4
          • v1.8.3
          • v1.8.2
          • v1.8.1
          • v1.8.0
          • v1.7.3
          • v1.7.2
          • v1.7.1
          • v1.7.0
          • v1.6.4
          • v1.6.3
          • v1.6.2
          • v1.6.1
          • v1.6.0
          • v1.5.3
          • v1.5.2
          • v1.5.1
          • v1.5.0
          • v1.4.2
          • v1.4.1
          • v1.4.0
          • v1.3.0
          • v1.2.0
          • v1.1.1
          • v1.0.0
          • v0.9.6
          • v0.8.2
    • Operation Guide
      • Configuration
      • Node Log
      • Log operation
      • Errors & Troubleshooting
      • Klaytn Command
      • Chaindata Change
      • Chaindata Migration
    • dApp Developers
      • JSON-RPC APIs
        • API references
          • eth
            • Caution
            • Account
            • Block
            • Transaction
            • Config
            • Filter
            • Gas
            • Miscellaneous
          • klay
            • Account
            • Block
            • Transaction
              • Working with Klaytn Transaction Types
            • Configuration
            • Filter
            • Gas
            • Miscellaneous
          • net
          • debug
            • Logging
            • Profiling
            • Runtime Tracing
            • Runtime Debugging
            • VM Tracing
            • VM Standard Tracing
            • Blockchain Inspection
          • admin
          • personal
          • txpool
          • governance
        • Service Chain API references
          • mainbridge
          • subbridge
        • Transaction Error Codes
      • RPC Service Providers
        • Public Endpoints
      • SDK & Libraries for interacting with Klaytn Node
        • caver-js
          • Getting Started
          • Sending a sample transaction
          • API references
            • caver.account
            • caver.wallet
              • caver.wallet.keyring
            • caver.transaction
              • Basic
              • Fee Delegation
              • Partial Fee Delegation
            • caver.rpc
              • caver.rpc.klay
              • caver.rpc.net
              • caver.rpc.governance
            • caver.contract
            • caver.abi
            • caver.kct
              • caver.kct.kip7
              • caver.kct.kip17
              • caver.kct.kip37
            • caver.validator
            • caver.utils
            • caver.ipfs
          • caver-js ~v1.4.1
            • Getting Started (~v1.4.1)
            • API references
              • caver.klay
                • Account
                • Block
                • Transaction
                  • Legacy
                  • Value Transfer
                  • Value Transfer Memo
                  • Account Update
                  • Smart Contract Deploy
                  • Smart Contract Execution
                  • Cancel
                • Configuration
                • Filter
                • Miscellaneous
              • caver.klay.net
              • caver.klay.accounts
              • caver.klay.Contract
              • caver.klay.KIP7
              • caver.klay.KIP17
              • caver.klay.abi
              • caver.utils (~v1.4.1)
            • Porting from web3.js
        • caver-java
          • Getting Started
          • API references
          • caver-java ~v1.4.0
            • Getting Started (~v1.4.0)
            • Porting from web3j
        • ethers.js
        • web3.js
      • Tutorials
        • Klaytn Online Toolkit
        • Fee Delegation Example
        • Count DApp
          • 1. Environment Setup
          • 2. Clone Count DApp
          • 3. Directory Structure
          • 4. Write Smart Contract
          • 5. Frontend Code Overview
            • 5-1. Blocknumber Component
            • 5-2. Auth Component
            • 5-3. Count Component
          • 6. Deploy Contract
          • 7. Run App
        • Klaystagram
          • 1. Environment Setup
          • 2. Clone Klaystagram DApp
          • 3. Directory Structure
          • 4. Write Klaystagram Smart Contract
          • 5. Deploy Contract
          • 6. Frontend Code Overview
          • 7. FeedPage
            • 7-1. Connect Contract to Frontend
            • 7-2. UploadPhoto Component
            • 7-3. Feed Component
            • 7-4. TransferOwnership Component
          • 8. Run App
        • Building a Buy Me a Coffee dApp
          • 1. Project Setup
          • 2. Creating a BMC Smart Contract
          • 3. Testing the contract using scripts
          • 4. Deploying BMC Smart contract
          • 5. Building the BMC Frontend with React and Web3Onboard
          • 6. Deploying Frontend code on IPFS using Fleek
          • 7. Conclusion
        • Migrating Ethereum App to Klaytn
        • Connecting MetaMask
        • Connecting Remix
        • Verifying Smart Contracts Using Block Explorers
      • Developer Tools
        • Wallets
          • Kaikas
          • Klaytn Wallet
          • Klaytn Safe
            • Klaytn Safe Design
            • Create a Safe
            • Add assets
            • Send assets
            • Contract Interaction
            • Transaction Builder
            • Points to Note
            • Frequently Asked Questions
          • SafePal S1
          • Wallet Libraries
            • Web3Auth
            • Web3Modal
            • Web3-Onboard
            • Particle Network
        • Oracles
          • Orakl Network
          • Witnet
          • SupraOracles
        • Indexers
          • SubQuery
        • Cross-chain
          • LayerZero
        • Block Explorers
          • Klaytnscope
          • Klaytnfinder
        • Klaytn Contracts Wizard
    • Glossary
  • ---
    • Klaytn Hard Fork History
    • Klaytn 2.0
      • Metaverse Package
      • Finality and Improvements
      • Ethereum Compatibility
      • Decentralizing Governance
      • Massive Eco Fund
    • FAQ
    • Open Source
    • Terms of Use
    • Languages
  • ℹ️Latest Klaytn Docs
Powered by GitBook
On this page
  • Prerequisites
  • Dependency
  • Installation
  • Managing Accounts
  • Creating an Account
  • Sending a Transaction
  • Getting KLAY via Baobab Faucet
  • Connecting to Baobab
  • Sending a Value Transfer Transaction
  • Checking Receipts
  • Sending Other Transaction Types
  • Account Update
  • Smart Contract
  • Fee Delegation
  • Using various AccountKey Types
  • AccountKey
  • AccountKeyPublic
  • AccountKeyWeightedMultiSig
  • AccountKeyRoleBased
  • Sending a Transaction with Multiple Signers
  • Sequential sender signing
  • Sequential fee-payer signing
  • Thanks to
  1. -
  2. dApp Developers
  3. SDK & Libraries for interacting with Klaytn Node
  4. caver-java
  5. caver-java ~v1.4.0

Getting Started (~v1.4.0)

Previouscaver-java ~v1.4.0NextPorting from web3j

Last updated 2 years ago

Prerequisites

Dependency

maven

<dependency>
  <groupId>com.klaytn.caver</groupId>
  <artifactId>core</artifactId>
  <version>1.4.0</version>
</dependency>

gradle

implementation 'com.klaytn.caver:core:1.4.0'

If you want to use Android dependency, just append -android at the end of the version string. (e.g. 1.0.1-android)

If you want to see details of the JSON-RPC requests and responses, please include dependency in your project. Below is a Gradle build file example. You can add the dependency to Maven as well. Since caver-java uses the logging facade, you can switch to your preferred logging framework instead of LOGBack.

implementation "ch.qos.logback:logback-classic:1.2.3"

Note: In the central repository, the RC, Android, and Java versions are listed together. If you use wildcards to get a version, you may be using a version that is not appropriate for your platform.

Installation

If you want to generate transactions related with a smart contract, you need to install a Solidity compiler and caver-java command-line tool first.

Solidity Compiler

$ brew install klaytn/klaytn/solidity@0.4.24  # version 0.4.24
$ brew install klaytn/klaytn/solidity@0.5.6   # version 0.5.6

Command-line Tool

The command-line tool allows you to generate Solidity smart contract function wrappers from the command line.

Installation (Homebrew)

Java 1.8+ is required to install this.

$ brew tap klaytn/klaytn
$ brew install caver-java

After installation you can run command 'caver-java' like below:

$ caver-java solidity generate -b <smart-contract>.bin -a <smart-contract>.abi -o <outputPath> -p <packagePath>

Installation (Other)

Currently, we do not support other package managers. As another solution, we provide a method to build the CLI below.

  • Download or fork caver-java.

  • Do task 'shadowDistZip' in the console module using Gradle. As a result, console/build/distributions/console-shadow-{version}.zip is generated.

    $ ./gradlew :console:shadowDistZip
  • Unzip the zip file in the build directory

    $ unzip ./console/build/distributions/console-shadow-{version}.zip
  • Execute the binary file to run the command-line tool like below. You can find a shell script file for macOS users and a batch file for Window users.

    $ ./console/build/distributions/console-shadow-{version}/bin/caver-java

Managing Accounts

Creating an Account

In order to sign transactions, you need to have either an EC (Elliptic Curve) key pair or a Klaytn keystore file.

Using an EC Key Pair

You can create a Klaytn account using an EC key pair like below:

KlayCredentials credentials = KlayCredentials.create(Keys.createEcKeyPair());
String privateKey = Numeric.toHexStringWithPrefix(credentials.getEcKeyPair().getPrivateKey()); 
String address = credentials.getAddress();

Using a Keystore File

KlayWalletUtils.generateNewWalletFile(
        <yourPassword>,
        new File(<walletFilePath>)
);

To load an account using a keystore file like below:

KlayCredentials credentials = KlayWalletUtils.loadCredentials(<password>, <walletFilePath>);

Sending a Transaction

Getting KLAY via Baobab Faucet

Connecting to Baobab

You can connect to the Baobab network like below:

Caver caver  = Caver.build(https://your.baobab.en.url:8651);

Sending a Value Transfer Transaction

After you get a Caver instance and create an account which has some KLAY, you can send 1 peb to a certain address(0xe97f27e9a5765ce36a7b919b1cb6004c7209217e) with a gas limit BigInteger.valueOf(100_000) like below:

TransactionManager transactionManager = new TransactionManager.Builder(caver, credentials)
        .setChaindId(ChainId.BAOBAB_TESTNET).build();

ValueTransferTransaction valueTransferTransaction = ValueTransferTransaction.create(
        credentials.getAddress(),  // fromAddress
        "0xe97f27e9a5765ce36a7b919b1cb6004c7209217e",  // toAddress
        BigInteger.ONE,  // value
        BigInteger.valueOf(100_000)  // gasLimit
);

KlayRawTransaction klayRawTransaction = transactionManager.sign(valueTransferTransaction);
String transactionHash = transactionManager.send(klayRawTransaction);

TransactionReceiptProcessor transactionReceiptProcessor = new PollingTransactionReceiptProcessor(caver, 1000, 15);  // pollingSleepDuration = 1000, pollingAttempts = 15
KlayTransactionReceipt.TransactionReceipt transactionReceipt = transactionReceiptProcessor.waitForTransactionReceipt(transactionHash);

If you use ValueTransfer class, you can more easily compose and send a transaction. This is because ValueTransfer class makes the processes above simple like below:

KlayTransactionReceipt.TransactionReceipt transactionReceipt
        = ValueTransfer.create(caver, credentials, ChainId.BAOBAB_TESTNET).sendFunds(
                redentials.getAddress(),  // fromAddress
                "0xe97f27e9a5765ce36a7b919b1cb6004c7209217e",  // toAddress
                BigDecimal.ONE,  // value 
                Convert.Unit.PEB,  // unit 
                BigInteger.valueOf(100_000)  // gasLimit
            ).send();

Checking Receipts

If you send a transaction via sendFunds, caver-java tries to get a transaction receipt by default. After you get a receipt, you can see the following log in the console.

{
   "jsonrpc":"2.0",
   "id":4,
   "result":{
      "blockHash":"0x45542cc3e3bce952f368c5da9d40f972c134fed2b2b6815231b5caf33c79dacd",
      "blockNumber":"0x39a57b",
      "contractAddress":null,
      "from":"0xe97f27e9a5765ce36a7b919b1cb6004c7209217e",
      "gas":"0x186a0",
      "gasPrice":"0x5d21dba00",
      "gasUsed":"0x5208",
      "logs":[],
      "logsBloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
      "nonce":"0x114e",
      "senderTxHash":"0x3d50b9fa9fec58443f5618ed7e0f5aec5e9a6f7269d9ff606ff87156ca5b4afd",
      "signatures":[
         {
            ...
         }
      ],
      "status":"0x1",
      "to":"0xe97f27e9a5765ce36a7b919b1cb6004c7209217e",
      "transactionHash":"0x3d50b9fa9fec58443f5618ed7e0f5aec5e9a6f7269d9ff606ff87156ca5b4afd",
      "transactionIndex":"0x1",
      "type":"TxTypeValueTransfer",
      "typeInt":8,
      "value":"0x1"
   }
}

Sending Other Transaction Types

Account Update

AccountUpdateTransaction accountUpdateTransaction = AccountUpdateTransaction.create(
        credentials.getAddress(),  // fromAddress
        AccountKeyPublic.create(
                "0xbf8154a3c1580b5478ceec0aac319055185280ce22406c6dc227f4de85316da1",  // publicKeyX
                "0x0dc8e4b9546adcc6d1f11796e43e478bd7ffbe302917667837179f4da77591d8"  // publicKeyY
        ),  // newAccountKey
        BigInteger.valueOf(100_000)  // gasLimit
);
Account.create(caver, credentials, ChainId.BAOBAB_TESTNET).sendUpdateTransaction(accountUpdateTransaction).send();

Smart Contract

$ solc <contract>.sol --bin --abi --optimize -o <output-dir>/
$ caver-java solidity generate -b <smart-contract>.bin -a <smart-contract>.abi -o <outputPath> -p <packagePath>

Above command will output <smartContract>.java. After generating the wrapper code, you can deploy your smart contract like below:

<smartContract> contract = <smartContract>.deploy(
        caver, credentials, <chainId>, <gasProvider>,
        <param1>, ..., <paramN>).send();

After the smart contract has been deployed, you can create a smart contract instance like below:

<smartContract> contract = <smartContract>.load(
        <deployedContractAddress>, caver, credentials, <chainId>, <gasProvider>
);

To transact with a smart contract:

KlayTransactionReceipt.TransactionReceipt transactionReceipt = contract.<someMethod>(
        <param1>,
        ...).send();

To call a smart contract:

<type> result = contract.<someMethod>(<param1>, ...).send();

Example

ERC20Mock erc20Mock = ERC20Mock.deploy(
        caver, credentials, 
        ChainId.BAOBAB_TESTNET,  // chainId
        new DefaultGasProvider(),  // gasProvider
        credentials.getAddress(),  // param1(initialAccount)
        BigInteger.valueOf(100)  // param2(initialBalance)
).send();
String deployedContractAddress = erc20Mock.getContractAddress();

To create an instance of the deployed ERC20Mock contract:

ERC20Mock erc20Mock = ERC20Mock.load(
        deployedContractAddress, 
        caver, credentials, 
        ChainId.BAOBAB_TESTNET,  // chainId 
        new DefaultGasProvider()  // gasProvider
);

If you transfer 10 tokens to a specified address (e.g., 0x2c8ad0ea2e0781db8b8c9242e07de3a5beabb71a), use the following code:

KlayTransactionReceipt.TransactionReceipt transactionReceipt = erc20Mock.transfer(
        "0x2c8ad0ea2e0781db8b8c9242e07de3a5beabb71a",  // toAddress
        BigInteger.valueOf(10)  // value
).send();

To check the balance of the recipient (e.g., 0x2c8ad0ea2e0781db8b8c9242e07de3a5beabb71a), use the code below:

BigInteger balance = erc20Mock.balanceOf(
        "0x2c8ad0ea2e0781db8b8c9242e07de3a5beabb71a"  // owner
).send();

Fee Delegation

Value Transfer

TransactionManager transactionManager = new TransactionManager.Builder(caver, credentials)
        .setChaindId(ChainId.BAOBAB_TESTNET).build();  // BAOBAB_TESTNET = 1001
ValueTransferTransaction valueTransferTransaction = ValueTransferTransaction.create(
        credentials.getAddress(),  // fromAddress
        "0xe97f27e9a5765ce36a7b919b1cb6004c7209217e",  // toAddress
        BigInteger.ONE,  // value
        BigInteger.valueOf(100_000)  // gasLimit
);
String senderRawTransaction = transactionManager.sign(valueTransferTransaction, true).getValueAsString();  // isFeeDelegated : true

A signed transaction, senderRawTransaction, is generated. Now the sender delivers the transaction to the fee payer who will pay for the transaction fee instead. Transferring transactions between the sender and the fee payer is not performed on the Klaytn network. The protocol should be defined by themselves.

After the fee payer gets the transaction from the sender, the fee payer can send the transaction using the FeePayerManager class as follows. FeePayerManager.executeTransaction() will sign the received transaction with the fee payer's private key and send the transaction to the Klaytn network.

KlayCredentials feePayer = KlayWalletUtils.loadCredentials(<password>, <walletfilePath>);
FeePayerManager feePayerManager = new FeePayerManager.Builder(caver, feePayer)
        .setChainId(ChainId.BAOBAB_TESTNET)
        .build();
feePayerManager.executeTransaction(senderRawTransaction);

Smart Contract Execution

String recipient = "0x34f773c84fcf4a0a9e2ef07c4615601d60c3442f";
BigInteger transferValue = BigInteger.valueOf(20);
Function function = new Function(
        ERC20Mock.FUNC_TRANSFER,  // FUNC_TRANSFER = "transfer"
        Arrays.asList(new Address(recipient), new Uint256(transferValue)),  // inputParameters
        Collections.emptyList()  // outputParameters
);
String data = FunctionEncoder.encode(function);

TransactionManager transactionManager = new TransactionManager.Builder(caver, credentials)
        .setChaindId(ChainId.BAOBAB_TESTNET).build();  // BAOBAB_TESTNET = 1001
SmartContractExecutionTransaction smartContractExecution = 
        SmartContractExecutionTransaction.create(
                credentials.getAddress(),  // fromAddress
                erc20Mock.getContractAddress(),  // contractAddress
                BigInteger.ZERO,  // value
                Numeric.hexStringToByteArray(data),  // data
                BigInteger.valueOf(100_000)  // gasLimit
        );
String senderRawTransaction = transactionManager.sign(smartContractExecution, true).getValueAsString();
KlayCredentials feePayer = KlayWalletUtils.loadCredentials(<password>, <walletfilePath>);
FeePayerManager feePayerManager = new FeePayerManager.Builder(caver, feePayer).build();
feePayerManager.executeTransaction(senderRawTransaction);

Using various AccountKey Types

AccountKey

AccountKeyPublic

AccountKeyPublic is an implementation of AccountKey with one public key. You can create it like this:

ECKeyPair newKeyPair = Keys.createEcKeyPair();
AccountKeyPublic newAccountKey = AccountKeyPublic.create(newKeyPair.getPublicKey());

To use the account updated with AccountKeyPublic, you need to create KlayCredentials as follows:

KlayCredentials validCredentails = KlayCredentials.create(newKeyPair, oldCredentials.getAddress());

// Because the account address is decoupled from the AccountKeyPublic (public key), you can't use the account if you create the credentials without address as below.
KlayCredentials invalidCredentails = KlayCredentials.create(newKeyPair);

AccountKeyWeightedMultiSig

AccountKeyWeightedMultiSig is an account key that contains multiple public keys with varying weights. AccountKeyWeightedMultiSig also defines the threshold, the sum of the weights of the keys that must be signed in order to use the account. The maximum number of keys supported is 10. You can create AccountKeyWeightedMultiSig as below:

List<AccountKeyWeightedMultiSig.WeightedPublicKey> weightedTransactionPublicKeys = new ArrayList<>();

int weight1 = 10;
int weight2 = 30;

ECKeyPair ecKeyPair1 = Keys.createEcKeyPair();
ECKeyPair ecKeyPair2 = Keys.createEcKeyPair();

AccountKeyWeightedMultiSig.WeightedPublicKey weightedPublicKey1 = AccountKeyWeightedMultiSig.WeightedPublicKey.create(
				BigInteger.valueOf(weight1),
				AccountKeyPublic.create(ecKeyPair1.getPublicKey())
);

AccountKeyWeightedMultiSig.WeightedPublicKey weightedPublicKey2 = AccountKeyWeightedMultiSig.WeightedPublicKey.create(
				BigInteger.valueOf(weight2),
				AccountKeyPublic.create(ecKeyPair2.getPublicKey())
);

weightedTransactionPublicKeys.add(weightedPublicKey1);
weightedTransactionPublicKeys.add(weightedPublicKey2);

AccountKeyWeightedMultiSig newAccountKey = AccountKeyWeightedMultiSig.create(
                BigInteger.valueOf(weight1 + weight2),
                weightedTransactionPublicKeys
);

To use the account updated with AccountKeyWeightedMultiSig, you can create KlayCredentials as follows:

List<ECKeyPair> transactionECKeyPairList = new ArrayList<>();

transactionECKeyPairList.add(ecKeyPair1);
transactionECKeyPairList.add(ecKeyPair2);

KlayCredentials newCredentails = KlayCredentials.create(transactionECKeyPairList, address);

AccountKeyRoleBased

AccountKeyRoleBased is a list of AccountKey. Each AccountKey is assigned to a specific role according to its position. AccountKey can be AccountKeyPublic, AccountKeyWeightedMultiSig, or AccountKeyFail. If AccountKeyNil is used for a specific role, the key will not be updated for that role and the existing AccountKey will be used. If AccountKeyFail is used, signing for the role will fail always, so be careful using AccountKeyFail.

List<AccountKey> roleBasedAccountKeyList = new ArrayList<>();

ECKeyPair newKeyPair1 = Keys.createEcKeyPair(); // for RoleTransaction
roleBasedAccountKeyList.add(AccountKeyPublic.create(newKeyPair1.getPublicKey()));

ECKeyPair newKeyPair2 = Keys.createEcKeyPair(); // for RoleAccountUpdate
roleBasedAccountKeyList.add(AccountKeyPublic.create(newKeyPair2.getPublicKey()));

ECKeyPair newKeyPair3 = Keys.createEcKeyPair(); // for RoleFeePayer
roleBasedAccountKeyList.add(AccountKeyPublic.create(newKeyPair3.getPublicKey()));

newAccountKey = AccountKeyRoleBased.create(roleBasedAccountKeyList);

To use the account updated with AccountKeyRoleBased, you can create KlayCredentials as follows:

List<ECKeyPair> transactionECKeyPairList = Arrays.asList(newKeyPair1);
List<ECKeyPair> updateECKeyPairList = Arrays.asList(newKeyPair2);
List<ECKeyPair> feePayerECKeyPairList = Arrays.asList(newKeyPair3);

KlayCredentials newCredentails = KlayCredentials.create(transactionECKeyPairList, updateECKeyPairList, feePayerECKeyPairList, address);

If the account does not have a key for a specific role, pass an empty List as an argument.

List<ECKeyPair> transactionECKeyPairList = Collections.emptyList();
List<ECKeyPair> updateECKeyPairList = Arrays.asList(newKeyPair2);
List<ECKeyPair> feePayerECKeyPairList = Collections.emptyList();

KlayCredentials newCredentails = KlayCredentials.create(transactionECKeyPairList, updateECKeyPairList, feePayerECKeyPairList, address);

If the account has multiple keys for a specific role, you can pass the multiple keys as follows.

List<ECKeyPair> transactionECKeyPairList = Collections.emptyList();
List<ECKeyPair> updateECKeyPairList = Arrays.asList(newKeyPair2-1, newKeyPair2-2, newKeyPair2-3);
List<ECKeyPair> feePayerECKeyPairList = Collections.emptyList();

KlayCredentials newCredentails = KlayCredentials.create(transactionECKeyPairList, updateECKeyPairList, feePayerECKeyPairList, address);

Sending a Transaction with Multiple Signers

If an account has AccountKeyMultiSig or AccountKeyRoleBased, each key can be managed by different people.

This section describes how to collect signatures and send the transaction if there are multiple signers.

Sequential sender signing

The rawTransaction has an RLP encoded transaction that contains both txSignatures and feePayerSignatures. feePayerSignature is included only when the transaction is a fee delegated transaction.

In the absence of a fee payer, the process of repeatedly signing and executing a transaction can be divided into three parts. 1. RLP-encode the transaction and send it to the signer in the form of rawTransaction. 2. Signer signs with its own key for the received rawTransaction. 3. Sending the signed rawTransaction to EN. Step 2 can be repeated if there are multiple signers.

//// 1. Alice creates a transaction, signs it, and sends it to Bob.
//// Alice Side
ValueTransferTransaction transactionTransformer = ValueTransferTransaction.create(from, to, BigInteger.ONE, GAS_LIMIT);

TransactionManager transactionManager_alice = new TransactionManager.Builder(caver, senderCredential_alice)
                    .setTransactionReceiptProcessor(new PollingTransactionReceiptProcessor(caver, 1000, 10))
                    .setChaindId(LOCAL_CHAIN_ID)
                    .build();

String rawTransaction_signed_alice = transactionManager_alice.sign(transactionTransformer).getValueAsString();

//// 2. Bob signs the received transaction and sends it to Charlie.
//// Bob Side
            TransactionManager transactionManager_bob = new TransactionManager.Builder(caver, senderCredential_bob)
                    .setTransactionReceiptProcessor(new PollingTransactionReceiptProcessor(caver, 1000, 10))
                    .setChaindId(LOCAL_CHAIN_ID)
                    .build();

String rawTransaction_signed_alice_and_bob = transactionManager_bob.sign(rawTransaction_signed_alice).getValueAsString();

//// 3. Charlie signs the received transaction and sends it to Klaytn EN.
//// Charlie Side
TransactionManager transactionManager_charlie = new TransactionManager.Builder(caver, senderCredential_charlie)
                    .setTransactionReceiptProcessor(new PollingTransactionReceiptProcessor(caver, 1000, 10))
                    .setChaindId(LOCAL_CHAIN_ID)
                    .build();

KlayTransactionReceipt.TransactionReceipt transactionReceipt = transactionManager_charlie.executeTransaction(rawTransaction_signed_alice_and_bob);

Sequential fee-payer signing

Fee-payer signature(s) can also be added sequentially. Signing with FeePayerManager accumulates feePayerSignatures in the transaction. The signing order is not important. If you sign with TransactionManager, the txSignature is added. If you sign with FeePayerManger, the feePayerSignatures is added to the raw transaction.

//// 1. Bob receives a transaction from Alice and signs the transaction as a fee payer.
//// Bob Side
FeePayerManager feePayerManager_bob = new FeePayerManager.Builder(caver, feePayerCredentials_bob)
                    .setTransactionReceiptProcessor(new PollingTransactionReceiptProcessor(caver, 1000, 10))
                    .setChainId(LOCAL_CHAIN_ID)
                    .build();

String rawTransaction_signed_alice_and_bob = feePayerManager_bob.sign(rawTransaction_signed_alice).getValueAsString();

//// 2. Charlie signs the received transaction and sends it to Klaytn EN.
//// Charlie Side
FeePayerManager feePayerManager_charlie = new FeePayerManager.Builder(caver, feePayerCredentials_charlie)
                    .setTransactionReceiptProcessor(new PollingTransactionReceiptProcessor(caver, 1000, 10))
                    .setChainId(LOCAL_CHAIN_ID)
                    .build();

KlayTransactionReceipt.TransactionReceipt transactionReceipt =  feePayerManager_charlie.executeTransaction(rawTransaction_signed_alice_and_bob);

Thanks to

You can install the Solidity compiler locally, following the instructions as per . Klaytn recommends you to install Solidity version either 0.4.24 or 0.5.6. If you are a macOS user, you can install the versions via Homebrew:

If you want to create a new account with a keystore file (you can also create a new keystore file in ):

After creating an account, you can receive some Baobab testnet KLAY for the Baobab testnet via Baobab Faucet, available at . The received testnet KLAY will be used for transaction fee later.

TransactionManager is introduced to hide the complexity of transaction types. For example, a FeeDelegatedValueTransferTransaction object can be transformed from a ValueTransferTransaction object. For more details, see . In addition to Fee Delegation, TransactionManager can be used with GetNonceProcessor, ErrorHandler, and TransactionReceiptProcessor.

In this receipt, you can check the status of the transaction execution. If the 'status' field in the receipt is "0x1", it means the transaction is processed successfully. If not, the transaction failed. The detailed error message is presented in the txError field. For more detail, see .

If you want to update the key of the given account to a new key:

An account key represents the key structure associated with an account. To get more details and types about the Klaytn account key, please read .

caver-java supports auto-generation of smart contract wrapper code. Using the wrapper, you can easily deploy and execute a smart contract. Before generating a wrapper code, you need to compile the smart contract first. Note: This will only work if a Solidity compiler is installed in your computer. See .

Then, generate the wrapper code using caver-java’s .

This section describes how to deploy and execute a smart contract on the Baobab testnet. In this example, we use a smart contract . If contract deployment fails and an empty contract address is returned, it will throw RuntimeException.

Klaytn provides feature which allows service providers to pay transaction fees instead of the users.

On the client side, client who initiates the transaction will generate a fee-delegated value transfer transaction as follows: A sender creates a default ValueTransferTransaction object, then returns a signed FeeDelegatedValueTransferTransaction object if the second parameter is set to true.

The difference between fee-delegated smart contract execution and fee-delegated value transfer above is that this needs input data to call a function of a smart contract. A sender can generate a fee-delegated smart contract execution transaction as shown below. Note that returns a TxTypeFeeDelegatedSmartContractExecution object if you pass true to the second parameter. The example below invokes the transfer method of contract which is described in .

After you get senderRawTransaction, the rest of the process using FeePayerManager is the same way as you saw in above:

caver-java introduces new classes to support the various types of supported by the platform. This feature is supported starting with version 1.2.0.

To update the account key on the Klaytn platform, caver-java provides the AccountKey interface. The following describes AccountKey implementations, AccountKeyPublic, AccountKeyWeightedMultiSig, and AccountKeyRoleBased. See for how to update an Account.

The project for the inspiration. 🙂

LOGBack
SLF4J
the project documentation
Klaytn Wallet
https://baobab.wallet.klaytn.foundation/
txError
ERC20Mock
transactionManager.sign()
web3j
Solidity Compiler
command-line tool
transactionManager.sign()
ERC20Mock
Smart Contract
fee-delegated value transfer
Account Update
Fee Delegation
Fee Delegation
AccountKeyPublic
AccountKey
AccountKey