2

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.

  • Have you tried 0x2E290A50d3193753F156e5b0b12e4231Bd568526? (That has the correct capitalization checksum.) – user19510 Jan 17 '18 at 3:42
  • What.. is the difference? – quantumpotato Jan 18 '18 at 19:57
  • The difference is the capitalization. – user19510 Jan 18 '18 at 21:20
  • @smarx I tried let addr = "0x2E290A50d3193753F156e5b0b12e4231Bd568526"; let from = this.toChecksumAddress(addr); window.web3.eth.sign(from ... same error – quantumpotato Jan 19 '18 at 2:01
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);
});
  • 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 – quantumpotato Jan 19 '18 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 '18 at 2:36
  • Thanks, I don't get an error just a pinwheel in metamask – quantumpotato Jan 19 '18 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 '18 at 2:41
  • 1
    And see my second edit for using signTypedData, which seems to be what you were after. – user19510 Jan 19 '18 at 2:49
2

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

  • 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 – quantumpotato Jan 18 '18 at 20:01
  • You might be using a beta version of web3 1.0.0. If so, web3.utils.toChecksumAddress instead. – user19510 Jan 18 '18 at 21:22
  • Hi @smarx , I am using beta and I tried web3.utils.toChecksumAddress. I get the same error. – quantumpotato Jan 19 '18 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 – quantumpotato Jan 19 '18 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 is the TX Hash. Transaction result != contract address – quantumpotato May 12 '18 at 15:19

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.