Skip to content

Commit

Permalink
Merge pull request #147 from skalenetwork/fix/update-for-the-latest-sm
Browse files Browse the repository at this point in the history
SKALE-2468 Add sign_hash to RPC wallet, update tests
  • Loading branch information
badrogger authored Apr 23, 2020
2 parents 1c0ffeb + ad536e2 commit 87a49b2
Show file tree
Hide file tree
Showing 9 changed files with 83 additions and 10 deletions.
4 changes: 2 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@

setup(
name='skale.py',
version='3.4',
version='3.5',
description='SKALE client tools',
long_description_markdown_filename='README.md',
author='SKALE Labs',
Expand All @@ -42,7 +42,7 @@
"web3==5.5.1",
"asyncio==3.4.3",
"pyyaml==5.3.1",
"sgx.py==0.4.dev6",
"sgx.py==0.5dev0",
],

python_requires='>=3.6,<4',
Expand Down
8 changes: 3 additions & 5 deletions skale/contracts/delegation/validator_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
# along with SKALE.py. If not, see <https://www.gnu.org/licenses/>.

from web3 import Web3
from eth_account import messages

from skale.contracts import BaseContract, transaction_method
from skale.utils.helper import format_fields
Expand Down Expand Up @@ -191,10 +190,9 @@ def register_validator(self, name: str, description: str, fee_rate: int,
name, description, fee_rate, min_delegation_amount)

def get_link_node_signature(self, validator_id: int) -> str:
unsigned_data = Web3.soliditySha3(['uint256'], [validator_id])
unsigned_message = messages.encode_defunct(hexstr=unsigned_data.hex())
signed_message = self.skale.wallet.sign_message(unsigned_message)
return signed_message.signature.hex()
unsigned_hash = Web3.soliditySha3(['uint256'], [validator_id])
signed_hash = self.skale.wallet.sign_hash(unsigned_hash.hex())
return signed_hash.signature.hex()

@transaction_method(GAS['link_node_address'])
def link_node_address(self, node_address: str, signature: str) -> TxRes:
Expand Down
4 changes: 4 additions & 0 deletions skale/wallets/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ def sign(self, tx):
def sign_and_send(self, tx_dict) -> str:
pass

@abstractmethod
def sign_hash(self, unsigned_hash: str):
pass

@property
@abstractmethod
def address(self):
Expand Down
3 changes: 3 additions & 0 deletions skale/wallets/ledger_wallet.py
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,9 @@ def sign_and_send(self, tx) -> str:
signed_tx = self.sign(tx)
return self._web3.eth.sendRawTransaction(signed_tx.rawTransaction).hex()

def sign_hash(self, unsigned_hash: str):
raise NotImplementedError('sign_hash is not implemented for hardware wallet')

@classmethod
def parse_derive_result(cls, exchange_result):
pk_len = exchange_result[0]
Expand Down
16 changes: 15 additions & 1 deletion skale/wallets/rpc_wallet.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,11 @@
import json
import logging
import urllib
import requests
import functools
import requests

from hexbytes import HexBytes
from eth_account.datastructures import AttributeDict

from skale.wallets.common import BaseWallet
from skale.utils.exceptions import RPCWalletError
Expand All @@ -32,6 +35,7 @@
ROUTES = {
'sign': '/sign',
'sign_and_send': '/sign-and-send',
'sign_hash': '/sign-hash',
'address': '/address',
'public_key': '/public-key',
}
Expand Down Expand Up @@ -79,6 +83,16 @@ def sign_and_send(self, tx_dict):
data = self._post(ROUTES['sign_and_send'], self._compose_tx_data(tx_dict))
return data['transaction_hash']

def sign_hash(self, unsigned_hash: str):
data = self._post(ROUTES['sign_hash'], {'unsigned_hash': unsigned_hash})
return AttributeDict({
'messageHash': HexBytes(data['messageHash']),
'r': data['r'],
's': data['s'],
'v': data['v'],
'signature': HexBytes(data['signature']),
})

@property
def address(self):
data = self._get(ROUTES['address'])
Expand Down
3 changes: 3 additions & 0 deletions skale/wallets/sgx_wallet.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ def sign_and_send(self, tx_dict) -> str:
signed_tx = self.sign(tx_dict)
return self._web3.eth.sendRawTransaction(signed_tx.rawTransaction).hex()

def sign_hash(self, unsigned_hash: str):
return self.sgx_client.sign_hash(unsigned_hash, self._key_name, self._web3.eth.chainId)

@property
def address(self):
return self._address
Expand Down
6 changes: 4 additions & 2 deletions skale/wallets/web3_wallet.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

from eth_keys import keys
from web3 import Web3
from eth_account import messages

from skale.wallets.common import BaseWallet
from skale.utils.web3_utils import get_eth_nonce
Expand Down Expand Up @@ -66,9 +67,10 @@ def sign(self, tx_dict):
private_key=self._private_key
)

def sign_message(self, unsigned_hash: str):
def sign_hash(self, unsigned_hash: str):
unsigned_message = messages.encode_defunct(hexstr=unsigned_hash)
return self._web3.eth.account.sign_message(
unsigned_hash,
unsigned_message,
private_key=self._private_key
)

Expand Down
30 changes: 30 additions & 0 deletions tests/wallets/rpc_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@
import pytest
import mock
import requests

from hexbytes import HexBytes
from eth_account.datastructures import AttributeDict

from skale.wallets.rpc_wallet import RPCWallet
from skale.utils.exceptions import RPCWalletError

Expand Down Expand Up @@ -56,6 +60,32 @@ def test_sign():
assert tx_hash == EMPTY_HEX_STR


def test_sign_hash():
wallet = RPCWallet(TEST_RPC_WALLET_URL)
sign_hash_response_data = {
'data': {
'messageHash': '0x0',
'r': 123,
's': 123,
'v': 27,
'signature': '0x0'
},
'error': None
}
res_mock = response_mock(HTTPStatus.OK, sign_hash_response_data)
with mock.patch('requests.post', new=request_mock(res_mock)):
signed_hash = wallet.sign_hash(TX_DICT)
assert signed_hash == AttributeDict(
{
'messageHash': HexBytes('0x00'),
'r': 123,
's': 123,
'v': 27,
'signature': HexBytes('0x00')
}
)


def test_address():
wallet = RPCWallet(TEST_RPC_WALLET_URL)
res_mock = response_mock(HTTPStatus.OK,
Expand Down
19 changes: 19 additions & 0 deletions tests/wallets/sgx_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,15 @@ def sign(self, transaction_dict, key_name):
'v': 37,
})

def sign_hash(self, message, key_name, chain_id):
return AttributeDict({
'messageHash': HexBytes('0x0'),
'r': 123,
's': 123,
'v': 27,
'signature': HexBytes('0x0')
})


def test_sgx_sign():
with mock.patch('skale.wallets.sgx_wallet.SgxClient',
Expand Down Expand Up @@ -113,6 +122,16 @@ def test_sgx_sign_with_key():
wallet.sign(tx_dict)


def test_sgx_sign_hash():
with mock.patch('skale.wallets.sgx_wallet.SgxClient',
new=SgxClient):
web3 = init_web3(ENDPOINT)
wallet = SgxWallet('TEST_ENDPOINT', web3, key_name='TEST_KEY')
unsigned_hash = '0x0'
signed_message = wallet.sign_hash(unsigned_hash)
assert signed_message.signature == HexBytes('0x0')


def test_sgx_key_init():
with mock.patch('skale.wallets.sgx_wallet.SgxClient',
new=SgxClient):
Expand Down

0 comments on commit 87a49b2

Please sign in to comment.