def ethereum_sign_tx(self, n, nonce, gas_price, gas_limit, to, value, data=''): from rlp.utils import int_to_big_endian n = self._convert_prime(n) try: self.transport.session_begin() response = self.call( proto.EthereumSignTx(address_n=n, nonce=int_to_big_endian(nonce), gas_price=int_to_big_endian(gas_price), gas_limit=int_to_big_endian(gas_limit), to=to, value=int_to_big_endian(value))) if data: data, chunk = data[1024:], data[:1024] response.data_initial_chunk = chunk response.data_length = len(data) while response.HasField('data_length'): data, chunk = data[1024:], data[:1024] response = self.call(proto.EthereumTxAck(data_chunk=chunk)) return response.signature_v, response.signature_r, response.signature_s finally: self.transport.session_end()
def ethereum_sign_tx(self, n, nonce, gas_price, gas_limit, to, value, data=''): from rlp.utils import int_to_big_endian n = self._convert_prime(n) try: self.transport.session_begin() response = self.call(proto.EthereumSignTx( address_n=n, nonce=int_to_big_endian(nonce), gas_price=int_to_big_endian(gas_price), gas_limit=int_to_big_endian(gas_limit), to=to, value=int_to_big_endian(value))) if data: data, chunk = data[1024:], data[:1024] response.data_initial_chunk = chunk response.data_length = len(data) while response.HasField('data_length'): data, chunk = data[1024:], data[:1024] response = self.call(proto.EthereumTxAck(data_chunk=chunk)) return response.signature_v, response.signature_r, response.signature_s finally: self.transport.session_end()
def sender(self): if not self._sender: if not is_bitcoin_available() or not is_secp256k1_available(): raise ImportError( "In order to derive the sender for transactions the " "`bitcoin` and `secp256k1` packages must be installed." ) from bitcoin import N from secp256k1 import PublicKey, ALL_FLAGS # Determine sender if self.v: has_invalid_signature_values = ( self.r >= N or self.s >= N or self.v < 27 or self.v > 28 or self.r == 0 or self.s == 0 ) if has_invalid_signature_values: raise ValueError("Invalid signature values!") rlpdata = rlp.encode(self, UnsignedTransaction) rawhash = decode_hex(sha3(rlpdata)) pk = PublicKey(flags=ALL_FLAGS) try: pk.public_key = pk.ecdsa_recover( rawhash, pk.ecdsa_recoverable_deserialize( pad_left( int_to_big_endian(self.r), 32, b'\x00', ) + pad_left( int_to_big_endian(self.s), 32, b'\x00', ), self.v - 27 ), raw=True ) pub = pk.serialize(compressed=False) except Exception: raise ValueError("Invalid signature values (x^3+7 is non-residue)") if pub[1:] == b"\x00" * (len(pub) - 1): raise ValueError("Invalid signature (zero privkey cannot sign)") self._sender = to_address(sha3(pub[1:])[-40:]) assert self.sender == self._sender else: self._sender = 0 return self._sender
def sender(self): if not self._sender: if not is_bitcoin_available() or not is_secp256k1_available(): raise ImportError( "In order to derive the sender for transactions the " "`bitcoin` and `secp256k1` packages must be installed.") from bitcoin import N from secp256k1 import PublicKey, ALL_FLAGS # Determine sender if self.v: has_invalid_signature_values = (self.r >= N or self.s >= N or self.v < 27 or self.v > 28 or self.r == 0 or self.s == 0) if has_invalid_signature_values: raise ValueError("Invalid signature values!") rlpdata = rlp.encode(self, UnsignedTransaction) rawhash = decode_hex(sha3(rlpdata)) pk = PublicKey(flags=ALL_FLAGS) try: pk.public_key = pk.ecdsa_recover( rawhash, pk.ecdsa_recoverable_deserialize( pad_left( int_to_big_endian(self.r), 32, b'\x00', ) + pad_left( int_to_big_endian(self.s), 32, b'\x00', ), self.v - 27), raw=True) pub = pk.serialize(compressed=False) except Exception: raise ValueError( "Invalid signature values (x^3+7 is non-residue)") if pub[1:] == b"\x00" * (len(pub) - 1): raise ValueError( "Invalid signature (zero privkey cannot sign)") self._sender = to_address(sha3(pub[1:])[-40:]) assert self.sender == self._sender else: self._sender = 0 return self._sender
def serialize_block(block, full_transactions): if full_transactions: transactions = [ serialize_txn(block, txn, txn_index) for txn_index, txn in enumerate(block.transaction_list) ] else: transactions = [encode_32bytes(txn.hash) for txn in block.transaction_list] logs_bloom_bytes = int_to_big_endian(block.bloom) return { "number": encode_number(block.number), "hash": encode_32bytes(block.hash), "parentHash": encode_32bytes(block.prevhash), "nonce": encode_data(block.nonce, 8), "sha3Uncles": encode_32bytes(block.uncles_hash), "logsBloom": encode_data(logs_bloom_bytes, 256), "transactionsRoot": encode_32bytes(block.tx_list_root), "stateRoot": encode_32bytes(block.state_root), "miner": encode_address(block.coinbase), "difficulty": encode_number(block.difficulty), "totalDifficulty": encode_number(block.chain_difficulty()), "size": encode_number(len(rlp.encode(block))), "extraData": encode_32bytes(block.extra_data), "gasLimit": encode_number(block.gas_limit), "gasUsed": encode_number(block.gas_used), "timestamp": encode_number(block.timestamp), "transactions": transactions, "uncles": block.uncles }
def serialize_block(block, full_transactions): if full_transactions: transactions = [ serialize_txn(block, txn, txn_index) for txn_index, txn in enumerate(block.transaction_list) ] else: transactions = [ encode_32bytes(txn.hash) for txn in block.transaction_list ] logs_bloom_bytes = int_to_big_endian(block.bloom) return { "number": encode_number(block.number), "hash": encode_32bytes(block.hash), "parentHash": encode_32bytes(block.prevhash), "nonce": encode_data(block.nonce, 8), "sha3Uncles": encode_32bytes(block.uncles_hash), "logsBloom": encode_data(logs_bloom_bytes, 256), "transactionsRoot": encode_32bytes(block.tx_list_root), "stateRoot": encode_32bytes(block.state_root), "miner": encode_address(block.coinbase), "difficulty": encode_number(block.difficulty), "totalDifficulty": encode_number(block.chain_difficulty()), "size": encode_number(len(rlp.encode(block))), "extraData": encode_32bytes(block.extra_data), "gasLimit": encode_number(block.gas_limit), "gasUsed": encode_number(block.gas_used), "timestamp": encode_number(block.timestamp), "transactions": transactions, "uncles": block.uncles }
def encode_number(value, length=None): """Encode interger quantity `data`.""" if not is_numeric(value): raise ValueError("Unsupported type: {0}".format(type(value))) hex_value = encode_data(int_to_big_endian(value), length) if length: return hex_value else: return add_0x(strip_0x(hex_value).lstrip(b'0') or b'0')
def encode_number(value, length=None): '''Encode interger quantity `data`.''' if not is_numeric(value): raise ValueError("Unsupported type: {0}".format(type(value))) hex_value = encode_data(int_to_big_endian(value), length) if length: return hex_value else: return add_0x(strip_0x(hex_value).lstrip(b'0') or b'0')
def encode(value, length): # pylint: disable=unused-argument return int_to_big_endian(value)
def test_ethereum_signtx_data(self): self.setup_mnemonic_nopin_nopassphrase() self.client.apply_policy('AdvancedMode', 0) with self.client: ret = self.client.call_raw( proto.EthereumSignTx( address_n=[0, 0], nonce=int_to_big_endian(0), gas_price=int_to_big_endian(20), gas_limit=int_to_big_endian(20), value=int_to_big_endian(10), to=binascii.unhexlify( '1d1c328764a41bda0492b66baa30c4a339ff85ef'), data_initial_chunk='abcdefghijklmnop' * 64, data_length=1024)) # Confirm the Output self.assertEqual( ret, proto.ButtonRequest( code=proto_types.ButtonRequest_ConfirmOutput)) self.client.debug.press_yes() ret = self.client.call_raw(proto.ButtonAck()) # Confirm Warning about AdvancedMode being turned off self.assertEqual( ret, proto.ButtonRequest(code=proto_types.ButtonRequest_Other)) self.client.debug.press_yes() ret = self.client.call_raw(proto.ButtonAck()) self.assertEqual(ret.code, proto_types.Failure_ActionCancelled) self.client.apply_policy('AdvancedMode', 1) sig_v, sig_r, sig_s = self.client.ethereum_sign_tx( n=[0, 0], nonce=0, gas_price=20, gas_limit=20, to=binascii.unhexlify('1d1c328764a41bda0492b66baa30c4a339ff85ef'), value=10, data='abcdefghijklmnop' * 16) self.assertEqual(sig_v, 28) self.assertEqual( binascii.hexlify(sig_r), '6da89ed8627a491bedc9e0382f37707ac4e5102e25e7a1234cb697cedb7cd2c0') self.assertEqual( binascii.hexlify(sig_s), '691f73b145647623e2d115b208a7c3455a6a8a83e3b4db5b9c6d9bc75825038a') sig_v, sig_r, sig_s = self.client.ethereum_sign_tx( n=[0, 0], nonce=123456, gas_price=20000, gas_limit=20000, to=binascii.unhexlify('1d1c328764a41bda0492b66baa30c4a339ff85ef'), value=12345678901234567890, data='ABCDEFGHIJKLMNOP' * 256 + '!!!') self.assertEqual(sig_v, 28) self.assertEqual( binascii.hexlify(sig_r), '4e90b13c45c6a9bf4aaad0e5427c3e62d76692b36eb727c78d332441b7400404') self.assertEqual( binascii.hexlify(sig_s), '3ff236e7d05f0f9b1ee3d70599bb4200638f28388a8faf6bb36db9e04dc544be') self.client.apply_policy('AdvancedMode', 0)
def encoded_abi_signature(self): return zpad(int_to_big_endian(self.abi_signature), 4)