问题描述
这是我到目前为止的 F# 代码 -
let parseChainId rawTransaction =
let tx = TransactionFactory.CreateTransaction rawTransaction
let chainIdWithAddend = (IntTypeDecoder().DecodeBigInteger tx.Signature.V - BigInteger 35) / BigInteger 2
let addend = ???
let chainId = chainIdWithAddend - addend
chainId
但是,我确信这段代码在某些情况下是不完整的,因为我不知道如何确定 https://github.com/ethereum/EIPs/blob/master/EIPS/eip-155.md
中指定的 {0,1} 加数如果我能弄清楚如何确定加数,那么我相信上面的chain id提取算法就完成了。
解决方法
我对以太坊(或一般的密码学)一无所知,但从阅读链接的文档来看,我认为您的逻辑并不完全正确。你所说的“加数”被定义为一个 parity 值,它总是 0 或 1。这就是为什么规范说 v = CHAIN_ID * 2 + 35
或 v = CHAIN_ID * 2 + 36
,这意味着CHAIN_ID = (v - {35,36}) / 2
。
这是一个完整的猜测,但我认为您可以通过知道 v
是偶数还是奇数来确定奇偶校验。如果是奇数,您想减去 35,如果是偶数,您想减去 36,这样无论哪种情况,您都可以将结果精确地除以 2。
如果这是真的,我们可以像这样重写您的代码:
let v = IntTypeDecoder().DecodeBigInteger tx.Signature.V
let parity = (if v % 2 = 0 then 1 else 0)
let chainId = (v - BigInteger (35 + parity)) / BigInteger 2 // no remainder possible
我认为您还可以通过依赖 F# 的整数除法来丢弃余数来隐式奇偶校验:
let v = IntTypeDecoder().DecodeBigInteger tx.Signature.V
let chainId = (v - BigInteger 35) / BigInteger 2 // ignore remainder
不过,请注意一对一错误。我还没有测试(甚至尝试编译)任何这些代码。
另一个警告:以上所有似乎只适用于某些条件,例如当九个元素被散列而不是六个时。我假设您已经考虑到了这一点。