Authereum
  • Introduction
  • Getting started
  • Live demos
  • Dapps using Authereum
  • Install
  • Integration
  • Web3 provider
  • Ethers Signer
  • StarkWare Provider
  • SDK
  • API Keys
  • Batched transactions
  • Verifying signatures
  • Testing
  • Browser compatibility
  • Contributing
  • Bug reports
  • FAQ
  • Dictionary
  • On the Web
  • Telegram Admins
  • Assets
Powered by GitBook
On this page
  • Verifying Signatures with EIP-1271
  • Using Web3.js
  • Using ethers.js
  • Using NPM package helper
  • Resources

Was this helpful?

Verifying signatures

PreviousBatched transactionsNextTesting

Last updated 5 years ago

Was this helpful?

Verifying Signatures with EIP-1271

Since contracts can’t generate signatures therefore ecrecoverwon’t work if the address is a contract, then the contract-based account needs to use the standard to verify signatures for contracts.

Verifying contract-based account signatures require calling the EIP1271 isValidSignature( data, signature) method on the account contract. Authereum, Dapper wallet, 0xProject, and a few others are already using EIP1271 to verify signatures where the "recovered address" is a contract address.

Below are examples of how to verify Authereum dapp key signatures:

Using Web3.js

const Web3 = require('web3')

const provider = new Web3.providers.HttpProvider('https://kovan.infura.io')
const web3 = new Web3(provider)

const eip1271Abi = [
  {
    "constant": true,
    "inputs": [
      {
        "name": "_messageHash",
        "type": "bytes"
      },
      {
        "name": "_signature",
        "type": "bytes"
      }
    ],
    "name": "isValidSignature",
    "outputs": [
      {
        "name": "magicValue",
        "type": "bytes4"
      }
    ],
    "payable": false,
    "stateMutability": "view",
    "type": "function"
  }
]

const account = '0x99bd0006D13542A0917Cf8F2F986Ca7667b84268'
const data = '0x47173285a8d7341e5e972fc677286384f802f8ef42a5ec5f03bbfa254cb01fad'
const signature = '0x0304494527023df3a811f5ad61aa35177a4455eb4bf098561f9380a574915f4c1ff4a5fc653afdfc086dcc9662848097703d18b82156618ccec1e5c9da7623e51b4760269d07f9a074dc2d6ab10cf52ff77852662e40fbb4b27289126a5bb538271e147c0952204161d710bb070a6e470b0b1ef65d11f1dc074e235e3dfaef00ae1b'

const magicValue = '0x20c13b0b'
const instance = await new web3.eth.Contract(eip1271Abi, account)
const result = await instance.methods.isValidSignature(data, signature).call()
const verified = (result === magicValue)

console.log(verified) // true

The isValidSignature method returns a magic which is computed from bytes4(keccak256("isValidSignature(bytes,bytes)"). The reason for returning a magic value to avoid accidentally returning true.

Using ethers.js

const ethers = require('ethers')

const provider = ethers.getDefaultProvider('kovan')

const eip1271Abi = [
  {
    "constant": true,
    "inputs": [
      {
        "name": "_messageHash",
        "type": "bytes"
      },
      {
        "name": "_signature",
        "type": "bytes"
      }
    ],
    "name": "isValidSignature",
    "outputs": [
      {
        "name": "magicValue",
        "type": "bytes4"
      }
    ],
    "payable": false,
    "stateMutability": "view",
    "type": "function"
  }
]

const account = '0x99bd0006D13542A0917Cf8F2F986Ca7667b84268'
const data = '0x47173285a8d7341e5e972fc677286384f802f8ef42a5ec5f03bbfa254cb01fad'
const signature = '0x0304494527023df3a811f5ad61aa35177a4455eb4bf098561f9380a574915f4c1ff4a5fc653afdfc086dcc9662848097703d18b82156618ccec1e5c9da7623e51b4760269d07f9a074dc2d6ab10cf52ff77852662e40fbb4b27289126a5bb538271e147c0952204161d710bb070a6e470b0b1ef65d11f1dc074e235e3dfaef00ae1b'

const magicValue = '0x20c13b0b'
const instance = new ethers.Contract(account, eip1271Abi, provider)
const result = await instance.isValidSignature(data, signature)
const verified = (result === magicValue)

console.log(verified) // true

Using NPM package helper

const validateContractSignature = require('is-valid-signature')
const Web3 = require('web3')

const provider = new Web3.providers.HttpProvider('https://kovan.infura.io')

const account = '0x99bd0006D13542A0917Cf8F2F986Ca7667b84268'
const data = '0x47173285a8d7341e5e972fc677286384f802f8ef42a5ec5f03bbfa254cb01fad'
const signature = '0x0304494527023df3a811f5ad61aa35177a4455eb4bf098561f9380a574915f4c1ff4a5fc653afdfc086dcc9662848097703d18b82156618ccec1e5c9da7623e51b4760269d07f9a074dc2d6ab10cf52ff77852662e40fbb4b27289126a5bb538271e147c0952204161d710bb070a6e470b0b1ef65d11f1dc074e235e3dfaef00ae1b'

const verified = await validateContractSignature(account, data, signature, provider)

console.log(verified) // true

Resources

For convenience, there's the NPM package you can use to validate signature for account contracts.

NPM Module

EIP1271
is-valid-signature
EIP-1271 specification
ERC-1271 : Standard Signature Validation Method for Contracts
is-valid-signature
Signature-based authentication server example