jennifer.lindgren93
30 days ago  Karma: 10
How to recover a PlasmaChain signer address from a signature?

I'm working on a PlasmaChain DApp and I want to send a signature, signed by a PlasmaChain address, and check that it is equal to the owner of an ERC721 token on the PlasmaChain. However, I am having trouble recovering the PlasmaChain signer in my contract, does anyone know how to do this?
I tried using the regular method (recreate the message, split signature, ecrecover, see my contract below) but it doesn't seem to work. I also can't get the address using the same method in javascript. I'm using LoomProvider and universal transaction signing. This is my PlasmaChain contract:
```solidity
pragma solidity 0.5.0;

import './EthicketsDappChain.sol';

contract EthicketsValidator {

address public ethicketsAddress;
mapping(uint256=>bool) public isTicketRedeemed;

constructor(address _ethicketsAddress) public {
ethicketsAddress = _ethicketsAddress;
}

function validate(
address owner,
uint256 ethicketId,
bytes memory signature,
bool redeem)
public returns (bool) {
if (isTicketRedeemed[ethicketId]) {
return false;
}

// Recreate the message signed on the client
bytes32 message = prefixed(keccak256(abi.encodePacked(this, owner, ethicketId)));
EthicketsDappChain ethickets = EthicketsDappChain(ethicketsAddress);
require(ethickets.ownerOf(ethicketId) == recoverSigner(message, signature),
'Signer has to own the ethicket.');
if (redeem) {
isTicketRedeemed[ethicketId] = true;
}
return true;
}

function splitSignature(bytes memory signature)
internal pure returns (uint8 v, bytes32 r, bytes32 s) {
require(signature.length == 65);
assembly {
// first 32 bytes, after the length prefix.
r := mload(add(signature, 32))
// second 32 bytes.
s := mload(add(signature, 64))
// final byte (first byte of the next 32 bytes).
v := byte(0, mload(add(signature, 96)))
}
return (v, r, s);
}

function recoverSigner(bytes32 message, bytes memory signature)
internal pure returns (address) {
(uint8 v, bytes32 r, bytes32 s) = splitSignature(signature);
return ecrecover(message, v, r, s);
}

/// builds a prefixed hash to mimic the behavior of eth_sign.
function prefixed(bytes32 hash) internal pure returns (bytes32) {
return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", hash));
}
}

and I sign with:
typescript
async signValidate(ethicketId: number) {
const hash = '0x' + ethereumjsAbi.soliditySHA3(
['address', 'address', 'uint256'],
[
this.getEthicketsDappChainAddress(),
this.dappChainAccountAddress,
ethicketId
]
).toString('hex');
const sig = await this.web3loom.eth.sign(hash, this.dappChainAccountAddress);
return sig;
}

where web3loom is:
typescript
this.loomProvider = new LoomProvider(this.client, privateKey);
this.loomProvider.callerChainId = this.callerChainId;
this.loomProvider.setMiddlewaresForAddress(mainnetAddress.local.toString(), [
new NonceTxMiddleware(
new Address(
this.callerChainId,
LocalAddress.fromHexString(this.mainnetAccountAddress)
),
this.client
),
new SignedEthTxMiddleware(signer)
]);
this.web3loom = await new Web3(this.loomProvider);
```

Thankful for any tips on this!

en
#loom
#solidity
plasma chain
#ethereum
jennifer.lindgren93
30 days ago  Karma: 10
How to recover a PlasmaChain signer address from a signature?

I'm working on a PlasmaChain DApp and I want to send a signature, signed by a PlasmaChain address, and check that it is equal to the owner of an ERC721 token on the PlasmaChain. However, I am having trouble recovering the PlasmaChain signer in my contract, does anyone know how to do this?
I tried using the regular method (recreate the message, split signature, ecrecover, see my contract below) but it doesn't seem to work. I also can't get the address using the same method in javascript. I'm using LoomProvider and universal transaction signing. This is my PlasmaChain contract:
```solidity
pragma solidity 0.5.0;

import './EthicketsDappChain.sol';

contract EthicketsValidator {

address public ethicketsAddress;
mapping(uint256=>bool) public isTicketRedeemed;

constructor(address _ethicketsAddress) public {
ethicketsAddress = _ethicketsAddress;
}

function validate(
address owner,
uint256 ethicketId,
bytes memory signature,
bool redeem)
public returns (bool) {
if (isTicketRedeemed[ethicketId]) {
return false;
}

// Recreate the message signed on the client
bytes32 message = prefixed(keccak256(abi.encodePacked(this, owner, ethicketId)));
EthicketsDappChain ethickets = EthicketsDappChain(ethicketsAddress);
require(ethickets.ownerOf(ethicketId) == recoverSigner(message, signature),
'Signer has to own the ethicket.');
if (redeem) {
isTicketRedeemed[ethicketId] = true;
}
return true;
}

function splitSignature(bytes memory signature)
internal pure returns (uint8 v, bytes32 r, bytes32 s) {
require(signature.length == 65);
assembly {
// first 32 bytes, after the length prefix.
r := mload(add(signature, 32))
// second 32 bytes.
s := mload(add(signature, 64))
// final byte (first byte of the next 32 bytes).
v := byte(0, mload(add(signature, 96)))
}
return (v, r, s);
}

function recoverSigner(bytes32 message, bytes memory signature)
internal pure returns (address) {
(uint8 v, bytes32 r, bytes32 s) = splitSignature(signature);
return ecrecover(message, v, r, s);
}

/// builds a prefixed hash to mimic the behavior of eth_sign.
function prefixed(bytes32 hash) internal pure returns (bytes32) {
return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", hash));
}
}

and I sign with:
typescript
async signValidate(ethicketId: number) {
const hash = '0x' + ethereumjsAbi.soliditySHA3(
['address', 'address', 'uint256'],
[
this.getEthicketsDappChainAddress(),
this.dappChainAccountAddress,
ethicketId
]
).toString('hex');
const sig = await this.web3loom.eth.sign(hash, this.dappChainAccountAddress);
return sig;
}

where web3loom is:
typescript
this.loomProvider = new LoomProvider(this.client, privateKey);
this.loomProvider.callerChainId = this.callerChainId;
this.loomProvider.setMiddlewaresForAddress(mainnetAddress.local.toString(), [
new NonceTxMiddleware(
new Address(
this.callerChainId,
LocalAddress.fromHexString(this.mainnetAccountAddress)
),
this.client
),
new SignedEthTxMiddleware(signer)
]);
this.web3loom = await new Web3(this.loomProvider);
```

Thankful for any tips on this!

en
#loom
#solidity
plasma chain
#ethereum

Earn tokens by posting and answering questions about blockchain!
Karma to eth
BE THE FIRST TO ANSWER