首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何正确地使用ecrecover来验证Ethereum签名?

如何正确地使用ecrecover来验证Ethereum签名?
EN

Ethereum用户
提问于 2016-03-19 06:35:36
回答 2查看 7.2K关注 0票数 9

我一直在找出我在这里做错了什么,但我还没有运气。据我所知,我正确地使用了ecrecover,但我似乎无法得到签名的Ethereum地址。

使用geth会话,我创建并签名了一个散列,检索每个Javascript的r、v和S值:

代码语言:javascript
复制
> var foobar = web3.sha3('foobar')
undefined
> foobar
"38d18acb67d25c8bb9942764b62f18e17054f66a817bd4295423adf9ed98873e"
> var foo = eth.sign('0x803c84d8b64be30554e2edb9c61b50bc78a7231f', foobar).slice(2)
undefined
> var r = foo.slice(0, 64); var s = foo.slice(64, 128); var v = foo.slice(128);
> v
"00"
> r
"723841761d213b60ac1cbf063207cbeba6c2725bcaf7c189e63f13d93fc1dc07"
> s
"789d1dd423d25f0772d2748d60f7e4b81bb14d086eba8e8e8efb6dcff8a4ae02"

然后,我将这些值转化为一个可靠的测试:

代码语言:javascript
复制
import 'dapple/test.sol';

contract ECRecoverTest is Test {
  function testRecovery() {
    bytes32 foobar = 0x38d18acb67d25c8bb9942764b62f18e17054f66a817bd4295423adf9ed98873e;
    uint8 v = 0x00;
    bytes32 r = 0x723841761d213b60ac1cbf063207cbeba6c2725bcaf7c189e63f13d93fc1dc07;
    bytes32 s = 0x789d1dd423d25f0772d2748d60f7e4b81bb14d086eba8e8e8efb6dcff8a4ae02;

    log_address(ecrecover(foobar, v, r, s));
  }
}

我希望看到我的签名地址(0x803c84d8b64be30554e2edb9c61b50bc78a7231f)被记录下来,但我看到的只是:

代码语言:javascript
复制
$ dapple test
Testing...
Using local solc installation...

ECRecoverTest
  test recovery
  LOG:  log_address
  LOG:    val: 0xb62f18e17054f66a817bd4295423adf9ed98873e
  Passed!

在签名之前,我还尝试将散列转换为ASCII,并在十六进制前缀加上"0x“,以防问题是由于eth.sign函数造成的,而不是摸索数据将被视为十六进制值。

有什么想法吗?我已经在pyethereum中查看了测试用例,以确保我正确地使用了它,并且我已经看到了关于这个StackExchange的另一个问题。不过,似乎并没有取得什么成功。

EN

回答 2

Ethereum用户

发布于 2016-03-19 07:19:26

我不确定这是否是你唯一的问题,但至少你得到的v值是错的,应该是27或28。不幸的是,许多签名函数都不能给您,但是您可以尝试两者,看看哪一个给出了正确的地址。没有必要使用十六进制的"v“-只是字面上喂它27或28作为一个整数。

另一个让我困惑了一段时间的小技巧是,如果您在哈希传递到ecrecover时要散列字节,那么您必须确保您在签名时也是散列字节。我不知道你说得对不对

这里有一个例子,如果这有帮助的话:https://github.com/edmundedgar/realitykeys-examples-ethereum/tree/master/sponsor

票数 4
EN

Ethereum用户

发布于 2016-08-07 09:38:03

这个要旨是如何使用ecrecover的一个很好的例子。它使用程序集过滤出签名的r、s、v部分,并将其填充到ecrecover函数中。

代码语言:javascript
复制
assembly {
            r := mload(add(sig, 32))
            s := mload(add(sig, 64))
            // Here we are loading the last 32 bytes, including 31 bytes
            // of 's'. There is no 'mload8' to do this.
            //
            // 'byte' is not working due to the Solidity parser, so lets
            // use the second best option, 'and'
            v := and(mload(add(sig, 65)), 255)
        }

还请注意Edmund提到的v 27,28部分。

票数 4
EN
页面原文内容由Ethereum提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://ethereum.stackexchange.com/questions/2171

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档