All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.klaytn.caver.wallet.keyring.RoleBasedKeyring Maven / Gradle / Ivy

There is a newer version: 1.12.2-android
Show newest version
/*
 * Copyright 2020 The caver-java Authors
 *
 * Licensed under the Apache License, Version 2.0 (the “License”);
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an “AS IS” BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.klaytn.caver.wallet.keyring;

import com.klaytn.caver.account.Account;
import com.klaytn.caver.account.AccountKeyRoleBased;
import com.klaytn.caver.account.WeightedMultiSigOptions;
import com.klaytn.caver.utils.Utils;
import org.web3j.crypto.CipherException;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;

/**
 * Representing a Keyring which includes "address" and "private keys" by roles.
 * @see AbstractKeyring
 * @see SingleKeyring
 * @see MultipleKeyring
 */
public class RoleBasedKeyring extends AbstractKeyring {

    /**
     * The Keys to use in RoleBasedKeyring.
     */
    List keys;

    /**
     * Creates a RoleBasedKeyring.
     * @param address The address of keyring.
     * @param keys The keys to use in RoleBasedKeyring.
     */
    public RoleBasedKeyring(String address, List keys) {
        super(address);
        this.keys = keys;
    }

    /**
     * Signs a transaction hash with all keys in specific role group and return signature list.
     * 
Example :
     * {@code
     * String txHash = "0x{txHash}";
     * int chainId = 0;
     * int role = RoleGroup.TRANSACTION;
     *
     * List signature = keyring.sign(txHash, chainId, role);
     * }
     * 
* * @param txHash The hash of transaction. * @param chainId The chainId specific to the network. * @param role A number indicating the role of the key. see {@link com.klaytn.caver.account.AccountKeyRoleBased.RoleGroup}. * @return {@code List} */ @Override public List sign(String txHash, int chainId, int role) { PrivateKey[] keyArr = getKeyByRole(role); return Arrays.stream(keyArr) .map(key-> { return key.sign(txHash, chainId); }).collect(Collectors.toList()); } /** * Signs a transaction hash with key in specific role group and return signature. *
Example :
     * {@code
     * String txHash = "0x{txHash}";
     * int chainId = 0;
     * int role = RoleGroup.TRANSACTION;
     * int index = 0;
     *
     * SignatureData signature = keyring.sign(txHash, chainId, role, index);
     * }
     * 
* * @param txHash The hash of transaction. * @param chainId The chainId specific to the network. * @param role A number indicating the role of the key. see {@link com.klaytn.caver.account.AccountKeyRoleBased.RoleGroup}. * @param index The index of the key to be used in the specific role group. * @return SignatureData */ @Override public SignatureData sign(String txHash, int chainId, int role, int index) { PrivateKey[] keyArr = getKeyByRole(role); validatedIndexWithKeys(index, keyArr.length); PrivateKey key = keyArr[index]; SignatureData signatureData = key.sign(txHash, chainId); return signatureData; } /** * Signs a transaction hash with all private keys in specific role group and returns a signature list which V is 0 or 1(parity of the y-value of a secp256k1 signature).

* The role used in caver-java can be checked through {@link com.klaytn.caver.account.AccountKeyRoleBased.RoleGroup}. *

Example :
     * {@code
     * RoleBasedKeyring keyring = new RoleBasedKeyring(.....);
     * List signatureList = keyring.ecsign("0xe9a11d9ef95fb437f75d07ce768d43e74f158dd54b106e7d3746ce29d545b550", AccountKeyRoleBased.RoleGroup.TRANSACTION);
     * }
     * 
* * @param txHash The hash of transaction. * @param role A number indicating the role of the key. * @return {@code List} */ @Override public List ecsign(String txHash, int role) { PrivateKey[] keyArr = getKeyByRole(role); return Arrays.stream(keyArr) .map(key-> { return key.ecsign(txHash); }).collect(Collectors.toList()); } /** * Signs a transaction hash with key in specific role group and returns a signature.

* The role used in caver-java can be checked through {@link com.klaytn.caver.account.AccountKeyRoleBased.RoleGroup}. *

Example :
     * {@code
     * RoleBasedKeyring keyring = new RoleBasedKeyring(.....);
     * SignatureData signature = keyring.ecsign("0xe9a11d9ef95fb437f75d07ce768d43e74f158dd54b106e7d3746ce29d545b550", AccountKeyRoleBased.RoleGroup.TRANSACTION, 0);
     * }
     * 
* * @param txHash The hash transaction * @param role A number indicating the role of the key. * @param index The index of the key to be used in the specific role group. * @return SignatureData */ @Override public SignatureData ecsign(String txHash, int role, int index) { PrivateKey[] keyArr = getKeyByRole(role); validatedIndexWithKeys(index, keyArr.length); PrivateKey key = keyArr[index]; SignatureData signatureData = key.ecsign(txHash); return signatureData; } /** * Signs a hashed data with all key in specific role group and return MessageSigned instance. *
Example :
     * {@code
     * Sting message = "message";
     * int role = RoleGroup.TRANSACTION;
     *
     * MessageSigned signedInfo = keyring.signMessage(message, role);
     * }
     * 
* * @param message The data string to sign. * @param role A number indicating the role of the key. see {@link com.klaytn.caver.account.AccountKeyRoleBased.RoleGroup}. * @return MessageSigned */ @Override public MessageSigned signMessage(String message, int role) { PrivateKey[] keyArr = getKeyByRole(role); String messageHash = Utils.hashMessage(message); List signatureDataList = Arrays.stream(keyArr) .map(key -> { return key.signMessage(messageHash); }).collect(Collectors.toCollection(ArrayList::new)); MessageSigned signed = new MessageSigned(messageHash, signatureDataList, message); return signed; } /** * Signs a hashed data with key in specific role group and return MessageSigned instance. *
Example :
     * {@code
     * Sting message = "message";
     * int role = RoleGroup.TRANSACTION;
     * int index = 0;
     *
     * MessageSigned signedInfo = keyring.signMessage(message, role, index);
     * }
     * 
* * @param message The data string to sign. * @param role A number indicating the role of the key. see {@link com.klaytn.caver.account.AccountKeyRoleBased.RoleGroup}. * @param index The index of the key to be used in the specific role group. * @return MessageSigned */ @Override public MessageSigned signMessage(String message, int role, int index) { PrivateKey[] keyArr = getKeyByRole(role); validatedIndexWithKeys(index, keyArr.length); PrivateKey key = keyArr[index]; String messageHash = Utils.hashMessage(message); SignatureData signatureData = key.signMessage(messageHash); MessageSigned signed = new MessageSigned(messageHash, Arrays.asList(signatureData), message); return signed; } /** * Encrypts a keyring and returns a KeyStore.(according to KeyStore V4)

* For more information, please refer to KIP3.

*

Example :
     * {@code
     * KeyStoreOption options = KeyStoreOption.getDefaultOptionWithKDF("pbkdf2");
     * KeyStore encrypted = keyring.encrypt("password", options);
     * }
     * 
* * @param password The password to be used for encryption. The encrypted in KeyStore can be decrypted with this password. * @param options The options to use when encrypt a keyring. * @return KeyStore */ @Override public KeyStore encrypt(String password, KeyStoreOption options) throws CipherException { List> cryptoList = new ArrayList<>(); for(int i = 0; i list = KeyStore.Crypto.createCrypto(privateKeys, password, options); cryptoList.add(list); } KeyStore keyStore = new KeyStore(); keyStore.setAddress(this.address); keyStore.setKeyring(cryptoList); keyStore.setVersion(KeyStore.KEY_STORE_VERSION_V4); keyStore.setId(UUID.randomUUID().toString()); return keyStore; } /** * Returns a copied RoleBasedKeyring instance. *
Example :
     * {@code
     * AbstractKeyring copied = keyring.copy();
     * }
     * 
* * @return RoleBasedKeyring */ @Override public AbstractKeyring copy() { return new RoleBasedKeyring(this.address, this.keys); } /** * Returns a public key strings.

* It returns a public key as a uncompressed format. *

Example :
     * {@code
     * String[] publicKey = keyring.getPublicKey();
     * }
     * 
* * * @return String array */ public List getPublicKey() { return getPublicKey(false); } /** * Returns a public key strings. *
Example :
     * {@code
     * String[] publicKey = keyring.getPublicKey(false);
     * }
     * 
* * @return String array */ public List getPublicKey(boolean compressed) { return this.keys.stream() .map(array -> { return Arrays.stream(array) .map(privateKey -> privateKey.getPublicKey(compressed)) .toArray(String[]::new); }) .collect(Collectors.toCollection(ArrayList::new)); } /** * Returns keys by role. If the key of the role passed as parameter is empty, the default key is returned. *
Example :
     * {@code
     * PrivateKey[] privateKeyArr = keyring.getKeyByRole(RoleGroup.TRANSACTION);
     * }
     * 
* * @param role A number indicating the role of the key. You can use `AccountRoleBased.RoleGroup`. * @return PrivateKey Array */ public PrivateKey[] getKeyByRole(int role) { if(role < 0 || role >= AccountKeyRoleBased.ROLE_GROUP_COUNT) { throw new IllegalArgumentException("Invalid role index : " + role); } PrivateKey[] keyArr = this.keys.get(role); if(keyArr.length == 0 && role > AccountKeyRoleBased.RoleGroup.TRANSACTION.getIndex()) { if(this.keys.get(AccountKeyRoleBased.RoleGroup.TRANSACTION.getIndex()).length == 0) { throw new IllegalArgumentException("The Key with specified role group does not exists. The TRANSACTION role group is also empty"); } keyArr = this.keys.get(AccountKeyRoleBased.RoleGroup.TRANSACTION.getIndex()); } return keyArr; } /** * Returns an instance of Account. *
Example:
     * {@code
     * Account account = keyring.toAccount();
     * }
     * 
* * @return Account */ public Account toAccount() { List options = WeightedMultiSigOptions.getDefaultOptionsForRoleBased(this.getPublicKey()); return toAccount(options); } /** * Returns an instance of Account. *
Example :
     * {@code
     * BigInteger[][] optionWeight = {
     *      {BigInteger.ONE, BigInteger.ONE},
     *      {},
     *      {BigInteger.ONE, BigInteger.ONE, BigInteger.ONE, BigInteger.ONE},
     * };
     *
     * WeightedMultiSigOptions[] weightedOptions = {
     *    new WeightedMultiSigOptions(BigInteger.valueOf(1), Arrays.asList(optionWeight[0])),
     *    new WeightedMultiSigOptions(),
     *    new WeightedMultiSigOptions(BigInteger.valueOf(1), Arrays.asList(optionWeight[2])),
     * };
     *
     * Account account = keyring.toAccount(Arrays.asList(weightedOptions));
     *
     * }
* @param options The option List that includes 'threshold' and 'weight'. This is only necessary when keyring use multiple private keys. * @return Account */ public Account toAccount(List options) { return Account.createWithAccountKeyRoleBased(this.address, this.getPublicKey(), options); } /** * Getter function of keys * @return PrivateKey Array */ public List getKeys() { return keys; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy