首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么TornadoCash智能契约调用address = 8?

为什么TornadoCash智能契约调用address = 8?
EN

Ethereum用户
提问于 2023-04-14 14:38:09
回答 1查看 20关注 0票数 1

我试图了解zkSNARK是如何在TornadoCash中工作的。我在代码中遇到了一些我无法理解的棘手问题。我在地址:https://etherscan.io/address/0xce172ce1f20ec0b3728c9965470eaf994a03557a#code#L1上研究了这个智能契约的代码

有一种配对方法,它使用内存,而不是静态调用:

代码语言:javascript
复制
    /* @return The result of computing the pairing check
     *         e(p1[0], p2[0]) *  .... * e(p1[n], p2[n]) == 1
     *         For example,
     *         pairing([P1(), P1().negate()], [P2(), P2()]) should return true.
     */
    function pairing(
        G1Point memory a1,
        G2Point memory a2,
        G1Point memory b1,
        G2Point memory b2,
        G1Point memory c1,
        G2Point memory c2,
        G1Point memory d1,
        G2Point memory d2
    ) internal view returns (bool) {
        G1Point[4] memory p1 = [a1, b1, c1, d1];
        G2Point[4] memory p2 = [a2, b2, c2, d2];

        uint256 inputSize = 24;
        uint256[] memory input = new uint256[](inputSize);

        for (uint256 i = 0; i < 4; i++) {
            uint256 j = i * 6;
            input[j + 0] = p1[i].X;
            input[j + 1] = p1[i].Y;
            input[j + 2] = p2[i].X[0];
            input[j + 3] = p2[i].X[1];
            input[j + 4] = p2[i].Y[0];
            input[j + 5] = p2[i].Y[1];
        }

        uint256[1] memory out;
        bool success;

        // solium-disable-next-line security/no-inline-assembly
        assembly {
            success := staticcall(sub(gas(), 2000), 8 /*??? why ???*/, add(input, 0x20), mul(inputSize, 0x20), out, 0x20)
            // Use "invalid" to make gas estimation work
            switch success case 0 { invalid() }
        }

        require(success, "pairing-opcode-failed");

        return out[0] != 0;
    }

那么,我的问题是为什么这个代码会在地址8进行静态测试呢?什么是魔法常数?

EN

回答 1

Ethereum用户

回答已采纳

发布于 2023-04-15 04:50:53

地址8是一对“预编译合同”

更具体地说,EIP-197:椭圆曲线alt上最优ate配对检查的预编译合同_bn128

对于素数阶为Q的循环群G,设log_P: G -> F_q是该群上关于生成元P的离散对数,即log_P( x )是最小的非负整数n,使得n*P=x。这两个发生器都具有相同的素数阶q。

代码语言:javascript
复制
Input: (a1, b1, a2, b2, ..., ak, bk) from (G_1 x G_2)^k
Output: If the length of the input is incorrect or any of the inputs are not elements of
        the respective group or are not encoded correctly, the call fails.
        Otherwise, return one if
        log_P1(a1) * log_P2(b1) + ... + log_P1(ak) * log_P2(bk) = 0
        (in F_q) and zero else.

注意,k是根据输入的长度确定的。在下面的编码部分之后,k是输入的长度除以192。如果输入长度不是192的倍数,则调用失败。空输入是有效的,并导致返回一个。为了检查输入是G_1的一个元素,验证坐标的编码并检查它们是否满足曲线方程(或者是无穷大的编码)是足够的。对于21888242871839275222246405745257275088548364400416034343698204186575808495617.,除此之外,元素的顺序必须检查为等于组顺序q= G_2

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

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

复制
相关文章

相似问题

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