コード例 #1
0
ファイル: identity.py プロジェクト: KaseMaster/snet-cli
    def transact(self, transaction, out_f):
        print("Sending transaction to trezor for signature...\n", file=out_f)
        signature = self.client.ethereum_sign_tx(
            n=[
                44 + bip32utils.BIP32_HARDEN, 60 + bip32utils.BIP32_HARDEN,
                bip32utils.BIP32_HARDEN, 0, self.index
            ],
            nonce=transaction["nonce"],
            gas_price=transaction["gasPrice"],
            gas_limit=transaction["gas"],
            to=bytearray.fromhex(transaction["to"][2:]),
            value=transaction["value"],
            data=bytearray.fromhex(transaction["data"][2:]))

        transaction.pop("from")
        unsigned_transaction = serializable_unsigned_transaction_from_dict(
            transaction)
        raw_transaction = encode_transaction(unsigned_transaction,
                                             vrs=(signature[0],
                                                  int(signature[1].hex(), 16),
                                                  int(signature[2].hex(), 16)))

        print("Submitting transaction...\n", file=out_f)
        txn_hash = self.w3.eth.sendRawTransaction(raw_transaction)

        # Wait for transaction to be mined
        receipt = None
        while receipt is None:
            time.sleep(1)
            receipt = self.w3.eth.getTransactionReceipt(txn_hash)

        return receipt
コード例 #2
0
ファイル: base.py プロジェクト: yfilali/Devise
    def _transact(self, function_call=None, transaction=None):
        """Transaction utility: builds a transaction and signs it with private key, or uses native transactions with
        accounts
        """
        # If we have no local means to sign transactions, raise error
        if not (self._ledger or self._key_file or self._private_key):
            raise ValueError(
                "No valid signing method found!\n"
                "Please specify one of: key_file, private_key, auth_type='ledger' or auth_type='trezor'"
            )

        private_key = self._private_key
        if self._key_file:
            password = self._password or getpass(
                "Password to decrypt keystore file %s: " % self.account)
            private_key = self._get_private_key(self._key_file, password)

        # get the nonce for the current address
        nonce = self.w3.eth.getTransactionCount(self.address)
        # Build a transaction to sign
        gas_buffer = 100000
        # Estimate gas cost
        if transaction is None:
            transaction = {}
        transaction.update({
            'nonce': nonce,
            'gas': 4000000,
            'gasPrice': self.w3.eth.generateGasPrice()
        })
        if function_call:
            transaction = function_call.buildTransaction(transaction)

        gas_limit = self.w3.eth.estimateGas(transaction) + gas_buffer
        transaction.update({'gas': gas_limit})

        if 'from' in transaction:
            del transaction['from']
        if private_key:
            # Sign the transaction using the private key and send it as raw transaction
            signed_tx = self.w3.eth.account.signTransaction(
                transaction, '0x' + private_key)
            tx_hash = self.w3.eth.sendRawTransaction(signed_tx.rawTransaction)
        else:
            unsigned_transaction = serializable_unsigned_transaction_from_dict(
                transaction)
            pos = self._ledger.get_account_index(self.address)
            (v, r, s) = self._ledger.sign(rlp.encode(unsigned_transaction),
                                          account_index=pos)
            encoded_transaction = encode_transaction(unsigned_transaction,
                                                     vrs=(v, r, s))
            tx_hash = self.w3.eth.sendRawTransaction(encoded_transaction)

        self.logger.info(
            "Submitted transaction %s, waiting for transaction receipt..." %
            tx_hash.hex())
        tx_receipt = self._wait_for_receipt(tx_hash)

        return hasattr(tx_receipt, "status") and tx_receipt["status"] == 1
コード例 #3
0
    def _sign_web3_transaction(tx: Dict[str, any], v: int, r: int,
                               s: int) -> (bytes, HexBytes):
        """
        Signed transaction can be send with w3.eth.sendRawTransaction
        """
        unsigned_transaction = serializable_unsigned_transaction_from_dict(tx)
        rlp_encoded_transaction = encode_transaction(unsigned_transaction,
                                                     vrs=(v, r, s))

        # To get the address signing, just do ecrecover_to_pub(unsigned_transaction.hash(), v, r, s)
        return rlp_encoded_transaction, unsigned_transaction.hash()
コード例 #4
0
ファイル: identity.py プロジェクト: rajeevbbqq/snet-cli
    def transact(self, transaction, out_f):
        tx = UnsignedTransaction(
            nonce=transaction["nonce"],
            gasPrice=transaction["gasPrice"],
            gas=transaction["gas"],
            to=bytes(bytearray.fromhex(transaction["to"][2:])),
            value=transaction["value"],
            data=bytes(bytearray.fromhex(transaction["data"][2:])))

        encoded_tx = rlp.encode(tx, UnsignedTransaction)

        overflow = len(self.dongle_path) + 1 + len(encoded_tx) - 255

        if overflow > 0:
            encoded_tx, remaining_tx = encoded_tx[:-overflow], encoded_tx[
                -overflow:]

        apdu = LedgerIdentityProvider.SIGN_TX_OP
        apdu += bytearray([
            len(self.dongle_path) + 1 + len(encoded_tx),
            int(len(self.dongle_path) / 4)
        ])
        apdu += self.dongle_path + encoded_tx
        try:
            print("Sending transaction to ledger for signature...\n",
                  file=out_f)
            result = self.dongle.exchange(apdu)
            while overflow > 0:
                encoded_tx = remaining_tx
                overflow = len(encoded_tx) - 255

                if overflow > 0:
                    encoded_tx, remaining_tx = encoded_tx[:
                                                          -overflow], encoded_tx[
                                                              -overflow:]

                apdu = LedgerIdentityProvider.SIGN_TX_OP_CONT
                apdu += bytearray([len(encoded_tx)])
                apdu += encoded_tx
                result = self.dongle.exchange(apdu)
        except CommException:
            raise RuntimeError(
                "Received commException from ledger. Are you sure your device is unlocked and the "
                "Ethereum app is running?")

        transaction.pop("from")
        unsigned_transaction = serializable_unsigned_transaction_from_dict(
            transaction)
        raw_transaction = encode_transaction(
            unsigned_transaction,
            vrs=(result[0], int.from_bytes(result[1:33], byteorder="big"),
                 int.from_bytes(result[33:65], byteorder="big")))
        return send_and_wait_for_transaction(raw_transaction, self.w3, out_f)
コード例 #5
0
ファイル: identity.py プロジェクト: arturgontijo/snet-cli
    def transact(self, transaction, out_f):
        tx = UnsignedTransaction(
            nonce=transaction["nonce"],
            gasPrice=transaction["gasPrice"],
            gas=transaction["gas"],
            to=bytes(bytearray.fromhex(transaction["to"][2:])),
            value=transaction["value"],
            data=bytes(bytearray.fromhex(transaction["data"][2:]))
        )

        encoded_tx = rlp.encode(tx, UnsignedTransaction)

        overflow = len(self.dongle_path) + 1 + len(encoded_tx) - 255

        if overflow > 0:
            encoded_tx, remaining_tx = encoded_tx[:-
                                                  overflow], encoded_tx[-overflow:]

        apdu = LedgerIdentityProvider.SIGN_TX_OP
        apdu += bytearray([len(self.dongle_path) + 1 +
                           len(encoded_tx), int(len(self.dongle_path) / 4)])
        apdu += self.dongle_path + encoded_tx
        try:
            print("Sending transaction to ledger for signature...\n", file=out_f)
            result = self.dongle.exchange(apdu)
            while overflow > 0:
                encoded_tx = remaining_tx
                overflow = len(encoded_tx) - 255

                if overflow > 0:
                    encoded_tx, remaining_tx = encoded_tx[:-
                                                          overflow], encoded_tx[-overflow:]

                apdu = LedgerIdentityProvider.SIGN_TX_OP_CONT
                apdu += bytearray([len(encoded_tx)])
                apdu += encoded_tx
                result = self.dongle.exchange(apdu)
        except CommException:
            raise RuntimeError("Received commException from ledger. Are you sure your device is unlocked and the "
                               "Ethereum app is running?")

        transaction.pop("from")
        unsigned_transaction = serializable_unsigned_transaction_from_dict(
            transaction)
        raw_transaction = encode_transaction(unsigned_transaction,
                                             vrs=(result[0],
                                                  int.from_bytes(
                                                      result[1:33], byteorder="big"),
                                                  int.from_bytes(result[33:65], byteorder="big")))
        return send_and_wait_for_transaction(raw_transaction, self.w3, out_f)
コード例 #6
0
def sign_keyvault(client, vault_url, key_name, key_version, tx, chain_id=0):
    unsigned_tx = serializable_unsigned_transaction_from_dict(tx)
    unsigned_tx_hash = unsigned_tx.hash()
    key_bundle = client.get_key(vault_url, key_name, key_version)
    json_key = key_bundle.key
    pubkey = convert_json_key_to_public_key_bytes(json_key)
    address_signer = public_key_to_address(pubkey[1:])

    sig_resp = client.sign(vault_url, key_name, key_version, 'ECDSA256', unsigned_tx_hash)

    vrs = convert_azure_secp256k1_signature_to_vrs(pubkey, unsigned_tx_hash, sig_resp.result, chain_id)

    ret_signed_transaction = encode_transaction(unsigned_tx, vrs)
    return address_signer, ret_signed_transaction
コード例 #7
0
    def transact(self, transaction, out_f):
        print("Sending transaction to trezor for signature...\n", file=out_f)
        signature = self.client.ethereum_sign_tx(n=[44 + BIP32_HARDEN, 60 + BIP32_HARDEN,
                                                    BIP32_HARDEN, 0, self.index],
                                                 nonce=transaction["nonce"],
                                                 gas_price=transaction["gasPrice"],
                                                 gas_limit=transaction["gas"],
                                                 to=bytearray.fromhex(transaction["to"][2:]),
                                                 value=transaction["value"],
                                                 data=bytearray.fromhex(transaction["data"][2:]))

        transaction.pop("from")
        unsigned_transaction = serializable_unsigned_transaction_from_dict(transaction)
        raw_transaction = encode_transaction(unsigned_transaction,
                                             vrs=(signature[0],
                                                  int(signature[1].hex(), 16),
                                                  int(signature[2].hex(), 16)))
        return send_and_wait_for_transaction(raw_transaction, self.w3, out_f)
コード例 #8
0
    def transact(self, transaction, out_f):
        tx = UnsignedTransaction(
            nonce=transaction["nonce"],
            gasPrice=transaction["gasPrice"],
            gas=transaction["gas"],
            to=bytes(bytearray.fromhex(transaction["to"][2:])),
            value=transaction["value"],
            data=bytes(bytearray.fromhex(transaction["data"][2:])))

        encoded_tx = rlp.encode(tx, UnsignedTransaction)

        apdu = LedgerIdentityProvider.SIGN_TX_OP
        apdu += bytearray([
            len(self.dongle_path) + 1 + len(encoded_tx),
            int(len(self.dongle_path) / 4)
        ])
        apdu += self.dongle_path + encoded_tx
        try:
            print("Sending transaction to ledger for signature...\n",
                  file=out_f)
            result = self.dongle.exchange(apdu)
        except CommException:
            raise RuntimeError(
                "Received commException from ledger. Are you sure your device is unlocked and the "
                "Ethereum app is running?")

        transaction.pop("from")
        unsigned_transaction = serializable_unsigned_transaction_from_dict(
            transaction)
        raw_transaction = encode_transaction(
            unsigned_transaction,
            vrs=(result[0], int.from_bytes(result[1:33], byteorder="big"),
                 int.from_bytes(result[33:65], byteorder="big")))

        print("Submitting transaction...\n", file=out_f)
        txn_hash = self.w3.eth.sendRawTransaction(raw_transaction)

        # Wait for transaction to be mined
        receipt = None
        while receipt is None:
            time.sleep(1)
            receipt = self.w3.eth.getTransactionReceipt(txn_hash)

        return receipt
コード例 #9
0
def sign_keyvault(addressSigner,
                  signingClient,
                  vault_url,
                  key_name,
                  key_version,
                  tx,
                  chain_id=0):
    unsigned_tx = serializable_unsigned_transaction_from_dict(tx)
    unsigned_tx_hash = unsigned_tx.hash()
    valid = False
    while not valid:
        sig_resp = signingClient.sign(vault_url, key_name, key_version,
                                      'ES256K', unsigned_tx_hash)
        v, r, s, valid = util.convert_azure_secp256k1_signature_to_vrs(
            pubkey, unsigned_tx_hash, sig_resp.result, chain_id)

    vrs = (v, r, s)
    ret_signed_transaction = encode_transaction(unsigned_tx, vrs)
    return address_signer, ret_signed_transaction
コード例 #10
0
ファイル: identity.py プロジェクト: arturgontijo/snet-cli
    def transact(self, transaction, out_f):
        print("Sending transaction to trezor for signature...\n", file=out_f)
        signature = self.client.ethereum_sign_tx(n=[44 + BIP32_HARDEN, 60 + BIP32_HARDEN,
                                                    BIP32_HARDEN, 0, self.index],
                                                 nonce=transaction["nonce"],
                                                 gas_price=transaction["gasPrice"],
                                                 gas_limit=transaction["gas"],
                                                 to=bytearray.fromhex(
                                                     transaction["to"][2:]),
                                                 value=transaction["value"],
                                                 data=bytearray.fromhex(transaction["data"][2:]))

        transaction.pop("from")
        unsigned_transaction = serializable_unsigned_transaction_from_dict(
            transaction)
        raw_transaction = encode_transaction(unsigned_transaction,
                                             vrs=(signature[0],
                                                  int(signature[1].hex(), 16),
                                                  int(signature[2].hex(), 16)))
        return send_and_wait_for_transaction(raw_transaction, self.w3, out_f)
コード例 #11
0
def sign_transaction_dict(eth_key, transaction_dict):
    # generate RLP-serializable transaction, with defaults filled
    unsigned_transaction = serializable_unsigned_transaction_from_dict(
        transaction_dict)

    transaction_hash = unsigned_transaction.hash()

    # detect chain
    if isinstance(unsigned_transaction, UnsignedTransaction):
        chain_id = None
    else:
        chain_id = unsigned_transaction.v

    # sign with private key
    (v, r, s) = sign_transaction_hash(eth_key, transaction_hash, chain_id)

    # serialize transaction with rlp
    encoded_transaction = encode_transaction(unsigned_transaction,
                                             vrs=(v, r, s))

    return (v, r, s, encoded_transaction)
コード例 #12
0
    def signTx(cls, tx):
        def int_to_big_endian(value):
            return value.to_bytes((value.bit_length() + 7) // 8, 'big')

        address_n = tools.parse_path(cls.hdpath())

        msg = proto.EthereumSignTx(address_n=address_n,
                                   nonce=int_to_big_endian(tx['nonce']),
                                   gas_price=int_to_big_endian(tx['gasPrice']),
                                   gas_limit=int_to_big_endian(tx['gas']),
                                   chain_id=int(tx['chainId']),
                                   value=int_to_big_endian(tx['value']))

        if tx['to']:
            msg.to = tx['to']

        data = None

        if tx['data'].__class__ is str:
            data = bytes.fromhex(tx['data'].replace('0x', ''))
        elif tx['data'].__class__ is bytes:
            data = tx['data']

        if data:
            msg.data_length = len(data)
            data, chunk = data[1024:], data[:1024]
            msg.data_initial_chunk = chunk

        try:
            response = cls.call_raw(msg, atomic=False)

            # Confused?   Ask trezor why.  I don't know why.
            # ButtonAck is a no-op afaict.  But you still have to send it.
            # Punch the monkey.
            # Punch it.
            # Punch the monkey.
            # Punch the monkey.
            # Punch the monkey.
            while response.__class__.__name__ == 'ButtonRequest':
                response = cls.call_raw(proto.ButtonAck())

            if response.__class__.__name__ == 'PinMatrixRequest':
                cls.matrix_request_window()
                raise SignTxError("Credstick needs to be unlocked")
            elif response.__class__.__name__ == 'PassphraseRequest':
                cls.passphrase_request_window()
                raise SignTxError("Credstick needs to be unlocked")
            elif response.__class__.__name__ == 'Failure':
                raise SignTxError

        except TransportException:
            raise SignTxError

        while response.data_length is not None:
            data_length = response.data_length
            data, chunk = data[data_length:], data[:data_length]
            response = cls.call_raw(proto.EthereumTxAck(data_chunk=chunk),
                                    atomic=False)

        # above, we were calling out with atomic=False to
        # prevent the session from being terminated.
        cls.transport.end_session()

        _v = response.signature_v
        _r = response.signature_r
        _s = response.signature_s

        sutx = serializable_unsigned_transaction_from_dict(tx)

        return cls.signed_tx(sutx, _v, int(_r.hex(), 16), int(_s.hex(), 16))
コード例 #13
0
    def signTx(cls, transaction_dict):
        apdu = None

        try:
            tx = serializable_unsigned_transaction_from_dict(transaction_dict)
            encodedTx = rlp.encode(tx)
            encodedPath = encode_path(cls.hdpath())
            # Each path element is 4 bytes.  How many path elements are we sending?

            derivationPathCount = (len(encodedPath) // 4).to_bytes(1, 'big')
            # Prepend the byte representing the count of path elements to the path encoding itself.
            encodedPath = derivationPathCount + encodedPath
            dataPayload = encodedPath + encodedTx

            # Big thanks to the Geth team for their ledger implementation (and documentation).
            # You guys are stars.
            #
            # To the others reading, the ledger can only take 255 bytes of data payload per apdu exchange.
            # hence, you have to chunk and use 0x08 for the P1 opcode on subsequent calls.

            p1_op = P1_FIRST_TRANS_DATA_BLOCK

            while len(dataPayload) > 0:
                chunkSize = 255
                if chunkSize > len(dataPayload):
                    chunkSize = len(dataPayload)

                encodedChunkSize = (chunkSize).to_bytes(1, 'big')
                apdu = CLA + INS_OPCODE_SIGN_TRANS + p1_op + P2_UNUSED_PARAMETER + encodedChunkSize + dataPayload[:
                                                                                                                  chunkSize]

                ## Keeping this here commented in case I need to debug it again.
                #apdufile = ''.join(random.choices(string.ascii_uppercase + string.digits, k=8))
                #f = open('logs/{}'.format(apdufile), 'wb')
                #f.write(apdu)
                #f.close()

                result = cls._driver.exchange(apdu)

                dataPayload = dataPayload[chunkSize:]
                p1_op = P1_SUBSEQUENT_TRANS_DATA_BLOCK

            _v = result[0]
            _r = int((result[1:1 + 32]).hex(), 16)
            _s = int((result[1 + 32:1 + 32 + 32]).hex(), 16)

            stx = cls.signed_tx(tx, _v, _r, _s)

        except (CommException, BaseException) as e:
            if apdu:
                logging.debug(
                    "Ledger device threw error {} while attempting SignTx with apdu {}"
                    .format(e, apdu))
                raise SignTxError(
                    "Ledger device threw error {}  while attempting SignTx with apdu {}"
                    .format(e, apdu))
            else:
                logging.debug(
                    "Ledger device threw error {} while attempting SignTx".
                    format(e))
                raise SignTxError(
                    "Ledger device threw error  while attempting SignTx: {}".
                    format(e))
        return stx
コード例 #14
0
ファイル: base.py プロジェクト: xuesong-hu/Devise
    def _transact(self, function_call=None, transaction=None):
        """Transaction utility: builds a transaction and signs it with private key, or uses native transactions with
        accounts
        """
        # If we have no local means to sign transactions, raise error
        if not (self._ledger or self._key_file or self._private_key):
            raise ValueError(
                "No valid signing method found!\n"
                "Please specify one of: key_file, private_key, auth_type='ledger' or auth_type='trezor'"
            )

        private_key = self._private_key
        if self._key_file:
            password = self._password or getpass(
                "Password to decrypt keystore file %s: " % self.account)
            private_key = self._get_private_key(self._key_file, password)

        # Build a transaction to sign
        gas_buffer = 100000
        # Estimate gas cost
        if transaction is None:
            transaction = {}

        auto_gas_price = self.w3.eth.generateGasPrice()
        user_gas_price = transaction.get('gasPrice')
        transaction.update({
            'nonce':
            transaction.get("nonce",
                            self.w3.eth.getTransactionCount(self.address)),
            'gas':
            4000000,
            'gasPrice':
            auto_gas_price
        })
        if function_call:
            transaction = function_call.buildTransaction(transaction)

        gas_limit = self.w3.eth.estimateGas(transaction) + gas_buffer
        transaction.update({
            'gas':
            gas_limit,
            'gasPrice':
            user_gas_price if user_gas_price is not None else auto_gas_price
        })

        if 'from' in transaction:
            del transaction['from']
        if private_key:
            # Sign the transaction using the private key and send it as raw transaction
            signed_tx = self.w3.eth.account.signTransaction(
                transaction, '0x' + private_key)
            tx_hash = self.w3.eth.sendRawTransaction(signed_tx.rawTransaction)
        else:
            unsigned_transaction = serializable_unsigned_transaction_from_dict(
                transaction)
            pos = self._ledger.get_account_index(self.address)
            self.logger.info(
                "Signing transaction with your hardware wallet, please confirm on the hardware device when prompted..."
            )
            (v, r, s) = self._ledger.sign(rlp.encode(unsigned_transaction),
                                          account_index=pos)
            encoded_transaction = encode_transaction(unsigned_transaction,
                                                     vrs=(v, r, s))
            tx_hash = self.w3.eth.sendRawTransaction(encoded_transaction)

        self.logger.info(
            "Submitted transaction %s, waiting for transaction receipt..." %
            tx_hash.hex())
        tx_receipt = None
        while not tx_receipt:
            try:
                tx_receipt = self._wait_for_receipt(tx_hash)
            except web3.utils.threads.Timeout:
                self.logger.warning(
                    "Transaction still pending after 1 minute, waiting some more..."
                )

        self.logger.info(
            "Gas used: %s at gas price of %.2f gwei (%.8f ether)" %
            (tx_receipt.get("gasUsed"),
             self.w3.fromWei(transaction.get("gasPrice"), 'gwei'),
             self.w3.fromWei(
                 tx_receipt.get("gasUsed") * transaction.get("gasPrice"),
                 'ether')))

        return hasattr(tx_receipt, "status") and tx_receipt["status"] == 1