I'm writing a contract based on the ring mixer contract from here https://ropsten.etherscan.io/address/0x5e10d764314040b04ac7d96610b9851c8bc02815
I've tested it with ganache. Everything worked fine until I tried to deploy it on my private network. Truffle gave me the following error:
"RingMixerV2" received a generic error from Geth that
can be caused by hitting revert in a contract constructor or running out of gas.
* Returned error: gas required exceeds allowance or always failing transaction.
* Try: + using the '–dry-run' option to reproduce this failure with clearer errors.
+ verifying that your gas is adequate for this deployment.`
I've cut down the codes as below but there's no luck. I was able to deploy it on Ropsten with Remix so I don't know what is wrong. I'm using truffle v5.0.2.
pragma solidity >0.4.99 <0.6.0;
contract RingMixerV2 {
//Debug Code
address public owner;
constructor() public {
//Debug Code
owner = msg.sender;
G1[0] = 1;
G1[1] = 2;
H = HashPoint(G1);
}
function Kill() public {
if ( (msg.sender != owner) && (owner != address(0)) ) revert();
selfdestruct(msg.sender);
}
//alt_bn128 constants
uint256[2] public G1;
uint256[2] public H;
uint256 constant public N = 0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001;
uint256 constant public P = 0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47;
//Used for Point Compression/Decompression
uint256 constant public ECSignMask = 0x8000000000000000000000000000000000000000000000000000000000000000;
uint256 constant public a = 0xc19139cb84c680a6e14116da060561765e05aa45a1c72a34f082305b61f3f52; // (p+1)/4
//Storage of Spent Key Images
mapping (uint256 => bool) public KeyImageUsed;
//Storage of Token Balances
mapping (address => uint256) public token_balance;
//Convenience tables for looking up acceptable mix-in keys
mapping (uint256 => uint256[]) public lookup_pubkey_by_balance;
mapping (uint256 => bool) public lookup_pubkey_by_balance_populated;
mapping (uint256 => uint256) public lookup_pubkey_by_balance_count;
function EvaluateCurve(uint256 x)
public view returns (uint256 y, bool onCurve)
{
uint256 y_squared = mulmod(x,x, P);
y_squared = mulmod(y_squared, x, P);
y_squared = addmod(y_squared, 3, P);
uint256 p_local = P;
uint256 a_local = a;
assembly {
//Get Free Memory Pointer
let p := mload(0x40)
//Store Data for Big Int Mod Exp Call
mstore(p, 0x20) //Length of Base
mstore(add(p, 0x20), 0x20) //Length of Exponent
mstore(add(p, 0x40), 0x20) //Length of Modulus
mstore(add(p, 0x60), y_squared) //Base
mstore(add(p, 0x80), a_local) //Exponent
mstore(add(p, 0xA0), p_local) //Modulus
//Call Big Int Mod Exp
let success := staticcall(sub(gas, 2000), 0x05, p, 0xC0, p, 0x20)
// Use "invalid" to make gas estimation work
//switch success case 0 { revert(p, 0xC0) }
switch success case 0 { invalid()}
//Store Return Data
y := mload(p)
}
//Check Answer
onCurve = (y_squared == mulmod(y, y, P));
}
//Return H = alt_bn128 evaluated at keccak256(p)
function HashPoint(uint256[2] memory p)
internal view returns (uint256[2] memory h)
{
bool onCurve;
h[0] = uint256(keccak256(abi.encodePacked(p[0], p[1]))) % N;
while(!onCurve) {
(h[1], onCurve) = EvaluateCurve(h[0]);
h[0]++;
}
h[0]--;
}
}
Any help would be appreciated.
Best Answer
You do not have byzantium enabled in your private network.
Check that you have
byzantiumBlock
set in the config section of your genesis.json.let success := staticcall(sub(gas, 2000), 0x05, p, 0xC0, p, 0x20)
is calling the precompiled contract at address 0x05, which is "Modular exponentiation (EIP 198)". This works only with byznatium enabled.