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

com.klaytn.caver.wallet.keyring.MultipleKeyring 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 array"
 * @see AbstractKeyring
 * @see SingleKeyring
 * @see RoleBasedKeyring
 */
public class MultipleKeyring extends AbstractKeyring{
    /**
     * The Keys to use in MultipleKeyring
     */
    PrivateKey[] keys;

    /**
     * Creates a MultipleKeyring instance.
     * @param address The address of keyring.
     * @param keys The keys to use in MultipleKeyring.
     */
    public MultipleKeyring(String address, PrivateKey[] 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) { validatedIndexWithKeys(index, this.keys.length); PrivateKey key = getKeyByRole(role)[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).

* MultipleKeyring doesn't define the role group, so it signs a transaction using all keys existed in MultipleKeyring.

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

Example :
     * {@code
     * MultipleKeyring keyring = new MultipleKeyring(.....);
     * List signatureList = keyring.ecsign("0xe9a11d9ef95fb437f75d07ce768d43e74f158dd54b106e7d3746ce29d545b550", AccountKeyRoleBased.RoleGroup.TRANSACTION);
     * }
     * 
* * @param txHash The hash of transaction. * @param role A number indicating the role of the key. see {@link com.klaytn.caver.account.AccountKeyRoleBased.RoleGroup}. * @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. * MultipleKeyring doesn't define the role group, so it signs a transaction using specific key existed in MultipleKeyring. * The role used in caver-java can be checked through {@link com.klaytn.caver.account.AccountKeyRoleBased.RoleGroup}. *
Example :
     * {@code
     * MultipleKeyring keyring = new MultipleKeyring(.....);
     * SignatureData signature = keyring.ecsign("0xe9a11d9ef95fb437f75d07ce768d43e74f158dd54b106e7d3746ce29d545b550", AccountKeyRoleBased.RoleGroup.TRANSACTION, 0);
     * }
     * 
* * @param txHash The hash transaction * @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 ecsign(String txHash, int role, int index) { validatedIndexWithKeys(index, this.keys.length); PrivateKey key = getKeyByRole(role)[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) { validatedIndexWithKeys(index, this.keys.length); PrivateKey key = getKeyByRole(role)[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 = KeyStore.Crypto.createCrypto(this.keys, password, options); KeyStore keyStore = new KeyStore(); keyStore.setAddress(this.address); keyStore.setVersion(KeyStore.KEY_STORE_VERSION_V4); keyStore.setId(UUID.randomUUID().toString()); keyStore.setKeyring(cryptoList); return keyStore; } /** * Returns a copied MultipleKeyring instance. *
Example :
     * {@code
     * AbstractKeyring copied = keyring.copy();
     * }
     * 
* * @return AbstractKeyring */ @Override public AbstractKeyring copy() { return new MultipleKeyring(address, 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 String[] getPublicKey() { return getPublicKey(false); } /** * Returns a public key strings. *
Example :
     * {@code
     * String[] publicKey = keyring.getPublicKey(false);
     * }
     * 
* * @param compressed Whether in compressed format or not. * @return String array */ public String[] getPublicKey(boolean compressed) { return Arrays.stream(this.keys).map(key -> { return key.getPublicKey(compressed); }).toArray(String[]::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. see {@link com.klaytn.caver.account.AccountKeyRoleBased.RoleGroup}. * @return {@code PrivateKey[]} */ public PrivateKey[] getKeyByRole(int role) { if(role < 0 || role >= AccountKeyRoleBased.ROLE_GROUP_COUNT) { throw new IllegalArgumentException("Invalid role index : " + role); } return this.keys; } /** * Returns an instance of Account. *
Example:
     * {@code
     * Account account = keyring.toAccount();
     * }
     * 
* * @return Account */ public Account toAccount() { WeightedMultiSigOptions options = WeightedMultiSigOptions.getDefaultOptionsForWeightedMultiSig(this.getPublicKey()); return toAccount(options); } /** * Returns an instance of Account *
Example:
     * {@code
     *  BigInteger[] optionWeight = {
     *     BigInteger.ONE, BigInteger.ONE, BigInteger.ONE,
     *  };
     *
     * WeightedMultiSigOptions weightedOption = new WeightedMultiSigOptions(
     *     BigInteger.ONE, Arrays.asList(optionWeight)
     * );
     *
     * Account account = keyring.toAccount(weightedOption);
     * }
     * 
* * @param options The options that includes 'threshold' and 'weight'. This is only necessary when keyring use multiple private keys. * @return Account */ public Account toAccount(WeightedMultiSigOptions options) { return Account.createWithAccountKeyWeightedMultiSig(address, this.getPublicKey(), options); } /** * Getter function of keys * @return PrivateKey Array */ public PrivateKey[] getKeys() { return keys; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy