mirror of
https://github.com/trezor/trezor-firmware.git
synced 2025-02-17 01:52:02 +00:00
Ethereum: EIP-155 replay protection
Added chain_id parameter to sign tx (and updated protobuf). Added a unit test with chain_id for Ropsten testnet. trezorctl: - Fixed compatibility with new ethjsonrpc - added chain_id parameter
This commit is contained in:
parent
4b98513ff7
commit
607893f9ac
@ -153,5 +153,32 @@ class TestMsgEthereumSigntx(common.TrezorTest):
|
|||||||
to=binascii.unhexlify('1d1c328764a41bda0492b66baa30c4a339ff85ef'),
|
to=binascii.unhexlify('1d1c328764a41bda0492b66baa30c4a339ff85ef'),
|
||||||
value=12345678901234567890)
|
value=12345678901234567890)
|
||||||
|
|
||||||
|
def test_ethereum_signtx_nodata_eip155(self):
|
||||||
|
self.setup_mnemonic_allallall()
|
||||||
|
|
||||||
|
sig_v, sig_r, sig_s = self.client.ethereum_sign_tx(
|
||||||
|
n=[0x80000000 | 44, 0x80000000 | 1, 0x80000000, 0, 0],
|
||||||
|
nonce=0,
|
||||||
|
gas_price=20000000000,
|
||||||
|
gas_limit=21000,
|
||||||
|
to=binascii.unhexlify('8ea7a3fccc211ed48b763b4164884ddbcf3b0a98'),
|
||||||
|
value=100000000000000000,
|
||||||
|
chain_id=3)
|
||||||
|
self.assertEqual(sig_v, 41)
|
||||||
|
self.assertEqual(binascii.hexlify(sig_r), 'a90d0bc4f8d63be69453dd62f2bb5fff53c610000abf956672564d8a654d401a')
|
||||||
|
self.assertEqual(binascii.hexlify(sig_s), '544a2e57bc8b4da18660a1e6036967ea581cc635f5137e3ba97a750867c27cf2')
|
||||||
|
|
||||||
|
sig_v, sig_r, sig_s = self.client.ethereum_sign_tx(
|
||||||
|
n=[0x80000000 | 44, 0x80000000 | 1, 0x80000000, 0, 0],
|
||||||
|
nonce=1,
|
||||||
|
gas_price=20000000000,
|
||||||
|
gas_limit=21000,
|
||||||
|
to=binascii.unhexlify('8ea7a3fccc211ed48b763b4164884ddbcf3b0a98'),
|
||||||
|
value=100000000000000000,
|
||||||
|
chain_id=3)
|
||||||
|
self.assertEqual(sig_v, 42)
|
||||||
|
self.assertEqual(binascii.hexlify(sig_r), '699428a6950e23c6843f1bf3754f847e64e047e829978df80d55187d19a401ce')
|
||||||
|
self.assertEqual(binascii.hexlify(sig_s), '087343d0a3a2f10842218ffccb146b59a8431b6245ab389fde22dc833f171e6e')
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
14
trezorctl
14
trezorctl
@ -182,6 +182,8 @@ class Commands(object):
|
|||||||
host, port = args.host.split(':')
|
host, port = args.host.split(':')
|
||||||
eth = EthJsonRpc(host, int(port))
|
eth = EthJsonRpc(host, int(port))
|
||||||
|
|
||||||
|
if not args.data:
|
||||||
|
args.gata = ''
|
||||||
if args.data.startswith('0x'):
|
if args.data.startswith('0x'):
|
||||||
args.data = args.data[2:]
|
args.data = args.data[2:]
|
||||||
data = binascii.unhexlify(args.data)
|
data = binascii.unhexlify(args.data)
|
||||||
@ -189,12 +191,12 @@ class Commands(object):
|
|||||||
if not gas_price:
|
if not gas_price:
|
||||||
gas_price = eth.eth_gasPrice()
|
gas_price = eth.eth_gasPrice()
|
||||||
|
|
||||||
if args.data:
|
if not gas_limit:
|
||||||
gas_limit = hex_to_dec(eth.eth_estimateGas(
|
gas_limit = eth.eth_estimateGas(
|
||||||
to_address=args.to,
|
to_address=args.to,
|
||||||
from_address=address,
|
from_address=address,
|
||||||
value=value,
|
value=("0x%x" % value),
|
||||||
data="0x"+args.data))
|
data="0x"+args.data)
|
||||||
|
|
||||||
if not nonce:
|
if not nonce:
|
||||||
nonce = eth.eth_getTransactionCount(address)
|
nonce = eth.eth_getTransactionCount(address)
|
||||||
@ -206,7 +208,8 @@ class Commands(object):
|
|||||||
gas_limit=gas_limit,
|
gas_limit=gas_limit,
|
||||||
to=to_address,
|
to=to_address,
|
||||||
value=value,
|
value=value,
|
||||||
data=data)
|
data=data,
|
||||||
|
chain_id=args.chain_id)
|
||||||
|
|
||||||
transaction = rlp.encode(
|
transaction = rlp.encode(
|
||||||
(nonce, gas_price, gas_limit, to_address, value, data) + sig)
|
(nonce, gas_price, gas_limit, to_address, value, data) + sig)
|
||||||
@ -411,6 +414,7 @@ class Commands(object):
|
|||||||
|
|
||||||
ethereum_sign_tx.arguments = (
|
ethereum_sign_tx.arguments = (
|
||||||
(('-a', '--host'), {'type': str, 'default': 'localhost:8545'}),
|
(('-a', '--host'), {'type': str, 'default': 'localhost:8545'}),
|
||||||
|
(('-c', '--chain-id'), {'type' : int, 'help': 'EIP-155 chain id (replay protection)', 'default': None}),
|
||||||
(('-n', '-address'), {'type': str}),
|
(('-n', '-address'), {'type': str}),
|
||||||
(('-v', '--value'), {'type': str, 'default': "0"}),
|
(('-v', '--value'), {'type': str, 'default': "0"}),
|
||||||
(('-g', '--gas'), {'type': int, 'help': 'Required for offline signing'}),
|
(('-g', '--gas'), {'type': int, 'help': 'Required for offline signing'}),
|
||||||
|
@ -503,7 +503,7 @@ class ProtocolMixin(object):
|
|||||||
return self.call(proto.EthereumGetAddress(address_n=n, show_display=show_display))
|
return self.call(proto.EthereumGetAddress(address_n=n, show_display=show_display))
|
||||||
|
|
||||||
@session
|
@session
|
||||||
def ethereum_sign_tx(self, n, nonce, gas_price, gas_limit, to, value, data=None):
|
def ethereum_sign_tx(self, n, nonce, gas_price, gas_limit, to, value, data=None, chain_id=None):
|
||||||
def int_to_big_endian(value):
|
def int_to_big_endian(value):
|
||||||
import rlp.utils
|
import rlp.utils
|
||||||
if value == 0:
|
if value == 0:
|
||||||
@ -527,6 +527,9 @@ class ProtocolMixin(object):
|
|||||||
data, chunk = data[1024:], data[:1024]
|
data, chunk = data[1024:], data[:1024]
|
||||||
msg.data_initial_chunk = chunk
|
msg.data_initial_chunk = chunk
|
||||||
|
|
||||||
|
if chain_id:
|
||||||
|
msg.chain_id = chain_id
|
||||||
|
|
||||||
response = self.call(msg)
|
response = self.call(msg)
|
||||||
|
|
||||||
while response.HasField('data_length'):
|
while response.HasField('data_length'):
|
||||||
|
Loading…
Reference in New Issue
Block a user