3

Provided address is invalid, the capitalization checksum test failed, or its an indrect IBAN address which can't be converted is not a dupe, this is about signing messages

My code:

const msgParams = [{
        type: 'string', name: 'Message', value: 'Hi, Alice!'  
     },{   type: 'uint32', name: 'A number', value: '1337'
      }];
      let from = Merchant.accounts[0];
      console.log(window.provider);
      let p = window.provider;
      console.log(Object.keys(window.web3));

      window.web3.eth.sign(from, msgParams, function(err, res) {
        console.log(err);
        console.log(res);
      });

(window.provider is the current provider.. window.web3 loses its current provider, see my other question window.web3.currentProvider is null for details)

Running this I get the error in the title

Metamask prompted to sign.. once. Now the prompt won't show. The signing prompt did have the Alice, 1337 data in it.

How do I sign a message with Metamask to get the encrypted string of that signed message?

EDIT: Merchant is my utility class for Metamask. The logged output of Merchant.accounts[0] is

0x2e290a50d3193753f156e5b0b12e4231bd568526

EDIT 2: I have tried this:

web3.eth.getAccounts(function(a,b) {
      Merchant.accounts = b;
      // alert("Saving accounts" + Merchant.accounts);
      console.log("Merchant accounts: " + Merchant.accounts);
      let x = web3.eth.getBalance;
      console.log(x);
    });



 toChecksumAddress (address) {
    address = address.toLowerCase().replace('0x', '')
    var hash = createKeccakHash('keccak256').update(address).digest('hex')
    var ret = '0x'

    for (var i = 0; i < address.length; i++) {
      if (parseInt(hash[i], 16) >= 8) {
        ret += address[i].toUpperCase()
      } else {
        ret += address[i]
      }
    }

    return ret
  }

reloadKeys() {
        const msgParams = [{
        type: 'string', name: 'Message', value: 'Hi, Alice!'  
     },{   type: 'uint32', name: 'A number', value: '1337'
      }];
      // Merchant.accounts[0]
      // let addr = 0x2E290A50d3193753F156e5b0b12e4231Bd568526;
      let from = this.toChecksumAddress(Merchant.accounts[0]);

      // window.web3.utils.toChecksumAddress();
      console.log(typeof(from));
      console.log(from);

      console.log(Object.keys(window.web3));

      window.web3.eth.sign(from, msgParams, function(err, res) {
        console.log(err);
        console.log(res);
      });

I still get this error.

4
  • Have you tried 0x2E290A50d3193753F156e5b0b12e4231Bd568526? (That has the correct capitalization checksum.)
    – user19510
    Jan 17, 2018 at 3:42
  • What.. is the difference?
    – user22075
    Jan 18, 2018 at 19:57
  • The difference is the capitalization.
    – user19510
    Jan 18, 2018 at 21:20
  • @smarx I tried let addr = "0x2E290A50d3193753F156e5b0b12e4231Bd568526"; let from = this.toChecksumAddress(addr); window.web3.eth.sign(from ... same error
    – user22075
    Jan 19, 2018 at 2:01

4 Answers 4

3

I think there are two issues:

  1. In Web3.js 1.0.0, the order of the parameters is web3.eth.sign(dataToSign, accountToSignWith, callback), but you're passing the account to sign with first.
  2. I don't think there's a way to sign objects like that, though maybe you know something I don't?

Try this to start with:

web3.eth.sign(web3.utils.sha3("test"), '0x2E290A50d3193753F156e5b0b12e4231Bd568526', function (err, result) { console.log(err, result); });

Make sure that works and then move on from there to signing what you want.

EDIT

Per https://github.com/MetaMask/metamask-extension/issues/1530, personal_sign may be a better option:

var fromAddress = '0x2E290A50d3193753F156e5b0b12e4231Bd568526';
web3.currentProvider.sendAsync({
  method: 'personal_sign',
  params: [
    web3.utils.fromAscii('hello world'),
    fromAddress,
  ],
  from: fromAddress,
}, function (err, result) {
  console.log(err, result);
});

EDIT2

Better yet, eth_signTypedData:

web3.currentProvider.sendAsync({
  method: 'eth_signTypedData',
  params: [
    [
      { type: 'string', name: 'Message', value: 'Hi, Alice!' },
      { type: 'uint32', name: 'A number', value: 1337 }
    ],
    fromAddress,
  ],
  from: fromAddress,
}, function (err, result) {
  console.log(err, result);
});
9
  • Hey, I'm able to sign a message when I switch the 2nd param to be one of my addresses! So I will mark this as correct for now. However, if I change the first parameter to a regular string eg. "test", when I click sign Metamask stays stuck spinning (odd). My intention behind this process is to sign a message proving that the message signer is the address they claim they are
    – user22075
    Jan 19, 2018 at 2:33
  • I believe the data to be signed has to be 32 bytes. When I try with a shorter string and inspect the MetaMask popup, I see an error logged to the console: "message length is invalid". See github.com/MetaMask/metamask-extension/issues/1530.
    – user19510
    Jan 19, 2018 at 2:36
  • Thanks, I don't get an error just a pinwheel in metamask
    – user22075
    Jan 19, 2018 at 2:38
  • If you right click on the MetaMask popup and click "inspect" and then view the console, you should see an error there that, when expanded, has the message I mentioned.
    – user19510
    Jan 19, 2018 at 2:41
  • 1
    And see my second edit for using signTypedData, which seems to be what you were after.
    – user19510
    Jan 19, 2018 at 2:49
1

Signing requires a checksummed address which can be generated using the web3 function toChecksumAddress. So your code needs to be adjusted as follows:

let from = web3.toChecksumAddress(Merchant.accounts[0]);

The checksum is calculated by capitalising certain hexadecimal letters according to the algorithm designed by Vitalk in EIP-55

4
  • Hello. web3.toChecksumADdress is not defined. web3.eth.iban.checksum var i = new web3.eth.iban("XE81ETHXREGGAVOFYORK"); is from the documentation ... I don't see a clear way to use it
    – user22075
    Jan 18, 2018 at 20:01
  • You might be using a beta version of web3 1.0.0. If so, web3.utils.toChecksumAddress instead.
    – user19510
    Jan 18, 2018 at 21:22
  • Hi @smarx , I am using beta and I tried web3.utils.toChecksumAddress. I get the same error.
    – user22075
    Jan 19, 2018 at 1:14
  • @smarx looks like there is a way to sign objects. medium.com/metamask/… , github.com/danfinlay/js-eth-personal-sign-examples << seems to work on the signing part, need to test verification
    – user22075
    Jan 19, 2018 at 2:36
0

The Remix transaction result address, that I copy to use as contract, in fact, are not valid anymore to web3 as contract hash (I don't know why). I went to etherscan.io and see all transactions from my address, click on the last "contract creation" that give me a different address than remix output.

I used that address and that error ends.


1 - Remix output hash from contract: 0x866e8ea2987873e4a0b985a5f408181c2b476cc9cf74f41dbb1e5e2231633821
2 - Etherscan transaction detail
3 - Contract address: 0x525d67ef6a08ad80c0956ca04af7eb2cd02a8bf0

1
  • 1
    #1 is the TX Hash. Transaction result != contract address
    – user22075
    May 12, 2018 at 15:19
0

had a similar problem, try copying the address directly from bscscan and passing it as a string e.g '0xE60000' no need for conversion again.

1
  • As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.
    – Community Bot
    Dec 13, 2021 at 22:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.