Skip to content
This repository has been archived by the owner on May 13, 2022. It is now read-only.

Commit

Permalink
Merge pull request #200 from loredanacirstea/contract-sign-lib
Browse files Browse the repository at this point in the history
Extract balance message hash logic for EIP712 in a separate contract
  • Loading branch information
LefterisJP authored Nov 28, 2017
2 parents f7818a9 + 81920e4 commit 0f1a374
Show file tree
Hide file tree
Showing 9 changed files with 185 additions and 14 deletions.
33 changes: 33 additions & 0 deletions contracts/contracts/MicroRaidenEIP712Helper.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
pragma solidity ^0.4.17;

contract MicroRaidenEIP712Helper {
/// @dev Returns the message hash used for creating the balance proof.
/// Used in the RaidenMicroTransferChannels contract.
/// Should be kept up-to-date with eth_signTypedData https://github.com/ethereum/EIPs/pull/712.
/// @param _receiver_address The address that receives tokens.
/// @param _open_block_number The block number at which a channel between the
/// sender and receiver was created.
/// @param _balance The amount of tokens owed by the sender to the receiver.
/// @param _contract RaidenMicroTransferChannels contract address
/// @return Hash of the message composed from the above parameters.
function getMessageHash(
address _receiver_address,
uint32 _open_block_number,
uint192 _balance,
address _contract)
public
pure
returns (bytes32)
{
// The variable names from below will be shown to the sender when signing
// the balance proof, so they have to be kept in sync with the Dapp client.
// The hashed strings should be kept in sync with this function's parameters
// (variable names and types)
bytes32 message_hash = keccak256(
keccak256('address receiver', 'uint32 block_created', 'uint192 balance', 'address contract'),
keccak256(_receiver_address, _open_block_number, _balance, _contract)
);

return message_hash;
}
}
31 changes: 21 additions & 10 deletions contracts/contracts/RaidenMicroTransferChannels.sol
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
pragma solidity ^0.4.17;

import "./Token.sol";
import "./lib/ECVerify.sol";
import './Token.sol';
import './lib/ECVerify.sol';
import './MicroRaidenEIP712Helper.sol';

/// @title Raiden MicroTransfer Channels Contract.
contract RaidenMicroTransferChannels {
Expand All @@ -21,6 +22,10 @@ contract RaidenMicroTransferChannels {
// Outdated contracts can still be used.
address public latest_version_address;

// Contract implementing EIP712 helper functions.
// Reason: EIP712 is not standardized at this moment and can have breaking changes.
MicroRaidenEIP712Helper public microraiden_eip712_helper;

Token public token;

mapping (bytes32 => Channel) public channels;
Expand Down Expand Up @@ -103,6 +108,13 @@ contract RaidenMicroTransferChannels {
latest_version_address = _latest_version_address;
}

/// @dev Sets the address for the contract-library implementing EIP712 helper functions.
/// @param _microraiden_eip712_helper The address for EIP712 helper contract.
function setEip712HelperContract(address _microraiden_eip712_helper) public isOwner {
require(addressHasCode(_microraiden_eip712_helper));
microraiden_eip712_helper = MicroRaidenEIP712Helper(_microraiden_eip712_helper);
}

/*
* Public helper functions (constant)
*/
Expand Down Expand Up @@ -137,16 +149,15 @@ contract RaidenMicroTransferChannels {
uint192 _balance,
bytes _balance_msg_sig)
public
constant
view
returns (address)
{
// The variable names from below will be shown to the sender when signing
// the balance proof, so they have to be kept in sync with the Dapp client.
// The hashed strings should be kept in sync with this function's parameters
// (variable names and types)
var message_hash = keccak256(
keccak256('address receiver', 'uint32 block_created', 'uint192 balance', 'address contract'),
keccak256(_receiver_address, _open_block_number, _balance, address(this))
// getMessageHash is a pure function
bytes32 message_hash = microraiden_eip712_helper.getMessageHash(
_receiver_address,
_open_block_number,
_balance,
address(this)
);

// Derive address from signature
Expand Down
21 changes: 19 additions & 2 deletions contracts/tests/fixtures_uraiden.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,25 @@ def get(token=None, transaction=None):


@pytest.fixture
def uraiden_instance(uraiden_contract):
return uraiden_contract()
def uraiden_instance(owner, uraiden_contract, eip712_instance):
uraiden_instance = uraiden_contract()
uraiden_instance.transact({'from': owner}).setEip712HelperContract(eip712_instance.address)
return uraiden_instance


@pytest.fixture()
def eip712_contract(chain, create_contract):
def get():
MicroRaidenEIP712Helper = chain.provider.get_contract_factory('MicroRaidenEIP712Helper')
eip712_contract = create_contract(MicroRaidenEIP712Helper, [])

return eip712_contract
return get


@pytest.fixture()
def eip712_instance(chain, eip712_contract):
return eip712_contract()


@pytest.fixture(params=['20', '223'])
Expand Down
2 changes: 2 additions & 0 deletions contracts/tests/test_channel_close.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@
get_uraiden_contract,
uraiden_contract,
uraiden_instance,
eip712_contract,
eip712_instance,
get_channel,
channel_settle_tests,
channel_pre_close_tests,
Expand Down
4 changes: 3 additions & 1 deletion contracts/tests/test_channel_create.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@
token_instance,
get_uraiden_contract,
uraiden_contract,
uraiden_instance
uraiden_instance,
eip712_contract,
eip712_instance
)


Expand Down
2 changes: 2 additions & 0 deletions contracts/tests/test_channel_topup.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
get_uraiden_contract,
uraiden_contract,
uraiden_instance,
eip712_contract,
eip712_instance,
get_channel
)
from tests.fixtures_uraiden import checkToppedUpEvent
Expand Down
4 changes: 3 additions & 1 deletion contracts/tests/test_ecverify.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@
token_instance,
get_uraiden_contract,
uraiden_contract,
uraiden_instance
uraiden_instance,
eip712_contract,
eip712_instance
)


Expand Down
100 changes: 100 additions & 0 deletions contracts/tests/test_eip712.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
import pytest
from ethereum import tester
from utils import sign
from tests.utils import balance_proof_hash
from eth_utils import force_bytes
from tests.fixtures import (
owner_index,
owner,
contract_params,
create_contract,
get_token_contract,
get_accounts,
create_accounts,
empty_address
)
from tests.fixtures_uraiden import (
token_contract,
token_instance,
get_uraiden_contract,
uraiden_contract,
uraiden_instance,
eip712_contract,
eip712_instance
)


def test_eip712_instance_fixture(uraiden_instance):
assert uraiden_instance.call().microraiden_eip712_helper()


def test_eip712_instance(owner, get_accounts, uraiden_contract, eip712_contract, eip712_instance):
uraiden_instance = uraiden_contract()
(A, B) = get_accounts(2)
assert uraiden_instance.call().microraiden_eip712_helper() == empty_address
uraiden_instance.transact({'from': owner}).setEip712HelperContract(eip712_instance.address)
assert uraiden_instance.call().microraiden_eip712_helper() == eip712_instance.address

# Test eip712_instance address change
eip712_instance2 = eip712_contract()
assert eip712_instance.address != eip712_instance2.address

# Only owner can change this
with pytest.raises(tester.TransactionFailed):
uraiden_instance.transact({'from': A}).setEip712HelperContract(eip712_instance2.address)

uraiden_instance.transact({'from': owner}).setEip712HelperContract(eip712_instance2.address)
assert uraiden_instance.call().microraiden_eip712_helper() == eip712_instance2.address


def test_get_message_hash(get_accounts, uraiden_instance, eip712_instance):
(A, B) = get_accounts(2)
receiver = '0x5601ea8445a5d96eeebf89a67c4199fbb7a43fbb'
block = 4804175
balance = 22000000000000000000

message_hash = sign.eth_signed_typed_data_message(
('address', ('uint', 32), ('uint', 192), 'address'),
('receiver', 'block_created', 'balance', 'contract'),
(receiver, block, balance, uraiden_instance.address)
)

eip712_message_hash = eip712_instance.call().getMessageHash(
receiver,
block,
balance,
uraiden_instance.address
)
assert force_bytes(eip712_message_hash) == message_hash

eip712_message_hash = eip712_instance.call().getMessageHash(
A,
block,
balance,
uraiden_instance.address
)
assert force_bytes(eip712_message_hash) != message_hash

eip712_message_hash = eip712_instance.call().getMessageHash(
receiver,
10,
balance,
uraiden_instance.address
)
assert force_bytes(eip712_message_hash) != message_hash

eip712_message_hash = eip712_instance.call().getMessageHash(
receiver,
block,
20,
uraiden_instance.address
)
assert force_bytes(eip712_message_hash) != message_hash

eip712_message_hash = eip712_instance.call().getMessageHash(
receiver,
block,
balance,
A
)
assert force_bytes(eip712_message_hash) != message_hash
2 changes: 2 additions & 0 deletions contracts/tests/test_uraiden.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
get_uraiden_contract,
uraiden_contract,
uraiden_instance,
eip712_contract,
eip712_instance,
get_channel,
event_handler
)
Expand Down

0 comments on commit 0f1a374

Please sign in to comment.