0xProject / 0x-monorepo

0x protocol monorepo - includes our smart contracts and many developer tools
Other
1.41k stars 467 forks source link

python: getting signature using private key #2748

Closed CooleRnax closed 3 years ago

CooleRnax commented 3 years ago

Expected Behavior

w3.eth.sign() approach is deprecated, I'm trying to get signature in the new way:

signature = w3.eth.account.sign_message(encode_defunct(hexstr=order_hash_hex), private_key)

but when I post an order api rejects it because of the invalid signature

Steps to Reproduce (for bugs)

order = zero_ex.contract_wrappers.exchange.types.Order(
     makerAddress=maker_address,
     takerAddress='0x0000000000000000000000000000000000000000',
     makerAssetAmount=amount_in,
     takerAssetAmount=amount_out,
     expirationTimeSeconds=expire,

     makerAssetData=asset_data_utils.encode_erc20(token_in),
     takerAssetData=asset_data_utils.encode_erc20(token_out),
     senderAddress='0x0000000000000000000000000000000000000000',
     feeRecipientAddress='0x1000000000000000000000000000000000000011',

     salt=int(time.time()),
     makerFee=0,
     takerFee=0,
     makerFeeAssetData='0x',
     takerFeeAssetData='0x',

)

order_hash_hex = zero_ex.order_utils.generate_order_hash_hex(
     order, contract_addresses.exchange, w3.eth.chainId
)

signature = w3.eth.account._sign_hash(order_hash_hex, private_key)

relayer.post_order(
    signed_order_schema=order_to_jsdict(
        order=order,
        exchange_address=contract_addresses.exchange,
        signature=signature.signature.hex(),
        chain_id=w3.eth.chainId,
    )
)[1]

Context

I'm trying to sign and send transaction

Your Environment

Windows | python 3.7

| Package | Version | 0x-contract-wrappers | 2.0.0 0x-order_utils | 4.0.0

| Network | mainnet

CooleRnax commented 3 years ago

I was coping valid order generated by 1inch.. I implemented sign_hash function part and almost was able to sign it, but the last character is different. What am I doing wrong?

I'm getting signature: 0x1ced85d5cd22c76361e376afb66d2c06dc304bddcd0454d0f9b9a1cba1c93bf082226f26f5e77dfd23k515f91fe0c49n92e80e912bf06247d5b50e61en6493d6c103

But valid signature is: 0x1ced85d5cd22c76361e376afb66d2c06dc304bddcd0454d0f9b9a1cba1c93bf082226f26f5e77dfd23k515f91fe0c49n92e80e912bf06247d5b50e61en6493d6c102

ec_signature = _parse_signature_hex_as_rsv(signature.signature.hex())
if ec_signature["v"] in valid_v_param_values:
    signature_as_vrst_hex = (
        _convert_ec_signature_to_vrs_hex(ec_signature)
        + _Constants.SignatureType.ETH_SIGN.value.to_bytes(
            1, byteorder="big"
        ).hex()
    )
    signature_as_vrst_hex

ec_signature = _parse_signature_hex_as_vrs(signature.signature.hex())
if ec_signature["v"] in valid_v_param_values:
    signature_as_vrst_hex = (
        _convert_ec_signature_to_vrs_hex(ec_signature)
        + _Constants.SignatureType.ETH_SIGN.value.to_bytes(
            1, byteorder="big"
        ).hex()
    )
    signature_as_vrst_hex
CooleRnax commented 3 years ago

ended with a solution:

        signature_as_vrst_hex = (
            zero_ex.order_utils._convert_ec_signature_to_vrs_hex(
                ec_signature) + '02'
        )